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
| Pitfall | Consequence | Prevention |
|---|---|---|
| Running rsync as root | Compromised backup = full server access | Use dedicated backup user |
| Unencrypted offsite backups | Data breach if cloud storage compromised | Encrypt before uploading |
| Password-based SSH for automation | Weak authentication for automated jobs | Use SSH keys exclusively |
.env / credentials in backup | Secrets exposed in backup storage | Exclude sensitive files |
| No firewall rules | Any IP can attempt SSH | Restrict to known IPs |
| No audit logging | Unauthorized access goes undetected | Log 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
- Secure Transfer — SSH setup and transport encryption
- Ownership and Permissions — File permission management
- Backup Strategies — Design your backup architecture