The Complete Guide to Moving Files Over SSH
Moving files between computers securely doesn’t have to be complicated. SSH gives you several powerful, encrypted ways to transfer data, and once you understand the basics, you’ll wonder how you ever managed without them.
Whether you’re a developer pushing code to servers, a system administrator managing backups, or just someone who needs to move files safely between machines, this guide covers everything you need to know about SSH-based file transfers.
Why SSH for File Transfers?
Unlike traditional FTP or other transfer methods, SSH encrypts everything end-to-end. Your files, passwords, and commands are all protected from prying eyes. Plus, if you’re already using SSH to manage servers, you’re using the same keys and configuration for file transfers too.
A quick note for modern systems: If you’re running OpenSSH 9.0 or later, scp now uses the SFTP protocol by default instead of the legacy scp protocol. This change fixes some old quirks, but if you specifically need the old behavior, just add the -O flag.
The Big Three: Choosing Your Tool
Think of SSH file transfer tools like different vehicles for different jobs:
SCP (Secure Copy) is like a pickup truck – simple, reliable, gets the job done for straightforward transfers. Perfect for copying individual files or directories when you just need to move something from point A to point B.
rsync is like a smart moving van – it only carries what’s changed, can resume interrupted moves, and has lots of options for complex jobs. Ideal for keeping directories in sync, backing up data, or any situation where you’re transferring the same files repeatedly.
SFTP is like having a remote file manager – interactive, great for browsing around and moving files by hand. Excellent when you need to explore what’s on a remote system and selectively transfer files.
Getting Started with SCP
SCP is the simplest way to copy files over SSH. The basic pattern is always the same: scp source destination.
Copying a file to a remote server looks like this:
scp document.pdf user@server:/home/user/docs/
Copying from a remote server to your local machine flips it around:
scp user@server:/var/log/app.log ./logs/
For directories, add the -r flag for recursive copying:
scp -r ./project_folder user@server:/var/www/
One thing to watch out for: if you use wildcards like ./folder/*, you’ll miss hidden files that start with dots. It’s usually better to copy the whole directory with the recursive flag.
Useful SCP Options
A few flags can make your SCP experience much smoother:
-ppreserves file timestamps and permissions-Ccompresses data during transfer (great for slow connections)-vshows verbose output if you want to see what’s happening-Plets you specify a different SSH port-ilets you use a specific SSH key
Here’s a practical example that combines several of these:
scp -Cp -P 2222 ./big_file.zip user@server:/backups/
This command compresses the file during transfer, preserves its attributes, and connects to port 2222 instead of the default SSH port.
Copying Between Remote Servers
Sometimes you need to copy files between two remote servers. The -3 flag routes the transfer through your local machine, which is usually more reliable than trying to make the remote servers talk directly:
scp -3 user1@server1:/path/file.txt user2@server2:/dest/
Mastering rsync for Efficient Transfers
While SCP is great for simple copies, rsync shines when you need more control or efficiency. The magic of rsync is that it only transfers the parts of files that have actually changed – this can save enormous amounts of time and bandwidth.
The most common rsync pattern uses the -avz flags:
rsync -avz ./local_folder/ user@server:/remote/folder/
Here’s what those flags do:
-ais “archive mode” – it preserves permissions, timestamps, and other file attributes-vgives you verbose output so you can see what’s happening-zcompresses data during transfer
The Trailing Slash Trick
Pay attention to trailing slashes with rsync – they change the behavior significantly:
rsync -avz source/ destination/copies the contents of source into destinationrsync -avz source destination/creates a folder called “source” inside destination
This small difference trips up a lot of people, so always double-check your slashes.
Dry Runs and Safety
Before running a complex rsync command, especially one that might delete files, use the -n flag to do a dry run:
rsync -avzn --delete ./local/ user@server:/remote/
The --delete flag makes rsync remove files from the destination that don’t exist in the source. It’s powerful but dangerous, so always test first.
Custom SSH Settings with rsync
When you need to use specific SSH settings with rsync, use the -e flag:
rsync -avz -e "ssh -p 2222 -i ~/.ssh/special_key" ./local/ user@server:/remote/
Filtering and Excluding Files
rsync has powerful filtering capabilities. You can exclude certain files or patterns:
rsync -avz --exclude="*.tmp" --exclude="logs/" ./project/ user@server:/var/www/
Or include only certain types of files:
rsync -avz --include="*.pdf" --exclude="*" ./documents/ user@server:/archives/
Interactive File Management with SFTP
SFTP gives you an interactive shell for file operations. It’s like having a file manager that works over SSH.
Start an SFTP session:
sftp user@server
Once connected, you have two sets of commands – ones that work on the remote server and ones that work on your local machine:
Remote commands:
pwdshows your current directory on the serverlslists files on the servercdchanges directories on the servermkdircreates directories on the server
Local commands (notice the ‘l’ prefix):
lpwdshows your current local directoryllslists your local fileslcdchanges your local directory
Transfer commands:
put local_file.txtuploads a fileget remote_file.txtdownloads a fileput -r local_directory/uploads a directory recursivelyget -r remote_directory/downloads a directory recursively
Resuming Interrupted Transfers
One of SFTP’s handy features is the ability to resume interrupted transfers:
reget filenameresumes a downloadreput filenameresumes an upload
Batch Mode for Automation
You can script SFTP operations by putting commands in a file:
# Create commands.txt with:
put /local/file1.txt
put /local/file2.txt
mkdir /remote/new_folder
cd /remote/new_folder
put -r /local/directory
# Then run:
sftp -b commands.txt user@server
Making SSH Transfers Faster and Easier
SSH Configuration Files
Instead of typing long commands with ports, keys, and usernames every time, create an SSH config file at ~/.ssh/config:
Host myserver
HostName server.example.com
User myusername
Port 2222
IdentityFile ~/.ssh/my_key
Compression yes
Host production
HostName prod.company.com
User deploy
IdentityFile ~/.ssh/prod_key
Now you can simply use:
scp file.txt myserver:/path/
rsync -avz ./dir/ production:/srv/app/
Connection Multiplexing
SSH can reuse connections, which speeds up multiple transfers significantly. Add this to your SSH config:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Don’t forget to create the sockets directory:
mkdir -p ~/.ssh/sockets
Jump Hosts and Bastions
If you need to go through a bastion host to reach your target server, SSH can handle that automatically:
# One-time usage
scp -J bastion user@internal-server:/path/file .
# Or in your SSH config:
Host internal-app
HostName 10.0.0.15
User deploy
ProxyJump bastion
Performance Tips and Tricks
Compression
On slow connections, compression can dramatically speed up transfers. Most of the tools support it:
- SCP: use
-C - rsync: use
-z - SSH config: add
Compression yes
For newer versions of rsync, you can even choose your compression algorithm:
rsync -av --compress-choice=zstd --compress-level=3 ./src/ user@server:/dest/
Parallel Transfers
While rsync doesn’t have built-in multi-threading, you can run multiple rsync processes for different files or directories:
# Example using GNU parallel
find ./large_directory -maxdepth 1 -type d | parallel rsync -avz {} user@server:/dest/
Cipher Selection
Different encryption ciphers have different performance characteristics. On modern CPUs with AES acceleration, [email protected] is often fastest. On older or low-power systems, [email protected] might be better.
You can test different ciphers:
scp -c aes128-ctr large_file.zip user@server:/dest/
Troubleshooting Common Issues
Permission Problems
The most common SSH transfer problems are permission-related. Make sure your SSH directory and key files have the right permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/id_*.pub
chmod 600 ~/.ssh/authorized_keys
Host Key Verification Failures
If you get a “host key verification failed” error, it usually means the server’s key has changed. This could be legitimate (server was rebuilt) or a sign of trouble. If you’re sure it’s legitimate:
ssh-keygen -R hostname
This removes the old key, and you’ll be prompted to accept the new one on your next connection.
Debugging Connection Issues
When things go wrong, verbose output is your friend:
scp -vvv problematic_file user@server:/dest/
ssh -vvv user@server
The triple -v gives you detailed information about what SSH is trying to do and where it’s failing.
Slow Transfer Speeds
If transfers are slower than expected:
- Try enabling compression with
-C(scp) or-z(rsync) - Check if your SSH config has
Compression yes - Test different ciphers to see if one performs better on your hardware
- Consider whether network conditions or server load might be the bottleneck
Security Best Practices
Keys Over Passwords
Always use SSH keys instead of passwords when possible. Generate a strong key:
ssh-keygen -t ed25519 -C "[email protected]"
Then copy it to your servers:
ssh-copy-id user@server
Verify Server Identity
On your first connection to a server, SSH will show you the server’s fingerprint. Don’t just hit “yes” – verify this fingerprint through another channel (like asking your system administrator or checking documentation).
Keep Things Updated
Regularly update your SSH client and server software. Security vulnerabilities are discovered and patched regularly.
Server Hardening
If you manage the servers you’re connecting to, consider these hardening steps:
- Disable root login:
PermitRootLogin no - Disable password authentication:
PasswordAuthentication no - Use
AllowUsersto restrict which accounts can SSH in - Change the default SSH port (reduces automated attacks, though it’s not a strong security measure)
- Use
fail2banor similar tools to automatically block brute-force attempts
Putting It All Together
SSH file transfers become second nature once you understand the strengths of each tool. Use SCP for quick, one-off copies. Reach for rsync when you’re syncing directories or need efficiency. Fire up SFTP when you want to browse around and selectively move files.
Set up your SSH config file to make connections seamless, and don’t forget about useful features like connection multiplexing and jump hosts. With these tools in your toolkit, moving files securely over the network becomes as natural as copying files on your local machine.
Remember: when in doubt, use the -n flag with rsync to do a dry run, and always verify that your transfers completed successfully. Your future self will thank you for taking these small precautions.
The beauty of SSH-based file transfers is that once you’ve got your keys and configuration set up properly, everything just works. No more juggling different protocols, ports, and authentication methods – just reliable, encrypted file transfers that integrate seamlessly with your existing SSH workflow.