# SSH
%%
## IPv4 vs. IPv6
![[IPv4 and IPv6 addresses in SSH]]
%%
## 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.](https://superuser.com/questions/370930/ssh-reverse-socks-tunnel/1434747#1434747)
### Local port forwarding
Forward `$LOCAL_PORT` from the local machine (`-L`), to `$TARGET_HOST` on `$TARGET_PORT`, relative to `$REMOTE_HOST`:
```bash
ssh -L $LOCAL_PORT:$TARGET_HOST$:$TARGET_PORT $REMOTE_USER@$REMOTE_HOST
```
(Traffic flows from `localhost:$LOCAL_PORT` > `$REMOTE_HOST` > `$TARGET_HOST:$TARGET_PORT`.)
%%
![[Open the Windows Firewall to incoming connections]]
%%
### Dynamic port forwarding
Create a tunnel from the local machine using `$LOCAL_PORT` as the `$REMOTE_HOST`:
```bash
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*:
```bash
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*:
```bash
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`.)
%%
### Forwarding UDP traffic
![[Forward UDP traffic with SSH and socat]]
## The SSH command line
![[Use the SSH command line]]
%%
## Change a key's passphrase
```bash
ssh-keygen -p -f $SSH_PRIVATE_KEY_FILE
```
## SSH on Windows
[OpenSSH](https://www.openssh.com) 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 [[Windows services|service]] on Windows, but is disabled by default.