Skip to main content

SSH Config Cheatsheet — 50+ Directives for ~/.ssh/config

SSH config cheatsheet — 50+ directives for ~/.ssh/config with copy-ready examples and common pitfalls.

  • Runs locally
  • Category Developer & DevOps
  • Best for Checking file type, size, metadata, and obvious mismatch signals before sharing.
Section:
51 directives
Basic (15)
HostHost <pattern> [<pattern2> ...]

Opens a config block that applies to hosts matching the pattern. Wildcards: * matches any sequence, ? matches any single character. For each directive, the first matching Host block wins — later blocks can add but not override already-set values.

Common pitfall: Host * (global defaults) must come LAST in the file. SSH processes blocks top-to-bottom and stops at the first match per directive, so a Host * at the top will shadow every specific block below it.

# ~/.ssh/config — specific host alias
Host dev
  HostName dev.example.com
  User alice
  Port 2222
  IdentityFile ~/.ssh/id_ed25519

# Connect: ssh dev
# Wildcard: any host in *.staging.company.com
Host *.staging.company.com
  User deployer
  IdentityFile ~/.ssh/staging_ed25519
# Global defaults — must be LAST
Host *
  ServerAliveInterval 60
  ServerAliveCountMax 3
  AddKeysToAgent yes
HostNameHostName <hostname|IP>

The real hostname or IP address to connect to. Use this when your Host alias does not match the actual server address. You can use a short alias in Host and put the full FQDN or IP here.

Host prod-api
  HostName 10.0.1.42
  User ubuntu
Host mysite
  HostName mysite.example.com
  User webmaster
UserUser <username>

Username to log in as. Without this, SSH uses your local username ($USER). Useful when the remote username differs from local — common with cloud VMs (ubuntu, ec2-user, admin).

Host aws-prod
  HostName 54.12.34.56
  User ec2-user
  IdentityFile ~/.ssh/aws_prod.pem
PortPort <number>

TCP port to connect to (default 22). Useful for hosts that run SSH on a non-standard port to avoid automated scanners or behind a firewall that only allows outbound 443.

Host jumpbox
  HostName jump.example.com
  Port 443
  User ops
IdentityFileIdentityFile <path>

Path to the private key file to use. Tilde expansion applies (~/.ssh/…). You can specify multiple IdentityFile lines in one block; SSH tries them in order. Relative paths are from $HOME.

Host github.com
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes
Host legacy-server
  IdentityFile ~/.ssh/id_rsa_legacy   # RSA fallback
IdentitiesOnlyIdentitiesOnly yes|no

When yes, SSH only offers the keys listed in IdentityFile for this host, ignoring any keys loaded in ssh-agent. Essential when you have multiple keys and the server rejects after too many auth attempts.

Common pitfall: Without IdentitiesOnly yes, SSH may offer every key in your agent. GitHub will reject connection after the first wrong key ("Too many authentication failures"). Always pair IdentityFile with IdentitiesOnly yes on GitHub hosts.

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes
AddKeysToAgentAddKeysToAgent yes|no|confirm|ask

Automatically add the private key to ssh-agent on first use so you only enter the passphrase once per session. `confirm` prompts on each use, `ask` prompts whether to add.

Host *
  AddKeysToAgent yes
  IdentityFile ~/.ssh/id_ed25519
ServerAliveIntervalServerAliveInterval <seconds>

Sends a keepalive packet to the server every N seconds over the encrypted channel. Prevents connection drops on idle sessions through NAT gateways, load balancers, or firewalls that close idle TCP connections.

Host *
  ServerAliveInterval 60
  ServerAliveCountMax 3
ServerAliveCountMaxServerAliveCountMax <number>

Number of unanswered keepalive packets before SSH closes the connection. With ServerAliveInterval 60 and ServerAliveCountMax 3, SSH gives up after 3 minutes of silence.

Host *
  ServerAliveInterval 60
  ServerAliveCountMax 3
  # Disconnects after 60 × 3 = 180 s of silence
ConnectTimeoutConnectTimeout <seconds>

Seconds before giving up on a TCP connection. The default is the OS TCP timeout (~75 s on Linux, 127 s on macOS). Reduce it for scripts that probe many hosts so you fail fast.

