Use linode as a frontend proxy server for an external backend server
I am trying to use get one of my linode servers to act as a sort of external router / firewall for one of my locally hosted game servers (Running a rust server which uses 28015 udp & 28082 tcp). To do so it needs to be able to forward all outgoing connections (or just select connections on certain ports) and route connections back to the locally hosted server. Initially I setup the linode as a openvpn server and connected the local server to it and used nginx to route all connections back the the server. This seemed to be working but it seems that nginx was having issues sending the udp traffic back and was running out of worker connections, and as such I adjusted them to 12x the origional setting 1024 > 12288 that let me connect to the server but it created issues with the servers listing on the steam public server lists for Rust and as reported by Nginx Amplify it was creating around 3300 open socket connections through nginx per client connected. So instead I have switched to using iptables and stayed with openvpn as the connection between local and linode and the connection seemed to be solid, I used it for both the 28015 udp port and the 28082 tcp port, but started to see issues with battlemetrics and the steam public listing not being able to query the server for information… but for whatever reason if a player knew the same server ip, they had no issues joining. The query port is the same port that is used for player connection. As such I thought maybe it was a issue with the vpn connection between the local server and the linode and I changed it to using a ipsec connection. Same thing. The config for iptables is listed below, any assistance would be greatly appreciated and any extra info that is needed I can add.
# Generated by iptables-save v1.8.7 on Sat Oct 1 01:51:49 2022
*filter
:INPUT ACCEPT [92:7225]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [2217257:2764732609]
-A INPUT -p udp -m udp --dport 1701 -m policy --dir in --pol none -j DROP
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p udp -m multiport --dports 500,4500 -j ACCEPT # IPSec
-A INPUT -p udp -m udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT
-A INPUT -p udp -m udp --dport 1701 -j DROP
-A INPUT -p udp -m udp --dport 1194 -j ACCEPT
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -i eth0 -o ppp+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i ppp+ -o eth0 -j ACCEPT
-A FORWARD -i ppp+ -o ppp+ -j ACCEPT
-A FORWARD -d linode_public_ip/32 -i eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s linode_public_ip/32 -o eth0 -j ACCEPT
-A FORWARD -s linode_public_ip/32 -o ppp+ -j ACCEPT
-A FORWARD -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 10.8.0.0/24 -j ACCEPT
-A FORWARD -j DROP
COMMIT
# Completed on Sat Oct 1 01:51:49 2022
# Generated by iptables-save v1.8.7 on Sat Oct 1 01:51:49 2022
*nat
:PREROUTING ACCEPT [1149:196646]
:INPUT ACCEPT [47:4512]
:OUTPUT ACCEPT [53:4096]
:POSTROUTING ACCEPT [70:11576]
-A PREROUTING -p udp -m udp --dport 28015 -j DNAT --to-destination local_server_public_ip:28015 # Rust Game Server
-A PREROUTING -p tcp -m tcp --dport 28082 -j DNAT --to-destination local_server_public_ip:28082 # Rust App
-A PREROUTING -p tcp -m tcp --dport 5678 -j DNAT --to-destination local_server_public_ip:5678 # Rust RCON
-A POSTROUTING -s 192.168.42.0/24 -o eth0 -j MASQUERADE
-A POSTROUTING -s 192.168.43.0/24 -o eth0 -m policy --dir out --pol none -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source linode_public_ip
-A POSTROUTING -o eth0 -p udp -m udp --dport 28015 -j MASQUERADE
-A POSTROUTING -o eth0 -p tcp -m tcp --dport 28082 -j MASQUERADE
-A POSTROUTING -o eth0 -p tcp -m tcp --dport 5678 -j MASQUERADE
COMMIT
# Completed on Sat Oct 1 01:51:49 2022
NOTE: THE ABOVE CONFIG IS FROM A IPTABLES-SAVE FILE
1 Reply
✓ Best Answer
Update: I have solved the issue, took me a while and I had posted this question after over a month of working on this issue for way too many hours a day. Not sure what the exact issue was but the server did not like me forwarding the connections to the public ip of the local server. So I did some messing around and changed the forwarding from the local servers public ip to the tunnel ip of the connected vpn client (which is a direct tunnel to the local server). now the prerouting entries look like this -A PREROUTING -p udp -m udp --dport 28015 -j DNAT --to-destination 192.168.42.10:28015
(Protocol tcp for entries that require it)