SSH Config File: Save Time with Aliases, Keys, and Tunnels

4 min read
Beginner SSH Linux Security Sysadmin

If you manage more than one server, you have probably typed something like this hundreds of times:

ssh -i ~/.ssh/work_key -p 2222 [email protected]

Every single time. The IP, the key, the port, the username. It gets old fast.

The SSH config file (~/.ssh/config) lets you define all of this once and then connect with just:

ssh myserver

This guide shows you how to set it up, with practical examples for every common scenario.

The Config File

The SSH config file lives at ~/.ssh/config. If it does not exist, create it:

touch ~/.ssh/config
chmod 600 ~/.ssh/config

The permissions must be 600 (owner read/write only) or SSH will refuse to use it.

Basic Host Alias

The simplest use case — give a server a short name:

Host myserver
    HostName 10.0.0.35
    User sam

Now instead of ssh [email protected], just type:

ssh myserver

This also works with scp, rsync, and any tool that uses SSH:

scp file.txt myserver:/tmp/
rsync -avz ./project/ myserver:/opt/project/

Common Options

Host myserver
    HostName 10.0.0.35
    User sam
    Port 2222
    IdentityFile ~/.ssh/work_key
    IdentitiesOnly yes
    ServerAliveInterval 60
    ServerAliveCountMax 3
    Compression yes
Option Purpose
HostName The actual IP or domain
User Username to log in as
Port SSH port (default 22)
IdentityFile Path to private key
IdentitiesOnly Only use the specified key (don't try others)
ServerAliveInterval Send keepalive every N seconds (prevents timeout)
ServerAliveCountMax Disconnect after N missed keepalives
Compression Compress data (useful for slow connections)

Multiple Servers

Host web
    HostName 10.0.0.10
    User www-data

Host db
    HostName 10.0.0.20
    User postgres

Host monitor
    HostName 10.0.0.30
    User admin
    Port 2222

Host vpn
    HostName vpn.samnet.dev
    User sam
    IdentityFile ~/.ssh/vpn_key

Now you have four memorable aliases:

ssh web
ssh db
ssh monitor
ssh vpn

Wildcard and Default Settings

Apply settings to all hosts with Host *:

# Apply to all connections
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    AddKeysToAgent yes
    IdentitiesOnly yes

# Specific server
Host myserver
    HostName 10.0.0.35
    User sam

Apply to a group of hosts with patterns:

# All hosts in the 10.0.0.x range
Host 10.0.0.*
    User sam
    IdentityFile ~/.ssh/homelab_key

# All hosts ending in .prod
Host *.prod
    User deploy
    IdentityFile ~/.ssh/prod_key
    LogLevel ERROR

SSH Key Management

Generate a Key Pair

# Ed25519 (recommended, modern, fast)
ssh-keygen -t ed25519 -C "[email protected]"

# RSA 4096-bit (wider compatibility)
ssh-keygen -t rsa -b 4096 -C "[email protected]"

Different Keys for Different Servers

Host work-*
    IdentityFile ~/.ssh/work_ed25519

Host personal-*
    IdentityFile ~/.ssh/personal_ed25519

Host github.com
    IdentityFile ~/.ssh/github_ed25519

Host gitlab.com
    IdentityFile ~/.ssh/gitlab_ed25519

Copy Your Key to a Server

ssh-copy-id -i ~/.ssh/mykey.pub myserver

Or manually:

cat ~/.ssh/mykey.pub | ssh myserver "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Key Permissions

SSH is strict about permissions. If they are wrong, authentication fails silently:

chmod 700 ~/.ssh/
chmod 600 ~/.ssh/id_ed25519       # Private key
chmod 644 ~/.ssh/id_ed25519.pub   # Public key
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config

Use our Chmod Calculator to verify the correct permission values.

Jump Hosts (ProxyJump)

When you need to SSH through a bastion/jump host to reach an internal server:

# The bastion host (publicly accessible)
Host bastion
    HostName bastion.samnet.dev
    User sam

# Internal server (only reachable from bastion)
Host internal-db
    HostName 10.0.1.50
    User admin
    ProxyJump bastion

Now ssh internal-db automatically tunnels through the bastion:

Your laptop → bastion.samnet.dev → 10.0.1.50

Multi-Hop

Chain multiple jump hosts:

Host internal-deep
    HostName 172.16.0.100
    User root
    ProxyJump bastion,middle-server

SSH Tunnels (Port Forwarding)

Local Port Forward

Access a remote service as if it were local:

Host db-tunnel
    HostName 10.0.0.20
    User admin
    LocalForward 5433 localhost:5432
ssh db-tunnel
# Now connect to localhost:5433 to reach the remote PostgreSQL

Dynamic SOCKS Proxy

Route your browser traffic through a remote server:

Host socks-proxy
    HostName myserver.com
    User sam
    DynamicForward 1080
ssh socks-proxy
# Configure browser to use SOCKS5 proxy at localhost:1080

Remote Port Forward

Expose a local service to the remote server:

Host expose-local
    HostName myserver.com
    User sam
    RemoteForward 8080 localhost:3000

This makes your local port 3000 accessible as port 8080 on the remote server.

Security Best Practices

Disable Password Authentication

Once you have key-based auth working, disable passwords on the server:

# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password
sudo systemctl restart sshd

Change Default Port

Moving SSH off port 22 reduces automated brute-force attempts:

# /etc/ssh/sshd_config
Port 2222

Update your config file:

Host myserver
    HostName 10.0.0.35
    Port 2222

Use Fail2Ban

Install fail2ban to automatically ban IPs after failed login attempts:

sudo apt install fail2ban
sudo systemctl enable --now fail2ban

Audit Your SSH Access

Check who is logging into your servers:

# Recent logins
last -10

# Failed attempts
journalctl -u sshd | grep "Failed password"

# Currently connected
who

Complete Example Config

Here is a realistic ~/.ssh/config for someone managing a homelab and work servers:

# === Defaults ===
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    AddKeysToAgent yes
    IdentitiesOnly yes
    Compression yes

# === Homelab ===
Host homelab
    HostName 10.0.0.35
    User sam
    IdentityFile ~/.ssh/homelab_ed25519

Host nas
    HostName 10.0.0.50
    User admin
    Port 2222
    IdentityFile ~/.ssh/homelab_ed25519

# === Work ===
Host work-bastion
    HostName bastion.company.com
    User shesami
    IdentityFile ~/.ssh/work_ed25519

Host work-web
    HostName 10.1.0.10
    User deploy
    ProxyJump work-bastion
    IdentityFile ~/.ssh/work_ed25519

Host work-db
    HostName 10.1.0.20
    User postgres
    ProxyJump work-bastion
    LocalForward 5433 localhost:5432

# === Git ===
Host github.com
    IdentityFile ~/.ssh/github_ed25519

Host gitlab.com
    IdentityFile ~/.ssh/gitlab_ed25519

Related Tools