SSH
SSH (Secure Shell) is the standard way to log into remote Linux machines, run commands, copy files, and tunnel network traffic securely. It encrypts everything between client and server, authenticates the server to you (host keys) and you to the server (keys, passwords, or certificates), and provides port forwarding that can reach services on private networks.
Almost every engineer uses SSH daily, for servers, Git remotes, and deployment tooling like Ansible. Using it well means key-based authentication instead of passwords, a tidy ~/.ssh/config, jump hosts for private networks, and hardened servers that don't invite brute-force attacks.
TL;DR
- Generate a key with
ssh-keygen -t ed25519; install the public key withssh-copy-id, and keep the private key600. - Use
ssh-agent(or a hardware key or password manager agent) so passphrases are entered once. - Put hosts, users, keys, and jump hosts in
~/.ssh/config, sossh prod-dbjust works. ProxyJumpreaches private hosts through a bastion;-L/-R/-Dcreate local, remote, and dynamic (SOCKS) tunnels.- Harden servers: disable password and root login, restrict users, keep OpenSSH updated, and consider SSH certificates for fleets.
- Verify host keys on first connect; a changed host key warning can mean a man-in-the-middle.
Quick Example
Core Concepts
How the Connection Works
- Transport: the client and server negotiate algorithms and perform a key exchange, establishing an encrypted channel.
- Server authentication: the server proves its identity with its host key. On first connection, you're asked to verify the fingerprint, which is then stored in
~/.ssh/known_hosts. - User authentication: public key (most common), password, keyboard-interactive (MFA), or certificates.
- Channels: shells, commands, file transfer (SFTP), and forwarded ports multiplexed over the connection.
Key-Based Authentication
You keep the private key; the server has your public key in ~/.ssh/authorized_keys. The server challenges you to prove possession of the private key, and nothing secret crosses the network.
- Ed25519 is the recommended key type: short, fast, secure. Use RSA (3072+ bits) only for legacy systems.
- Protect private keys with a passphrase and
chmod 600, with~/.sshat700(see Linux permissions). - Hardware-backed keys (
ssh-keygen -t ed25519-skwith a FIDO2 security key) keep the private key on a device that requires a touch, which resists malware theft. authorized_keysentries can be restricted:from="10.0.0.0/8",command="/usr/local/bin/backup",no-port-forwarding ssh-ed25519 AAAA….
ssh-agent
The agent holds decrypted keys in memory and answers authentication challenges, so you type a passphrase once. Agent forwarding (-A) lets a remote host use your agent, which is convenient but risky: anyone with root on that host can use your keys while you're connected. Prefer ProxyJump, which doesn't expose your agent to intermediate hosts.
The Client Config File
~/.ssh/config sets per-host options: HostName, User, Port, IdentityFile, ProxyJump, LocalForward, ServerAliveInterval, and connection multiplexing (ControlMaster auto, ControlPath, ControlPersist 10m), which reuses one connection for many sessions and makes repeated SSH commands and Ansible runs much faster. Patterns (Host prod-*) apply shared settings, and the first matching value wins.
Port Forwarding
Add -N (no remote command) and -f (background) for pure tunnels. Servers control forwarding with AllowTcpForwarding and GatewayPorts.
Jump Hosts (Bastions)
ProxyJump (ssh -J bastion target) connects to the target through the bastion, with end-to-end encryption between your client and the target. The bastion only relays traffic. Chains (-J hop1,hop2) work too. This is the standard pattern for reaching servers in private subnets.
File Transfer
scp: simple copies (modern OpenSSH uses the SFTP protocol underneath).sftp: interactive file transfer.rsync -e ssh: efficient incremental sync, the best choice for deployments and backups.
Server Hardening
Key settings in /etc/ssh/sshd_config (or a drop-in in sshd_config.d/):
Validate with sshd -t before reloading, and keep a second session open while changing settings so you don't lock yourself out. Additional layers:
- Keep OpenSSH patched: serious vulnerabilities do occur.
- Limit exposure: security groups or firewalls allowing SSH only from VPN or bastion addresses;
fail2banor similar for brute-force noise. - MFA for interactive logins, or hardware-backed keys.
- Audit: log authentication (
journalctl -u ssh), and reviewauthorized_keysregularly.
SSH Certificates
For fleets, managing authorized_keys on every server doesn't scale. An SSH certificate authority signs short-lived user certificates (for example valid for 8 hours, for specific principals), and servers trust the CA (TrustedUserCAKeys). Offboarding becomes "stop issuing certificates", and host certificates eliminate trust-on-first-use prompts. Tools: ssh-keygen -s, HashiCorp Vault's SSH engine, Smallstep, Teleport. See privileged access management.
Best Practices
One Key per Device, With a Passphrase
Generate separate keys per laptop or workstation, so a lost device means revoking one key. Use passphrases plus the agent, or hardware keys.
Never Ignore Host Key Warnings
"REMOTE HOST IDENTIFICATION HAS CHANGED" can mean a rebuilt server, or a man-in-the-middle. Verify the new fingerprint through a trusted channel before removing the old entry (ssh-keygen -R host). Distribute known host keys or use host certificates for managed fleets.
Prefer ProxyJump Over Agent Forwarding
ProxyJump gives the same convenience without exposing your agent to intermediate machines.
Consider Identity-Aware Access for Production
Cloud-native options (AWS Systems Manager Session Manager, GCP IAP TCP forwarding, Azure Bastion, Teleport, Tailscale SSH) tie access to SSO identity, eliminate open SSH ports, and record sessions, which fits zero trust models.
Common Mistakes
Loose Key Permissions
Fix with chmod 600 ~/.ssh/id_ed25519 and chmod 700 ~/.ssh. The server similarly ignores authorized_keys if the home directory or .ssh is group or world writable.
Password Authentication Left Enabled on Public Servers
Internet-facing SSH with passwords receives constant brute-force attempts, and one weak password is all it takes. Use keys only.
Sharing Private Keys Between People
Shared "team keys" make revocation and auditing impossible. Each person gets their own key or certificate, and access is managed centrally.
FAQ
Which SSH key type should I use?
Ed25519 for nearly all purposes, or ed25519-sk with a hardware security key for stronger protection. Use RSA with at least 3072 bits only when a system doesn't support Ed25519. Avoid DSA and small RSA keys, which modern OpenSSH rejects.
How do I connect to a server in a private subnet?
Use a bastion host with ProxyJump (ssh -J bastion private-host, or configure it in ~/.ssh/config), a VPN, or a cloud session manager (SSM, IAP, Azure Bastion) that doesn't require any inbound SSH port.
What's the difference between -L and -R forwarding?
-L opens a port on your local machine that forwards through the SSH server to a destination reachable from the server, which is great for accessing private databases. -R opens a port on the remote server that forwards back through your client to a destination reachable from you, which is useful for exposing a local service to a remote environment.
Is SSH still relevant with Kubernetes and containers?
Less for application debugging (kubectl exec and ephemeral containers cover that), but it remains central for VMs, nodes, network devices, Git over SSH, and configuration management. Many organizations are replacing direct SSH with identity-aware access proxies for auditability.
Related Topics
- Linux — The operating system overview
- Linux Permissions — Key and directory permissions
- Zero Trust — Identity-aware access instead of network trust
- Privileged Access Management — Controlling admin access at scale
- Encryption — The cryptography behind SSH
- Ansible — Configuration management over SSH