Stage 2 · Tools
Network Scripting
SSH Automation
Key-based auth, tunneling, SSH config, and parallel SSH for remote management.
Key-Based Authentication
SSH keys replace password authentication with cryptographic keys. They are more secure, enable automation (no password prompts), and are the standard for server access.
# Generate a new key pair
ssh-keygen -t ed25519 -C "your@email.com"
# Copy public key to server
ssh-copy-id user@server
# Test connection (should work without password)
ssh user@server "echo 'Key auth works'"
# List keys
ssh-add -l
# Add specific key to agent
ssh-add ~/.ssh/deploy_key
# Remove all keys from agent
ssh-add -Ded25519 is the recommended key type — it is faster and more secure than RSA. ssh-copy-id handles the authorized_keys setup automatically. ssh-agent caches keys so you do not re-enter passphrases.
Add your key to ssh-agent: eval $(ssh-agent) && ssh-add ~/.ssh/id_ed25519. The agent caches your decrypted key so you only enter the passphrase once per session.
SSH Config File
The SSH config file (~/.ssh/config) simplifies connections by defining host aliases, default options, and credentials. It eliminates repetitive command-line arguments.
# ~/.ssh/config
# Simple host alias
Host staging
HostName staging.example.com
User deploy
Port 2222
IdentityFile ~/.ssh/staging_key
# Production server
Host prod-web-*
HostName %h.example.com
User ops
IdentityFile ~/.ssh/prod_key
ForwardAgent no
ServerAliveInterval 60
# Jump host / bastion
Host internal-*
ProxyJump bastion.example.com
User admin
# Default settings
Host *
ServerAliveInterval 300
ServerAliveCountMax 2
AddKeysToAgent yesAfter configuring, ssh staging connects to staging.example.com on port 2222 as deploy. ProxyJump creates SSH tunnels through bastion hosts. %h substitutes the hostname.
Running Remote Commands
SSH can execute commands remotely without opening an interactive session. This is the basis for SSH automation.
# Execute single command
ssh server "df -h /"
# Multiple commands
ssh server "cd /opt/app && ./status.sh"
# Pipe local data to remote
cat local-config.yml | ssh server "cat > /etc/app/config.yml"
# Execute script on remote server
ssh server 'bash -s' < local-script.sh
# Get exit code
ssh server "test -f /var/lock/app.lock" && echo "Running" || echo "Stopped"SSH closes the connection when the remote command finishes. The exit code of the remote command becomes the exit code of the ssh command. This is useful for scripting.
SSH Tunneling
SSH tunnels forward ports through encrypted connections. They are essential for accessing services behind firewalls, securing unencrypted traffic, and debugging network issues.
# Local forward: access remote:5432 on localhost:5432
ssh -L 5432:localhost:5432 user@server
# Access remote MySQL on local port
ssh -L 3306:db-server:3306 user@bastion
# Remote forward: expose local:3000 to remote
ssh -R 8080:localhost:3000 user@server
# Dynamic SOCKS proxy
ssh -D 1080 user@server
# Then configure browser to use SOCKS proxy localhost:1080
# Tunnel through bastion
ssh -J bastion.example.com user@internal-serverLocal forward (-L) makes a remote port available locally. Remote forward (-R) makes a local port available remotely. Dynamic (-D) creates a SOCKS proxy. -J is ProxyJump shorthand.
Use ssh -L 5432:db-host:5432 user@bastion to access a database behind a firewall. The database appears to be on localhost:5432. This is secure and requires no firewall changes.
Parallel SSH
Running commands on multiple servers simultaneously saves time. There are several approaches for parallel SSH execution.
# Simple background jobs
for server in web1 web2 web3; do
ssh "$server" "sudo systemctl restart nginx" &
done
wait
# GNU Parallel
parallel -j 3 ssh {} "uptime" ::: web1 web2 web3 web4
# Using xargs
echo -e "web1\nweb2\nweb3" | xargs -P 3 -I {} ssh {} "uptime"
# With a server list file
while read -r server; do
ssh "$server" "df -h /" &
done < servers.txt
waitBackground jobs with wait is the simplest approach. GNU Parallel (-j N) handles concurrency, output collection, and error handling. Always wait for background jobs before continuing.
rsync Over SSH
rsync over SSH is the standard for file synchronization. It provides encrypted transfer, compression, and incremental sync.
# Sync to remote
rsync -avz -e ssh /local/path/ user@server:/remote/path/
# Sync from remote
rsync -avz -e ssh user@server:/remote/path/ /local/path/
# Use SSH config host
rsync -avz staging:/opt/app/ ./local-backup/
# With bandwidth limit
rsync -avz --bwlimit=1000 -e ssh /data/ user@server:/backup/
# Delete files not in source
rsync -avz --delete -e ssh /source/ user@server:/dest/-e ssh specifies SSH as the transport. -a preserves permissions and timestamps. -v is verbose. -z compresses during transfer. Use SSH config host names for cleaner commands.
Always verify SSH host keys on first connection. To automate without prompts, pre-populate known_hosts: ssh-keyscan server >> ~/.ssh/known_hosts. Never disable host key checking in production.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.