College-Level Course Module | RHEL System Administration
Why encryption matters and how SSH protects file transfers
Copy files and directories between local and remote systems
Navigate remote filesystems and transfer files interactively
Synchronize files efficiently, transferring only differences
Secure file transfer encrypts both authentication credentials and data content, preventing eavesdropping and tampering during transmission.
scp, sftp, and rsync all use SSH for secure transport. They inherit SSH authentication, encryption, and configuration.
# All three tools use SSH and share its configuration
# SSH config applies (~/.ssh/config)
[user@host ~]$ cat ~/.ssh/config
Host webserver
HostName 192.168.1.100
User admin
Port 2222
IdentityFile ~/.ssh/web_key
# Now all tools use these settings:
[user@host ~]$ scp file.txt webserver:/tmp/
[user@host ~]$ sftp webserver
[user@host ~]$ rsync -av data/ webserver:/backup/
# Common SSH options work with scp and sftp:
# -P port (note: uppercase for scp/sftp)
# -i keyfile (specify identity/key file)
# -o option (pass SSH options)
Best for: Quick, simple copies
Style: Command-line, non-interactive
Features: Basic copy, recursive dirs
Efficiency: Full file transfer each time
Best for: Interactive browsing
Style: Interactive session
Features: Navigate, list, get, put
Efficiency: Full file transfer each time
Best for: Sync, backup, large transfers
Style: Command-line, powerful
Features: Delta sync, preserve, resume
Efficiency: Transfers only differences!
| Feature | scp | sftp | rsync |
|---|---|---|---|
| Interactive mode | No | Yes | No |
| Resume interrupted | No | Limited | Yes |
| Transfer only changes | No | No | Yes |
| Preserve permissions | Yes (-p) | Yes | Yes (-a) |
scp (secure copy) copies files between hosts using SSH. Syntax is similar to cp, with remote locations specified as user@host:path.
# Copy local file TO remote system
[user@local ~]$ scp report.pdf admin@server:/home/admin/
report.pdf 100% 2.5MB 12.3MB/s 00:00
# Copy remote file TO local system
[user@local ~]$ scp admin@server:/var/log/messages ./server-messages.log
# Copy to/from specific directory
[user@local ~]$ scp config.txt admin@server:/etc/myapp/
# Copy with different remote username
[user@local ~]$ scp file.txt root@192.168.1.100:/tmp/
: separates host from path. server:file is remote. ./file is local.
# Copy directories recursively with -r
[user@local ~]$ scp -r project/ admin@server:/home/admin/backup/
file1.txt 100% 1024 50.0KB/s 00:00
file2.txt 100% 2048 98.5KB/s 00:00
subdir/file3.txt 100% 512 25.0KB/s 00:00
# Preserve modification times and permissions with -p
[user@local ~]$ scp -rp project/ admin@server:/backup/
# Use specific SSH port with -P (uppercase!)
[user@local ~]$ scp -P 2222 file.txt admin@server:/tmp/
# Use specific SSH key
[user@local ~]$ scp -i ~/.ssh/mykey file.txt admin@server:/tmp/
# Limit bandwidth (in Kbit/s)
[user@local ~]$ scp -l 1000 largefile.iso admin@server:/data/
# Verbose output for debugging
[user@local ~]$ scp -v file.txt admin@server:/tmp/
-P (uppercase) for scp, but -p (lowercase) for ssh. Lowercase -p in scp means preserve attributes!
# Copy between two remote hosts (through local machine)
[user@local ~]$ scp admin@server1:/data/file.txt admin@server2:/backup/
# This routes traffic: server1 -> local -> server2
# Requires authentication to both servers from local machine
# Use -3 to force routing through local (default in newer scp)
[user@local ~]$ scp -3 admin@server1:/data/file.txt admin@server2:/backup/
# Alternative: SSH to server1 and scp from there
[user@local ~]$ ssh admin@server1
[admin@server1 ~]$ scp /data/file.txt admin@server2:/backup/
sftp (SSH File Transfer Protocol) provides an interactive file transfer session. Navigate directories, list files, and transfer interactively - all encrypted over SSH.
# Connect to remote system
[user@local ~]$ sftp admin@server
Connected to server.
sftp>
# You are now in an interactive sftp session
sftp> pwd # Show remote working directory
Remote working directory: /home/admin
sftp> lpwd # Show LOCAL working directory
Local working directory: /home/user
sftp> ls # List remote files
documents downloads scripts
sftp> lls # List LOCAL files
file1.txt file2.txt project/
sftp> help # Show available commands
sftp> cd /var/log # Change remote directory
sftp> pwd
Remote working directory: /var/log
sftp> ls -la # Detailed listing (remote)
drwxr-xr-x 2 root root 4096 Jan 20 10:00 .
drwxr-xr-x 22 root root 4096 Jan 15 08:30 ..
-rw-r--r-- 1 root root 102400 Jan 20 10:00 messages
-rw-r--r-- 1 root root 51200 Jan 20 09:00 secure
sftp> lcd ~/downloads # Change LOCAL directory
sftp> lpwd
Local working directory: /home/user/downloads
# Use wildcards
sftp> ls *.log
messages.log secure.log boot.log
# Check file size before downloading
sftp> ls -l messages
-rw-r--r-- 1 root root 104857600 Jan 20 10:00 messages
# Download file from remote (get)
sftp> get messages
Fetching /var/log/messages to messages
/var/log/messages 100% 100MB 12.5MB/s 00:08
# Download with different local name
sftp> get messages server-messages.log
# Download multiple files (wildcards)
sftp> mget *.log
Fetching /var/log/messages.log to messages.log
Fetching /var/log/secure.log to secure.log
# Upload file to remote (put)
sftp> put config.txt
Uploading config.txt to /home/admin/config.txt
config.txt 100% 1024 50.0KB/s 00:00
# Upload multiple files
sftp> mput *.txt
# Download/upload directories recursively
sftp> get -r project/
sftp> put -r backup/
# Create remote directory
sftp> mkdir newdir
# Remove remote file
sftp> rm oldfile.txt
# Remove remote directory
sftp> rmdir emptydir
# Rename remote file
sftp> rename oldname.txt newname.txt
# Change remote file permissions
sftp> chmod 644 config.txt
# Batch mode - commands from file
[user@local ~]$ sftp -b commands.txt admin@server
# Exit sftp session
sftp> exit
# Or: quit, bye, Ctrl+D
rsync efficiently synchronizes files between locations. It transfers only the differences between source and destination, saving time and bandwidth.
# Basic rsync to remote (uses SSH automatically)
[user@local ~]$ rsync file.txt admin@server:/backup/
# rsync with common options
[user@local ~]$ rsync -avz data/ admin@server:/backup/data/
sending incremental file list
./
file1.txt
file2.txt
subdir/
subdir/file3.txt
sent 1,234 bytes received 89 bytes 2,646.00 bytes/sec
total size is 10,240 speedup is 7.74
# Archive mode (-a): recursive, preserves everything
[user@local ~]$ rsync -a source/ dest/
# -a equals: -rlptgoD (recurse, links, perms, times, group, owner, devices)
# Common useful combinations:
[user@local ~]$ rsync -av source/ admin@server:/dest/ # Archive + verbose
[user@local ~]$ rsync -avz source/ admin@server:/dest/ # + compression
[user@local ~]$ rsync -avzP source/ admin@server:/dest/ # + progress + partial
# Show progress for large transfers
[user@local ~]$ rsync -av --progress largefile.iso admin@server:/data/
largefile.iso
524,288,000 50% 10.23MB/s 0:00:24
# Delete files in dest that do not exist in source (mirror)
[user@local ~]$ rsync -av --delete source/ admin@server:/dest/
# Dry run - show what WOULD be done without doing it
[user@local ~]$ rsync -avn --delete source/ admin@server:/dest/
deleting oldfile.txt
newfile.txt
-n) first to see what would be deleted.
Critical! Trailing slash on source directory changes behavior significantly. This is the most common rsync mistake.
# WITH trailing slash: copy CONTENTS of source INTO dest
[user@local ~]$ rsync -av source/ dest/
# Result: dest/file1.txt, dest/file2.txt
# WITHOUT trailing slash: copy source directory INTO dest
[user@local ~]$ rsync -av source dest/
# Result: dest/source/file1.txt, dest/source/file2.txt
# Example with actual paths:
[user@local ~]$ ls project/
app.py config.yaml data/
# This copies contents into /backup/
[user@local ~]$ rsync -av project/ admin@server:/backup/
# Remote: /backup/app.py, /backup/config.yaml, /backup/data/
# This creates project dir inside /backup/
[user@local ~]$ rsync -av project admin@server:/backup/
# Remote: /backup/project/app.py, /backup/project/config.yaml
# Basic backup to remote server
[user@local ~]$ rsync -avz --delete ~/data/ admin@backup:/backups/data/
# Backup with excluded files/directories
[user@local ~]$ rsync -avz --exclude='*.tmp' --exclude='cache/' \
~/project/ admin@backup:/backups/project/
# Exclude patterns from file
[user@local ~]$ cat exclude.txt
*.log
*.tmp
.git/
node_modules/
__pycache__/
[user@local ~]$ rsync -avz --exclude-from=exclude.txt \
~/project/ admin@backup:/backups/project/
# Resume interrupted transfer
[user@local ~]$ rsync -avzP --partial ~/large.iso admin@server:/data/
# If interrupted, run same command again - it resumes!
# Specify SSH port
[user@local ~]$ rsync -avz -e 'ssh -p 2222' data/ admin@server:/backup/
# Use specific SSH key
[user@local ~]$ rsync -avz -e 'ssh -i ~/.ssh/backup_key' data/ admin@server:/backup/
# Multiple SSH options
[user@local ~]$ rsync -avz -e 'ssh -p 2222 -i ~/.ssh/mykey' \
data/ admin@server:/backup/
# If using SSH config, just use the alias
[user@local ~]$ cat ~/.ssh/config
Host backup
HostName backup.example.com
User backupadmin
Port 2222
IdentityFile ~/.ssh/backup_key
[user@local ~]$ rsync -avz data/ backup:/backups/
# SSH config settings automatically apply!
# Limit bandwidth (KBytes/sec)
[user@local ~]$ rsync -avz --bwlimit=1000 data/ admin@server:/backup/
# Limits to 1000 KB/s (about 8 Mbit/s)
# Useful for not saturating network links
[user@local ~]$ rsync -avz --bwlimit=5000 bigdata/ admin@server:/archive/
# Compress for slow links
[user@local ~]$ rsync -avz data/ admin@server:/backup/
# Skip compression for fast links or already-compressed data
[user@local ~]$ rsync -av data/ admin@server:/backup/
# Transfer statistics
[user@local ~]$ rsync -av --stats data/ admin@server:/backup/
Number of files: 150
Number of files transferred: 12
Total file size: 1,234,567 bytes
Total transferred file size: 45,678 bytes
Literal data: 45,678 bytes
Matched data: 0 bytes
...
| Scenario | Best Tool | Command |
|---|---|---|
| Copy one file quickly | scp | scp file.txt user@server:/path/ |
| Browse and select files | sftp | sftp user@server (interactive) |
| Daily backup of directory | rsync | rsync -avz --delete src/ user@server:/backup/ |
| Deploy web application | rsync | rsync -avz --exclude='.git' app/ user@web:/var/www/ |
| Download large file (resumable) | rsync | rsync -avzP user@server:/data/large.iso ./ |
| Mirror directory exactly | rsync | rsync -avz --delete src/ dst/ |
| Automated script transfer | scp | scp -q file.txt user@server:/path/ |
| Explore remote, pick files | sftp | sftp user@server then ls, cd, get |
Always Secure: Use SSH-based tools (scp, sftp, rsync). Never use unencrypted FTP or rcp.
scp: Simple secure copy. scp file user@host:/path/ for quick transfers.
sftp: Interactive sessions. Connect, browse, get/put files. Great for exploration.
rsync: Efficient sync. rsync -avz src/ user@host:/dest/. Delta transfer, resume, backup.
Next: Managing Network Security with Firewall