Understanding Environment Differences: Why SSL Certificates Fail When Moving from crontab to /etc/cron.hourly in Linux


2 views

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:

  1. Root crontab: Uses /root/.subversion/auth/
  2. 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