Host *
  ConnectTimeout 10
# In a script probing many servers:
# ssh -o ConnectTimeout=5 host
TCPKeepAliveTCPKeepAlive yes|no

OS-level TCP keepalives, separate from ServerAliveInterval. Helps detect broken connections (e.g. cable pulled) but goes through NAT tables less reliably. Usually combine both: TCPKeepAlive yes + ServerAliveInterval 60.

Host *
  TCPKeepAlive yes
  ServerAliveInterval 60
CompressionCompression yes|no

Enable gzip compression on the SSH stream. Helps on slow or high-latency links (mobile, satellite, VPN over WAN). Wastes CPU on fast LAN links where bandwidth is not the bottleneck.

Host remote-office
  HostName office.example.com
  Compression yes
LogLevelLogLevel QUIET|FATAL|ERROR|INFO|VERBOSE|DEBUG|DEBUG1|DEBUG2|DEBUG3

Verbosity of diagnostic messages from the SSH client. INFO is the default. DEBUG3 is equivalent to `ssh -vvv` and prints full protocol negotiation. Use QUIET to suppress banner messages in scripts.

Host debug-host
  LogLevel DEBUG3
  # Equivalent to: ssh -vvv debug-host
Host *
  LogLevel QUIET  # suppress banner in scripts
BatchModeBatchMode yes|no

In batch mode, SSH never prompts for a passphrase, password, or host key confirmation. Ideal for scripts and cron jobs where there is no terminal. If auth fails, SSH exits non-zero immediately.

Host deploy-target
  BatchMode yes
  StrictHostKeyChecking yes
  # Good for CI pipelines
ExitOnForwardFailureExitOnForwardFailure yes|no

Exit with an error if any requested port forward cannot be established. By default SSH connects even if a forward fails silently. Enable this in scripts where the forward is the whole point of the connection.

Host db-tunnel
  HostName bastion.example.com
  LocalForward 5433 db.internal:5432
  ExitOnForwardFailure yes
Advanced (14)
ProxyJumpProxyJump <[user@]host[:port]> [,<host2> ...]

Connect to the target through one or more jump hosts. SSH establishes a TCP tunnel through each jump host without opening a shell on them. Comma-separate for multi-hop chains. Requires OpenSSH 7.3+ (2016).

Common pitfall: ProxyJump requires the jump host to allow TCP forwarding (AllowTcpForwarding on the server). If the sysadmin disabled it, fall back to ProxyCommand.

# Single jump host
Host prod-db
  HostName db.private.example.com
  ProxyJump bastion.example.com

# Connect: ssh prod-db
# Multi-hop: jump1 → jump2 → target
Host deep-server
  HostName 10.10.1.5
  ProxyJump jump1.example.com,jump2.example.com

# Override jump host at command line:
# ssh -J other-jump prod-db
ProxyCommandProxyCommand <command>

Execute a command whose stdin/stdout become the SSH transport. More flexible than ProxyJump — use it with nc, socat, AWS SSM, Cloudflare Tunnel, or any custom proxy. %h and %p expand to the target host and port.

# Classic nc proxy (OpenBSD nc with -W flag)
Host private-host
  ProxyCommand ssh bastion nc -w 3 %h %p
# AWS SSM Session Manager (no inbound ports)
Host aws-private
  HostName i-0abc123def456789
  ProxyCommand aws ssm start-session --target %h \
    --document-name AWS-StartSSHSession --parameters portNumber=%p
LocalForwardLocalForward <localPort> <remoteHost:remotePort>

Forward a local port through the SSH connection to a remote host:port. `ssh -N host` in the background makes localhost:localPort reach remoteHost:remotePort as seen from the SSH server. Classic use: access a remote database locally.

Common pitfall: By default, LocalForward only binds to localhost (127.0.0.1), not all interfaces. To share the tunnel with other machines on your LAN, add `GatewayPorts yes` — but this opens the port to your whole local network.

# Access remote PostgreSQL locally on port 5433
Host db-tunnel
  HostName bastion.example.com
  LocalForward 5433 postgres.internal:5432

# Start tunnel: ssh -N db-tunnel
# Connect: psql -h localhost -p 5433 mydb
# Multiple forwards in one block
Host dev-tunnel
  HostName dev.example.com
  LocalForward 8080 app.internal:80
  LocalForward 9090 prometheus.internal:9090
