SSH is a utility for login, data transfer, and executing commands on remote machines. Being extremely widely used for network work, it is necessary to know at least what it can do. Below I present options and commands I use regularly, covering both basic use and the tunneling capabilities that make SSH indispensable.

Password vs. Cryptographic Keys

In addition to password-based SSH access, access using cryptographic keys is also possible. This method provides enhanced security and is much more convenient, practically eliminating the need to remember dozens of passwords. The private key is never shared. The content of the public key is copied to ~/.ssh/authorized_keys on every computer you want direct, passwordless access to. When creating the key pair you can set a passphrase to protect the private key locally; this has nothing to do with the password on any server.

ssh-keygen  # creates a key pair (private and public)
# ~/.ssh/id_rsa         # private key
# ~/.ssh/id_rsa.pub     # public key

Connecting and Commands

# connect to rohost.com as root
ssh root@rohost.com

# execute the uptime command on the server
ssh root@rohost.com uptime

# copy a file to the server
scp archive.zip root@rohost.com:/home/rohost/

# copy a file from the server to the current directory
scp root@rohost.com:/home/rohost/archive.zip ./

# copy an entire directory to /tmp on the server
scp -r archive rohost.com:/tmp

SSH Client Configuration

The client configuration file contains preferences applied at every SSH invocation. Practically all command-line flags can be saved here instead.

# ~/.ssh/config
ForwardAgent            no

Host *
    Compression         no
    ControlMaster       auto
    ControlPath         ~/.ssh/master-%h:%r:%p
    ControlPersist      60

Local Port Forwarding

If you want to access a service hidden behind a firewall, use the SSH connection to reach it. The command below maps local port 6606 to port 3306 at 127.0.0.1 as seen from the remote server. Any connection to port 6606 on your machine gives access to MySQL on that server.

ssh -fNnT -L 6606:127.0.0.1:3306 cosmin@mysql.rohost.com
# -f puts ssh in background
# -N doesn't execute remote command
# -n prevents reading from stdin
# -T doesn't allocate tty
# -L local port forwarding

If you use the above command frequently, add it to SSH config. Omit -f to keep the tunnel in the foreground, exiting on CTRL+C.

Host db
    HostName mysql.rohost.com
    LocalForward 6606 127.0.0.1:3306
    User cosmin
# open tunnel using 'db' alias from SSH config
ssh -fN db

SOCKS5 SSH Proxy

Create a SOCKS proxy through a remote server, then configure your browser to use 127.0.0.1:9999. All traffic will appear to originate from that server, encrypted between you and it. FoxyProxy for Firefox allows routing only certain sites through the proxy.

ssh -fN -D 127.0.0.1:9999 cosmin@rohost.com

Remote Port Forwarding

Expose a local port publicly through a server you can SSH into. The server must have GatewayPorts yes in /etc/ssh/sshd_config.

ssh -fN -R 80:127.0.0.1:8080 cosmin@rohost.com
# -R remote port forwarding

Persistent Reverse Tunnel with autossh

autossh re-establishes the SSH connection automatically, even when your IP changes.

# create persistent tunnel
autossh -f -- -o 'ControlPath none' -R 9999:127.0.0.1:22 cosmin@rohost.com -fN

# from the server, access the machine behind the firewall
ssh 127.0.0.1 -p 9999

Escape Character ~

Type ~ at the beginning of a new line inside an active SSH session to access special actions:

Reverse SSH on an Existing Connection

Copy files without leaving the current session or opening a new connection.

# press Enter, then ~C to open a command line
ssh> -R 4000:localhost:22

# copy through the tunnel just created
scp -P 4000 file.tar.gz localhost:/path/on/laptop

Remote MySQL Dump to Local File

ssh user@server "/usr/bin/mysqldump -u user -p password database" | dd of=/tmp/dump.sql

Redirect Local Output to a Remote File

tar -cz directory | ssh cosmin@rohost.com "cat > directory.tar.gz"

SSH Chain

Reach a server behind a firewall that is only accessible through a gateway, in one command. The SSH config form applies automatically to all matching hostnames.

ssh -t proxy@rohost.com ssh root@s33.rohost.com
# ~/.ssh/config
Host gateway
    User proxy
    HostName rohost.com
Host s**.rohost.com
    ProxyCommand ssh -q gateway nc -w 1 %h 22