SSH Config and Tips

ssh linux remote security


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

OptionDescription
HostNameActual hostname/IP
UserUsername to connect as
PortSSH port (default 22)
IdentityFilePath to private key
IdentitiesOnlyOnly use specified key
ForwardAgentForward SSH agent
ProxyJumpJump through another host
ProxyCommandCustom proxy command
LocalForwardLocal port forward
RemoteForwardRemote port forward
DynamicForwardSOCKS proxy
ServerAliveIntervalKeepalive interval (seconds)
ServerAliveCountMaxMax missed keepalives
CompressionEnable compression
StrictHostKeyCheckingHost 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 -D

Jump 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 bastion

ProxyCommand (Legacy/Custom)

Host internal
    HostName 10.0.0.50
    ProxyCommand ssh -W %h:%p bastion

Port 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:3306

Access: localhost:8080remote: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:3000

Access: 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 1080

Use: 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@server

Multiplexing (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/sockets

Troubleshooting

Verbose Connection

# Increasing verbosity
ssh -v user@server
ssh -vv user@server
ssh -vvv user@server

Test Config Syntax

ssh -G hostname

Common Issues

IssueSolution
Permission denied (publickey)Check key permissions, ssh-add, verify authorized_keys
Host key verification failedRemove old key: ssh-keygen -R hostname
Connection refusedCheck port, firewall, sshd running
Connection timeoutCheck network, firewall, correct IP
Too many authentication failuresUse 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_keys

Security 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/mountpoint