RemoteForwardRemoteForward <remotePort> <localHost:localPort>

Forward a port on the remote server back to a local host:port. The remote machine can reach localHost:localPort through remotePort. Used to expose a local dev server to a remote machine, or to give a remote server access to a local service.

# Expose local dev server (port 3000) on remote port 8080
Host dev-server
  RemoteForward 8080 localhost:3000

# On remote: curl http://localhost:8080 → hits your local :3000
# VS Code Remote: forward local Git credential helper
Host vscode-host
  RemoteForward /run/user/1000/gnupg/S.gpg-agent ~/.gnupg/S.gpg-agent
DynamicForwardDynamicForward <localPort>

Opens a local SOCKS5 proxy on the specified port. Any application that supports SOCKS5 (browsers, curl, git) can route traffic through the SSH server. Useful for tunnelling office intranet traffic from home.

Host office-proxy
  HostName ssh.company.com
  DynamicForward 1080

# Start: ssh -N office-proxy
# Use:   curl --socks5 localhost:1080 http://intranet.company.com
# Browser: set SOCKS5 proxy to localhost:1080
ControlMasterControlMaster yes|no|auto|ask|autoask

Enable connection multiplexing. `auto` opens a new master if none exists, then reuses it for subsequent connections. Subsequent SSH, SCP, or rsync sessions to the same host share the existing connection — no new TCP handshake, no new key exchange.

Host *
  ControlMaster auto
  ControlPath ~/.ssh/cm/%r@%h:%p
  ControlPersist 10m

# Create socket dir first:
# mkdir -p ~/.ssh/cm && chmod 700 ~/.ssh/cm
ControlPathControlPath <path>

Path template for the multiplexing control socket file. %r expands to remote username, %h to hostname, %p to port. Keep it short — Unix sockets paths have a 104-byte limit on macOS, 108 on Linux.

Common pitfall: Long ControlPath values fail silently because Unix domain socket paths are limited to ~104 bytes on macOS. Use %C (hash of %l%h%p%r) for a compact path: `ControlPath ~/.ssh/cm/%C`.

Host *
  ControlPath ~/.ssh/cm/%r@%h:%p   # readable
  # or compact (avoid long-path bug):
  # ControlPath ~/.ssh/cm/%C
ControlPersistControlPersist yes|no|<time>

Keep the master socket alive for <time> after the last client disconnects. A value like 10m means the next `git push` within 10 minutes reuses the open socket and skips auth entirely. Without this, the socket closes when you close the terminal.

Host *
  ControlMaster auto
  ControlPath ~/.ssh/cm/%C
  ControlPersist 10m

# Check open masters: ssh -O check hostname
# Stop master:       ssh -O stop hostname
ForwardAgentForwardAgent yes|no

Forward your local ssh-agent to the remote host. Allows you to use your local private keys from the remote machine without copying keys there. Necessary when git-cloning from a remote server using your local GitHub key.

Common pitfall: Never enable ForwardAgent globally (Host *). If the remote host is compromised, an attacker can use your forwarded agent to authenticate as you to other servers. Scope it to specific, trusted jump hosts only.

# Only on a trusted bastion you control
Host bastion.example.com
  ForwardAgent yes
IncludeInclude <file|glob>

Include another SSH config file. Supports glob patterns. Useful for splitting config by project, team, or environment. Included files are processed in glob-expansion order before the rest of the current file.

# ~/.ssh/config
Include ~/.ssh/conf.d/work.conf
Include ~/.ssh/conf.d/personal.conf

# ~/.ssh/conf.d/work.conf
Host *.work.example.com
  User alice
  IdentityFile ~/.ssh/id_ed25519_work
RequestTTYRequestTTY yes|no|force|auto

Control TTY (pseudoterminal) allocation. `force` allocates a TTY even when stdin is not a terminal — useful for running interactive commands via pipes. `auto` (default) allocates if stdin is a TTY.

Host tmux-host
  RequestTTY force
  RemoteCommand tmux new-session -A -s main

# ssh tmux-host → auto-attaches tmux
SendEnvSendEnv <VARIABLE> [<VAR2> ...]

