How to Use Rsync Over SSH with Root Access on Both Servers for Secure Data Migration


2 views

When migrating data between Linux servers (especially system directories like /home), you often need root privileges on both ends:

  • Source server requires root to read all files (including those with restrictive permissions)
  • Destination server needs root to properly set ownership/permissions in protected directories

Before proceeding, ensure:

# On both servers:
sudo apt-get install rsync openssh-server
sudo systemctl status ssh

The safest approach uses SSH keys with careful sudo configurations:

# On source server (as root):
ssh-keygen -t rsa -b 4096
cat ~/.ssh/id_rsa.pub | ssh root@new-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Here's the complete migration command for /home:

sudo rsync -avz -e "ssh -i /root/.ssh/id_rsa" \
--rsync-path="sudo rsync" \
--delete \
--numeric-ids \
--chown=root:root \
/home/ root@new-server:/home/

Key parameters explained:

  • -a: Archive mode (preserves permissions, timestamps)
  • -v: Verbose output
  • -z: Compression during transfer
  • --rsync-path: Ensures rsync runs with sudo on remote
  • --numeric-ids: Preserves UID/GID numbers

For systems where direct root SSH is restricted:

rsync -avz -e ssh --rsync-path="sudo rsync" \
--fake-super \
/home/user/ user@new-server:/home/user/

Permission denied errors:

# On destination server:
visudo
# Add line:
youruser ALL=NOPASSWD: /usr/bin/rsync

SSH connection refused:

# In /etc/ssh/sshd_config:
PermitRootLogin prohibit-password
# Then:
systemctl restart sshd

For large transfers:

rsync -avz --progress -e "ssh -T -c aes128-gcm@openssh.com -o Compression=no -x" \
--bwlimit=50000 \
/home/ root@new-server:/home/

When migrating data between Linux servers where file permissions must be preserved, standard user-level rsync operations often fail. The scenario becomes particularly tricky when:

  • Source files have restricted permissions (e.g., 0600 root:root)
  • Destination paths require root write access (e.g., /home/user directories)
  • Both servers enforce sudo authentication

Before diving into the solution, let's address three critical security aspects:

  • SSH key authentication should be configured between servers
  • Sudoers configuration must allow passwordless rsync operations
  • Firewall rules need to permit SSH traffic

Here's the complete rsync command that handles root-to-root transfers:

rsync -avz -e "ssh -T" --rsync-path="sudo rsync" \
--delete --numeric-ids --chown=root:root \
/path/to/source/ root@destination:/path/to/target/

Let's break down the components:

-a : Archive mode (preserves permissions, ownership, timestamps)
-v : Verbose output
-z : Compression during transfer
-e "ssh -T" : Disables pseudo-terminal allocation
--rsync-path="sudo rsync" : Elevates privileges on remote host
--delete : Mirrors source exactly (deletes extra files at destination)
--numeric-ids : Preserves numeric UID/GID values
--chown : Ensures proper ownership at destination

For copying /home/user1 from ubuntu-old to debian-new:

rsync -avz -e "ssh -T" --rsync-path="sudo rsync" \
--delete --numeric-ids --chown=root:root \
/home/user1/ root@debian-new:/home/

For large transfers or unstable connections:

rsync -avz --partial --progress --bwlimit=50000 \
-e "ssh -T -o ServerAliveInterval=60" \
--rsync-path="sudo rsync" /source/ root@dest:/target/

If you encounter "sudo: no tty present" errors, add this to your sudoers file:

Defaults:youruser !requiretty
youruser ALL=(ALL) NOPASSWD: /usr/bin/rsync

For "failed to set permissions" warnings, ensure:

  • Target filesystem supports Linux permissions (not FAT/NTFS)
  • No SELinux conflicts exist on destination