>_cmd.script

ssh

Secure encrypted remote login and command execution

Networking

By CMD Script Team · 4 min read · Last updated

SYNTAX
ssh [OPTIONS] [user@]host [command]

Options

Command options and flags
FlagDescription
-pConnect to a non-default remote port (lowercase, unlike scp/sftp's -P)
-iUse a specific private key file for authentication
-LSet up local port forwarding, e.g. -L 8080:localhost:80
-NDo not execute a remote command, useful with port forwarding only
-vVerbose mode, useful for debugging connection/auth problems
-XEnable X11 forwarding for remote GUI applications
-AForward the local SSH agent so the remote host can use your local keys

Distribution compatibility

  • Ubuntu
  • Debian
  • Fedora
  • Arch
  • macOS

What it does

ssh (Secure Shell) opens an encrypted connection to a remote host for interactive login, running remote commands, or tunneling other traffic. It replaced the old plain-text r-commands (rlogin, rsh, rcp, telnet) as the standard way to administer Unix/Linux systems remotely, providing strong encryption plus flexible authentication (passwords, public keys, certificates) and features like port forwarding and agent forwarding on top of the basic remote-shell functionality.

Beginner examples

  • ssh user@server.example.com — log in interactively to a remote host
  • ssh server.example.com — connect using your current local username as the remote username
  • ssh user@server.example.com 'uptime' — run a single command remotely and print its output locally
  • exit — end the remote session and return to the local shell
ssh alice@10.0.0.5

Advanced examples

  • Connect on a custom port: ssh -p 2222 user@server.example.com
  • Authenticate with a specific private key: ssh -i ~/.ssh/deploy_key deploy@server.example.com
  • Forward a remote service to a local port (local port forwarding): ssh -L 8080:localhost:80 user@server.example.com then browse http://localhost:8080
  • Set up a SOCKS proxy through the remote host: ssh -D 1080 user@server.example.com
  • Forward your local SSH agent so the remote host can use your keys to hop further: ssh -A user@jumphost.example.com
ssh -p 2200 -i ~/.ssh/deploy_key -L 5432:localhost:5432 deploy@server.example.com -N

Common mistakes

  • Confusing ssh's lowercase -p (port) with scp/sftp's uppercase -P — using the wrong case connects to the wrong port or errors out.
  • Blindly accepting an unexpected "host key changed" warning instead of verifying it — this check exists specifically to catch man-in-the-middle attacks or misconfigured infrastructure.
  • Leaving password authentication enabled and internet-facing without fail2ban or key- only auth, inviting brute-force login attempts.
  • Forgetting -N when only tunneling a port and not wanting an interactive shell — the connection is fine either way, but -N makes the intent explicit and avoids an idle shell prompt.

Tips

  • Use ~/.ssh/config to define per-host shortcuts (Host prod, HostName, User, Port, IdentityFile) so you can just type ssh prod instead of the full command every time.
  • ssh-copy-id user@host is the quickest way to install your public key into a remote authorized_keys file for password-less login.
  • Use ssh -J jumphost user@target (ProxyJump) to hop through a bastion host in a single command instead of manually chaining two ssh sessions.

Best practices

  • Disable password authentication and root login in sshd_config once key-based auth is set up, to close off the most common brute-force attack surface.
  • Protect private keys with a passphrase and use ssh-agent so you don't have to re-type it on every connection.
  • Keep known_hosts entries accurate and never disable strict host key checking globally just to silence warnings — investigate mismatches instead.

Try it yourself

A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.

Real-world use cases

  • Administering remote servers: deploying code, checking logs, restarting services, all over an encrypted session.
  • Tunneling a database or internal admin UI that's only reachable from inside a private network, via local port forwarding.
  • Running one-off remote diagnostics from automation/CI (ssh host 'systemctl status app') without needing a full interactive session.

Common interview questions

  • How does SSH key-based authentication work at a high level? The server holds your public key in authorized_keys; during login, the server challenges the client to prove possession of the matching private key (via a signed challenge), so the private key itself never crosses the network.
  • What's the difference between local and remote port forwarding? -L exposes a remote-reachable service on a local port; -R exposes a locally-reachable service on a port on the remote host, tunneling traffic back to your machine.
  • How would you securely automate an SSH login for a cron job or CI pipeline? Use a dedicated key pair with no passphrase (or unlocked via an agent), restrict what that key can do with authorized_keys options (like command=), and avoid password-based auth entirely.

Frequently Asked Questions

How do I log in without typing a password every time?

Generate a key pair with ssh-keygen, copy the public key to the remote host's ~/.ssh/authorized_keys with ssh-copy-id user@host, then ssh will authenticate automatically using the private key (optionally unlocked once via ssh-agent).

How do I run a single command on a remote host without opening a full shell?

ssh user@host 'command' — e.g. ssh user@host 'df -h' runs df -h remotely and prints the output locally, then the connection closes.

What's the difference between -L and -R port forwarding?

-L (local forwarding) makes a port on your machine tunnel to a service reachable from the remote host; -R (remote forwarding) does the opposite, exposing a port on the remote host that tunnels back to a service on your local machine.

Why does ssh warn about a changed host key?

SSH remembers each host's public key fingerprint in ~/.ssh/known_hosts; if it changes unexpectedly, ssh warns loudly because it could mean the server was rebuilt (benign) or you're being man-in-the-middled (not benign) — always verify before accepting.

Cheat sheet

Download a quick-reference cheat sheet for ssh.