Send local environment variables to the remote session. The server must also allow them (AcceptEnv on the server side). Commonly used for LANG and LC_* to set the remote locale without logging in and running export.

Host *
  SendEnv LANG LC_*   # common default in OpenSSH
MatchMatch <criteria> [!]<value> [...]

Conditional block — applies directives only when the criteria match. Criteria include: User, Host, OriginalHost, LocalUser, LocalPort, Exec (runs a shell command), and All/Final. More powerful than Host when you need logic.

# Apply only when local username is alice
Match User alice
  IdentityFile ~/.ssh/id_ed25519_alice

# Apply when on VPN subnet (Exec runs locally)
Match Exec "ip addr show tun0 2>/dev/null | grep -q 10.8.0"
  ProxyJump none
ForwardX11ForwardX11 yes|no

Forward the X11 display from the remote server to your local X server. Lets you run GUI apps on the server and have their windows appear locally. Requires an X server on your local machine (XQuartz on macOS, Xming on Windows).

Host workstation
  ForwardX11 yes
  # or: ForwardX11Trusted yes (for older apps)
Security (12)
StrictHostKeyCheckingStrictHostKeyChecking yes|no|accept-new|ask

Controls what happens when the server's host key is not in known_hosts. `yes` refuses new keys (safe for prod). `accept-new` adds new keys automatically but rejects changed keys (good for automation). `no` accepts everything (dangerous). `ask` is the interactive default.

Common pitfall: StrictHostKeyChecking no in automation scripts disables TOFU (trust on first use) protection and opens you to MITM attacks. Use accept-new instead — it auto-trusts new servers but still rejects a changed key, which is the actual attack signal.

# Interactive use: ask (default)
Host *
  StrictHostKeyChecking ask

# CI/CD pipelines: accept new, reject changed keys
Host deploy-targets
  StrictHostKeyChecking accept-new
  UserKnownHostsFile ~/.ssh/known_hosts_ci
UserKnownHostsFileUserKnownHostsFile <path> [<path2> ...]

Path to the file that stores known host keys. Default is ~/.ssh/known_hosts. Use a different file per project or environment to isolate key trust domains. `/dev/null` disables known hosts entirely (combined with StrictHostKeyChecking no).

Host staging-*
  UserKnownHostsFile ~/.ssh/known_hosts_staging
  StrictHostKeyChecking accept-new
PasswordAuthenticationPasswordAuthentication yes|no

Enable or disable password authentication for this connection. Set to no to enforce key-based auth only, preventing accidental password fallback when a key agent is unavailable.

Host prod-*
  PasswordAuthentication no  # keys only
# To disable globally:
Host *
  PasswordAuthentication no
PubkeyAuthenticationPubkeyAuthentication yes|no

Enable or disable public key authentication. Default is yes. Rarely need to set this to no — but useful in BatchMode scripts where you know the host requires password/GSSAPI and you want to skip the key-offer phase.

Host kerberos-host
  PubkeyAuthentication no
  GSSAPIAuthentication yes
PreferredAuthenticationsPreferredAuthentications <method>[,<method2>...]

Order in which SSH tries authentication methods. Methods: gssapi-with-mic, hostbased, publickey, keyboard-interactive, password. Narrow this list to skip methods the server does not support and speed up auth.

# Force public key only (fail fast if no key)
Host prod-*
  PreferredAuthentications publickey
# For a host that only accepts passwords:
Host legacy-host
  PreferredAuthentications password
  PasswordAuthentication yes
CiphersCiphers <cipher>[,<cipher2>...]

List of symmetric ciphers in preference order. Restrict to modern ciphers for compliance (PCI-DSS, FIPS, NIST). Removing weak ciphers like arcfour/3des-cbc also eliminates negotiation overhead. Check the server's available ciphers first with `ssh -vvv`.

Host secure-host
  Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,chacha20-poly1305@openssh.com
MACsMACs <mac>[,<mac2>...]

Message Authentication Code algorithms in preference order. ETM (Encrypt-then-MAC) variants are more secure than MAC-then-encrypt. For compliance, restrict to hmac-sha2-* or the implicit ETM variants built into AES-GCM and ChaCha20-Poly1305.

Host compliance-host
  MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithmsKexAlgorithms <alg>[,<alg2>...]

