Skip to main content

Security Hardening

Rsync backups protect your data from loss — but if the backups themselves are insecure, they become a target for attackers. Hardening your rsync operations means protecting data in transit, data at rest, and access to backup systems.

info

For SSH setup, key-based authentication, and transport security details, see Secure Transfer.

Principle of Least Privilege

Dedicated Backup User

Never run rsync as root. Create a dedicated user with minimal permissions:

# Create backup user
sudo useradd -r -m -s /bin/bash backupuser
sudo mkdir -p /backup
sudo chown backupuser:backupuser /backup

# Grant read access to web files
sudo usermod -aG www-data backupuser

Restrict SSH Access

Limit the backup user to rsync operations only:

~backupuser/.ssh/authorized_keys
command="rsync --server --sender -vlogDtprze.iLsfxCIvu . /var/www/html/",no-port-forwarding,no-X11-forwarding,no-pty ssh-ed25519 AAAA... backup-key

This allows only rsync over SSH — no shell access, no port forwarding.

Encrypting Backups at Rest

GPG Encryption

# Encrypt a backup archive
tar -czf - /backup/latest/ | \
gpg --symmetric --cipher-algo AES256 \
--output /tmp/backup-$(date +%F).tar.gz.gpg

# Decrypt when needed
gpg --decrypt /tmp/backup-$(date +%F).tar.gz.gpg | tar -xzf -

Automated Encryption in Backup Scripts

#!/bin/bash
# encrypted-backup.sh
set -euo pipefail

GPG_PASSPHRASE_FILE="/root/.backup-passphrase"
BACKUP_DIR="/backup/$(date +%F)"

# Step 1: rsync backup
rsync -av --link-dest=/backup/latest \
/var/www/html/ "$BACKUP_DIR/files/"

# Step 2: Database export
mysqldump --defaults-file=/root/.my.cnf \
--single-transaction --all-databases | \
gzip > "$BACKUP_DIR/databases.sql.gz"

# Step 3: Create encrypted archive for offsite
tar -czf - "$BACKUP_DIR/" | \
gpg --batch --symmetric --cipher-algo AES256 \
--passphrase-file "$GPG_PASSPHRASE_FILE" \
--output "/offsite/backup-$(date +%F).tar.gz.gpg"

ln -sfn "$BACKUP_DIR" /backup/latest

Excluding Sensitive Files

Prevent sensitive data from being synced to less-secure destinations:

rsync-secure-exclude.txt
# Credentials
.env
*.pem
*.key
*.p12
wp-config.php

# Database dumps (encrypt separately)
*.sql
*.sql.gz

# SSH keys
.ssh/
id_rsa*

# Application secrets
config/secrets.yml
config/master.key
rsync -avz --exclude-from='rsync-secure-exclude.txt' \
/var/www/html/ user@remote:/backups/www/

Network Security

Firewall Rules

Restrict rsync access to known IPs:

# Allow rsync only from backup server IP
sudo ufw allow from 10.0.0.50 to any port 22 proto tcp comment "Backup server SSH"
sudo ufw deny 873 comment "Block rsync daemon port"

Non-Standard SSH Port

rsync -avz -e "ssh -p 2222" /var/www/html/ user@backup:/backups/

Rsync Daemon Security (If Used)

/etc/rsyncd.conf
[backups]
path = /backup
read only = yes
auth users = backupuser
secrets file = /etc/rsyncd.secrets
hosts allow = 10.0.0.0/24
hosts deny = *
# Secrets file format: username:password
echo "backupuser:strong_password_here" | sudo tee /etc/rsyncd.secrets
sudo chmod 600 /etc/rsyncd.secrets

Audit and Monitoring

Log All Rsync Operations

rsync -avz --log-file=/var/log/rsync/backup.log \
/var/www/html/ user@backup:/backups/

# Review for anomalies
grep -i "error\|denied\|failed" /var/log/rsync/backup.log

Monitor for Unauthorized Access

# Check SSH login attempts for backup user
grep "backupuser" /var/log/auth.log | tail -20

# Monitor rsync daemon connections
grep "rsync" /var/log/rsyncd.log | tail -20

Fail2Ban for SSH Protection

/etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 3600

Security Checklist

  • SSH key authentication (disable password login)
  • Dedicated backup user with minimal permissions
  • Backups encrypted before offsite transfer
  • Sensitive files excluded from general backups
  • Firewall restricts SSH to known IPs
  • Rsync daemon disabled (use SSH instead) or properly secured
  • Log all backup operations
  • Fail2Ban protecting SSH

Common Pitfalls

PitfallConsequencePrevention
Running rsync as rootCompromised backup = full server accessUse dedicated backup user
Unencrypted offsite backupsData breach if cloud storage compromisedEncrypt before uploading
Password-based SSH for automationWeak authentication for automated jobsUse SSH keys exclusively
.env / credentials in backupSecrets exposed in backup storageExclude sensitive files
No firewall rulesAny IP can attempt SSHRestrict to known IPs
No audit loggingUnauthorized access goes undetectedLog and monitor all operations

Quick Reference

# Rsync with SSH key
rsync -avz -e "ssh -i ~/.ssh/backup_key" /src/ backup@server:/dest/

# Encrypt backup for offsite
tar -czf - /backup/latest/ | gpg -c --cipher-algo AES256 > backup.tar.gz.gpg

# Exclude sensitive files
rsync -avz --exclude-from='rsync-secure-exclude.txt' /src/ remote:/dest/

# Restrict backup user SSH
# In authorized_keys: command="rsync --server ..." ssh-ed25519 ...

# Check backup logs for anomalies
grep -i "error\|denied" /var/log/rsync/backup.log

What's Next