# ssh — Encrypted Remote Access and Tunneling from the Command Line

> Practical guide to SSH — connecting to remote hosts, managing keys, setting up port forwarding and transferring files securely.

Source: https://www.jpkc.com/db/en/cheatsheets/networking/ssh/

<!-- PROSE:intro -->
SSH (Secure Shell) is the standard tool for logging into remote systems securely, running commands on distant machines, and transferring files – all over a single cryptographically protected connection. Whether you're reaching a lone server or navigating a complex infrastructure with jump hosts and SOCKS proxies, SSH handles it. This guide covers the key commands and options, from your first connection through key management to port forwarding and multiplexing.
<!-- PROSE:intro:end -->

## Connecting

`ssh <user>@<host>` — Connect to a remote host as a specific user.

```bash
ssh deploy@server.example.com
```

`ssh <host>` — Connect using the current local username.

```bash
ssh server.example.com
```

`ssh -p <port> <user>@<host>` — Connect on a non-standard SSH port.

```bash
ssh -p 2222 deploy@server.example.com
```

`ssh -i <keyfile> <user>@<host>` — Connect using a specific private key file.

```bash
ssh -i ~/.ssh/deploy_key deploy@server.example.com
```

`ssh -v <user>@<host>` — Verbose mode. Show debug information during connection for troubleshooting.

```bash
ssh -v deploy@server.example.com
```

`ssh -vvv <user>@<host>` — Maximum verbosity. Show all debug levels for deep troubleshooting.

```bash
ssh -vvv deploy@server.example.com
```

`ssh -o StrictHostKeyChecking=no <user>@<host>` — Skip host key verification (insecure, useful for scripts and ephemeral hosts).

```bash
ssh -o StrictHostKeyChecking=no deploy@staging.example.com
```

`ssh -o ConnectTimeout=<seconds> <user>@<host>` — Set a connection timeout in seconds.

```bash
ssh -o ConnectTimeout=5 deploy@server.example.com
```

## Remote Commands

`ssh <user>@<host> <command>` — Execute a single command on the remote host and return.

```bash
ssh deploy@server.example.com uptime
```

`ssh <user>@<host> '<command1> && <command2>'` — Execute multiple chained commands remotely.

```bash
ssh deploy@server.example.com 'cd /var/www && git pull'
```

`ssh <user>@<host> 'bash -s' < <script>` — Execute a local script on the remote host via stdin.

```bash
ssh deploy@server.example.com 'bash -s' < deploy.sh
```

`ssh -t <user>@<host> <command>` — Force pseudo-terminal allocation. Required for interactive commands like sudo or top.

```bash
ssh -t deploy@server.example.com sudo apt update
```

`ssh <user>@<host> 'cat > <remote_file>' < <local_file>` — Transfer a file to a remote host using stdin redirection.

```bash
ssh deploy@server.example.com 'cat > /tmp/config.json' < config.json
```

## Key Management

`ssh-keygen -t ed25519 -C "<comment>"` — Generate a new Ed25519 key pair (recommended, most secure and fastest).

```bash
ssh-keygen -t ed25519 -C "deploy@server.example.com"
```

`ssh-keygen -t rsa -b 4096 -C "<comment>"` — Generate a new RSA key pair with 4096 bits.

```bash
ssh-keygen -t rsa -b 4096 -C "user@example.com"
```

`ssh-keygen -t ed25519 -f <path>` — Generate a key pair and save to a specific file path.

```bash
ssh-keygen -t ed25519 -f ~/.ssh/deploy_key
```

`ssh-keygen -p -f <keyfile>` — Change the passphrase of an existing private key.

```bash
ssh-keygen -p -f ~/.ssh/id_ed25519
```

`ssh-keygen -l -f <keyfile>` — Show the fingerprint of a key file.

```bash
ssh-keygen -l -f ~/.ssh/id_ed25519.pub
```

`ssh-keygen -R <host>` — Remove a host entry from known_hosts (fixes host key changed warnings).

```bash
ssh-keygen -R server.example.com
```

`ssh-keygen -y -f <private_key>` — Extract the public key from a private key file.

```bash
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub
```

## Key Distribution

`ssh-copy-id <user>@<host>` — Copy your public key to a remote host's authorized_keys file.

```bash
ssh-copy-id deploy@server.example.com
```

`ssh-copy-id -i <keyfile> <user>@<host>` — Copy a specific public key to the remote host.

```bash
ssh-copy-id -i ~/.ssh/deploy_key.pub deploy@server.example.com
```

`ssh-copy-id -p <port> <user>@<host>` — Copy public key to a remote host on a non-standard port.

```bash
ssh-copy-id -p 2222 deploy@server.example.com
```

`cat <keyfile> | ssh <user>@<host> 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'` — Manual alternative to ssh-copy-id when it is not available.

```bash
cat ~/.ssh/id_ed25519.pub | ssh deploy@server.example.com 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'
```

## SSH Agent

`eval "$(ssh-agent -s)"` — Start the SSH agent and set environment variables in the current shell.