Key exchange algorithm preference list. Modern choices: curve25519-sha256, ecdh-sha2-nistp256. Older servers may require diffie-hellman-group14-sha256. Removing weak DH groups (group1/group14-sha1) prevents downgrade attacks.

Host hardened-host
  KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521
HostKeyAlgorithmsHostKeyAlgorithms <alg>[,<alg2>...]

Accepted host key types in preference order. ed25519 is the modern choice — fast, small, and immune to timing side-channels. Restrict to ed25519 and ecdsa-sha2-nistp256 for new servers; keep rsa-sha2-512 for legacy compatibility.

Host modern-servers
  HostKeyAlgorithms ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512
CheckHostIPCheckHostIP yes|no

When yes, also stores the IP address of the server in known_hosts alongside the hostname. If the IP changes (e.g. DNS hijack), SSH warns. Useful for catching IP-spoofing attacks on non-DNSSEC domains.

Host *
  CheckHostIP yes
HashKnownHostsHashKnownHosts yes|no

Hash hostnames in known_hosts so the file does not expose your infrastructure inventory. A stolen known_hosts file reveals which servers you connect to — hashing prevents that. Existing unhashed entries can be hashed with `ssh-keygen -H`.

Host *
  HashKnownHosts yes

# Hash existing entries:
# ssh-keygen -H && rm ~/.ssh/known_hosts.old
UpdateHostKeysUpdateHostKeys yes|no|ask

When the server advertises a new or rotated host key via SSH protocol, automatically update known_hosts. Keeps your known_hosts current when admins rotate server keys, reducing "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED" false alarms.

Host *
  UpdateHostKeys yes
Tips & Patterns (10)
Pattern: Host * global defaultsHost * (must be last)

Put Host * at the end of your config to set defaults for all connections. Because the first matching block wins, specific blocks above it take precedence. A well-crafted Host * block replaces typing common flags on every command line.

# ~/.ssh/config — Host * MUST be last
Host dev
  HostName dev.example.com
  User alice
  Port 2222

Host *.prod
  User ubuntu
  IdentityFile ~/.ssh/prod_key

# Global fallbacks — last in file
Host *
  AddKeysToAgent yes
  ServerAliveInterval 60
  ServerAliveCountMax 3
  ControlMaster auto
  ControlPath ~/.ssh/cm/%C
  ControlPersist 10m
Pattern: GitHub dual accountHost github-work / Host github-personal

Use two Host aliases both pointing to github.com, each with a different IdentityFile and IdentitiesOnly yes. Change each repository's remote URL to use the matching alias. This is the only correct multi-account approach — GitHub identifies you by the public key, not the username.

# ~/.ssh/config
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
  IdentitiesOnly yes
# Set remote URL to use alias:
# git remote set-url origin git@github-work:company/repo.git
# git remote set-url origin git@github-personal:alice/blog.git
Pattern: ProxyJump bastion chainProxyJump jump1.example.com,jump2.example.com

Comma-separate jump hosts in ProxyJump for a multi-hop chain. SSH connects through each in order without opening shells. You only need your local private key — no keys need to be on intermediate hosts if agent forwarding is not being used.

# ~/.ssh/config
Host bastion-1
  HostName bastion1.example.com
  User ops

Host bastion-2
  HostName bastion2.internal.example.com
  User ops
  ProxyJump bastion-1

Host deep-internal
  HostName 10.10.10.5
  User ubuntu
  ProxyJump bastion-1,bastion-2

# Or inline at command line:
# ssh -J bastion1,bastion2 10.10.10.5
Pattern: VS Code Remote SSHControlMaster + RemoteForward for VS Code

VS Code Remote SSH reads ~/.ssh/config and applies all directives. Add ControlMaster/ControlPersist to speed up repeated VS Code reconnects. Use RemoteForward to expose local servers to your remote workspace. Set VisualStudioCode-specific env with SetEnv.

Host vscode-devbox
  HostName devbox.example.com
  User alice
  IdentityFile ~/.ssh/id_ed25519
  ControlMaster auto
  ControlPath ~/.ssh/cm/%C
  ControlPersist 1h
  # Forward local dev server to remote port 3001
  RemoteForward 3001 localhost:3000
  # Increase alive timeouts for long VS Code sessions
  ServerAliveInterval 120
  ServerAliveCountMax 10
