Port forwarding

The most important thing to remember about SSH port forwarding is that specifications are read as $FROM_SPEC:$TO_SPEC. So a local port forward creates a port that the local system uses to communicate with the remote host/port specified by $TO_SPEC, while a remote port forward creates a port that the remote system uses to communicate with the local host/port specified by $TO_SPEC. (It’s actually a little more complicated than this, as the $FROM_SPEC might be something like *:8888, which opens up port 8888 to all systems on the local subnet, not just localhost.

Note

Port forwarding is always one-way, from the created port to the destination port.

It’s also possible to use SSH as a SOCKS5 proxy (with a tool like proxychains). As of OpenSSH 7.6, proxy ports can be opened up for both local and remote systems.

Local port forwarding

Forward $LOCAL_PORT from the local machine (-L), to $TARGET_HOST on $TARGET_PORT, relative to $REMOTE_HOST:

ssh -L $LOCAL_PORT:$TARGET_HOST$:$TARGET_PORT $REMOTE_USER@$REMOTE_HOST

(Traffic flows from localhost:$LOCAL_PORT$REMOTE_HOST$TARGET_HOST:$TARGET_PORT.)

Dynamic port forwarding

Create a tunnel from the local machine using $LOCAL_PORT as the $REMOTE_HOST:

ssh -D $LOCAL_PORT $REMOTE_USER@$REMOTE_HOST

(Traffic flows from localhost:$LOCAL_PORT$REMOTE_HOST → the remote network, with $REMOTE_HOST acting as a SOCKS proxy for the local machine.)

Remote port forwarding

Forward $REMOTE_PORT from $REMOTE_HOST (-R), to $TARGET_HOST on $TARGET_PORT, relative to the local machine:

ssh -R $REMOTE_PORT:$TARGET_HOST:$TARGET_PORT $REMOTE_USER@$REMOTE_HOST

(Traffic flows from $REMOTE_HOST:$REMOTE_PORT → local machine → $TARGET_HOST:$TARGET_PORT.)

Reverse dynamic port forwarding

Create a tunnel from the $REMOTE_HOST using $REMOTE_PORT as the local machine:

ssh -R $REMOTE_PORT $REMOTE_USER@$REMOTE_HOST

(Traffic flows from $REMOTE_HOST:$REMOTE_PORT → local machine → the local network, with the local machine acting as a SOCKS proxy for the $REMOTE_HOST.)

Change a key’s passphrase

ssh-keygen -p -f $SSH_PRIVATE_KEY_FILE

SSH on Windows

OpenSSH has come bundled with Windows since Windows 10 1803.

By default, SSH on Windows uses the full Kerberos username, $DOMAIN\$USER. This can often cause problems when interacting with non-Windows systems; the solution is to explicitly specify the username used in a given connection, either on the command line or in ~/.ssh/config.

SSH-Agent on Windows

The ssh-agent daemon is available as a service on Windows, but is disabled by default.