iptables Filtering in FORWARD or INPUT Chain – Interaction with NAT

firewalliptablesnat;

This page seems to suggest that, if there is a rule in the PREROUTING chain of the nat table that translates destination 1.2.3.4:80 to 10.1.1.1:8080, then the rules in the INPUT and FORWARD chain should match on 10.1.1.1:8080, not 1.2.3.4:80.

What if one wants to implement an order of operation more like what's outlined here? That is, how do you perform filtering on characteristics of packets before NAT?

One possibility seems to be using the PREROUTING chain of the raw table. The issue is that conntrack isn't available in raw/PREROUTING (see note 1), and e.g. a non-initial UDP fragment will not be related to the initial fragment and will produce unexpected matches.

Please let me know if I've described the dilemma clearly, and whether there's any workaround.

Note 1:
Correct me if I'm wrong, but when I tried to use conntrack in raw/PREROUTING, all initial SYN packets were marked "INVALID" rather than "NEW". It also seems like, in the Netfilter flowchart, "conntrack" is after raw/PREROUTING.

Best Answer

You don't need any raw/PREROUTING rules. You can use the conntrack match to filter the packets by original (before translation) destination/source address/port number. The conntrack is a successor of the older state match. It can check various additional metadata, related with conntrack entry (and NAT).

Couple of examples:

# allow any port-forwarded packets
iptables -t filter -A FORWARD -m conntrack --ctstate DNAT -j ACCEPT

# check the original destination address of DNATed packets
iptables -t filter -A FORWARD -p tcp --dport 8080 -m conntrack --ctstate DNAT --ctorigdstport 80 --ctorigdst X.X.X.X --ctdir ORIGINAL -j ACCEPT

For more details check the output of iptables -m conntrack --help and man iptables-extensions.

Related Topic