Pattern: SOCKS5 office proxyDynamicForward 1080 via SSH server

Start an SSH connection with DynamicForward to create a local SOCKS5 proxy through an SSH server inside your office or VPN. Configure your browser or system proxy to use SOCKS5 at localhost:1080 to browse internal sites.

Host office-socks
  HostName ssh.company.com
  DynamicForward 1080
  Compression yes

# Start: ssh -N office-socks
# macOS: networksetup -setsocksfirewallproxy Wi-Fi 127.0.0.1 1080
# curl: curl --socks5 localhost:1080 http://internal.company.com
Pattern: Ephemeral cloud VMsStrictHostKeyChecking accept-new + UserKnownHostsFile /dev/null

Cloud VMs get new host keys every time they are recreated. For ephemeral instances (CI, dev environments) where you know the IP is trustworthy but the key changes, use UserKnownHostsFile /dev/null to avoid "changed host key" warnings without using the insecure StrictHostKeyChecking no.

# For ephemeral CI build agents
Host ci-runner-*
  StrictHostKeyChecking accept-new
  UserKnownHostsFile ~/.ssh/known_hosts_ci
  BatchMode yes
Tip: Verify effective config with ssh -Gssh -G <hostname>

Print the effective SSH config that would be used for a host, without connecting. Shows which Host block matched and the resolved value of every directive — the fastest way to debug config issues. Available since OpenSSH 6.7 (2014).

# Show effective config for 'dev':
ssh -G dev

# Grep for specific directives:
ssh -G dev | grep -E 'hostname|user|identityfile|proxyjump'

# Useful outputs:
# hostname dev.example.com
# user alice
# port 2222
# identityfile ~/.ssh/id_ed25519
Tip: Debug with ssh -v / -vvvssh -v | -vv | -vvv <host>

Add -v for verbose debug output, -vv for more, -vvv for full protocol trace. Output shows which config files were read, which identities were offered and rejected, and exactly where a connection failed. Most SSH problems are diagnosed within the first 20 lines of -v output.

ssh -v hostname              # basic debug
ssh -vvv hostname            # full protocol trace
ssh -v -G hostname           # show config + debug
Tip: File permissionschmod 700 ~/.ssh && chmod 600 config key

SSH silently ignores config files and private keys that are group- or world-readable. The ~/.ssh directory must be 700, config and private keys must be 600 or 400, public keys can be 644. Wrong permissions are the #1 cause of "config does nothing".

