Iptables – How to forward ports to DMZ using iptables and separate modem

dmziptablesnat;

I have a network that looks like this:

 ADSL          VLAN 2              VLAN 3
------[Modem]----------[firewall]----------[intranet PC]
                            |
                            |      VLAN 4
                             \-------------[DMZ server]

I want to set up port forwarding to expose a web server in the DMZ to the Internet. The IPs are:

  • Modem: 192.168.0.1
  • Firewall eth0.2: 192.168.0.126
  • Firewall eth0.3: 192.168.1.1
  • Firewall eth0.4: 192.168.2.1
  • PC: 192.168.1.2
  • Server: 192.168.2.2

I opened ports 80 and 443 on the modem and have them forwarded to the firewall (192.168.0.126). And I have these rules in iptables on the firewall:

NAT:

-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A PREROUTING -d 192.168.0.126/32 -p tcp -m multiport --dports 80,443 \
    -j DNAT --to-destination 192.168.2.2
-A PREROUTING -d 192.168.1.1/32 -p tcp -m multiport --dports 80,443 \
    -j DNAT --to-destination 192.168.2.2
-A POSTROUTING -o eth0.2 -j MASQUERADE

Forwarding:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

# Disallow new connections from DMZ to modem and intranet
-A FORWARD -d 192.168.0.0/16 -i eth0.4 -m state --state NEW -j DROP

# Allow intranet to access Internet
-A FORWARD -i eth0.3 -o eth0.2 -j ACCEPT
-A FORWARD -i eth0.2 -o eth0.3 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow DMZ to access Internet
-A FORWARD -i eth0.4 -o eth0.2 -j ACCEPT
-A FORWARD -i eth0.2 -o eth0.4 -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow web ports to DMZ
-A FORWARD -i eth0.2 -o eth0.4 -p tcp -m multiport --dports 80,443 -j ACCEPT

# Allow intranet to access DMZ
-A FORWARD -i eth0.3 -o eth0.4 -j ACCEPT
-A FORWARD -i eth0.4 -o eth0.3 -m state --state RELATED,ESTABLISHED -j ACCEPT

Everything seems to work well except for the port forwarding. If I open 192.168.1.1 in a browser from an intranet PC, I see the DMZ server. And this is how it looks in telnet:

$ telnet 192.168.1.1 80
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'

But if I try to open it from the Internet using the modem's external IP, I get this:

$ telnet <EXT_IP> 80
Trying <EXT_IP>...
telnet: Unable to connect to remote host: No route to host

I tried setting up a hairpin NAT as described in the answer to this similar question, but there was no change. Maybe I didn't use the right addresses.

So, two questions 🙂

  1. Why can't incoming connections see the DMZ server?
  2. Is my iptables configuration gernerally OK? Or should I be dropping packets by default somewhere?

The firewall is running Debian Jessie, Linux 3.16.

Best Answer

Well I feel sheepish. The firewall rules work OK, but port 80 was being blocked at the ISP.