iptables – How to Exclude Local LAN from Port Forward Prerouting

iptables

I use several PREROUTING rules in Jessie Debian to do port forward from WAN to LAN ip with following rule

iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8088 -j DNAT --to-destination 192.168.1.6:8088

ETH0 is public static IP
ETH0:0 is Local lan ip 192.168.1.2

These are NAT related IPTABLES

iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  -- !192.168.0.0/24       0.0.0.0/0            tcp dpt:8088 to:192.168.1.6:8088
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8091 to:192.168.1.7:80
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8092 to:192.168.1.1:80
DNAT       tcp  -- !192.168.0.0/24       0.0.0.0/0            tcp dpt:10554 to:192.168.2.10:554
DNAT       udp  -- !192.168.0.0/24       0.0.0.0/0            udp dpt:10554 to:192.168.2.10:554
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:10080 to:192.168.2.1:8081
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:10443 to:192.168.2.4:10443
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:10052 to:192.168.2.1:8080
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:34567 to:192.168.2.10:34567
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:10050 to:192.168.2.1:10050

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0           
SNAT       tcp  --  0.0.0.0/0            192.168.2.10         tcp dpt:554 to:192.168.1.2
SNAT       udp  --  0.0.0.0/0            192.168.2.10         udp dpt:554 to:192.168.1.2
SNAT       tcp  --  0.0.0.0/0            192.168.2.1          tcp dpt:8081 to:192.168.1.2
SNAT       tcp  --  0.0.0.0/0            192.168.2.4          tcp dpt:10443 to:192.168.1.2
SNAT       tcp  --  0.0.0.0/0            192.168.2.1          tcp dpt:8080 to:192.168.1.2
SNAT       tcp  --  0.0.0.0/0            192.168.2.10         tcp dpt:34567 to:192.168.1.2
SNAT       tcp  --  0.0.0.0/0            192.168.2.1          tcp dpt:10050 to:192.168.1.2

However this rule is applied also when accessing that port from LAN. As result I can enter any IP and port 8088 to browser URL and it will always reach destination. for example I can enter http://1.1.1.1:8088 and it will work. this is not desired behaviour.

I'd like to exclude LAN from PREROUTING.

I tried ! -s 192.168.0.0/24 but in prerouting "!" for source parameter does not work

I tried also another approach to use destination parameter "-d mydoman.com" in the rule, but this only works if I remove mydoman.com line from /etc/hosts because mydoman.com links to server local network IP. I'd like to keep that record too.

is there better way to avoid prerouting rule for local network?

Best Answer

If you intend to exclude 192.168.1.8 from the DNAT rule, you shall use 192.168.0.0/23 or 192.168.1.0/24 as the ! -s parameter. The network range 192.168.0.0/24 finishes at 192.168.0.255.

$ ipcalc 192.168.0.0/24
Address:   192.168.0.0          11000000.10101000.00000000. 00000000
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   192.168.0.0/24       11000000.10101000.00000000. 00000000
HostMin:   192.168.0.1          11000000.10101000.00000000. 00000001
HostMax:   192.168.0.254        11000000.10101000.00000000. 11111110
Broadcast: 192.168.0.255        11000000.10101000.00000000. 11111111
Hosts/Net: 254 

You may restrict the DNAT rule by interfaces instead of using addresses. For example:

iptables -t nat -A PREROUTING '!' -i eth0 -p tcp --dport 8088 \
    -j DNAT --to-destination 192.168.1.6:8088

Or:

iptables -t nat -A PREROUTING -i ${your_wan_interface} -p tcp --dport 8088 \
    -j DNAT --to-destination 192.168.1.6:8088

Using the RETURN target is also a possible choice:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8088 -j RETURN