Port forwarding is amazingly useful. If you’ve never used this feature before, the tl;dr is you can bind a port on your local system to a port on a remote system. This allows you to interact with a service as if it were running on your computer (eg, connect to a database that is firewalled off).
ssh
can also perform “dynamic” port forwarding. This creates a SOCKS http proxy through the remote
host. Any tool that respects the https_proxy
environment variable can access services on (or
access the internet through) the remote server.
Example: accessing remote Kubernetes API
I run k3d on my desktop as a local kubernetes “cluster”. Sometimes I want to sit on the couch and keep working on a project. It’s easy enough to use either method to get access working as if I were sitting at my desk!
⚠️
k3d
binds to0.0.0.0
on a random port by default. I prefer to set it to127.0.0.1
and a known port, making simple port binding more predictable.
Dynamic (socks proxy)
Easy to setup, but requires https_proxy
environment variable to be set. Not all applications work
out of the box.
# Starting out on my laptop, can't access kubernetes API
❯ kubectl --context k3d-blog-example get node
The connection to the server 127.0.0.1:6550 was refused - did you specify the right host or port?
❯ screen -S k3d-tunnel
...
# Inside screen window
❯ ssh -NnD 127.0.0.1:9001 $user@$desktop
...
# `Ctrl+a d` to detach from screen
[detached from 53775.k3d-tunnel]
❯ kubectl --context k3d-blog-example get node
The connection to the server 127.0.0.1:6550 was refused - did you specify the right host or port?
# THAT'S MORE LIKE IT
❯ https_proxy=socks5://127.0.0.1:9001 kubectl --context k3d-blog-example get node
NAME STATUS ROLES AGE VERSION
k3d-blog-example-server-0 Ready control-plane,master 111s v1.20.6+k3s1
Local port binding
A little more basic, but this binds the desired port locally – effectively behaving as if the
service was truly on my local system. The downside is I need to bind a new port for every service
I wish to access (e.g., 8080
& 8443
to access the loadbalancer service of my local cluster).
# Starting out on my laptop, can't access kubernetes API
❯ kubectl --context k3d-blog-example get node
The connection to the server 127.0.0.1:6550 was refused - did you specify the right host or port?
❯ screen -S k3d-tunnel
...
# Inside screen window
❯ ssh -NnT -L 6550:localhost:6550 $user@$desktop
...
# `Ctrl+a d` to detach from screen
[detached from 53775.k3d-tunnel]
❯ https_proxy=socks5://127.0.0.1:9001 kubectl --context k3d-blog-example get node
NAME STATUS ROLES AGE VERSION
k3d-blog-example-server-0 Ready control-plane,master 1m v1.20.6+k3s1