Batch 5: Protocols & Security Networking Apache & NGINX Docker ← Full TOC

← Protocols Index

🔑 SSH & SCP & SFTP — SSH keys, config, tunnels, SCP file transfer, SFTP

SSH (Secure Shell) provides encrypted remote access to servers. It's the primary tool for Linux system administration. SSH key authentication is more secure than passwords and required by most cloud providers.

📋 Reference

ItemSyntax / ValueDescription
sshssh user@host / ssh -p 2222 user@hostConnect to remote host
ssh -issh -i ~/.ssh/mykey.pem ubuntu@hostUse specific private key
ssh-keygenssh-keygen -t ed25519 -C 'alice@example.com'Generate SSH key pair
ssh-keygen rsassh-keygen -t rsa -b 4096 -C 'comment'Generate RSA key (legacy compatibility)
ssh-copy-idssh-copy-id -i ~/.ssh/id_ed25519.pub user@hostCopy public key to server
authorized_keys~/.ssh/authorized_keysServer-side file of allowed public keys
~/.ssh/configHost alias with connection settingsShortcut: 'ssh myserver' instead of 'ssh -i key ubuntu@1.2.3.4'
ssh -Lssh -L 8080:localhost:3000 user@hostLocal port forward: localhost:8080 goes to host:3000
ssh -Rssh -R 9090:localhost:80 user@hostRemote port forward: expose local port on remote
ssh -Dssh -D 1080 user@hostDynamic SOCKS proxy — route traffic through host
ssh -Nssh -N -L 5432:db:5432 user@jumphostNo command — tunnels only
ssh -Jssh -J jumphost user@targetJump through bastion/proxy host
ssh-agenteval $(ssh-agent) && ssh-add ~/.ssh/id_ed25519Load key into agent — no passphrase prompts
StrictHostKeyCheckingStrictHostKeyChecking no # ~/.ssh/configSkip host key verification (dev only — insecure!)
scpscp file.txt user@host:/remote/path/Copy file to remote host
scp -rscp -r ./local-dir/ user@host:/remote/Copy directory recursively
scp -Pscp -P 2222 file.txt user@host:/path/SCP on non-standard port
scp from remotescp user@host:/remote/file.txt ./local/Download file from remote
sftpsftp user@hostInteractive SFTP session
sftp putsftp> put localfile remotefileUpload file in SFTP session
sftp getsftp> get remotefile localfileDownload file in SFTP session
sftp mputsftp> mput *.htmlUpload multiple files
rsyncrsync -avz ./local/ user@host:/remote/Sync files — only transfers changes
rsync --deletersync -avz --delete ./local/ user@host:/remote/Delete files on remote not in local
rsync --dry-runrsync -avz --dry-run ./local/ user@host:/remote/Preview changes without syncing
rsync -ersync -avz -e 'ssh -p 2222' ./local/ user@host:/remote/rsync over non-standard SSH port
/etc/sshd_configPermitRootLogin no, PasswordAuthentication noServer SSH hardening configuration

💡 Example

# ── SSH Key Setup ─────────────────────────────────────────────
# Generate ED25519 key (preferred — faster and more secure than RSA)
ssh-keygen -t ed25519 -C "alice@mywebuniversity.com" -f ~/.ssh/mwu_ed25519
# Files created: ~/.ssh/mwu_ed25519 (private) and ~/.ssh/mwu_ed25519.pub (public)

# View public key (copy this to server's authorized_keys)
cat ~/.ssh/mwu_ed25519.pub

# Copy public key to server
ssh-copy-id -i ~/.ssh/mwu_ed25519.pub ubuntu@mywebuniversity.com
# Or manually: cat ~/.ssh/mwu_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# ── ~/.ssh/config ─────────────────────────────────────────────
cat > ~/.ssh/config << 'EOF'
Host mwu
    HostName      mywebuniversity.com
    User          ubuntu
    IdentityFile  ~/.ssh/mwu_ed25519
    Port          22
    ServerAliveInterval 60
    ServerAliveCountMax 3

Host mwu-jump
    HostName      192.168.1.10
    User          ubuntu
    IdentityFile  ~/.ssh/mwu_ed25519
    ProxyJump     mwu          # connect through mwu first

Host *
    AddKeysToAgent    yes
    IdentitiesOnly    yes
    StrictHostKeyChecking accept-new
EOF
chmod 600 ~/.ssh/config

# Now connect simply:
ssh mwu                        # instead of: ssh -i ~/.ssh/mwu_ed25519 ubuntu@mywebuniversity.com
ssh mwu-jump                   # jump through bastion

# ── SSH Tunnels ───────────────────────────────────────────────
# Access remote PostgreSQL on localhost:5432
ssh -L 5432:localhost:5432 mwu -N -f
psql -h localhost -p 5432 -U admin mywebuniversity

# Access remote Redis on localhost:6379
ssh -L 6379:localhost:6379 mwu -N -f
redis-cli -h localhost

# Access remote web server through firewall
ssh -L 8080:localhost:80 mwu -N -f
curl http://localhost:8080/

# ── File Transfer ─────────────────────────────────────────────
# SCP — simple file copy
scp index.html mwu:/var/www/React/prod/
scp -r ./html/ mwu:/var/www/React/prod/
scp mwu:/var/log/apache2/error.log ./error.log  # download

# rsync — smart sync (only transfers changes)
rsync -avz --progress ./html/ mwu:/var/www/React/prod/
rsync -avz --delete   ./html/ mwu:/var/www/React/prod/  # mirror (deletes remote extras)
rsync -avz --exclude='*.log' --exclude='.git/' ./  mwu:/app/

# ── SSH server hardening /etc/ssh/sshd_config ─────────────────
sudo tee /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
PermitRootLogin          no
PasswordAuthentication   no
PubkeyAuthentication     yes
PermitEmptyPasswords     no
X11Forwarding            no
MaxAuthTries             3
LoginGraceTime           30
AllowUsers               ubuntu deploy
ClientAliveInterval      300
ClientAliveCountMax      2
Protocol                 2
EOF
sudo sshd -t          # test config
sudo systemctl reload sshd

# ── Python: Paramiko SSH ──────────────────────────────────────
# pip install paramiko
import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('mywebuniversity.com', username='ubuntu',
               key_filename='/home/user/.ssh/mwu_ed25519')

# Run commands
stdin, stdout, stderr = client.exec_command('df -h / && uptime')
print(stdout.read().decode())

# Upload file
sftp = client.open_sftp()
sftp.put('deploy.sh', '/tmp/deploy.sh')
sftp.close()
client.close()
# python3 ssh_demo.py

← SSL & TLS / OpenSSL  |  🏠 Index  |  REST APIs & curl →