Reverse Proxy to Applications in Homelab / Private Data Center with WireGuard and Netmaker

Cameron Tully-Smith
netmaker
Published in
5 min readOct 31, 2022

--

Overview

You’ve always wondered (or are wondering now) how to publicly expose a service in your home/local network. You want regular internet traffic to reach the machine, but you want to do it in a secure way. There are many ways to accomplish this, but this article shows you how to do it with WireGuard tunnels and Netmaker, to make managing such services easy.

Note: this article has been written to make the components explicit for learning purposes. In a production setup you might combine the applications onto fewer hosts depending on your security and scalability needs.

Deploy an Application on a Home Server

For this you can deploy a simple web server such as the one at https://gobyexample.com/http-servers .

You’ll first need to set up Golang locally if running go version fails.

Instructions for Golang setup are at https://go.dev/doc/install

Put the following in main.go:

This is the code we’ll use in main.go:package mainimport (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "hello\n")}func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8090", nil)}

Once the server is set up you can run it via

go run main.go &

And test it with

curl http://localhost:8090

At this point, depending on the local machine’s firewall settings, you may not be able to reach the machine even from a machine on the local network. To test the setup, try this from the local machine (the one you just set up above and tested with curl) to get the IP address for another local network (LAN) machine to access:

ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'

Then try this from another machine on the LAN:

curl http://xxx.xxx.xxx.xxx:8090

where xxx.xxx.xxx.xxx is replaced with the local network address of the machine that has the web server running. Confirm it fails (which it should if the web server’s firewall is blocking port 8090). It has failed (to be expected) when accessed from the LAN if you get an error like this:

curl: (7) Failed to connect to xxx.xxx.xxx.xxx port 8090 after 4 ms: No route to host

Deploy a VPS in the Cloud to Host Netmaker

  1. Create a VPS (eg a droplet if using DigitalOcean)
  2. Load Netmaker server. For this article, I used the quick install instructions.

Create a network on the Netmaker server:

  • Go to the Netmaker dashboard (e.g., https://dashboard.mydomain.com where mydomain.com is the base domain you used when installing Netmaker)
  • Log in (create a user if this is your first time logging into the server)
  • Go to the Networks tab (in the UI or go to https://dashboard.mydomain.com/networks )
  • Click Create Network
  • Click Autofill
  • Click Create Network

Create an access key to use from your other nodes (eg your web server):

  • Go to the Access Keys tab in the Netmaker UI either through the UI or directly via https://dashboard.mydomain.com/access-keys/mesh where mesh is replaced by the network name you just used when creating the network.
  • Click Create Access Key
  • Change the # of uses eg to 5 (to make things easy for this article). The “name” of the access key is optional.
  • Click Create
  • Copy the netclient join command to use later in this article (click the 2 overlapping pages next to the Join Command box and save the command somewhere safe while working on this article’s steps)

Join the Network from Your Local (Web) Server

On your local web server:

  • Set up the netclient
  • Join from the command line using the Join Command saved above (preceded by sudo if you get an “elevated privileges” message)
  • Confirm that the node is now on the network by checking the Netmaker UI’s Graphs tab for the network you created (e.g., mesh if that’s the name that you used)
  • From the web server (newly joined netclient) ping your only current peer. You can find the address for your other peer node by looking at the Netmaker UI graph and clicking the node that is not the Netmaker server and is not your own node (ie has a name that is not netmaker-1 and not the name of your node). Then run ping yyy.yyy.yyy.yyy where yyy.yyy.yyy.yyy is the IP address shown in the Netmaker UI’s graph view in “IP address” when the other peer node has been clicked.

Deploy a Reverse Proxy on a Netclient node

For this article we’ll use Caddy.

On your node that will run the proxy:

  1. Install docker if it’s not installed. Run docker and if it returns commands (when on Ubuntu) to install it, do so. A typical way to install on Ubuntu would be to run snap install docker
  2. Install the Netclient as above
  3. Join the Netmaker network as above
  4. Set up the proxy which will receive from Internet hosts on a port that you’d like to receive data on and proxy over the WireGuard tunnel (i.e., through the Netmaker network) to the local network machine that’s running the application (e.g., the machine in your homelab that hosts the application to serve to the Internet).

Once you’ve done 1 and 2 above, proceed as follows:

  • Create a file /root/Caddyfile as follows:
http://yyy.yyy.yyy.yyy {
reverse_proxy http://xxx.xxx.xxx.xxx:8090
}

Where xxx.xxx.xxx.xxx is replaced by the WireGuard network IP address of the machine running the web server and yyy.yyy.yyy.yyy is the public IP address of the machine hosting the proxy (Caddy in this case). You can see this from Netmaker’s graph of the network by clicking on the web server node and checking the IP address that appears to the right of the graph.

  • Create a file /root/docker-compose.yml as follows:
version: "3.4"services:
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
network_mode: host # Wants ports 80 and 443!
volumes:
- /root/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_conf:/config
volumes:
caddy_data: {}
caddy_conf: {}
  • Run docker-compose up -d and confirm that the container starts as shown by a message like this
Creating caddy ... done
  • Run docker ps and confirm that caddyis in the list

Test Reaching Your Service from Another PC

From another PC (outside of your Netmaker network) try the public IP by visiting this URL from a browser

http://yyy.yyy.yyy.yyy:8090

Conclusion

You’ve been able to reach your local service from a machine on another physical network via the secure Netmaker network indirectly (via the reverse proxy). Congratulations!

You’ll want to clean up by urning off the service: close the main.go process on your web server which you can do by killing the process after getting the PID via

ps -eaf | grep main.go

--

--

Cameron Tully-Smith
netmaker

Cameron Tully-Smith is a Sr Software Engineer at Netmaker (https://netmaker.io), a cloud networking company building the next-gen virtual networking platform.