1. Library
  2. Servers and Infrastructure
  3. Remote Access

Updated 10 hours ago

The SSH config file eliminates repetition. Instead of typing ssh -p 2222 -i ~/.ssh/id_ed25519_production deploy@prod.example.com every time you deploy, you type ssh prod. Every character you don't type is friction you don't feel.

If you connect to multiple servers with different usernames, keys, or ports, the config file transforms SSH from tedious to effortless.

What Is the SSH Config File?

The SSH config file is a plain text file at ~/.ssh/config that defines connection settings. You describe each server once—hostname, username, port, key—then reference it by a short nickname forever after.

SSH client commands (ssh, scp, sftp) all read this file, so your shortcuts work everywhere.

If the file doesn't exist, create it:

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

The permissions matter. SSH ignores the config file if others can read it.

Basic Structure

The config file uses Host sections followed by indented options:

Host prod
    HostName prod.example.com
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_production

Now ssh prod does what ssh -p 2222 -i ~/.ssh/id_ed25519_production deploy@prod.example.com used to do.

The Host line defines a pattern. When you type ssh prod, SSH scans the config file for a matching Host section and applies those settings.

Practical Examples

Simple server shortcut:

Host web
    HostName webserver.example.com
    User admin

ssh web connects to webserver.example.com as admin.

Using a specific key:

Host production
    HostName prod.example.com
    User deploy
    IdentityFile ~/.ssh/id_ed25519_production

When you have multiple keys, this ensures the right one is used without thinking.

Non-standard port:

Host router
    HostName 192.168.1.1
    User root
    Port 2222

No more forgetting -p 2222.

Jump host configuration:

Host internal
    HostName 10.0.1.50
    User admin
    ProxyJump bastion

Host bastion
    HostName bastion.example.com
    User admin

When you ssh internal, SSH first connects to bastion, then from there to the internal server. SSH handles the two-hop choreography invisibly. You just say where you want to go.

Patterns and Wildcards

The Host directive supports patterns for applying settings to multiple servers.

Wildcards:

Host *.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_work

Host *.personal.net
    User myname
    IdentityFile ~/.ssh/id_ed25519_personal

Work servers get work credentials. Personal servers get personal credentials. Automatically.

Multiple patterns:

Host web* db*
    User admin
    Port 2222

Applies to any nickname starting with "web" or "db".

Default settings for all hosts:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

Host * matches everything. Settings here apply to all connections unless a more specific section overrides them. Specific hosts must come before general patterns—SSH uses the first match.

Useful Configuration Options

Connection keep-alive:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

Sends a keep-alive every 60 seconds. After three failures, the connection is considered dead. Prevents those mysterious frozen terminals.

Connection multiplexing:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h:%p
    ControlPersist 600

The first connection to a server creates a master connection. Subsequent connections reuse it, making them nearly instantaneous. ControlPersist keeps the master alive for 10 minutes after the last session closes.

Create the sockets directory first: mkdir -p ~/.ssh/sockets

Compression:

Host slow-link
    Compression yes

Helps over slow connections or when transferring lots of text.

Agent forwarding:

Host trusted
    ForwardAgent yes

Lets the remote server use your local SSH keys for further connections. Only enable this for servers you fully trust—it's powerful but has security implications.

Disable host key checking (development only):

Host vagrant-*
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

Skips host key verification. Use only for disposable VMs you recreate constantly. Never for production.

Force IPv4:

Host ipv4-only
    AddressFamily inet

For servers or networks with IPv6 issues.

Connection timeout:

Host flaky
    ConnectTimeout 10

Give up after 10 seconds instead of hanging.

Dynamic Configuration with Match

The Match directive enables conditions beyond hostname matching.

Match by user:

Match user admin
    IdentityFile ~/.ssh/id_ed25519_admin

Match user deploy
    IdentityFile ~/.ssh/id_ed25519_deploy

Match by hostname and user:

Match host "*.internal.example.com" user admin
    ProxyJump bastion.example.com

Use the jump host only for internal servers when connecting as admin.

Organizing Large Config Files

Use comments:

# Production
Host prod-web
    HostName web.prod.example.com
    User deploy

# Development
Host dev-web
    HostName web.dev.example.com
    User developer

# Personal
Host blog
    HostName blog.mysite.com
    User me

Comments start with #. Future you will thank present you.

Split large configs:

Include ~/.ssh/config.d/*

Then create ~/.ssh/config.d/work.conf, ~/.ssh/config.d/personal.conf, etc.

Common Gotchas

Order matters. SSH uses the first matching configuration:

# Wrong order
Host *
    User admin

Host webserver
    User deploy  # Never used—Host * already matched
# Correct order
Host webserver
    User deploy

Host *
    User admin

Permissions must be correct:

chmod 600 ~/.ssh/config

Debug with -G:

ssh -G hostname

Shows the final configuration SSH will use without connecting. Invaluable for debugging.

Security Considerations

  • Never store passwords in the config file. There's no option for this—intentionally.
  • Enable ForwardAgent only for servers you completely trust.
  • Don't disable StrictHostKeyChecking for production servers.
  • Protect your config file—it reveals server names, usernames, and connection patterns.
  • Be careful with broad patterns that might apply settings where they shouldn't.

Advanced Tricks

Different keys for different Git hosts:

Host github.com
    IdentityFile ~/.ssh/id_ed25519_github

Host gitlab.work.com
    IdentityFile ~/.ssh/id_ed25519_work

Essential when you have work and personal GitHub accounts.

Proxy through SOCKS:

Host through-proxy
    ProxyCommand nc -x localhost:1080 %h %p

Local command on connect:

Host logged
    LocalCommand echo "Connected to %h at $(date)" >> ~/.ssh/connection.log
    PermitLocalCommand yes

Key Takeaways

  • The SSH config file (~/.ssh/config) turns long commands into short nicknames.
  • Host sections define hostname, username, port, and key for each server.
  • Wildcards (Host *.example.com or Host *) apply settings to multiple servers. Specific hosts must come before general patterns.
  • Connection multiplexing (ControlMaster, ControlPath, ControlPersist) makes subsequent connections nearly instant.
  • Keep-alive settings (ServerAliveInterval) prevent idle timeouts.
  • ProxyJump handles jump hosts transparently.
  • Use chmod 600 for permissions and ssh -G hostname for debugging.

Frequently Asked Questions About SSH Config

Was this page helpful?

😔
🤨
😃
SSH Config Tips • Library • Connected