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