Networking / Beginners

Running Public Services on Private IP Addresses

You are running a public server on a private IP address, so it is not directly accessible to the Internet. So, you need to configure your iptables firewall to forward traffic to your server.

First of all, you need to add a third network interface card to your firewall box. We'll call it eth2, and assign it a different subnet than the LAN interface. This is very important-do not use the same subnet, or your networking will not work at all.

Let's say the three interfaces have these addresses:

  • eth0 192.168.1.10 (LAN)
  • eth1 11.22.33.44 (WAN)
  • eth2 192.168.2.25 (DMZ)

You have one server in the DMZ with an IP address of 192.168.2.50.

Set up your firewall according to the previous sections, so you have the four scripts: fw_ flush, fw_nat, fw_status, and the firewall init script. Add the new interface to fw_nat:

DMZ_IFACE="eth2"

Add FORWARD rules to allow traffic between the DMZ, and your WAN and LAN interfaces:

$ipt -A FORWARD -i $LAN_IFACE -o $DMZ_IFACE -m state \
--state NEW,ESTABLISHED,RELATED -j ACCEPT
$ipt -A FORWARD -i $DMZ_IFACE -o $LAN_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT
$ipt -A FORWARD -i $DMZ_IFACE -o $WAN_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT
$ipt -A FORWARD -i $WAN_IFACE -o $DMZ_IFACE -m state \
--state NEW,ESTABLISHED,RELATED -j ACCEPT

Now, you need to route incoming HTTP traffic to your server with a PREROUTING rule:

$ipt -t nat -A PREROUTING -p tcp -i $WAN_IFACE -d 11.22.33.44 \
--dport 80 -j DNAT --to-destination 192.168.2.50

If you are using more than one port on your web server, such as 443 for SSL, or some alternate ports for testing like 8080, you can list them all in one rule with the multiport match:

$ipt -t nat -A PREROUTING -p tcp -i $WAN_IFACE -d 11.22.33.44 \
-m multiport --dport 80,443,8080 -j DNAT --to-destination 192.168.2.50

Other services work in the same way, so all you need to do is substitute their port numbers and addresses.

You may use DNAT to send traffic to a different port, like this:

$ipt -t nat -A PREROUTING -p tcp -i $WAN_IFACE -d 11.22.33.44 \
--dport 80 -j DNAT --to-destination 192.168.2.50:100

Because your web server has a private, nonroutable address, it needs to be rewritten using Destination Network Address Translation (DNAT) to the publicly routable address that the Internet thinks your web server has. Because this is really your router's WAN address, it needs to be rewritten and forwarded to your real server address. Then, on the way out, it needs to rewritten back to the your WAN address. Our SNAT rule takes care of this by rewriting all outgoing packets to the WAN address.

Your LAN hosts will not be able to access your web server because DNAT makes a hash of routing. The easy way to give them access is to have a separate LAN DNS server that uses internal addresses. Another easy way is to have a physically separate DMZ that does not share your LAN router. The hard way is to write a bunch more iptables rules that do more address rewriting, which will drive you nuts, cost you your job, and ruin your life.

[Previous] [Contents] [Next]