How to Use SSH

Sources:

  1. SSH Essentials: Working with SSH Servers, Clients, and Keys

How to Use SSH

Mental model

SSH provides:

  • an encrypted transport (confidentiality + integrity) over an untrusted network
  • server authentication (host keys; prevents talking to the wrong machine)
  • user authentication (most commonly public-key auth)
  • optional tunneling (port forwarding)

You can assume the cryptography; the only practical bit to remember is the key material:

  • private key stays on the client (or in an agent)
  • public key is installed on the server (typically in ~/.ssh/authorized_keys)

In public-key auth, the server challenges the client; the client proves possession of the private key by signing, and the server verifies using the public key.

How the client picks a key (public-key auth)

When connecting, the client may have multiple candidate private keys. OpenSSH (a common SSH client implementation) will try candidates until the server accepts one.

Typical search order:

  1. Keys offered by ssh-agent (ssh-agent is a software helding ssh keys to be queried by OpenSSH; forwarded agent counts as an agent too)
  2. Default private key files in ~/.ssh/ (id_ed25519, id_rsa, id_ecdsa, …)
  3. Keys specified by IdentityFile in ~/.ssh/config
  4. Keys from /etc/ssh/ssh_config
  5. (Platform-specific) keychains

The first accepted key determines which public key on the server matched, i.e. “which account/keypair you authenticated with”.

Why you care:

  • deterministic auth on machines with many keys
  • avoid accidentally using the “wrong” key on shared servers

IdentitiesOnly

If you want to stop the “try everything” behavior and only offer explicitly configured keys, edit

1
2
3
Host github.com
User git
IdentitiesOnly yes # Add this

in ~/.ssh/config.

Agent forwarding

When developing on a remote server, you often need to access other SSH services (e.g. [email protected]). You generally do not want private keys sitting on that remote machine.

Agent forwarding lets the remote host use your local ssh-agent to sign challenges, while your private key remains local.

Enable per-connection:

1
ssh -A -p port_number username@hostname

Or persist on the local machine via ~/.ssh/config:

1
2
3
4
5
Host my_server
HostName 192.160.96.180
User anon
Port 22
ForwardAgent yes

Verify on the remote:

1
ssh-add -l

Usage

Connect

1
ssh username@remote_host

Non-default port:

1
ssh -p 2222 username@remote_host

Specify a key explicitly:

1
ssh -i ~/.ssh/id_ed25519 -p 2222 username@remote_host

Run commands remotely

1
ssh username@remote_host "command command_arguments"

Notes:

  • Quote the command string. On some systems (e.g. Manjaro), improper quoting can lead to only the first token running remotely and the rest running locally.

Pipelines: local vs remote grep

Because | is interpreted by the local shell unless quoted:

  • Local grep (remote produces output; local filters):

    1
    ssh foobar@server ls | grep PATTERN
  • Remote grep (local produces output; remote filters):

    1
    ls | ssh foobar@server grep PATTERN

Interactive commands: -t for TTY

If the remote command needs interaction:

1
ssh -t username@remote_host "command"

Configuration

~/.ssh/config

Plain-text config read by the OpenSSH client.

1
2
3
4
5
6
7
8
9
Host vm
User foobar
HostName 172.16.174.141
Port 2222
IdentityFile ~/.ssh/id_ed25519
LocalForward 9999 localhost:8888

Host *.mit.edu
User foobaz

Then:

1
ssh vm

Shell alias (quick but less maintainable)

1
alias my_server="ssh -i ~/.id_ed25519 --port 2222 -L 9999:localhost:8888 foobar@remote_server"

Keys

Generate a key

1
ssh-keygen -t rsa -b 1024 -f yourkeyname -C "备注"
参数 解释
-b 采用长度 1024 bit 的密钥对(b=bits),最长 4096
-t rsa 采用 RSA 加密方式(t=type
-f 生成文件名(f=output_keyfiles
-C 备注(C=comment
-a rounds:迭代次数;数值越高越安全也越慢;默认为 16

Notes:

  • 公钥和私钥默认位于 ~/.ssh
  • 使用 ssh-agentgpg-agent 避免每次都输入密码。

Derive public key from a private key:

1
ssh-keygen -y -f ~/.ssh/id_rsa

Key-based login (authorized_keys)

On the server, SSH consults ~/.ssh/authorized_keys.

Append your local public key to the remote authorized_keys:

1
cat .ssh/id_ed25519.pub | ssh foobar@remote 'cat >> ~/.ssh/authorized_keys'

Or:

1
ssh-copy-id -i .ssh/id_ed25519.pub foobar@remote

Tunneling

Local port forwarding (-L)

Scenario:

  • Remote server x.x.x.x is reachable only via SSH (22) due to VPN/firewall constraints.
  • A service (e.g. moodist) runs on the server at port 8080.
  • You cannot reach http://x.x.x.x:8080 directly.

Forward a local port to the remote service:

1
ssh -f -N -q -L localPort:localhost:remotePort username@remoteHost
  • -L: local forwarding
  • -f: background the SSH process
  • -N: no remote command (tunnel only)
  • -q: quiet

Example:

1
ssh -f -N -q -L 8080:localhost:8080 [email protected]

Then visit:

  • http://localhost:8080

File transfer

ssh + tee (stream local → remote)

1
cat localfile | ssh remote_server "tee serverfile"

scp

Local → remote:

1
scp <local_file> <username>@<remote_host>:<remote_directory>

Remote → local:

1
scp <username>@<remote_host>:<remote_file> <local_directory>
  • -r: directories
  • scp can leave an incomplete destination file if interrupted.

rsync

rsync improves upon scp:

  • skips identical files
  • better metadata control (symlinks, permissions)
  • resumable transfers via --partial

Syntax is similar to scp.

Process management

List SSH processes:

1
ps aux | grep ssh

Kill all SSH processes (local machine):

1
killall ssh

Warning: this kills all your SSH sessions/forwardings on the local machine.