Port Forwarding: Helpful tricks

Port forwarding can be quite useful, let's explore some interesting use-cases.

Coming from a networking background, I’ve always found a use for port forwarding. Throughout the years, I’ve encountered many co-workers that didn’t have the same background and were quite flabbergasted with the concept. I’m writing this down to share with them, and you, some simple port forwarding applications and show you why it’s a very useful tool to have in your toolbox.

What is port forwarding?

Probably you’ll have heard about port forwarding in the context of your home router. Whenever there is a service or application running on your local network, you can expose it to the internet. Let’s say you have a service running on port 8080 on your local machine, you can configure your router to forward all incoming traffic on port 8080 to your local machine. Effectively, to the outside world, your router will seem to be running a service on port 8080.

This is a very basic example, which you might have run into when setting up services or applications on your local network. Some examples of services or applications you might want to expose to the internet are:

  • Gaming consoles
  • IP cameras
  • Home automation systems
  • Remote desktop applications
  • Web servers
  • Media servers
  • Email servers
  • VPN servers

Port Forwarding In A Private Home Situation

Introduce some scenario’s. Local <–> local, local <–> remote, remote <–> remote

Useful tools

Socat

Socat is a CLI tool that establishes two streams and transfers data between them. Think of it as the router, but solely on your local machine. It will let you pass data between two ports.

Example:

# Forward traffic from port 8080 to port 80
socat TCP-LISTEN:8080,fork TCP:localhost:80

# Forward traffic from port 8080 to port 80 on `www.google.com`
socat TCP-LISTEN:8080,fork TCP:www.google.com:80

# Forward traffic from port 5432 to port 5432 on `my-remote-postgresql-server`
socat TCP-LISTEN:5432,fork TCP:my-remote-postgresql-server:5432

This utility allows you to do all kinds of neat tricks, passing around data between different ports on your local machine, or to a remote host.

localtunnel

There are several alternatives of this tool (ngrok, http tunnel, localtunnels), but at the moment I really like localtunnel. It allows you to easily access a publicly accessible URL for services running on your local machine. It even takes care of SSL certificates for you.

# This exposes your local service running on port 8080 to the internet
$ npx localtunnel --port 8080
your url is: https://unique-name-123.loca.lt

Perfect use-cases for this are when you’re developing a web application and want to show it to a client or colleague, or when you’re testing a webhook from an external service.

SSH tunnel

SSH tunneling is a powerful tool that allows you to create an encrypted connection between your local machine and a remote server. Using it, you can port forward a local port to a remote port, or vice versa. This is useful when you want to access a service running on a remote server, but don’t want to expose it to the internet.

# Forward traffic from port 8080 on your local machine to port 80 on a remote server
ssh -L 8080:localhost:80 user@remote-server

# Forward traffic from port 8080 on a remote server to port 80 on your local machine
ssh -R 8080:localhost:80 user@remote-server

Kubernetes port forwarding

If you are working in a more complex Kubernetes environment, you might want to forward traffic from a pod to your local machine. This is useful when you want to debug a service running in a pod, or when you want to access a service running in a pod from your local machine.

# Forward traffic from port 8080 on a pod to port 8080 on your local machine
kubectl port-forward pod/my-pod 8080:8080

Bringing it all together

Let’s come up with an interesting scenario where we can use all these tools together:

  1. [LOCAL] Web application running on port 8080
  2. [SSH] Remote PostgreSQL server running on port 5432
  3. [K8S] Kubernetes pod running a service on port 1337
  4. [PUBLIC] Expose the web application running on port 8080 to the internet
  5. [FIREWALL] Your firewall disallows 8080, but allows 9090

Here’s how you can set this up:

# Forward traffic from port 5432 on your local machine to port 5432 on the remote PostgreSQL server via SSH
ssh -L 5432:localhost:5432 user@remote-postgresql-server

# Forward traffic from port 1337 on the Kubernetes pod to port 1337 on your local machine
kubectl port-forward pod/my-pod 1337:1337

# Start your local service on port 8080
./service-start --port 8080

# Forward traffic from port 8080 to port 9090 on your local machine
socat TCP-LISTEN:9090,fork TCP:localhost:8080

# Expose your local service running on port 9090 to the internet
npx localtunnel --port 9090

Summarize

Port forwarding is a powerful tool that allows us to forward traffic between different technologies and networks. It can be extremely powerful and useful during development, debugging, and testing.