```bash
eval "$(ssh-agent -s)"
```

`ssh-add <keyfile>` — Add a private key to the SSH agent.

```bash
ssh-add ~/.ssh/id_ed25519
```

`ssh-add` — Add the default key (~/.ssh/id_rsa, id_ed25519, etc.) to the agent.

```bash
ssh-add
```

`ssh-add -l` — List fingerprints of all keys currently loaded in the agent.

```bash
ssh-add -l
```

`ssh-add -L` — List full public keys currently loaded in the agent.

```bash
ssh-add -L
```

`ssh-add -d <keyfile>` — Remove a specific key from the agent.

```bash
ssh-add -d ~/.ssh/deploy_key
```

`ssh-add -D` — Remove all keys from the agent.

```bash
ssh-add -D
```

`ssh -A <user>@<host>` — Enable agent forwarding. Allows the remote host to use your local SSH keys.

```bash
ssh -A deploy@bastion.example.com
```

## Port Forwarding (Tunneling)

`ssh -L <local_port>:<target_host>:<target_port> <user>@<host>` — Local port forwarding. Access a remote service through a local port.

```bash
ssh -L 3306:localhost:3306 deploy@server.example.com
```

`ssh -L <local_port>:<remote_host>:<remote_port> <user>@<host>` — Forward to a host accessible from the SSH server (not just localhost).

```bash
ssh -L 5432:db.internal:5432 deploy@bastion.example.com
```

`ssh -R <remote_port>:<local_host>:<local_port> <user>@<host>` — Remote (reverse) port forwarding. Expose a local service on the remote host.

```bash
ssh -R 8080:localhost:3000 deploy@server.example.com
```

`ssh -D <port> <user>@<host>` — Dynamic port forwarding. Create a SOCKS5 proxy on the local port.

```bash
ssh -D 1080 deploy@server.example.com
```

`ssh -L <local_port>:<target>:<target_port> -N <user>@<host>` — Forward a port without opening a remote shell (-N = no command).

```bash
ssh -L 3306:localhost:3306 -N deploy@server.example.com
```

`ssh -L <local_port>:<target>:<target_port> -N -f <user>@<host>` — Forward a port in the background (-f = fork to background).

```bash
ssh -L 3306:localhost:3306 -N -f deploy@server.example.com
```

## Jump Hosts (Bastion/ProxyJump)

`ssh -J <jump_host> <user>@<target_host>` — Connect to a target host through a jump host (bastion).

```bash
ssh -J bastion.example.com deploy@internal-server
```

`ssh -J <user1>@<jump1>,<user2>@<jump2> <user>@<target>` — Chain multiple jump hosts to reach the target.

```bash
ssh -J admin@bastion1,admin@bastion2 deploy@internal-server
```

`ssh -J <jump_host>:<port> <user>@<target_host>` — Use a jump host running SSH on a non-standard port.

```bash
ssh -J bastion.example.com:2222 deploy@internal-server
```

`ssh -o ProxyJump=<jump_host> <user>@<target_host>` — Alternative syntax using the ProxyJump option.

```bash
ssh -o ProxyJump=bastion.example.com deploy@internal-server
```

## SCP (Secure Copy)

`scp <local_file> <user>@<host>:<remote_path>` — Copy a local file to a remote host.

```bash
scp ./config.json deploy@server.example.com:/etc/app/
```

`scp <user>@<host>:<remote_file> <local_path>` — Copy a file from a remote host to the local machine.

```bash
scp deploy@server.example.com:/var/log/app.log ./logs/
```

`scp -r <local_dir> <user>@<host>:<remote_path>` — Copy a directory recursively to a remote host.

```bash
scp -r ./dist/ deploy@server.example.com:/var/www/html/
```

`scp -P <port> <local_file> <user>@<host>:<remote_path>` — Copy using a non-standard SSH port (note: uppercase -P for scp).

```bash
scp -P 2222 ./config.json deploy@server.example.com:/etc/app/
```

`scp -i <keyfile> <local_file> <user>@<host>:<remote_path>` — Copy using a specific private key file.

```bash
scp -i ~/.ssh/deploy_key ./app.tar.gz deploy@server.example.com:/tmp/
```

`scp <user>@<host1>:<file> <user>@<host2>:<path>` — Copy a file between two remote hosts (data flows through local machine).

```bash
scp deploy@server1.example.com:/backup.sql deploy@server2.example.com:/import/
```

## SFTP (Secure File Transfer)

`sftp <user>@<host>` — Start an interactive SFTP session with a remote host.

```bash
sftp deploy@server.example.com
```

`sftp -P <port> <user>@<host>` — Connect via SFTP on a non-standard SSH port.

```bash
sftp -P 2222 deploy@server.example.com
```

`sftp> get <remote_file> <local_path>` — Download a file from the remote host (inside SFTP session).

```bash
sftp> get /var/log/app.log ./logs/
```

`sftp> put <local_file> <remote_path>` — Upload a file to the remote host (inside SFTP session).

