Wanted to document a quick project I put together yesterday for posterity. I haven’t mentioned it before, but the way that I host this website as well as most of my other services is through a pretty convuluted reverse proxy. See I have a server at home that is more then capable of running all of this, but obviously my home internet plan does not come with a guranteed permanent public IPv4 address. Some time ago when I was setting all of this up I decided that I didn’t want to mess with dynamic DNS and I wasn’t a fan of port forwarding my router and listing my home IP address in my DNS records. So instead I set up a reverse proxy solution. To accomplish this I rent a virtual private server (VPS) from a company for a small monthly fee. While this VPS does not have the power necessary to run all of my publically hosted services (hence the small fee, a beefier VPS would be significantly more expensive), it does come with a guranteed permanent public IPv4 for the time that I keep renting it.

I set this VPS up with Wireguard and basically turned it into an edge device on my network. It maintains a point to point VPN with a VM on my home server. Additionally on both the VPS and the VM that it’s connected to I’m running HAProxy, configured as a reverse proxy. With this setup I can point all of my DNS A records at the VPS. Any request towards any of my home serivces first goes to the VPS and then behind the scenes this gets proxied to whatever service is requested. This setup offers a number of benefits:

  • I don’t have to open any ports on my router
  • I can easily DMZ off any public facing service on my network with virtualization
  • I can easily spin up / down services at a whim by simply creating a box, adding the applicable DNS CNAME, and modifiying my HAProxy config.
  • All public facing, inspectable traffic doesn’t actually go to my ISP. All my ISP sees is a host on my network talking to a VPS somewhere.

The main downside of this setup is that I have to pay for a VPS, but since the only thing this VPS has to do is route packets around I can get away with some very anemic hardware, and I get a very good price.

Anyway, yesterday I set out to achieve something I had been thinking of for some time but had not gotten around to, which was to set up a Minecraft server in this same fashion. Basically I wanted to run a Minecraft server (running MineOS) on my local server, but have the access to this server occur through the VPS reverse proxy.

minecraft_proxy_network_plan.png

This is more challenging then it seems on the surface since Minecraft is not HTTP based. Since Minecraft is not HTTP based, HAProxy can not route it properly. The solution I picked for this was to use some specific Minecraft proxying software called Velocity. Velocity is maintained by the same group as PaperMC and is specifically designed to route Minecraft (namely for PaperMC/Spigot servers). Following some advice found on this post on the Level1Forums, I downloaded velocity on my VPS, configured it as described in the Velocity documentation, and wrote a systemd service file to enable it as a systemctl service. I then set up another Wireguard VPN client endpoint on my MineOS VM (so that both my HAProxy VM and my MineOS VM connect to my VPS on boot and at all other times).

Following this tutorial I learned that Minecraft requires two DNS listings, an A record and an SRV record, so I set that up (using the Velocity default port of 25577 instead of Minecraft’s port 25565). Also, as a quick note, I made sure that my server was running PaperMC since Velocity allows for very easy and secure player information forwarding with Paper, and I made sure to enforce the whitelist on the server.

And honestly, that was about it. I had to mess around with some firewall rules a little bit, but it was about that simple. And it works great! Unfortunately I don’t actually have a lot of friends that are playing Minecraft currently, but I really wanted to see if I could get a server to work in this manner. I’m pretty pleased with the results.

minecraft_server_setup.png

minecraft_ingame.png