SSH Command-Line Interface (ssh)

Secure, encrypted remote-shell and tunnelling utility

The ssh program from OpenSSH ≥ 9.x provides authenticated, encrypted, bidirectional byte streams between hosts. It replaces insecure protocols such as telnet, rlogin, and unencrypted rcp.


$ ssh [options] user@host [command …]
		

The ssh client also supports sophisticated features such as agent forwarding, jump-host chaining, connection multiplexing, dynamic port forwarding, and querying available algorithms. All options below can be set on the CLI or in ~/.ssh/config via Host blocks.

Connection & Session Options

Controlling transport, login, and basic session behaviour

  1. -p port Connect to a non-default TCP port (default 22).
  2. -l user Login name (overrides user@host syntax).
  3. -i identity_file Private-key(s) to use; repeatable for alternative keys (ED25519, ECDSA, RSA, etc.).
  4. -o Option=Value Inline configuration override (any keyword from ssh_config(5)).
  5. -F path Alternate ssh_config file.
  6. -4 / -6 Force IPv4 or IPv6.
  7. -C Enable zlib compression after authentication.
  8. -q Quiet mode — suppress most diagnostics.

Authentication Mechanisms

Keys, passwords, agents, and multi-factor options

  1. -A Agent forwarding — delegate client keys to remote hops.
  2. -a Disable agent forwarding (opposite of -A).
  3. -K GSSAPI authentication & credential forwarding.
  4. -k Disable GSSAPI credential forwarding.
  5. -o PreferredAuthentications=… Order methods (password, publickey, keyboard-interactive, etc.).
  6. -E hash_alg Select hash when hashing known_hosts with -H (e.g. sha256).
  7. -J user@jump One-shot ProxyJump; multiple hops comma-separated.

# Example — agent + jump host
$ ssh -A -J bastion.example.com user@10.42.0.5
		

Port Forwarding & Tunnelling

Local, remote, and dynamic SOCKS tunnels

  1. -L [bind:]lport:host:port Local → remote; listens on lport.
  2. -R [bind:]rport:host:port Remote → local; server listens on rport.
  3. -D [bind:]dport Dynamic SOCKS v5 proxy (acts like a VPN).
  4. -W host:port TCP forward-only (drop interactive shell); complements -J.
  5. -N Do not execute remote command (pure tunnelling).
  6. -f Background after authentication (requires -N or explicit command).

# Expose local PostgreSQL to office workstation
$ ssh -N -L 5432:localhost:5432 office@vpn.example.net

# SOCKS proxy on port 1080
$ ssh -f -N -D 1080 user@gateway
		

Connection Multiplexing (ControlMaster)

Reuse a single TCP connection for multiple sessions

Multiplexing dramatically speeds up scripted SSH workflows by avoiding repeated handshakes. Typical config block:


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

After the first session, subsequent ssh invocations to the same host instantly attach to the master socket.

Crypto Algorithms & Host-Key Management

Choosing ciphers, MACs, KEX, and querying capabilities

  1. -Q cipher|mac|kex|key List algorithms supported by current build.
  2. -v, -vvv Diagnostic verbosity — shows algorithm negotiation.
  3. -o Ciphers=…, -o MACs=…, -o KexAlgorithms=… Override defaults; comma-separated preference list.
  4. -o HostKeyAlgorithms=… Advertise acceptable server key types (e.g. ssh-ed25519).

# Audit supported MAC algorithms
$ ssh -Q mac

# Force FIPS-compliant suite
$ ssh -o Ciphers=aes256-gcm@openssh.com \
          -o MACs=hmac-sha2-512-etm@openssh.com \
          secure@example.gov
		

Other Useful Flags

Environment, escapes, and pseudo-tty management

  1. -t / -T Force / disable allocation of pseudo-TTY.
  2. -X / -Y Untrusted / trusted X11 forwarding.
  3. -x Disable X11 forwarding in config that enables it.
  4. -e char Set escape character (default ~); -e none disables.
  5. -V Print version & compile-time options.
  6. -G Dump final config after all sources are processed then exit.

Exit Status & Escape Sequences

Debugging session health at the CLI

ssh returns the remote command’s exit code.
If no command is executed, it exits 0 on graceful logout, 255 on connection failure, or another local-error code (SIGINT → 130, etc.).

Interactive escapes (typed at column 1 after Enter):

  1. ~. Terminate connection immediately.
  2. ~^Z Suspend ssh and retain connection.
  3. ~# List forwarded ports.
  4. ~& Background session (like -fN).

Practical Recipes

Ready-to-use command lines for daily admin

  1. Non-interactive file transfer (native scp replacement):
    
    $ ssh -o StrictHostKeyChecking=yes \
            -o BatchMode=yes \
            user@host 'tar czf - /var/log' | tar xzf -
    				
  2. Ad-hoc remote command with specific key & JSON output:
    
    $ ssh -i ~/.ssh/ci_ed25519 \
            -o LogLevel=ERROR \
            deploy@api 'jq -n --arg now "$(date -Is)" "{time:$now}"'
    				
  3. Reverse proxy from cloud VPS to NAT’ed Pi:
    
    # On Raspberry Pi (behind router)
    $ ssh -R 443:localhost:9443 \
            -N -f -o ServerAliveInterval=30 \
            pi@vps.example.net