Secure Server-to-Server File Transfers with rsync and tmux
Table of Contents 📑
This guide provides a definitive, “terminal-first” approach to transferring large amounts of data directly between two remote servers. By combining the power of rsync
for data synchronization, tmux
for session persistence, and a securely configured SSH deploy key for authentication, you can create a “fire-and-forget” transfer process that is robust, efficient, and secure.
This method avoids routing traffic through your local machine, saving you bandwidth and making the process immune to local network disconnects.
Changelog
Date | Change |
---|---|
2025-08-08 | Initial Version: Article created. |
1. The Goal: Direct, Robust Server-to-Server Transfers
Before we begin, it’s essential to understand the data flow we are building.
ℹ️ UNDERSTANDING THE ARCHITECTURE |
The goal is to initiate a transfer that runs entirely on Server1, pulling data from itself and pushing it directly to Server2. Your local computer is only used to set up the infrastructure and start the process; it can be disconnected immediately afterward. Data Flow: |
2. Prerequisites
- You have key-based SSH access from your local computer to two Linux servers,
Server1
andServer2
. - Password authentication on your servers is (correctly) disabled.
- You have
sudo
orroot
privileges onServer1
to install software.
Local SSH Configuration (For Your Convenience)
Define aliases for your servers in your local computer’s ~/.ssh/config
file. This only makes it easier for you to connect; it does not affect the servers themselves.
# In ~/.ssh/config on your LOCAL machine
Host Server1
HostName cloud.server1.xyz
User your_user
Host Server2
HostName cloud.server2.xyz
User root
Port 2222 # Use your actual port
3. The Core Method: Building the Key Infrastructure
This is the most critical part of the tutorial. We will:
- Create a deploy key on
Server1
. - Configure the SSH client on
Server1
so it knows how to findServer2
. - Use our local PC as a trusted intermediary to securely install and restrict the key on
Server2
.
3.1. On Server1: Create the Deploy Key
# On your local machine, connect to Server1
ssh Server1
# Now, on Server1, generate a new, passwordless SSH key pair
# When prompted for a passphrase, press Enter twice to leave it empty.
ssh-keygen -t ed25519 -f ~/.ssh/id_deploy_to_server2 -C "rsync deploy key for server2"
3.2. On Server1: Configure its SSH Client
We must teach Server1
how to connect to Server2
. We do this by creating a config
file in its .ssh
directory.
# On Server1, create and open the config file
nano ~/.ssh/config
Add the following configuration. Replace the values with the actual connection details for Server2
.
Host Server2
HostName cloud.server2.xyz
User root
Port 2222
IdentityFile ~/.ssh/id_deploy_to_server2
IdentityFile
: This line is key. It tellsServer1
’s SSH client: “When connecting to the host aliased as ‘Server2’, always use this specific private key.”
Save the file (Ctrl+X
, then Y
, then Enter
) and set the correct permissions:
# On Server1
chmod 600 ~/.ssh/config
3.3. On Server1: Copy the Public Key for Transfer
Display the public key so you can copy it to your clipboard.
# On Server1
cat ~/.ssh/id_deploy_to_server2.pub
Action: Mark and copy the entire output (the line starting ssh-ed25519 AAAA...
). Then, log out from Server1
.
exit
3.4. From Your Local PC: Install and Restrict the Key on Server2
# 1. On your local PC, append the key to Server2's authorized_keys.
# Replace 'PASTE_KEY_FROM_CLIPBOARD_HERE' with the key you just copied.
ssh Server2 "echo 'PASTE_KEY_FROM_CLIPBOARD_HERE' >> ~/.ssh/authorized_keys"
# 2. Now, SSH to Server2 to restrict the key.
ssh Server2
# 3. Once on Server2, open the file for editing.
nano ~/.ssh/authorized_keys
In the editor, find the key you just added at the bottom of the file. Navigate to the very beginning of that line and prepend the command
restriction.
Before:
ssh-ed25519 AAAA... rsync deploy key for server2
After (replace /path/to/destination/
with your actual path!):
command="rsync --server -vlogDtpre.iL --partial . /path/to/destination/",no-port-forwarding,no-x11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA... rsync deploy key for server2
Save the file and exit the editor (Ctrl+X
, then Y
, then Enter
).
4. Test the Connection and Launch the Transfer
4.1. Test the Inter-Server Connection
This test now verifies that the new configuration on Server1
is working correctly.
# On your local PC
ssh Server1
# Now, on Server1, this command will work because of the new ~/.ssh/config
ssh Server2
💡 SUCCESS LOOKS LIKE A FAILURE! |
The terminal may appear to hang and show a message like Press |
4.2. Launch the Uninterruptible Transfer
# On Server1, install tmux if you haven't already
sudo apt update && sudo apt install tmux
# Start a new tmux session
tmux new -s syncJob
# Inside the tmux session, execute the now-simplified rsync command.
# No -e option is needed because Server1's SSH client is now configured!
rsync -avh --info=progress2 --partial \
/path/to/source/ \
Server2:/path/to/destination/
4.3. Detach and Disconnect
The process is now running. Detach from the tmux
session and log out.
Ctrl+b
, thend
# On Server1
exit
5. Managing the rsync
Session
You can check on, re-attach, or terminate your transfer at any time.
- To check the progress:
ssh Server1
and thentmux attach -t syncJob
. - To kill the session:
ssh Server1
and thentmux kill-session -t syncJob
.
6. Quick Troubleshooting
Problem | Solution |
---|---|
“Could not resolve hostname Server2” | The ~/.ssh/config file on Server1 is missing, has incorrect permissions (should be 600), or the Host Server2 entry is misspelled. |
“Permission denied (publickey).” | The IdentityFile path in Server1 ’s ~/.ssh/config might be wrong. Or, the public key was not correctly added to Server2 ’s authorized_keys . |
ssh Server2 test works, but rsync fails | Check the User in Server1 ’s ~/.ssh/config . Does that user have permission to write to the destination directory on Server2 ? Also, check the path in the command= restriction. |
Files are copied into a nested directory | You likely omitted the trailing slash (/ ) on your source path. /path/to/source copies the directory itself, while /path/to/source/ copies its contents. |
7. Conclusion
By following this definitive guide, you have built a powerful and professionally architected data transfer system. The key was configuring the client (Server1
) to know how to reach the target (Server2
), a fundamental concept for any automated inter-server task. This setup is ideal for large backups, data migrations, and any scenario where a direct, robust, server-to-server connection is required.