Secure Rsync: The Complete Hardening Guide
1. Purpose and Overview
Rsync is a powerful utility for efficiently transferring and synchronizing files across systems. While valued for its speed and efficiency, improperly configured rsync installations can present significant security risks. This guide provides comprehensive instructions for deploying rsync with enhanced security controls to protect data confidentiality, integrity, and availability.
Recent security vulnerabilities in rsync (including critical CVE-2024-12084 with CVSS 9.8) underscore the need for proper security hardening when deploying this tool. This guide will help administrators configure rsync in a security-focused manner to mitigate potential threats.
2. Table of Contents
- Purpose and Overview
- Table of Contents
- Installation
- Configuration
- Security Best Practices
- Integrations
- Testing and Validation
- References and Further Reading
- Appendices
3. Installation
Linux (Debian/Ubuntu)
1
2
3
4
5
6
7
8
| # Update package lists
sudo apt update
# Install rsync
sudo apt install rsync
# Verify installation
rsync --version
|
Linux (RHEL/CentOS/Fedora)
1
2
3
4
5
| # Install rsync
sudo dnf install rsync
# Verify installation
rsync --version
|
macOS
1
2
3
4
5
| # Using Homebrew
brew install rsync
# Verify installation
rsync --version
|
Windows
On Windows, rsync can be installed through various methods:
- Windows Subsystem for Linux (WSL): Install a Linux distribution through WSL and follow Linux installation instructions.
- Cygwin: Install Cygwin with the rsync package.
- MinGW/MSYS2: Install MSYS2 and then install rsync using pacman.
1
2
| # Example for MSYS2
pacman -S rsync
|
3.2 Version Verification
After installation, verify you have the latest version of rsync to ensure all security patches are applied:
Security Note: As of May 2025, ensure you’re running rsync version 3.4.0 or newer to protect against recent critical vulnerabilities like CVE-2024-12084, CVE-2024-12085, and others that were patched in this version.
3.3 Installation Verification
To verify your rsync installation is working correctly:
1
2
3
4
5
6
7
8
9
| # Create test directories
mkdir -p ~/rsync-test/source ~/rsync-test/destination
echo "test file" > ~/rsync-test/source/test.txt
# Run local test
rsync -av ~/rsync-test/source/ ~/rsync-test/destination/
# Verify results
ls -la ~/rsync-test/destination/
|
4. Configuration
4.1 Basic Configuration
Rsync can be used in two primary modes:
- Direct command-line usage for ad-hoc transfers between systems
- Daemon mode for setting up a persistent rsync server
Command-line Basic Usage
Basic secure command to copy files from a local directory to a remote server using SSH:
1
| rsync -avz -e ssh /path/to/local/directory/ user@remote-server:/path/to/destination/
|
Key options:
-a
: Archive mode (preserves permissions, timestamps, etc.)-v
: Verbose output-z
: Compress data during transfer-e ssh
: Use SSH as the transport mechanism
Daemon Mode Basic Configuration
For daemon mode, create or edit /etc/rsyncd.conf
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # Global settings
uid = nobody
gid = nobody
use chroot = yes
max connections = 5
timeout = 600
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
# Module definition
[backup]
path = /srv/backup
comment = Backup directory
read only = false
list = yes
auth users = backupuser
secrets file = /etc/rsyncd.secrets
|
4.2 Advanced Configuration
Secure Daemon Configuration
A more hardened /etc/rsyncd.conf
with security-focused settings:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # Global security settings
uid = nobody
gid = nobody
use chroot = yes
max connections = 5
timeout = 300
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
# Non-standard port for added security
port = 28873
# Limit hosts that can connect
hosts allow = 192.168.1.0/24 10.0.0.5
hosts deny = *
# Secured module
[secure_backup]
path = /srv/backup
comment = Secure backup directory
read only = false
list = no
auth users = backupuser
secrets file = /etc/rsyncd.secrets
strict modes = true
ignore nonreadable = yes
refuse options = checksum delete
transfer logging = yes
|
SSH Configuration for Rsync
For enhanced security when using rsync over SSH, consider these SSH configurations:
1
2
3
4
5
6
7
8
9
| # In /etc/ssh/sshd_config or ~/.ssh/config
# Restrict rsync user to only run rsync commands
Match User rsyncuser
ForceCommand /usr/bin/rsync --server --daemon .
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
|
4.3 Common Misconfigurations
These common rsync security misconfigurations should be avoided:
- Missing Authentication: Using modules without the
auth users
directive makes data publicly accessible1
2
3
4
| # INSECURE - No authentication required
[public]
path = /srv/data
read only = false
|
- Overly Permissive Host Access: Allowing all hosts to connect without restrictions
1
2
| # INSECURE - No host restrictions
hosts allow = *
|
- Running as Root: Running the rsync daemon as root unnecessarily
1
2
3
| # INSECURE - Running with elevated privileges
uid = root
gid = root
|
- Insecure Secrets File: Improper permissions on the rsyncd.secrets file
1
2
3
| # INSECURE - World-readable secrets
$ ls -la /etc/rsyncd.secrets
-rw-r--r-- 1 root root 45 May 4 09:12 /etc/rsyncd.secrets
|
- Default Port Usage: Using the default rsync port (873) which is commonly scanned
1
2
| # INSECURE - Default port
port = 873
|
5. Security Best Practices
5.1 Rsync Over SSH
Using SSH as the transport mechanism for rsync provides encryption, authentication, and integrity checking. This is the recommended approach for secure file transfers.
Basic syntax:
1
| rsync -avz -e "ssh -p 22" /source/path/ user@remote:/destination/path/
|
Enhanced SSH security for rsync:
1
2
3
4
5
| # Use specific SSH key
rsync -avz -e "ssh -i /path/to/private_key -p 2222" /source/path/ user@remote:/destination/path/
# With additional SSH hardening options
rsync -avz -e "ssh -i /path/to/private_key -p 2222 -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/path/to/known_hosts" /source/path/ user@remote:/destination/path/
|
For automated scripts, set up SSH key-based authentication without passphrase, but with restricted commands:
1
2
| # In authorized_keys on the server
command="rsync --server --sender -logDtprze.iLsfxC . /allowed/path/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAAA...
|
5.2 Restricting Access
Network-level Restrictions
Restrict rsync daemon access using firewall rules:
1
2
3
4
5
6
7
8
9
10
| # UFW (Ubuntu)
sudo ufw allow from 192.168.1.0/24 to any port 28873 proto tcp
# firewalld (RHEL/CentOS/Fedora)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="28873" protocol="tcp" accept'
sudo firewall-cmd --reload
# iptables
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 28873 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 28873 -j DROP
|
User and Filesystem Restrictions
- Use dedicated user accounts for rsync operations
- Apply filesystem permissions to restrict access
- Use chroot environments
1
2
3
4
5
6
7
| # Create dedicated rsync user
sudo useradd -r -s /bin/false rsyncuser
# Set proper permissions on rsync directories
sudo mkdir -p /srv/rsync/backup
sudo chown rsyncuser:rsyncuser /srv/rsync/backup
sudo chmod 700 /srv/rsync/backup
|
5.3 Module Configuration Security
Secure module configuration in /etc/rsyncd.conf
:
1
2
3
4
5
6
7
8
9
10
11
12
13
| [secure_module]
path = /srv/data
comment = Secured data directory
read only = true # Read-only unless needed
write only = false
list = false # Hide module from listing
auth users = rsyncuser # Require authentication
secrets file = /etc/rsyncd.secrets
hosts allow = 192.168.1.5 # Restrict by IP
ignore nonreadable = yes # Skip unreadable files
refuse options = checksum delete # Prevent potentially risky operations
incoming chmod = D0700,F600 # Force restrictive permissions on uploads
outgoing chmod = D0700,F600 # Force restrictive permissions on downloads
|
5.4 Secrets Management
Properly secure rsync authentication credentials:
- Create secrets file with strict permissions:
1
2
3
4
5
6
| # Create secrets file
echo "rsyncuser:securepassword" > /etc/rsyncd.secrets
# Set restrictive permissions
chmod 600 /etc/rsyncd.secrets
chown root:root /etc/rsyncd.secrets
|
- Client-side password file:
1
2
3
4
5
6
7
8
| # Create client password file
echo "securepassword" > ~/.rsync-password
# Restrict permissions
chmod 600 ~/.rsync-password
# Use with rsync
rsync -av --password-file=~/.rsync-password /source/ rsyncuser@server::module/
|
- Use SSH keys instead of passwords when possible
5.5 Logging and Auditing
Configure comprehensive logging for rsync operations:
1
2
3
4
| # In /etc/rsyncd.conf
log file = /var/log/rsyncd.log
transfer logging = yes
log format = %t: %o %h [%a] %m (%u) %f %l
|
For client-side logging when using rsync commands:
1
| rsync -avz --log-file=/path/to/rsync.log /source/ destination/
|
Monitor logs for suspicious activity:
1
2
3
4
5
| # Basic log monitoring
grep "auth failed" /var/log/rsyncd.log
# Set up log rotation
sudo nano /etc/logrotate.d/rsync
|
Sample /etc/logrotate.d/rsync
configuration:
1
2
3
4
5
6
7
8
9
10
11
12
| /var/log/rsyncd.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
create 640 root adm
postrotate
systemctl kill -s HUP rsync.service >/dev/null 2>&1 || true
endscript
}
|
6. Integrations
6.1 SSH Integration
SSH Configuration for Restricted Rsync
Create a dedicated SSH user with restricted rsync access:
1
2
3
4
5
| # Create rsync user
sudo useradd -m -s /bin/bash rsyncuser
# Configure SSH to restrict the user to rsync only
sudo mkdir -p /home/rsyncuser/.ssh
|
In /home/rsyncuser/.ssh/authorized_keys
, add the following prefix to the SSH key:
1
| command="/usr/bin/rsync --server --daemon .",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAAA...
|
SSH Tunnel for Rsync Daemon
To securely connect to an rsync daemon over an SSH tunnel:
1
2
3
4
5
| # Create SSH tunnel
ssh -L 8873:localhost:873 user@remote-server
# Use rsync through the tunnel
rsync -av rsync://localhost:8873/module /local/path/
|
6.2 Backup Systems
Integrate rsync with backup systems securely:
Borg Backup with Rsync
1
2
3
4
5
| # First sync files with rsync
rsync -avz -e ssh /source/ user@backup-server:/staging/
# Then create Borg backup from staged files
ssh user@backup-server "cd /staging && borg create ::backup-{now} ."
|
Rsnapshot Configuration
Secure /etc/rsnapshot.conf
configuration:
1
2
3
4
5
6
7
8
9
10
| config_version 1.2
snapshot_root /backup/
cmd_rsync /usr/bin/rsync
cmd_ssh /usr/bin/ssh
ssh_args -i /path/to/key -p 2222
interval daily 7
interval weekly 4
interval monthly 3
backup user@remote-server:/important/data/ server/
|
6.3 Scheduled Tasks
Setting up secure scheduled rsync transfers:
Systemd Timer
Create a systemd service file /etc/systemd/system/secure-rsync.service
:
1
2
3
4
5
6
7
8
| [Unit]
Description=Secure Rsync Backup
After=network.target
[Service]
Type=oneshot
User=rsyncuser
ExecStart=/usr/bin/rsync -avz -e "ssh -i /home/rsyncuser/.ssh/backup_key" /source/ remote:/destination/
|
Create a timer file /etc/systemd/system/secure-rsync.timer
:
1
2
3
4
5
6
7
8
9
10
| [Unit]
Description=Run secure rsync backup daily
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=900
Persistent=true
[Install]
WantedBy=timers.target
|
Enable and start the timer:
1
2
| sudo systemctl enable secure-rsync.timer
sudo systemctl start secure-rsync.timer
|
Cron Job with Security Measures
1
2
| # Crontab entry with logging and error reporting
0 2 * * * /usr/bin/rsync -avz --log-file=/var/log/backup.log -e "ssh -i /home/user/.ssh/backup_key" /source/ user@remote:/destination/ || echo "Backup failed on $(date)" | mail -s "Backup Error" [email protected]
|
7. Testing and Validation
7.1 Security Testing
Test SSH-based Rsync
1
2
3
4
5
| # Test SSH connection with verbose output
ssh -v user@remote-server
# Test rsync with dry-run
rsync -avzn -e ssh /source/ user@remote-server:/destination/
|
Test Rsync Daemon Security
1
2
3
4
5
6
7
8
9
10
| # Test daemon anonymously (should fail with proper security)
rsync rsync://server/module/
# Test with incorrect credentials (should fail)
echo "wrongpassword" > /tmp/wrong-pwd
chmod 600 /tmp/wrong-pwd
rsync -av --password-file=/tmp/wrong-pwd /source/ rsyncuser@server::module/
# Test with correct credentials
rsync -av --password-file=~/.rsync-password /source/ rsyncuser@server::module/
|
Scan for Open Rsync Ports
1
2
| # Check if rsync port is open to the internet (should show no open port)
nmap -p 873,28873 server_ip
|
7.2 Transfer Validation
Verify file integrity after transfers:
1
2
3
4
5
6
7
8
9
10
11
12
| # Generate checksums on source
cd /source
find . -type f -exec md5sum {} \; > /tmp/source_checksums.md5
# Transfer files
rsync -avz -e ssh /source/ user@remote:/destination/
# Copy checksums to destination
scp /tmp/source_checksums.md5 user@remote:/tmp/
# Verify checksums on destination
ssh user@remote "cd /destination && md5sum -c /tmp/source_checksums.md5"
|
8. References and Further Reading
Official Documentation
Security Resources
Best Practices
9. Appendices
9.1 Troubleshooting
Common Issues and Solutions
Issue | Solution |
---|
“Permission denied” errors | Check file permissions, user privileges, and SSH keys |
“auth failed on module” | Verify credentials in secrets file and check permissions on secrets file |
Connection refused | Check firewall rules, daemon running status, and port configuration |
Slow transfers | Consider using -z for compression or --bwlimit to limit bandwidth |
“Protocol incompatibility” | Ensure compatible rsync versions on both client and server |
Debugging Commands
1
2
3
4
5
6
7
8
9
10
11
| # Run rsync with increased verbosity
rsync -avvvz -e ssh /source/ user@remote:/destination/
# Test daemon connectivity
telnet server 873
# Check rsync daemon status
systemctl status rsync
# View recent rsync log entries
tail -f /var/log/rsyncd.log
|
9.2. Known Vulnerabilities
As of May 2025, these critical vulnerabilities have been identified and patched:
CVE ID | CVSS | Description | Affected Versions | Fixed In |
---|
CVE-2024-12084 | 9.8 | Heap buffer overflow allowing RCE | < 3.4.0 | 3.4.0 |
CVE-2024-12085 | 7.5 | Information leak via uninitialized stack data | < 3.4.0 | 3.4.0 |
CVE-2024-12086 | 6.5 | Server leaks arbitrary client files | < 3.4.0 | 3.4.0 |
CVE-2024-12087 | 5.9 | Path traversal via –inc-recursive option | < 3.4.0 | 3.4.0 |
CVE-2024-12088 | 5.9 | Bypass of –safe-links option | < 3.4.0 | 3.4.0 |
CVE-2024-12747 | 5.6 | Race condition in handling symbolic links | < 3.4.0 | 3.4.0 |
Ensure you’re running the latest version of rsync to mitigate these vulnerabilities.