The ssh command in Linux
ssh (secure shell) opens an encrypted session on a remote machine. It is the front door to every Linux server on the planet: deployments, debugging, file transfers (via scp/sftp) and tunnels all ride on it. The single biggest quality-of-life upgrade is switching from passwords to key-based authentication.
How ssh works
An SSH session is built in three stages. First, key exchange: client and server negotiate ephemeral keys and derive a symmetric session key — with forward secrecy, so recording traffic today does not help decrypt it after a key leak tomorrow. Second, host authentication: the server proves its identity with its host key, which your client checks against ~/.ssh/known_hosts — the "authenticity of host can't be established" prompt is this trust-on-first-use moment. Third, user authentication: keys are tried before passwords; with a key, the client signs a challenge, proving possession without the key ever leaving your machine.
After authentication, everything rides one encrypted transport as multiplexed channels: your interactive shell is a channel, each -L tunnel is a channel, an sftp transfer is a channel. That architecture is why one connection can carry a session and three port forwards simultaneously, and why ControlMaster can share a single authenticated connection across many ssh invocations, making the second and third connection to a host instant.
Syntax
ssh [OPTIONS] [USER@]HOST [COMMAND] Common options
| Option | What it does |
|---|---|
-p PORT | Connect to a non-default port (default is 22). |
-i FILE | Use a specific private key file. |
-L local:host:remote | Local port forwarding: expose a remote service on your machine. |
-N | No remote command — useful with tunnels. |
-J HOST | Jump host: reach a machine through a bastion. |
-v | Verbose output — your first tool when a connection fails. |
How to use ssh: examples
$ ssh user@203.0.113.10 Open a shell on the remote machine as "user".
$ ssh -p 2222 user@example.com Connect on a custom port.
$ ssh user@server "df -h" Run a single command remotely and return — no interactive session.
$ ssh-keygen -t ed25519 Generate a modern key pair (run once on your machine).
$ ssh-copy-id user@server Install your public key on the server so future logins skip the password.
$ ssh -L 8080:localhost:80 user@server Tunnel: the server's port 80 becomes localhost:8080 on your machine.
Real-world use cases for ssh
A config file that remembers everything
Instead of ssh -p 2222 -i ~/.ssh/work deploy@203.0.113.7, define a Host block in ~/.ssh/config with HostName, User, Port and IdentityFile — then the whole incantation becomes ssh web1. Multiply by every server you touch and the config file becomes your infrastructure address book.
Reaching a database behind a firewall
Production databases rightly refuse public connections. ssh -N -L 5433:localhost:5432 user@dbserver makes the remote Postgres appear at localhost:5433 on your laptop; your GUI client connects there and the traffic rides the encrypted tunnel.
Pro tips and common mistakes
- ssh-copy-id is the whole key-installation ceremony in one command — no manual editing of authorized_keys.
- Debug failed connections with -v (add v's for more detail): it shows which keys were offered and why each was rejected.
- Run remote one-offs without a session: ssh host "systemctl status nginx" — and quote the remote command as one argument.
- Long sessions over flaky Wi-Fi: put ServerAliveInterval 60 in ~/.ssh/config, and run tmux on the server so disconnects cost nothing.
Frequently asked questions about ssh
How do I log in without typing a password?
Generate a key pair with ssh-keygen -t ed25519, then run ssh-copy-id user@server. Your public key lands in the server's ~/.ssh/authorized_keys and subsequent logins use the key.
What does "Permission denied (publickey)" mean?
The server only accepts key authentication and none of your keys matched. Check you are using the right key (-i), the right user name, and that your public key is in the server's authorized_keys with correct permissions (700 on ~/.ssh, 600 on the files).
How do I keep a session alive?
Add ServerAliveInterval 60 to ~/.ssh/config, or better, run tmux or screen on the server so your work survives disconnections.
Related commands
Change file permissions with numeric (755, 644) and symbolic (u+x) modes — clearly explained.
tarCreate and extract archives: tar.gz, tar.bz2 — with the flag combinations finally explained.
curlDownload files, test APIs, send POST requests with JSON, and inspect headers.