SSH tunnels from first principles – with a working self-hosted setup

ap_211 pts0 comments

Port Forwarding<br>Arvind Parekhdeveloper | thinker<br>Toggle theme<br>Home1Writing2About3Work4Microblog5Photos6Journey7Stack8Bookmarks9Ping0

Online X (Twitter) GitHub LinkedIn Medium Instagram YouTube Bluesky

Writingsvg]:px-2.5">RSS feed

Port Forwarding27 June, 2026 Understanding Convex – How I built a real-time application under 4 hours15 October, 2025 Compounding21 July, 2025 Exploring CRDTs – Conflict-Free Replicated Data Types7 July, 2025 Building Agentic Systems – AI Agent Architecture Patterns6 July, 2025 To Pretend or Not?22 June, 2025 What exactly is Serverless?23 May, 2025 Human tendency for Structuredness and still the need for Unstructuredness6 May, 2025 How Media Changes Our Opinions on Reality So Fast — And Why That Might Be a Good Thing5 May, 2025 Typescript – Nullish Coalescing vs Logical OR23 April, 2025 Exploring JWTs from First Principles5 March, 2025 Learning AWS21 Feb, 2025

Port Forwarding<br>27 June, 2026tech self-hosted

This is a practical guide to SSH tunnels - Local and Remote Port Forwarding. This captures my learnings and realizations about the things I could do, or could've done, over the course of owning and building my self-hosted setup.

My self-hosted setup is pretty minimal right now. I own a personal VPS through Oracle, where I self-host a couple of applications. I do use my stack very often though, and it has made a meaningful difference in the way I use software, and made me a better developer.

The main mechanism to converse with my server is SSH (Secure Shell). SSH is a multiplexed, encrypted, bidirectional pipe between two machines. Simply put, SSH is a protocol used for logging into a remote machine over a network. Before SSH, people used Telnet, which sent everything (including confidential information, like passwords) as plain text. Anyone watching the network traffic could read it. SSH wraps everything in encryption.

When you type:

ssh ubuntu@132.145.149.218

Local machine opens a TCP connection to port 22 on 132.145.149.218.

Both sides do a cryptographic handshake. They agree on encryption keys without ever sending those keys as plain text (Diffie-Hellman).

You get an encrypted shell. Whatever you type, goes over to the remote machine and executes there.

So SSH is fundamentally just an encrypted pipe between two machines, with the terminal on one side (usually) and a shell on the other.

An obvious part of hosting a remote server is the ability to interact with the remote machine from the local machine and vice versa. SSH enables that ability for authenticated users to control devices over the network. SSH as mentioned, creates a single, encrypted bidirectional pipe between two machines. However, the processes running on each server, do not know what SSH is, and therefore, cannot send data over the common pipe. SSH's "tunneling" features, however, allows users to modify what information really travels through the pipe.

Let's say App-A on the local machine wants to communicate with App-B on the remote machine. Theoretically, it should be possible now that we have a data-transfer mechanism between the two. But as-is, the local application doesn't know what SSH is. Curl, postgres client, browser, all they know is TCP. They need a plain local address to connect to. Similarly, if App-B wants to access services of App-A, it'd need a plain local address to connect to, since it doesn't inherently understand SSH.

Technically, one could use a network address for connecting to remote services, but that'd require creating a new SSH connection - each with it's new credentials, keys, passwords. You'd be establishing full SSH handshakes just to send individual requests. It is expensive and extremely wasteful.

Solution is Port Forwarding, and the literal meaning makes sense now.

Local Port Forwarding: forwards a local port to the SSH pipe

Remote Port Forwarding: forwards a remote port to the SSH pipe

(forward just means to pass-over data: requests and responses)

The Network Topology

To understand the full extent of capabilities provided by port forwarding, it's helpful to understand the different networks and attached hosts that'd come into play when you perform port forwarding. These hosts are:

Internal - a device on the home network

Local - your workstation. This sits on both the home network and public internet

Remote - the remote workstation (server, gateway, router, etc). This sits on both the private VPC network and the public internet.

Private - a device on the Remote host's private VPC (a database, for example).

(Refer to the sections below for a refresher on ports, networks and the need and utility of private networks, since it'll be useful later for understanding port forwarding)

What a Network actually is

Every computer has a network interface - a piece of hardware that can send and receive electrical signals (and radio waves for WiFi). A network is just a bunch of machines with network interfaces connected together so they can exchange those...

port remote network local forwarding pipe

Related Articles