5

Does iptables implicitly and automatically add the reverse/inverse rules for every NAT rule that is added explicitly?

Typically, assuming a DROP policy, for each INPUT rule in the filter table there is a corresponding OUTPUT rule which accepts related or established traffic (and vice versa). For example, to enable inbound SSH to pass through an iptables firewall there would be an INPUT rule to allow incoming connections to be established:

iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

But there would also be a corresponding OUTPUT rule allowing return traffic:

iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

While this kind of explicit reverse-traffic rule is necessary in the filter table, it seems that this is not the case for the NAT table.

Consider the following excerpts from various unofficial references:

  1. Digital Ocean: A Deep Dive into Iptables and Netfilter Architecture

Certain events will cause a table's chain to be skipped during processing. For instance, only the first packet in a connection will be evaluated against the NAT rules. Any nat decisions made for the first packet will be applied to all subsequent packets in the connection without additional evaluation. Responses to NAT'ed connections will automatically have the reverse NAT rules applied to route correctly.

  1. SuperUser: Internal working of rules in forward chain for NAT

But netfilter (i.e., the packet filtering/mangling framework that's the 'engine' of iptables) is smart enough. Whenever an incoming [NAT] packet is received, it's matched with netfilter's conntrack table. If the packet is a reply to an existing outgoing connection (ACK flag set, matching IP:port, matching TCP sequence number, etc), netfilter automatically performs DNAT. No need for additional rules.

  1. Karl Rupp: NAT Tutorial

Fortunately the netfilter framework automatically adds to each rule its inverse rule, therefore we only have to set one explicit rule. Usually the decision for one of these two rules is made by taking the one with the lower level of undetermination. For example, the rule 'Replace the sender's address for all packets from the local subnet' is much easier than 'if a client has sent something to a server, then replace the receipient in the server's response by something'. As a rule of thumb can be used that the rule that is executed first is the one that is set explicitly in the kernel.

I've perused the official netfilter documentation but I haven't managed to find this behavior mentioned anywhere. Is there an official reference that corroborates the preceding claims?

igal
  • 9,666
  • 1
  • 42
  • 58
  • The important keyword is *conntrack*. And iptables doesn't "add any implicit rules", it's just that established connections get special treatment. I have no idea about official references (kernel source code?), but the effect is easy to test. – dirkt Nov 15 '17 at 22:56
  • @dirkt From the perspective of the filter table it seems like there are implicit rules here, no? Established connections aren't automatically allowed through there, right? Or am I really missing something? – igal Nov 15 '17 at 23:37
  • Well, *something* additional happens, but I'm not even sure if you can express this something correctly with ipfilter rules, so I'm not sure why you insist on thinking of this something as "additional implicit rules". Think "established connections are tracked, and when the kernel code detects packets belonging to such a connection, they get additional treatment based on the existing rules. This may include evaluating existing rules for the 'reverse' case". – dirkt Nov 16 '17 at 07:17
  • @dirkt I'm not insisting on anything. I'm using the language which was used in the articles I referenced (where they talk about "automatically added inverse rules"). This is in part what motivated my question. I've updated my question to clarify why I find this somewhat confusing. Does my question make more sense now? – igal Nov 16 '17 at 07:34
  • It's called `masquerading` – daisy Nov 16 '17 at 07:40
  • 2
    @daisy I'm pretty sure that's not what masquerading is. Masquerading is similar to (or a type of) SNAT. The SNAT target requires the rule to specify an IP address whereas the MASQUERADE target accepts an interface (see [Difference between SNAT and Masquerade](https://unix.stackexchange.com/questions/21967/difference-between-snat-and-masquerade)). But what I'm asking about applies to DNAT as well, and there's definitely no masquerading going on there (see [SNAT vs. DNAT vs. Masquerading](https://arstechnica.com/civis/viewtopic.php?t=678069)). – igal Nov 16 '17 at 07:45
  • 2
    Note, you can see the currently tracked connections with `sudo conntrack -L` (package conntrack-tools). – meuh Nov 16 '17 at 14:08
  • @meuh Thank you for the suggestion. I did not know that. I'll try it out and see if that sheds any light on the situation. – igal Nov 16 '17 at 14:18
  • What says there needs to be an accept rule for outbound (return) packets just cause there is a reject or drop rule for inbound packets? I think the problem here is you've reached the point where the fire**wall** analogy breaks down. It's not a wall. In fact, there's no "real" structure that's analogous. Unless you explicitly block outbound packets they are _all_ accepted. And that has no relationship to the rules governing inbound packets in any way. Like a wall that (ideally) is solid and impermeable when walking through it in one direction... but no more solid than morning fog in the other. – Cliff Armstrong Aug 11 '19 at 04:38
  • And @daisy was not wrong. Your #2 example is exactly describing SNAT. Done in the other direction, it's DNAT (Destination Network Address Translation). Neither create rules in netfilter tables... they use the conntrack table that's part of the kernel. – Cliff Armstrong Aug 11 '19 at 04:40
  • Oh, and DNAT and Masquerading are two names for the same thing. – Cliff Armstrong Aug 11 '19 at 04:47
  • 1
    @CliffArmstrong In this context, DNAT stands for Destination NAT (see https://en.wikipedia.org/wiki/Network_address_translation#DNAT). It doesn't seem like DNAT and masquerading are two names for the same thing. For a general discussion, see the link in my previous comment - or this one: https://serverfault.com/questions/119365/what-is-the-difference-between-a-source-nat-destination-nat-and-masquerading. Also see the Netfilter documentation: *[There is a specialized case of Source NAT called masquerading](https://netfilter.org/documentation/HOWTO/NAT-HOWTO-6.html)* – igal Aug 11 '19 at 12:51
  • Apologies. I meant SNAT. And I stand corrected on them not being one and the same. I've never seen a case where they weren't used interchangeably. – Cliff Armstrong Aug 11 '19 at 13:18

2 Answers2

3

Does iptables implicitly and automatically add the reverse/inverse rules for every NAT rule that is added explicitly?

Not exactly

Your first two quotes are correct, the third is confused ramblings of someone who doesn't understand how the system works.

iptables nat (unlike iptables filtering) works on connections. The first packet of the connection passes through the nat tables and is translated according to it. Later packets belonging to the same connection do not pass through the nat tables they are simply translated accoridng to the rules established when the first packet was translated.

The iptables man page https://linux.die.net/man/8/iptables documents that the nat table is consulted for "the first packet of a connection" and the man page section for the DNAT and SNAT target say "(and all future packets in this connection will also be mangled)".

Unfortunately I haven't seen any official documentation which goes into more depth than that. My go-to reference for iptables is the frozentux iptables tutorial but I don't think it's official.

plugwash
  • 4,242
  • 1
  • 18
  • 32
  • 1
    It sounds to me like you're just repeating a statement that's already in the body of the question. What I was asking for was a reference to where this is explained in the official documentation. Am I missing something here? – igal Mar 06 '18 at 21:52
1

The question was already answered but you did ask for a ref to the "official" documentation, this is what I found (was looking for the answer myself).

From the official documentation (2.1. What is Network Address Translation?)

If one of these links were to do NAT, then they would alter the source or destinations of the packet as it passes through. As you can imagine, this is not how the system was designed to work, and hence NAT is always something of a crock. Usually the link doing NAT will remember how it mangled a packet, and when a reply packet passes through the other way, it will do the reverse mangling on that reply packet, so everything works.

Sancho Pancho
  • 123
  • 1
  • 6