```bash
sftp> put ./config.json /etc/app/
```

`sftp> ls` — List files in the current remote directory.

```bash
sftp> ls -la
```

`sftp> lcd <path>` — Change the local working directory.

```bash
sftp> lcd ~/Downloads
```

## Config File (~/.ssh/config)

`Host <alias>` with `HostName`, `User` — Define a host alias with default user. Connect with: ssh <alias>

```bash
Host production
  HostName server.example.com
  User deploy
```

`Host <alias>` with `HostName`, `Port`, `IdentityFile` — Define a host with custom port and key file.

```bash
Host staging
  HostName staging.example.com
  Port 2222
  IdentityFile ~/.ssh/staging_key
```

`Host <alias>` with `HostName`, `ProxyJump` — Define a host that connects through a jump host (bastion).

```bash
Host internal-db
  HostName db.internal
  ProxyJump bastion.example.com
```

`Host *` with `ServerAliveInterval`, `ServerAliveCountMax` — Global settings for all hosts. Keep connections alive with periodic pings.

```bash
Host *
  ServerAliveInterval 60
  ServerAliveCountMax 3
  AddKeysToAgent yes
```

`Host <pattern>*` with `User`, `IdentityFile` — Use wildcards to apply settings to multiple hosts.

```bash
Host aws-*
  User ec2-user
  IdentityFile ~/.ssh/aws_key
```

## Multiplexing & Keep-Alive

`ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-%r@%h:%p -o ControlPersist=10m <user>@<host>` — Enable connection multiplexing. Subsequent SSH sessions reuse the connection.

```bash
ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-%r@%h:%p -o ControlPersist=10m deploy@server.example.com
```

`ssh -O check <user>@<host>` — Check if a multiplexed master connection is running.

```bash
ssh -O check deploy@server.example.com
```

`ssh -O exit <user>@<host>` — Terminate a multiplexed master connection.

```bash
ssh -O exit deploy@server.example.com
```

`ssh -o ServerAliveInterval=<seconds> <user>@<host>` — Send keep-alive packets to prevent connection timeout.

```bash
ssh -o ServerAliveInterval=60 deploy@server.example.com
```

## Escape Sequences

`~.` — Terminate a stuck SSH session. Press Enter first, then type ~. (tilde dot).

```bash
~.
```

`~^Z` — Suspend the SSH session and return to local shell. Resume with fg.

```bash
~^Z
```

`~#` — List all forwarded connections in the current session.

```bash
~#
```

`~?` — Show a list of all available escape sequences.

```bash
~?
```

`~C` — Open the SSH command line to add port forwards on-the-fly during a session.

```bash
~C then: -L 3306:localhost:3306
```

## Security & Troubleshooting

`ssh-keyscan <host>` — Fetch the public host keys from a remote server.

```bash
ssh-keyscan server.example.com >> ~/.ssh/known_hosts
```

`ssh-keyscan -t ed25519 <host>` — Fetch only a specific key type from the remote server.

```bash
ssh-keyscan -t ed25519 server.example.com
```

`ssh -Q key` — List all supported key types by the local SSH client.

```bash
ssh -Q key
```

`ssh -Q cipher` — List all supported ciphers by the local SSH client.

```bash
ssh -Q cipher
```

`ssh -Q mac` — List all supported MAC algorithms.

```bash
ssh -Q mac
```

`chmod 700 ~/.ssh` — Set correct permissions on the .ssh directory (required for SSH to work).

```bash
chmod 700 ~/.ssh
```

`chmod 600 ~/.ssh/id_ed25519` — Set correct permissions on a private key file (must not be accessible by others).

```bash
chmod 600 ~/.ssh/id_ed25519
```

`chmod 644 ~/.ssh/authorized_keys` — Set correct permissions on authorized_keys.

```bash
chmod 644 ~/.ssh/authorized_keys
```

<!-- PROSE:outro -->
## Conclusion

SSH is far more than a terminal replacement: keys instead of passwords, agent forwarding for bastion hosts, port tunnels for locked-down services, and multiplexing for fast reconnections make it the backbone of any infrastructure. Keep your config file tidy and protect your keys with passphrases – you'll work faster and more securely at the same time.

## Further Reading

- [OpenSSH – official website](https://www.openssh.com/) – documentation and changelog
- [ssh(1) – manual page](https://man.openbsd.org/ssh) – every option at a glance
- [Secure Shell – Wikipedia](https://en.wikipedia.org/wiki/Secure_Shell) – background and history
<!-- PROSE:outro:end -->

## Related Commands

- [scp](https://www.jpkc.com/db/en/cheatsheets/networking/scp/) – securely copy files to and from remote hosts
- [ssh-keygen](https://www.jpkc.com/db/en/cheatsheets/networking/ssh-keygen/) – generate and manage SSH key pairs
- [mosh](https://www.jpkc.com/db/en/cheatsheets/networking/mosh/) – SSH alternative for unreliable or high-latency connections

