SSH Config and Tips
SSH Config File
Location: ~/.ssh/config
Basic Host Entry
Host myserver
HostName 192.168.1.100
User admin
Port 22
Then connect with: ssh myserver
Full Example
# Default settings for all hosts
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
IdentitiesOnly yes
# Work server
Host work
HostName work.example.com
User jsmith
IdentityFile ~/.ssh/id_work
ForwardAgent yes
# Jump through bastion
Host internal
HostName 10.0.0.50
User admin
ProxyJump bastion
# Bastion/jump host
Host bastion
HostName bastion.example.com
User jump
IdentityFile ~/.ssh/id_bastion
# Multiple hosts with pattern
Host dev-*
User developer
IdentityFile ~/.ssh/id_dev
# Specific server in pattern
Host dev-db
HostName 10.1.1.100
Host dev-web
HostName 10.1.1.101
Common Config Options
| Option | Description |
|---|---|
HostName | Actual hostname/IP |
User | Username to connect as |
Port | SSH port (default 22) |
IdentityFile | Path to private key |
IdentitiesOnly | Only use specified key |
ForwardAgent | Forward SSH agent |
ProxyJump | Jump through another host |
ProxyCommand | Custom proxy command |
LocalForward | Local port forward |
RemoteForward | Remote port forward |
DynamicForward | SOCKS proxy |
ServerAliveInterval | Keepalive interval (seconds) |
ServerAliveCountMax | Max missed keepalives |
Compression | Enable compression |
StrictHostKeyChecking | Host key verification |
Key Management
Generate Key
# ED25519 (recommended)
ssh-keygen -t ed25519 -C "your@email.com"
# RSA (4096 bit)
ssh-keygen -t rsa -b 4096 -C "your@email.com"
# With custom filename
ssh-keygen -t ed25519 -f ~/.ssh/id_work -C "work key"Copy Key to Server
# Standard method
ssh-copy-id user@server
# Specific key
ssh-copy-id -i ~/.ssh/id_work.pub user@server
# Manual method
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"SSH Agent
# Start agent
eval "$(ssh-agent -s)"
# Add key to agent
ssh-add ~/.ssh/id_ed25519
# Add with timeout (12 hours)
ssh-add -t 43200 ~/.ssh/id_ed25519
# List keys in agent
ssh-add -l
# Remove all keys
ssh-add -DJump Hosts / Bastion
ProxyJump (Preferred)
# Command line
ssh -J bastion.example.com internal-server
# Multiple jumps
ssh -J jump1.example.com,jump2.example.com target
# In config
Host internal
HostName 10.0.0.50
ProxyJump bastionProxyCommand (Legacy/Custom)
Host internal
HostName 10.0.0.50
ProxyCommand ssh -W %h:%p bastionPort Forwarding
Local Forward (Access Remote Service Locally)
# Forward local:8080 to remote-server:80
ssh -L 8080:localhost:80 user@server
# Forward to different host through server
ssh -L 8080:internal-db:3306 user@bastion
# In config
Host tunnel-db
HostName bastion.example.com
LocalForward 3306 internal-db:3306Access: localhost:8080 → remote:80
Remote Forward (Expose Local Service)
# Expose local:3000 on remote:8080
ssh -R 8080:localhost:3000 user@server
# In config
Host expose-local
HostName server.example.com
RemoteForward 8080 localhost:3000Access: server:8080 → your localhost:3000
Dynamic Forward (SOCKS Proxy)
# Create SOCKS proxy on local:1080
ssh -D 1080 user@server
# In config
Host socks-proxy
HostName proxy.example.com
DynamicForward 1080Use: Configure browser/app to use SOCKS5 proxy localhost:1080
Persistent Tunnels
# Background tunnel that reconnects
ssh -f -N -L 8080:localhost:80 user@server
# Options:
# -f Background
# -N No command (just tunnel)
# With autossh (auto-reconnect)
autossh -M 0 -f -N -L 8080:localhost:80 user@serverMultiplexing (Connection Sharing)
Speed up multiple connections to same host:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Create sockets directory:
mkdir -p ~/.ssh/socketsTroubleshooting
Verbose Connection
# Increasing verbosity
ssh -v user@server
ssh -vv user@server
ssh -vvv user@serverTest Config Syntax
ssh -G hostnameCommon Issues
| Issue | Solution |
|---|---|
| Permission denied (publickey) | Check key permissions, ssh-add, verify authorized_keys |
| Host key verification failed | Remove old key: ssh-keygen -R hostname |
| Connection refused | Check port, firewall, sshd running |
| Connection timeout | Check network, firewall, correct IP |
| Too many authentication failures | Use IdentitiesOnly yes |
Key File Permissions
# Fix permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/id_*.pub
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/authorized_keysSecurity Best Practices
Server-Side (/etc/ssh/sshd_config)
# Disable root login
PermitRootLogin no
# Disable password auth (key only)
PasswordAuthentication no
# Limit users
AllowUsers admin deploy
# Change port (security through obscurity)
Port 2222
# Disable empty passwords
PermitEmptyPasswords no
# Limit auth attempts
MaxAuthTries 3
Client-Side
Host *
# Use only specified keys
IdentitiesOnly yes
# Hash known_hosts
HashKnownHosts yes
# Verify host keys
StrictHostKeyChecking ask
Useful One-Liners
# Copy file to remote
scp file.txt user@server:/path/
# Copy file from remote
scp user@server:/path/file.txt .
# Copy directory
scp -r ./dir user@server:/path/
# Rsync over SSH
rsync -avz -e ssh ./local/ user@server:/remote/
# Execute command remotely
ssh user@server "ls -la /var/log"
# Execute local script remotely
ssh user@server 'bash -s' < local_script.sh
# Mount remote filesystem (SSHFS)
sshfs user@server:/remote/path /local/mountpointRelated
- Linux - Common Commands
- Git - Cheat Sheet - For SSH-based git auth