Step by step with illustrations on how to configure Ubiquiti Unifi Dream Machine to host services in the lan over VPN connection with port forwarding.

In the earlier post we discussed how to host services behind restrictive firewall, including CGNAT, by routing the traffic through a vpn endpoint and port forwarding. This of course requires running the VPN client on the local machine to maintain connection to vpn endpoint. However, it is more appropriate to handle network on a networking device, and let the local servers focus on serving.

In this tutorial, we shall perform the following tasks:

To minimize potential for errors, we’ll use the same port number 32208 throughout: i.e. our AirVPN instance will forward port 32208 to the same port 32208 to the client, UDMP will DNAT this port to the same port on the LAN server, and HTTP server we are exposing as a test will also be configured to listen on that same port.

If a different port is desired at any step, it can also be accommodated in DNAT and firewall rules, but this will give us a working baseline configuration.

Configure a simple web server for testing

For this I’m using an instance of thttpd running in FreeBSD jail as a proof of concept. The setup is pretty straightforward:

mkdir -p /var/www
echo "Hi there, hello!" > /var/www/index.html
pkg install -y thttpd
sysrc thttpd_flags="-p 32208 -d /var/www"
service thttpd enable
service thttpd start

# verify
curl localhost:32208

Configure Wireguard VPN endpoint with Port Forwarding

I’ll be using AirVPN endpoint in this tutorial, however, any other VPN that allows to configure port forwarding will work. Refer to the earlier post for configuring your own VPN server with port forwarding on Oracle Instance.

Generate the wireguard configuration file for the chosen server(s) for TCP/IP v4 only; if you accidentally generated for both—edit the file and delete the references to ipv6. You may also consider deleting the DNS and MTU configuration parameters. The configuration file should look something like this:

[Interface]
Address = 10.191.243.112/32
PrivateKey = redacted
DNS = 10.128.0.1

[Peer]
PublicKey = redacted
PresharedKey = redacted
Endpoint = 198.44.134.6:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 15

(No dark mode screenshot: if you are using dark theme—apologies for the crude concoction)

AirVPN Port Forwarding

Configure Ubiquiti Dream Machine to forward traffic to the LAN server

Create VPN Client connection

Go to Settings → VPN → VPN Client → Create New, and upload your vpn configuration file. Give the connection some descriptive name, and disagree to create a traffic policy for now. We’ll do it later:

Setting up VPN client

Configure Policy-Based Routing from LAN server to VPN (optional)

If you want all the traffic originating on your server to go via the tunnel, for example, if you plan to use DDNS with updater running on the same host, to track your VPN endpoints’ changing IP, go to Routing → Policy Based Routing → Create Entry, and configure it like so:

Option Value
What to Route? All traffic
Source Select your server machine
Interface/VPN Tunnel Select you vpn interface
Fallback Turn off if you want your server to see the world only via VPN
Setting up Policy-Based routing

It will end up looking like so:

Configured Policy-Based routing

Configure DNAT from VPN to LAN server

To forward packets arriving to VPN interface to the server in the lan configure Destination NAT:

Go to Routing → NAT → Destination → Create Entry. Set the following parameters:

Option Value
Protocol TCP or TCP/UDP
Interface Select your VPN client interface name you picked on previous step
Destination port The one server is listening on, 32208 in this example
Translated IP address Server LAN address, 10.0.17.249 in this example

Don’t configure anything else. Translated Port can be adjusted later if needed.

Configuring DNAT

Create firewall policy

Create firewall rule to allow traffic arriving from the VPN connection to the server in the lan.

Note, on UDMP VPN client is in External zone, and the LAN is in Internal zone.

Go to Security → Firewall → Create Policy.

Set the following:

Option Value
Source Zone External, Any (or put IP of your VPN local endpoint)
Port Any
Action Allow
Destination Zone Internal
Destination Zone → Internal → IP Specific → add your server’s IP, 10.0.17.249 in this example
Destination Zone → Internal → Port Specific → add port DNAT is configured to, 32208 in this example
IP Version IPv4
Protocol as needed, probably TCP/UDP
Connection State All

The result will look like so:

Configuring Firewall

Testing and caveats

Attempt to reach the server from outside (e.g., mobile location, or other service like iCloud Private Relay) using the external IP address or DDNS name. Attempts from the lan will likely fail (see Hairpin NAT).

For example, http://hi-there-hello.airdns.org:32208

If this does not immediately work, check for traffic on port 32208 on various interfaces involved (vpn endpoint and lan bridge on UDMP and server lan adapter) with tcpdump -i <adapter name> port 32208