Quick reference tables
SSH key generation
| Command | What it does |
|---|---|
ssh-keygen -t ed25519 -C "[email protected]" | Generate Ed25519 key (recommended) |
ssh-keygen -t rsa -b 4096 -C "[email protected]" | Generate RSA 4096 (legacy systems) |
ssh-keygen -t ed25519 -f ~/.ssh/work_key | Custom filename |
ssh-keygen -p -f ~/.ssh/id_ed25519 | Change passphrase on existing key |
ssh-keygen -l -f ~/.ssh/id_ed25519.pub | Show key fingerprint |
SSH connections
| Command | What it does |
|---|---|
ssh user@host | Connect to a host |
ssh -p 2222 user@host | Non-standard port |
ssh -i ~/.ssh/mykey user@host | Use specific key |
ssh -v user@host | Verbose (debug connection issues) |
ssh -A user@host | Enable agent forwarding |
ssh -J jump@bastion user@target | Jump host (ProxyJump) |
ssh user@host "ls /var/log" | Run command without interactive shell |
Copy keys & files
| Command | What it does |
|---|---|
ssh-copy-id user@host | Copy public key to server |
ssh-copy-id -i ~/.ssh/mykey.pub user@host | Copy specific key |
scp file.txt user@host:/remote/path/ | Copy file to remote |
scp user@host:/remote/file.txt ./ | Copy file from remote |
scp -r dir/ user@host:/path/ | Copy directory recursively |
rsync -avz src/ user@host:/dest/ | Sync directories (resumable) |
SSH agent
| Command | What it does |
|---|---|
eval "$(ssh-agent -s)" | Start ssh-agent |
ssh-add ~/.ssh/id_ed25519 | Add key to agent |
ssh-add -l | List keys in agent |
ssh-add -d ~/.ssh/id_ed25519 | Remove key from agent |
ssh-add -D | Remove all keys from agent |
ssh-add -t 3600 ~/.ssh/id_ed25519 | Add with 1-hour expiry |
SSH tunnels / port forwarding
| Command | What it does |
|---|---|
ssh -L 8080:localhost:80 user@host | Forward local 8080 → remote 80 |
ssh -R 8080:localhost:3000 user@host | Forward remote 8080 → local 3000 |
ssh -D 1080 user@host | SOCKS5 proxy on local port 1080 |
ssh -N -L 5432:localhost:5432 user@host | DB tunnel (no shell, just tunnel) |
ssh -f -N -L 8080:localhost:80 user@host | Background tunnel |
GPG key management
| Command | What it does |
|---|---|
gpg --gen-key | Generate a new GPG key |
gpg --full-generate-key | Full key generation (custom settings) |
gpg --list-keys | List all public keys |
gpg --list-secret-keys | List private keys |
gpg --export -a "Name" | Export public key (ASCII) |
gpg --export-secret-keys -a "Name" | Export private key |
gpg --import key.asc | Import a key |
gpg --delete-key "Name" | Delete a public key |
gpg --delete-secret-key "Name" | Delete a private key |
gpg --send-keys KEY_ID | Upload to keyserver |
gpg --recv-keys KEY_ID | Download from keyserver |
GPG encryption & signing
| Command | What it does |
|---|---|
gpg -e -r "[email protected]" file.txt | Encrypt file for recipient |
gpg -d file.txt.gpg | Decrypt file |
gpg --sign file.txt | Sign file (binary signature) |
gpg --clearsign file.txt | Sign with readable text |
gpg --detach-sign file.txt | Detached signature (.sig file) |
gpg --verify file.txt.sig file.txt | Verify signature |
Git commit signing
| Command | What it does |
|---|---|
git config --global user.signingkey KEY_ID | Set signing key |
git config --global commit.gpgsign true | Sign all commits |
git commit -S -m "message" | Sign this commit |
git log --show-signature | Show signatures in log |
git verify-commit HEAD | Verify last commit signature |
Detailed sections
SSH config file — stop typing long commands
Create ~/.ssh/config to give servers short aliases:
# Personal GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
# Work GitHub
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/work_key
# Remote server
Host myserver
HostName 192.168.1.100
User ubuntu
Port 22
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
# Bastion jump host
Host internal-server
HostName 10.0.0.50
User ec2-user
ProxyJump [email protected]
IdentityFile ~/.ssh/prod_key
Now you can just:
ssh myserver # instead of: ssh -i ~/.ssh/id_ed25519 [email protected]
git clone github-work:org/repo # uses work key automatically
ssh internal-server # jumps through bastion automatically
Add SSH key to GitHub / GitLab
# 1. Generate key
ssh-keygen -t ed25519 -C "[email protected]"
# 2. Start agent and add key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# 3. Copy public key to clipboard
cat ~/.ssh/id_ed25519.pub # copy this output
# On macOS:
pbcopy < ~/.ssh/id_ed25519.pub
# On Linux:
xclip -selection clipboard < ~/.ssh/id_ed25519.pub
# 4. Add to GitHub: Settings → SSH Keys → New SSH Key
# 5. Test connection
ssh -T [email protected]
# "Hi username! You've successfully authenticated..."
SSH agent forwarding — connecting from server to server
If you SSH into a server and need to clone a private repo from there, agent forwarding lets you use your local keys without copying them to the server.
# Connect with agent forwarding
ssh -A user@jumpserver
# Now on jumpserver, your local keys work:
git clone [email protected]:org/private-repo.git
# Or connect to another server from there
ssh user@internal-server
Set it permanently in ~/.ssh/config:
Host jumpserver
HostName jump.example.com
ForwardAgent yes
Security note: Only enable agent forwarding on servers you trust. Anyone with root on that server can use your forwarded agent.
Database tunneling — access remote DB locally
This is one of the most useful SSH tricks for developers:
# Forward remote PostgreSQL to local port
ssh -N -L 5432:localhost:5432 user@prod-server
# Now connect with any local Postgres client:
psql -h localhost -U dbuser mydb
# or open TablePlus, DBeaver, etc. connecting to localhost:5432
Run it in background:
ssh -f -N -L 5432:localhost:5432 user@prod-server
# -f = background, -N = no command, just tunnel
Kill it:
ps aux | grep "5432:localhost" | awk '{print $2}' | xargs kill
Set up GPG for signed commits
Signed commits show a “Verified” badge on GitHub. Here’s the full setup:
# 1. Generate GPG key
gpg --full-generate-key
# Choose: RSA and RSA, 4096 bits, key doesn't expire
# Enter your name and your GitHub email
# 2. Get your key ID
gpg --list-secret-keys --keyid-format=long
# sec rsa4096/3AA5C34371567BD2 2024-01-01
# ^^^^^^^^^^^^^^^^ this is your key ID
# 3. Export public key for GitHub
gpg --armor --export 3AA5C34371567BD2
# Copy the output
# 4. Add to GitHub: Settings → SSH and GPG keys → New GPG Key
# 5. Configure Git
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true
git config --global gpg.program gpg
# 6. On macOS, fix GPG agent (required)
brew install pinentry-mac
echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
# 7. Test — commit should be signed
git commit -m "test: signed commit"
git log --show-signature -1
Encrypt files with GPG
# Encrypt for someone else (they need their key imported)
gpg --encrypt --armor -r [email protected] secrets.txt
# Creates: secrets.txt.asc
# Encrypt for yourself
gpg --encrypt --armor -r [email protected] secrets.txt
# Decrypt
gpg --decrypt secrets.txt.asc > secrets.txt
# Symmetric encryption (password only, no keys)
gpg --symmetric --armor secrets.txt
# Enter password twice
# Creates: secrets.txt.asc
# Decrypt symmetric
gpg --decrypt secrets.txt.asc
SSH hardening — server-side config
In /etc/ssh/sshd_config:
# Disable password auth (use keys only)
PasswordAuthentication no
ChallengeResponseAuthentication no
# Disable root login
PermitRootLogin no
# Only allow specific users
AllowUsers ubuntu deploy
# Change default port (security through obscurity, but reduces log noise)
Port 2222
# Timeout idle connections
ClientAliveInterval 300
ClientAliveCountMax 2
After editing:
sudo sshd -t # test config for errors
sudo systemctl reload sshd
New to SSH keys? Start with How to Set Up SSH Keys for GitHub.
Related Reading.
curl Cheat Sheet: API Testing, Auth & File Upload
Complete curl reference — GET and POST requests, headers, authentication, file upload, response inspection, timing breakdown, webhook testing, and scripting patterns.
Linux & Bash Cheat Sheet: Commands Every Dev Needs
Complete Linux and Bash reference — file operations, permissions, processes, grep, find, networking, pipes, cron jobs, SSH, and shell scripting.
Git Cheat Sheet: Every Command You Actually Need
Complete Git reference with copy-paste commands for setup, staging, branching, merging, rebasing, stashing, undoing mistakes, remotes, and log inspection.