Single use port of multiple mincraft servers

After for some time hosting a couple of vanilla and modded Minecraft servers for friends, I had to give them an IP address with port number to connect. Each time I created a new server, whether vanilla or modded. I needed to configure a new port-forwarding rule on the router. Over time, I was became annoying, especially having to specify a different port number for each server, on my router. I wanted a cleaner setup, with a neater address that doesn’t require specifying a port, and instead uses domain names to point to specific Minecraft servers.

Install HAProxy using your distribution’s package manager:

  • Ubuntu and Debian:
    apt install haproxy
  • Arch Linux:
    pacman -S haproxy
  • Fedora Linux:
    dnf install haproxy

After installing HAProxy, navigate to the configuration directory:

cd /etc/haproxy/

It’s a good idea to back up the default configuration file before making changes:

mv haproxy.cfg haproxy.cfg.bak

Now create a new haproxy.cfg file.

frontend minecraft
    bind *:25565
    mode tcp
    tcp-request inspect-delay 5s
    
    acl is_mc_vanilla payload(4,21) -m sub vanilla.example.home
    acl is_mc_creative payload(4,22) -m sub creative.example.home
    acl is_mc_modded payload(4,20) -m sub modded.example.home
    
    tcp-request content accept if is_mc_vanilla || is_mc_creative || is_mc_modded
    
    use_backend vanilla_backend if is_mc_vanilla
    use_backend creative_backend if is_mc_creative
    use_backend modded_backend if is_mc_modded

backend mc_vanilla_backend
    server mc_vanilla 192.168.1.5:25565

backend mc_creative_backend
    server mc_creative 192.168.1.5:25566

backend mc_modded_backend
    server mc_modded 192.168.1.7:25565

The function payload(Offset, Length). takes two parameters:

  • Offset: The starting position of the scan.
  • Length: Determinant how many bytes/characters will be scanned.

Note:
When calculating Length, you must add +1 byte/character to the domain length.
This ensures the full domain is scanned correctly.

Now after configuring proxy, now If I add a new server in the future, I don’t have to remember what port was assign on my router, I just need to remember what domain was assign.

Here some option quick characters counter

Linux and MacOS bash:

echo "example.com" | wc -c

Windows PowerShell:

echo (("example.com".Length + 1))

Python:

print(len("example.com") + 1)