# Fix all permissions at once:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_*       # private keys
chmod 644 ~/.ssh/*.pub      # public keys
chmod 600 ~/.ssh/known_hosts

# Check:
ls -la ~/.ssh/
Tip: Generate and manage keysssh-keygen -t ed25519 -C "comment" -f ~/.ssh/name

Generate a new Ed25519 key (preferred over RSA). The -C flag adds a comment (usually your email or machine name) visible in authorized_keys. The -f flag names the file. Use different key files per server group or role to limit blast radius if a key is compromised.

# Generate Ed25519 key:
ssh-keygen -t ed25519 -C "alice@laptop" -f ~/.ssh/id_ed25519_work

# Copy public key to server:
ssh-copy-id -i ~/.ssh/id_ed25519_work.pub user@host

# List keys in agent:
ssh-add -l

# Add key to agent:
ssh-add ~/.ssh/id_ed25519_work

What this tool does

Searchable SSH config cheat sheet covering 50+ directives you actually use in ~/.ssh/config. Basic: Host pattern matching, HostName, User, Port, IdentityFile, IdentitiesOnly, AddKeysToAgent, ServerAliveInterval, ServerAliveCountMax, ConnectTimeout, BatchMode, TCPKeepAlive, LogLevel, Compression, ExitOnForwardFailure. Advanced: ProxyJump for bastion hosts and multi-hop chains, ProxyCommand for custom tunnels, LocalForward and RemoteForward for port forwarding, DynamicForward for SOCKS5 proxy, ControlMaster / ControlPath / ControlPersist for connection multiplexing that makes repeated SSH and rsync/scp blazing fast, ForwardAgent, ForwardX11, SendEnv, SetEnv, RequestTTY, Include for splitting config into per-project files, and the Match block for conditional config. Security: how to harden host key checking (StrictHostKeyChecking, UserKnownHostsFile, CheckHostIP, HashKnownHosts), disable password auth (PasswordAuthentication), lock down ciphers and MACs for compliance, manage multiple keys with IdentitiesOnly, and use accept-new for new hosts. Tips and patterns: Host * global defaults, subdomain wildcards, multiple aliases, GitHub / GitLab dual-account config, bastion via ProxyJump chain, SOCKS5 proxy for office tunnelling, VS Code Remote SSH, and debugging with ssh -vvv. Every entry shows a ready-to-paste ~/.ssh/config snippet, bilingual description, and a common pitfall where one exists. Search across directive name, description, examples, and pitfall simultaneously. Category chips filter to Basic / Advanced / Security / Tips. One-click copy the config snippet. 100% client-side, nothing uploaded.

Tool details

Input
Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy + Preview
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 28 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How SSH Config Cheatsheet fits into your work

Use it before upload, handoff, archive, support review, or any moment where a file needs one local check before it leaves your machine.

File jobs

  • Checking file type, size, metadata, and obvious mismatch signals before sharing.
  • Preparing mixed folders for upload, archive, intake, or review.
  • Keeping sensitive files in the browser instead of sending them to an account-based service.

File checks

  • Do not treat the extension alone as proof of the real file type.
  • Review metadata before a file goes to customers, vendors, or a public page.
  • Keep the original file until the copied, converted, or exported result is verified.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 Nginx Cheatsheet Nginx cheat sheet — common configs, location/server blocks, SSL, reverse proxy, gzip, real examples & gotchas. Open
  2. 2 Bash Cheatsheet Bash cheat sheet — 100+ commands & idioms for variables, conditionals, loops, functions, pipes, traps, with real one-liners. Open
  3. 3 curl Cheatsheet curl cheat sheet — 80+ curl commands for GET/POST/auth/upload/download/SSL/proxy, with real examples and pitfalls. Open

Real-world use cases

  • Connect to ten production servers without remembering any IPs

    Your team has ten EC2 instances with ugly IP addresses and non-standard ports. You add ten Host blocks to ~/.ssh/config once, with aliases like `ssh prod-api`, `ssh prod-db`, `ssh staging-web`. With ControlMaster and ControlPersist=10m in a Host * block, the second connection in a burst (ansible, rsync, cap deploy) reuses the socket and skips the handshake entirely — a deploy that hit 10 hosts in series went from 45 seconds to 8 seconds.

  • Access an internal database from your laptop via a bastion host

    Your PostgreSQL database lives on a private subnet, accessible only from a bastion. You add a LocalForward entry: `LocalForward 5433 db.internal:5432` under the bastion Host block. Running `ssh -N bastion` in the background makes `psql -h localhost -p 5433 mydb` work locally with full TLS to the DB. The cheat sheet's LocalForward entry shows the exact syntax and the ExitOnForwardFailure pitfall.

  • Set up VS Code Remote SSH to work through a corporate jump host

    VS Code Remote SSH runs `ssh` under the hood, so it reads ~/.ssh/config. You add ProxyJump and ControlMaster to the target host block, and VS Code's "Open Remote SSH" picks them up automatically. The tips section's VS Code entry shows the exact config and the RemoteForward entry for accessing your local dev server from the remote IDE.

Common pitfalls

  • Forgetting chmod 600 on the config file. SSH silently ignores world- or group-readable config files. Always run `chmod 600 ~/.ssh/config` after editing.

  • Putting specific Host blocks after Host *. SSH stops at the first matching block per directive, so wildcard defaults must come last or they will be shadowed.

  • ForwardAgent yes globally. Forwarding your agent to an untrusted host lets anyone on that host use your keys. Scope it to specific trusted jump hosts only.

Privacy

Every directive entry, the search box, the category chips, and the copy button run entirely in your browser against an in-memory array. No config snippet, no search term, and nothing you copy is sent to a server. Open DevTools → Network while using the tool: you will see zero outbound requests. Works behind a corporate proxy, on a plane, or on an air-gapped jump host with a browser — which is exactly where you tend to need an SSH config reference.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-07-01