When migrating a Subversion backup script from root's crontab to /etc/cron.hourly, many administrators encounter SSL certificate validation failures. This occurs because the execution environment differs significantly between these two scheduling methods.
The key distinction lies in how environment variables are loaded:
Root crontab inherits a minimal set of environment variables from the user's profile, while /etc/cron.* directories execute scripts through run-parts with an even more restricted environment.
# Typical environment in root crontab:
HOME=/root
LOGNAME=root
PATH=/usr/bin:/bin
SHELL=/bin/sh
# Environment in /etc/cron.hourly:
PATH=/usr/bin:/bin
SHELL=/bin/sh
Subversion stores accepted SSL certificates in the user's home directory (~/.subversion/auth/svn.ssl.server/). When run through /etc/cron.hourly:
- The HOME environment variable may not be properly set
- The script runs with different permissions
- The SSL certificate cache isn't accessible
Here are three approaches to resolve this:
1. Explicit Certificate Acceptance
Pre-accept the certificate manually or via script:
sudo -u svnuser svn ls https://svn.example.com/repo \
--non-interactive \
--trust-server-cert \
--username backupuser \
--password "password"
2. Environment Wrapper Script
Create a wrapper that sets the proper environment:
#!/bin/bash
export HOME=/root
export LANG=en_US.UTF-8
export PATH=/usr/local/bin:/usr/bin:/bin
/path/to/your/actual/backup-script.sh
3. Direct run-parts Configuration /h2>
Modify the run-parts behavior in /etc/crontab:
17 * * * * root HOME=/root /usr/bin/run-parts /etc/cron.hourly
To diagnose environment issues, add this to your script:
env > /tmp/cron.env
whoami >> /tmp/cron.env
pwd >> /tmp/cron.env
On CentOS with anacron, additional considerations apply:
# /etc/anacrontab example:
@hourly 10 cron.hourly HOME=/root /bin/bash /etc/cron.hourly/your-script
When moving an SVN backup script from root's crontab to /etc/cron.hourly
, the sudden SSL certificate prompts reveal fundamental differences in execution environments. The root cause lies in how these scheduling methods initialize shell environments.
Compare the environments with this diagnostic script:
#!/bin/bash
env > /tmp/env_comparison.txt
printenv | sort >> /tmp/env_comparison.txt
Typical missing variables in cron.hourly include:
HOME
(points to /root for crontab but undefined in cron.hourly)USER
(root vs. nobody)SVN_SSH
(if using SSH tunneling)LANG
/LC_*
(affects certificate validation)
Subversion stores accepted certificates in ~/.subversion/auth/
. When run through:
- Root crontab: Uses
/root/.subversion/auth/
- cron.hourly: Looks for
/nonexistent/.subversion/auth/
Modify your backup script to include certificate acceptance:
#!/bin/bash
# Force HOME for certificate cache
export HOME=/root
# Non-interactive certificate acceptance
svnsync sync file:///path/to/repo \
--config-option servers:global:ssl-trust-default-ca=yes \
--config-option servers:global:ssl-authority-files=/path/to/cert.pem \
--non-interactive \
--no-auth-cache \
--trust-server-cert
Run this once as root to precache certificates:
sudo -u root svn ls https://svn.example.com/repo
# Accept certificate when prompted
For production systems, consider:
- Creating a dedicated backup user with proper
~/.subversion
directory - Using certificate pinning with
--trust-server-cert
- Setting strict permissions on the auth directory:
chmod 700 /root/.subversion
Add this to your script to log environment issues:
{
echo "=== ENV DUMP ==="
env
echo "=== SVN VERSION ==="
svn --version --quiet
echo "=== ATTEMPTING SYNC ==="
svnsync sync file:///path/to/repo 2>&1
} >> /var/log/svnsync.log 2>&1