[IPTABLES] Make a service available from LAN as from WAN
Posted: Wed Feb 13, 2013 7:57 pm
[Problem]
You have a service running, e.g. some replication service, and can access it from outside without a problem using a normal POSTROUTING IPTables Line; But from the inside, you hit a wall if you use the EXTERNAL PUBLIC IP and thus must reconfigure the client every time depening on if you're in LAN or WAN. Well, not anymore.
[Solution]
-s 192.168.1.0/24 = Only if the request comes from our LAN, AND
-d PUBLIC IP = the destination IP is our PUBLIC IP AND
-dport SERVICE PORT = the port it wants to connect is the service we want
THEN DNAT to the actual SERVER_IP of the server running the service.
On the way back, we check mostly for the same things, but the SNAT of the Source is the IP of the ROUTER = The machine running the iptables. It knows the way the packets must go back, dont worry.
The whole thing looks funny, but works like a charm. Also, make sure you have needed ACCEPT rules in the appropriate INPUT, OUTPUT and FORWARD Chains, as well as IP_FORWARDING = 1 set on the router itself.
In case you're scared now, here a example with fake IPs, assuming:
Our Webserver has the Public IP 1.2.3.4 and the LAN IP 192.168.1.10
Our Router is 192.168.1.1 (the machine where you are editing the iptables)
Our Service Port is a Webserver = 80
(I hope i didn't mess up the example now... the whole thing is a pretty huge brainfuck as-is...)
You have a service running, e.g. some replication service, and can access it from outside without a problem using a normal POSTROUTING IPTables Line; But from the inside, you hit a wall if you use the EXTERNAL PUBLIC IP and thus must reconfigure the client every time depening on if you're in LAN or WAN. Well, not anymore.
[Solution]
Code: Select all
${IPTABLES} -t nat -A PREROUTING -s 192.168.1.0/24 -d ${PUBLIC_IP} -p tcp --dport $SERVICE_PORT -j DNAT --to-destination $SERVER_IP
-d PUBLIC IP = the destination IP is our PUBLIC IP AND
-dport SERVICE PORT = the port it wants to connect is the service we want
THEN DNAT to the actual SERVER_IP of the server running the service.
Code: Select all
${IPTABLES} -t nat -A POSTROUTING -s 192.168.1.0/24 -p tcp --dst $SERVER_IP --dport $SERVICE_PORT -j SNAT --to-source $IP_LAN_ROUTER
The whole thing looks funny, but works like a charm. Also, make sure you have needed ACCEPT rules in the appropriate INPUT, OUTPUT and FORWARD Chains, as well as IP_FORWARDING = 1 set on the router itself.
In case you're scared now, here a example with fake IPs, assuming:
Our Webserver has the Public IP 1.2.3.4 and the LAN IP 192.168.1.10
Our Router is 192.168.1.1 (the machine where you are editing the iptables)
Our Service Port is a Webserver = 80
Code: Select all
${IPTABLES} -t nat -A PREROUTING -s 192.168.1.0/24 -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10
${IPTABLES} -t nat -A POSTROUTING -s 192.168.1.0/24 -p tcp --dst 192.168.1.10 --dport 80 -j SNAT --to-source 192.168.1.1