DEV Community

Svyatoslav Pavlov
Svyatoslav Pavlov

Posted on Originally published at termal.in on

The SSH flags you'll actually use (a practical cheat sheet)

The SSH command flags worth memorizing, organized by task — connection basics, -o, forwarding, jump hosts, session control — plus a compact reference table.

ssh --help dumps forty flags in alphabetical order, which is the least useful way to learn them. You reach for flags by what you're trying to do — connect as a different user, forward a port, hop through a bastion, debug a refusal — so here's the same set organized by task, with a note on which ones to stop typing and put in your ssh_config instead.

The rule underneath all of it: flags are for one-offs; config is for permanence. Anything you pass twice belongs in the file.

Connection basics

The flags that answer "who, where, and with what key."

  • -p <port> — connect to a non-standard port. ssh -p 2222 user@host. (Lowercase -p; uppercase -P is scp's port flag, which trips everyone up once.)
  • -l <user> — the login user, an alternative to the user@ prefix. ssh -l deploy host equals ssh deploy@host; you'll see -l in scripts and older docs.
  • -i <identity> — point at a specific private key. ssh -i ~/.ssh/work_ed25519 user@host. The most useful flag when auth fails: it forces the exact key instead of letting the agent guess.
  • -F <configfile> — use a different config file. ssh -F ./project.sshconfig web1, or -F /dev/null to ignore your personal config and test with zero customization.
  • -v / -vv / -vvv — verbosity, and the flag that ends most mysteries. One -v shows the auth methods tried and keys offered; -vvv shows the full handshake. When something fails, run it again with -vvv before you theorize.

The -o escape hatch

This is the flag worth understanding deeply, because it subsumes dozens of others. -o sets any ssh_config option inline. Anything you could write in ~/.ssh/config under a Host block, you can pass as -o Option=value — not a short list of blessed options, but the entire config vocabulary, available for a single connection.

A few that come up constantly:

ssh -o IdentitiesOnly=yes -i ~/.ssh/right_key user@host   # offer only this key
ssh -o StrictHostKeyChecking=accept-new user@host          # trust new hosts, still catch changes
ssh -o ServerAliveInterval=30 user@host                    # keepalive for a flaky link
ssh -o ProxyJump=bastion.example.com db.internal           # hop through a bastion inline
Enter fullscreen mode Exit fullscreen mode

-o IdentitiesOnly=yes is the fix for Too many authentication failures when your agent offers six keys and a strict server cuts you off after five. -o StrictHostKeyChecking=accept-new is the sane middle ground — auto-trust a host you've never seen, but still scream if a known host's key changes.

The point: you don't need a special flag for each behavior. If you know the config directive, you know the flag — it's -o Directive=value. Once you're passing three or four every time, move them into config for good.

Forwarding and tunnels

The port-plumbing flags. The mental model — which side opens the port — gets its own read in SSH port forwarding explained; here's the flag summary.

  • -L <local>:<host>:<port> — local forward. Open a port on your machine that tunnels to a destination reachable from the server. ssh -L 5432:localhost:5432 db.example.com brings a remote database to your 127.0.0.1:5432.
  • -R <remote>:<host>:<port> — remote forward. Open a port on the server that tunnels back to your side — the reverse-tunnel trick for reaching a machine behind NAT.
  • -D <port> — dynamic forward. A SOCKS proxy on your machine; destination chosen per connection. ssh -D 1080 jump.example.com, then point a browser at 127.0.0.1:1080.
  • -N — don't run a remote command. Pair with any forward when you want only the tunnel and no shell.
  • -f — background ssh after it connects. Combine with -N for a fire-and-forget tunnel: ssh -fN -L 5432:localhost:5432 db.example.com.
  • -g — let other machines on your LAN use a local (-L/-D) forward, not just 127.0.0.1. A small exposure — you're opening the tunnel to your whole network, so use it deliberately.

Jump hosts and the agent

Reaching the next hop, and the flag you should be cautious with.

  • -J <jumphost> — ProxyJump. Tunnel through a bastion and authenticate end-to-end from your laptop to the target. ssh -J bastion.example.com db.internal. The bastion only shuttles encrypted bytes; your key never lands on it — the right way through a gateway. Full case: ProxyJump: reach servers behind a bastion.
  • -A — agent forwarding. Exposes a socket on the remote host that proxies signing requests back to your local agent, so a process there can authenticate as you to the next server. Convenient and riskier than it looks: anyone with root on that host can borrow your identity while the session is open. Use -J for "reach the next hop" and keep -A for hosts you fully trust — the reasons are in agent forwarding is convenient and dangerous.

Between the two: -J gets your shell to a host behind the bastion without lending anyone your keys; -A lends your keys' live use to the box you connected to. Not the same trade.

Session control

The small flags that fix specific annoyances.

  • -t — force a pseudo-terminal. Needed for a remote command that expects an interactive TTY: ssh -t host 'sudo systemctl status nginx' gives you a real terminal for the sudo prompt and colored output. Double it (-tt) to force one when there's no local TTY.
  • -q — quiet mode. Suppresses warnings and banners; useful in scripts where you want only the command's own output.
  • -C — request compression. A real win on slow, high-latency links; negligible or slightly negative on a fast LAN.
  • -o BatchMode=yes — never prompt. If auth would need a password or passphrase, fail immediately instead of hanging. This is what makes SSH safe inside cron and CI — a stuck prompt in an unattended script hangs forever.

The compact reference

Flag Does ssh_config equivalent
-p 2222 Non-standard port Port 2222
-l user / user@ Login user User user
-i ~/.ssh/key Specific identity IdentityFile ~/.ssh/key
-F file Alternate config file — (this is the config)
-v … -vvv Verbose / debug LogLevel DEBUG3
-o Opt=val Any config option inline (the option itself)
-L a:host:b Local forward LocalForward a host:b
-R a:host:b Remote forward RemoteForward a host:b
-D 1080 Dynamic (SOCKS) forward DynamicForward 1080
-N No remote command RequestTTY no (+ no command)
-f Background after connect — (one-off only)
-g Open forward to your LAN GatewayPorts yes
-J host Jump through a bastion ProxyJump host
-A Forward the agent ForwardAgent yes
-t Force a TTY RequestTTY force
-q Quiet LogLevel QUIET
-C Compression Compression yes
-o BatchMode=yes Never prompt BatchMode yes

The right column is the tell. Almost every flag has a config equivalent, and that's the workflow: use the flag once to prove a connection works, then move the ones you'll repeat into ~/.ssh/config so ssh web1 carries all of them with no flags at all. The flags with no config equivalent — -f, -F, the debug verbosity — are the genuinely one-off ones.

Where a client keeps the state for you

Flags and config both live in your dot-files, per machine, and that hurts at scale: settings copied across laptops by hand, tunnels re-run after every sleep, no way to see which of forty hosts is up. Termalin keeps the same facts a flag would carry — port, user, key, jump host, saved local/remote/dynamic forwards — attached to the host as structured data, organized into folders and tags, synced across your machines end-to-end encrypted (on Pro). It verifies each server on first connect, shows live status per host, and starts saved tunnels at launch and restarts them if they drop, instead of a retyped command. The flags teach you what's happening; a client stops you retyping them every morning.


Termalin is a free, cross-platform SSH client that stores per-host settings, keys and tunnels for you — download it, or read how it handles your keys safely.

Top comments (0)