SSH
Appearance
SSH
SSH (Secure Shell) is the fundamental protocol for secure remote access. Essential for server administration, development workflows, and secure file transfer.
Quick Reference
| Task | Command |
|---|---|
| Connect | ssh user@host
|
| Copy file to remote | scp file.txt user@host:/path/
|
| Copy file from remote | scp user@host:/path/file.txt .
|
| Sync directories | rsync -avz dir/ user@host:/path/
|
| Local port forward | ssh -L 8080:localhost:80 user@host
|
| Remote port forward | ssh -R 9090:localhost:3000 user@host
|
| SOCKS proxy | ssh -D 1080 user@host
|
SSH Key Setup
Generate Keys
# Modern Ed25519 (recommended) ssh-keygen -t ed25519 -C "[email protected]" # RSA 4096-bit (legacy compatibility) ssh-keygen -t rsa -b 4096 -C "[email protected]"
Copy Key to Server
# Automatic method ssh-copy-id user@hostname # Manual method cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
SSH Config
The config file (~/.ssh/config) eliminates repetitive typing:
# Personal VPS
Host vps
HostName 123.45.67.89
User debian
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 30
ServerAliveCountMax 3
# Jump through bastion
Host internal-server
HostName 10.0.0.50
User admin
ProxyJump bastion
# Bastion/jump host
Host bastion
HostName bastion.example.com
User jumpuser
IdentityFile ~/.ssh/bastion_key
# Wildcard for work servers
Host *.work.example.com
User workuser
IdentityFile ~/.ssh/work_key
ForwardAgent yes
Useful options:
ServerAliveInterval 30- Keep connection aliveServerAliveCountMax 3- Retry 3 times before disconnectProxyJump host- Jump through another hostForwardAgent yes- Forward SSH agent (use carefully)LocalForward 8080 localhost:80- Persistent port forwardCompression yes- Enable compression
Port Forwarding
Local Forward
Access remote service locally:
# Access remote PostgreSQL on localhost:5433 ssh -L 5433:localhost:5432 user@dbserver # Access internal web app ssh -L 8080:internal-app:80 user@bastion
Remote Forward
Expose local service to remote:
# Let remote server access your local dev server ssh -R 9000:localhost:3000 user@remote # Expose to all interfaces (requires GatewayPorts yes on server) ssh -R 0.0.0.0:9000:localhost:3000 user@remote
Dynamic Forward (SOCKS Proxy)
# Create SOCKS5 proxy ssh -D 1080 user@host # Use with curl curl --socks5 localhost:1080 https://example.com
macOS Setup
Enable SSH Server
- macOS Ventura+: System Settings → General → Sharing → "Remote Login" ON
- Older macOS: System Preferences → Sharing → "Remote Login"
Prevent Sleep (for always-on Mac)
sudo pmset -c sleep 0 sudo pmset -c disablesleep 1 sudo pmset -c womp 1 # Wake on network
Keychain Integration
Add to ~/.ssh/config:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Linux/Debian Server Setup
Install and Enable
sudo apt update && sudo apt install openssh-server sudo systemctl enable ssh sudo systemctl start ssh
Harden SSH
Edit /etc/ssh/sshd_config:
# Disable password auth (keys only) PasswordAuthentication no ChallengeResponseAuthentication no # Disable root login PermitRootLogin no # Limit users AllowUsers debian # Change port (optional security through obscurity) # Port 2222 # Timeout settings ClientAliveInterval 300 ClientAliveCountMax 2
Apply changes: sudo systemctl reload ssh
Mosh (Mobile Shell)
For unstable connections (WiFi, mobile, high latency):
# Install (both client and server) brew install mosh # macOS sudo apt install mosh # Debian # Connect mosh user@hostname # With custom port mosh --ssh="ssh -p 2222" user@hostname
Why Mosh:
- Survives IP changes and sleep/wake
- Local echo for instant feedback
- UDP-based, handles packet loss
Troubleshooting
Connection Refused
# Check if SSH is running sudo systemctl status ssh # Linux sudo systemsetup -getremotelogin # macOS # Check if port is open nc -zv hostname 22 # Firewall issues sudo ufw status # UFW sudo iptables -L -n # iptables
Permission Denied
# Fix key permissions (must be restrictive) chmod 700 ~/.ssh chmod 600 ~/.ssh/id_* chmod 644 ~/.ssh/id_*.pub chmod 600 ~/.ssh/authorized_keys # Debug connection ssh -vvv user@hostname
Host Key Changed
# Remove old host key ssh-keygen -R hostname # Or edit ~/.ssh/known_hosts manually
Slow Connection
# Often DNS-related, disable reverse lookup on server # Add to /etc/ssh/sshd_config: UseDNS no
Advanced Techniques
SSH Agent
# Start agent eval $(ssh-agent -s) # Add key ssh-add ~/.ssh/id_ed25519 # List loaded keys ssh-add -l
Multiplexing
Speed up multiple connections to same host:
# Add to ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Run Remote Commands
# Single command ssh user@host 'ls -la /var/log' # Multiple commands ssh user@host 'cd /app && git pull && pm2 restart all' # With sudo ssh -t user@host 'sudo systemctl restart nginx'
Copy with Progress
# rsync with progress rsync -avz --progress largefile.tar.gz user@host:/path/ # scp with compression scp -C largefile.tar.gz user@host:/path/
Related
| ⚡ Technical | |
|---|---|
| Core | Technical · CLI · Dotfiles · Nvim · SSH · VPS |
| Tools | Sketchybar · ArchiveBox · ThinkPad Linux |
| Systems | Automation · Personal APIs · Quantified Self |
| Reference | Runbooks · New Computer Runbook · Syntax guide |