The ssh Command

Run a Speed Test

The ssh command is the standard way to open a secure remote shell. It encrypts the session, verifies the server identity, supports password or key authentication, and can also carry tunnels for ports that should not be exposed directly.

Full syntax

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

ssh user@example.com
ssh -p 2222 user@example.com
ssh -i ~/.ssh/id_ed25519 user@example.com
ssh user@example.com "uptime"
ssh -J jumphost user@internal-server

The first form opens an interactive shell. The second connects to a non-standard port. The third specifies a private key. The fourth runs a single remote command and exits — useful for scripts and automation. The fifth connects through a jump host without agent forwarding exposure.

Essential flags

FlagMeaningExample
-pPort numberssh -p 2222 user@host
-iIdentity file (private key)ssh -i ~/.ssh/id_ed25519 user@host
-LLocal port forwardssh -L 8080:internal:80 user@host
-RRemote port forwardssh -R 9090:localhost:3000 user@host
-DDynamic SOCKS5 proxyssh -D 1080 user@host
-NNo remote shell (tunnel only)ssh -N -L 5432:db:5432 user@host
-fBackground after authenticationCombine with -N for persistent tunnels
-JJump host (ProxyJump)ssh -J jump user@internal
-v / -vvvVerbose debug outputShows each negotiation step; use -vvv for maximum detail

~/.ssh/config format

The config file eliminates repetitive typing and makes connection settings explicit and version-controllable. A well-structured config also prevents subtle mistakes like connecting with the wrong key or wrong username.

Host prod
    HostName server.example.com
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60
    ServerAliveCountMax 3

Host *.internal
    ProxyJump bastion.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519

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

ServerAliveInterval 60 sends a keepalive every 60 seconds to prevent idle disconnects. ControlMaster auto with ControlPersist 10m enables connection multiplexing — subsequent ssh, scp, and sftp calls to the same host reuse the existing TCP connection, making them near-instant.

SCP and SFTP

SCP (Secure Copy) copies files over SSH. Basic usage: scp file.txt user@host:/remote/path/ to upload, scp user@host:/remote/file.txt ./ to download. Use -r for directories and -P (capital P, unlike ssh's lowercase) for non-standard ports. Note: SCP is deprecated in recent OpenSSH releases in favor of SFTP-based file transfer, though the scp command still works by using SFTP internally on modern servers.

SFTP provides an interactive file transfer session: sftp user@host. Inside the session: ls and cd navigate the remote filesystem, put file uploads, get file downloads, mput *.log uploads multiple files, mget *.csv downloads multiple files. SFTP is the standard for managed file transfer where scp's simplicity is insufficient.

SSH key generation

Generate an Ed25519 key pair: ssh-keygen -t ed25519 -C "your@email.com". The -C comment helps identify the key in authorized_keys files. Accept the default path (~/.ssh/id_ed25519) or specify a custom path for keys used with different services. Set a strong passphrase — it encrypts the private key file at rest so it is useless if stolen without the passphrase. Copy the public key to a server: ssh-copy-id user@host, which appends it to ~/.ssh/authorized_keys with correct permissions. Verify the key works before disabling password auth.

SSH agent

The SSH agent holds decrypted private keys in memory so you enter the passphrase once per session rather than per connection. Start the agent: eval $(ssh-agent). Add a key: ssh-add ~/.ssh/id_ed25519. The agent socket path is stored in SSH_AUTH_SOCK — SSH and SCP read this environment variable automatically to find the agent. On macOS, the system keychain integrates with the agent; on Linux, most desktop environments start an agent at login. For headless servers, use a persistent agent tool or configure ControlMaster multiplexing instead.

Debugging connection failures

Run ssh -vvv user@host to see every step: DNS resolution, TCP connection, SSH version exchange, algorithm negotiation, host key check, and authentication attempts. Common errors and their causes:

  • Permission denied (publickey): The server did not accept any offered key. Check that the public key is in ~/.ssh/authorized_keys on the server with permissions 600, and that the file's parent directory has permissions 700. Use -v to see which key was offered.
  • Host key verification failed: The stored fingerprint in ~/.ssh/known_hosts does not match what the server presented. The server may have been rebuilt — verify the fingerprint out-of-band (cloud console, datacenter KVM), then remove the old entry with ssh-keygen -R hostname.
  • Connection refused: Nothing is listening on that port, or a firewall is sending a TCP RST. Verify the SSH service is running and the firewall allows port 22 (or your custom port) from your source IP.
  • Connection timed out: The TCP SYN is being dropped by a firewall — no RST, just silence. Check security group rules, iptables, or network ACLs between you and the server.
  • Slow login after authentication: Often caused by the server performing a reverse DNS lookup on your IP. Add UseDNS no to sshd_config to eliminate the delay.

Security Habits

  • Prefer key authentication over passwords.
  • Protect private keys with a passphrase.
  • Do not ignore host key warnings casually.
  • Use a firewall so SSH is reachable only where needed.
  • Disable root login on internet-facing servers when possible.

Frequently Asked Questions

What does ssh do?

It opens an encrypted remote login session or runs a command on a remote machine.

What port does SSH use?

TCP port 22 by default.

Is SSH safer than Telnet?

Yes. SSH encrypts traffic and authenticates the server. Telnet is plaintext.

Related Guides

More From This Section