This post again is related to my Home lab setup. (Please come back later for my actual travel blog.) This time the task is to expose the development server to the outside world. Keep in mind that we are still on the go working from a public wifi. Meaning Port Forwarding is not an option.
To do the trick we will route the traffic to another server on the internet that we have control over and create a little rendezvous. Right here. In Finland! 🇫🇮
Let me explain: When I provisioned my Cloud Server at Hetzner a while ago, I did not think much about the location of the data center. Finland was preselected, so I went along. This blog is also served to you from that very server. 👋
$ whois $(dig +short mesterheide.net)
% This is the RIPE Database query service.
% The objects are in RPSL format.
%
inetnum: 95.216.0.0 - 95.217.255.255
netname: DE-HETZNER-20090224
country: FI
For readability sake, let’s call the development server „Site Go“ and this webserver „Site Fin“.
Fin already has a public IPv4 address preconfigured. While we could use the existing IP address, we want to keep things separate so we order a new Floating IP address from Hetzner and simply assign it to the same server. In earlier days the idea of a computer having more than one IP address was a strange concept to me, but actually it’s neither strange nor unusual.
Here is what Hetzner wants use to do on our Ubuntu 20.04 server Fin to make the new configuration permanent:
# File: /etc/netplan/60-floating-ip.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses:
- 159.69.XXX.XXX/32
Followed by a sudo netplan apply we are up. Next we also want the Apache server that is serving WordPress to only listen on port 443 and port 80 on the IP address that mesterheide.net resolves to. By default Apache listens on all interfaces via 0.0.0.0 including our newly assigned Floating IP. Let’s restrict that:
# File: /etc/apache2/ports.conf
Listen 95.216.XXX.XXX:80
<IfModule ssl_module>
Listen 95.216.XXX.XXX:443
</IfModule>
<IfModule mod_gnutls.c>
Listen 95.216.XXX.XXX:443
</IfModule>
After restarting Apache we can confirm everything is working with ss -lntp to investigate the TCP sockets, especially their Local Address and Port.
Let’s also update our DNS zone file like this to get a new subdomain pointing to our Floating IP address:
$ORIGIN mesterheide.net.
$TTL 86400
; A Records
@ 600 IN A 95.216.XXX.XXX
bruh.homelab 600 IN A 159.69.XXX.XXX
Neat! But so far nobody is listening…

Let’s address out development server Go for a moment. How do we establish a connection to it from anywhere on the Internet? After all that is what we are aiming at, exposing it to the outside world.
At this point there are multiple solutions possible, but all of them invariably use some form of indirection or reverse proxying. Instead of connecting directly to Site Go, we have Site Go connect to Site Fin and forward all incoming traffic to Go.
The only tool we neet to accomplish this is our trusty OpenSSH client. It features the -R option which is basically the inverse of the more common -L option.
# From the man page
-R [bind_address:]port:host:hostport
-R [bind_address:]port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket
-R [bind_address:]port
Specifies that connections to the given TCP port or Unix socket
on the remote (server) host are to be forwarded to the local
side.
-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
Specifies that connections to the given TCP port or Unix socket
on the local (client) host are to be forwarded to the given host
and port, or Unix socket, on the remote side. This works by al‐
locating a socket to listen to either a TCP port on the local
side, optionally bound to the specified bind_address, or to a
Unix socket. Whenever a connection is made to the local port or
socket, the connection is forwarded over the secure channel, and
a connection is made to either host port hostport, or the Unix
socket remote_socket, from the remote machine.
For as long as we want to expose the development server Go on our imaginary bruh.homelab.mesterheide.net subdomain we run the following command on the command line on the Go server:
ssh -nN -R 159.69.XXX.XXX:443:localhost:443 -R 159.69.XXX.XXX:80:localhost:80 bruh[at]mesterheide.net
This will forward all HTTP/S traffic. With a little detour to Finland.