I got tired of paying $20/month to cloud providers for hosting my side projects, especially when I have 3 raspberry pis sitting idle. I moved my projects in-house this past weekend.
Traefik has been useful for serving multiple projects, but I realize what I really want is a reverse proxy directly on the router. My router has ARM architecture, 50 MB disk space, and <500 MB RAM, so traefik is out of the question.
I could use HAProxy or nginx, but the thought of maintaining their config files really dampens my spirits; infrequent config changes always causes dozens of search queries for reminders of how to update config.
Caddy 2 came very close to being a straightforward solution, but I specifically need to route based on HTTP headers, and I hit a wall at the somewhat sparsely detailed quick-start guide (it seems possible, but it's hard to tell).
Finally, I was pleasantly surprised by skipper, whose "eskip" config is as straightforward as it gets. With the help of the docs, I was able to install it on the router and route traffic in ~30 minutes.
# Suggested setup
To use the router as a reverse proxy server, it will need to be equipped with ssh. This guide uses OpenWRT, but other software might also do the trick.
Alternatively, if using the router is too much trouble, you can port forward to a dedicated reverse proxy machine.
If you choose this option then replace all instances of "router" with "dedicated skipper server"
Machines with unique hostnames
I don't assume that my servers will always have the same LAN ip, especially if I need to replace the router for some reason.
Hostnames are static and useful for contextual routing, so each of my backend severs gets a specific hostname:
Personally I like to use random Halo Monitor names as hostnames
# machine: backbend server echo 'noble-operator' | sudo tee /etc/hostname
# Install Skipper
Select the appropriate architecture from the releases page and install it on the router.
# machine: router curl -L https://github.com/zalando/skipper/releases/download/v0.11.98/skipper-v0.11.98-linux-arm7.tar.gz -o skipper.tar.gz tar -zxvf skipper.tar.gz cd skipper-v0.11.98-linux-arm7/
Need curl in OpenWRT?
opkg update; opkg install curl
Then save the following to
routes.eskip (it's only a simple ping/pong health check for now).
// machine: router // routes.eskip ping: Host("ping") -> status(200) -> inlineContent("pong\n") -> <shunt>;
# Run skipper
This guide will assume you serve skipper from port
12345, so replace that with whichever port you choose.
# machine: router ./skipper -routes-file=routes.eskip -address 0.0.0.0:12345 -metrics-flavour=prometheus -enable-connection-metrics
Then run this curl command:
# machine: router curl -H Host:ping http://127.0.0.1:12345
If you got a
pong back, it's working!
# Open the gates
And now for the magic hack that opens up this proxy to the world, port-forward your desired ports (usually 80/443) to the router itself. I guess this is hardly port "forwarding," per se, now it's more like port "consuming."
If you're using a dedicated reverse proxy machine inside the LAN (and not the router), then port forward to that instead.
Then test it from the internet (I use my phone, disconnected from wifi, to make sure there's no network shenanigans):
# machine: something that is not on your LAN curl -H Host:ping http://220.127.116.11 # replace 18.104.22.168 with your public IP
If all is right, you should get another
# Add routes
Now you're ready to start routing.
// machine: router // routes.eskip ping: Host("ping") -> status(200) -> inlineContent("pong\n") -> <shunt>; example: Host("example.com") ->preserveHost("true") -> "http://noble-operator";
This example forwards
example.com to the server with the
Now you can explore the docs and skipper's many features, such as metrics, ratelimiting, filters, and protcols.