# SSH Tunneling and Port Forwarding Techniques: A Command-Line Reference

> Master SSH tunneling and port forwarding with command-line techniques. Securely route traffic, create SOCKS proxies, and expose local servers using -L -D -R flags. Access remote services safely.

- Repository: [Joshua Levy/the-art-of-command-line](https://github.com/jlevy/the-art-of-command-line)
- Tags: how-to-guide
- Published: 2026-02-24

---

**SSH tunneling and port forwarding techniques enable secure network traffic routing through encrypted channels using the `-L`, `-D`, and `-R` flags, allowing you to access remote services, browse via SOCKS proxies, and expose local development servers safely.**

The `jlevy/the-art-of-command-line` repository identifies SSH tunneling and port forwarding techniques as fundamental competencies for secure remote operations. As documented in the [`README.md`](https://github.com/jlevy/the-art-of-command-line/blob/main/README.md) at line 173, the OpenSSH client provides robust encryption capabilities that extend beyond simple remote shells to create sophisticated network tunnels. This guide presents the exact command structures and configuration patterns found in the repository source code to help you implement production-ready secure connections.

## Local Port Forwarding (-L)

**Local port forwarding** binds a port on your local machine to a destination reachable from the remote server. This technique is essential for accessing databases, web services, or internal APIs that are not exposed to the public internet.

According to the source code in [`README.md`](https://github.com/jlevy/the-art-of-command-line/blob/main/README.md), the standard syntax uses the `-L` flag followed by `[local_port]:[remote_host]:[remote_port]`:

```bash
ssh -L 3306:127.0.0.1:3306 user@remote.example.com

```

After establishing this connection, your local port 3306 forwards traffic to `127.0.0.1:3306` on the remote host. You can then connect to the remote MySQL instance using `mysql -h 127.0.0.1 -P 3306` as if it were running locally.

## Dynamic SOCKS Proxy (-D)

**Dynamic port forwarding** transforms your SSH client into a SOCKS5 proxy, routing arbitrary application traffic through the encrypted tunnel. This approach is ideal for secure web browsing or when you need to route multiple protocols through a single remote gateway.

The `jlevy/the-art-of-command-line` repository documents this technique using the `-D` flag to specify a local port:

```bash
ssh -D 1080 user@remote.example.com

```

Configure your browser or operating system to use `localhost:1080` as a SOCKS5 proxy. All TCP traffic will then traverse the encrypted SSH connection to `remote.example.com` before reaching its final destination, masking your local IP address and bypassing local network restrictions.

## Remote Port Forwarding (-R)

**Remote port forwarding** reverses the direction, exposing a service running on your local machine to the remote server. While used less frequently due to security considerations, this technique enables external access to local development servers or internal tools.

The syntax follows `[remote_port]:[local_host]:[local_port]`:

```bash
ssh -R 8080:localhost:3000 user@remote.example.com

```

Once connected, any user who can reach `remote.example.com:8080` will be proxied to your local service on port 3000. This is particularly useful for sharing local development previews with colleagues or integrating with webhook services that require public endpoints.

## Connection Optimization with SSH Config

The repository provides a configuration snippet in [`README.md`](https://github.com/jlevy/the-art-of-command-line/blob/main/README.md) (lines 175-184) that optimizes tunnel stability through connection multiplexing and keepalive settings. Add the following to your `~/.ssh/config` file:

```text
Host *
    TCPKeepAlive=yes
    ServerAliveInterval=15
    ServerAliveCountMax=6
    Compression=yes
    ControlMaster auto
    ControlPath /tmp/%r@%h:%p
    ControlPersist yes

```

These settings enable **ControlMaster** multiplexing, allowing multiple SSH sessions to share a single underlying TCP connection. The `ServerAliveInterval` and `ServerAliveCountMax` parameters ensure tunnels remain active during periods of inactivity by sending periodic keepalive packets.

### Establishing Persistent Master Connections

To leverage multiplexing, first establish a master connection that persists in the background:

```bash
ssh -M -S /tmp/$(whoami)@myhost:22 user@myhost

```

Subsequent tunnel commands reuse this socket connection, making them nearly instantaneous and reducing TCP handshake overhead:

```bash
ssh -S /tmp/$(whoami)@myhost:22 -L 5432:127.0.0.1:5432 user@myhost

```

## Config-Based Tunnel Aliases

For frequently used tunnels, the repository recommends defining shortcuts directly in `~/.ssh/config` using the `LocalForward` directive. This approach eliminates the need to remember port numbers and hostnames:

```text
Host mytunnel
    HostName remote.example.com
    User user
    LocalForward 5900 localhost:5900

```

With this configuration, you initiate the tunnel using a single command:

```bash
ssh mytunnel

```

This establishes the connection and automatically forwards local port 5900 to the remote VNC server, demonstrating how SSH tunneling and port forwarding techniques integrate seamlessly with standard configuration management.

## Summary

- **SSH tunneling and port forwarding techniques** provide encrypted pathways for network traffic using the `-L`, `-D`, and `-R` flags documented in the `jlevy/the-art-of-command-line` repository.
- **Local forwarding** (`-L`) connects local ports to remote services, while **remote forwarding** (`-R`) exposes local services to remote hosts.
- **Dynamic forwarding** (`-D`) creates SOCKS5 proxies for comprehensive traffic routing through secure channels.
- The [`README.md`](https://github.com/jlevy/the-art-of-command-line/blob/main/README.md) configuration snippet (lines 175-184) implements **ControlMaster** multiplexing to reduce connection latency and improve reliability.
- Persistent tunnels benefit from `ServerAliveInterval` and `TCPKeepAlive` settings to prevent timeout disconnection during idle periods.

## Frequently Asked Questions

### What is the difference between SSH local and remote port forwarding?

**Local port forwarding** (`-L`) forwards traffic from your local machine to a destination accessible by the remote server, useful for reaching remote databases or internal web services. **Remote port forwarding** (`-R`) operates in reverse, allowing the remote server to access services running on your local machine, commonly used for exposing local development servers to the internet through a remote gateway.

### How does SSH connection multiplexing improve tunnel performance?

Connection multiplexing, configured through `ControlMaster auto` and `ControlPath` settings in `~/.ssh/config`, allows multiple SSH sessions to reuse a single established TCP connection. This eliminates the overhead of repeated authentication handshakes and TCP slow-start phases, making subsequent tunnel connections instantaneous and reducing overall network latency when managing multiple ports.

### How do I keep SSH tunnels alive automatically?

Configure your `~/.ssh/config` with `ServerAliveInterval 15` and `ServerAliveCountMax 6` as shown in the repository's recommended snippet (lines 175-184). These directives instruct the client to send periodic keepalive messages every 15 seconds, preventing firewalls or NAT routers from terminating idle connections and ensuring persistent tunnels remain active during extended operations.

### When should I use a dynamic SOCKS proxy instead of local port forwarding?

Use **dynamic forwarding** (`-D`) when you need to route multiple protocols or arbitrary destinations through a secure tunnel, such as when browsing websites or using applications that connect to various external APIs. Local port forwarding is preferable when targeting specific, known services like a single database instance or Redis server that operates on a fixed port.