Is SNAT messed up, or is my thinking messed up?

In the course of helping another forum member earlier, I had cause to tinker with SNAT and DNAT. Reflexively I reached for the latest stable version of OpenWRT (19.07.7) and got stuck in. And then promptly got confused.

The other forum member was using 18.06.4, so I checked my thinking and spun up 18.06.4 alongside 19.07.7 for a comparison.

I set up SNAT and DNAT on both 18.06.4 and 19.07.7, and compared the GUI, the /etc/config/firewall files, and the iptables rules for the NAT table. For example IP addresses, I picked addresses which resembled the OpenWRT version numbers, purely for illustrative purposes.

First the iptables rules.
DNAT:

  • 18.06.4: -A zone_wan_prerouting -d 18.0.6.4/32 -m comment --comment "!fw3: Inbound DNAT 18.06.4" -j DNAT --to-destination 172.18.6.4
  • 19.07.7: -A zone_wan_prerouting -d 19.0.7.7/32 -m comment --comment "!fw3: Inbound DNAT 19.07.7" -j DNAT --to-destination 172.19.7.7

SNAT:

  • 18.06.4: -A zone_wan_postrouting -s 172.18.6.4/32 -m comment --comment "!fw3: Outbound SNAT 18.06.4" -j SNAT --to-source 18.0.6.4
  • 19.07.7: -A zone_wan_postrouting -s 172.19.7.7/32 -m comment --comment "!fw3: Outbound SNAT 19.07.7" -j SNAT --to-source 19.0.7.7

Unless I miss my guess, that looks alright. Both sets of SNAT and DNAT rules appear to accomplish what one would expect from their purpose. So... what's the problem, right?

The GUI for DNAT looks reasonably sane:

The 19.07.7 GUI has some cosmetic changes, but the description of the NAT actions seems understandable across both versions.

The GUI for SNAT starts to look a bit odd:

18.06.4 clearly shows that the source host is in the "lan" zone. In contrast, 19.07.7 says the source host can be in any zone.

The contents of /etc/config/firewall seem consistent for DNAT:
18.06.4:

config redirect
        option target 'DNAT'
        option src 'wan'
        option dest 'lan'
        option name 'Inbound DNAT 18.06.4'
        option src_dip '18.0.6.4'
        option dest_ip '172.18.6.4'
        option proto 'all'

19.07.7:

config redirect
        option src 'wan'
        option name 'Inbound DNAT 19.07.7'
        option src_dip '19.0.7.7'
        option dest_ip '172.19.7.7'
        option dest 'lan'
        option target 'DNAT'
        list proto 'all'

But, the contents of /etc/config/firewall for SNAT have melted my brain. I think I know what Winnie the Pooh felt like.

18.06.4:

config redirect
        option enabled '1'
        option target 'SNAT'
        option src 'lan'
        option dest 'wan'
        option proto 'all'
        option src_dip '18.0.6.4'
        option name 'Outbound SNAT 18.06.4'
        option src_ip '172.18.6.4'

19.07.7:

config nat
        option name 'Outbound SNAT 19.07.7'
        option src_ip '172.19.7.7'
        option target 'SNAT'
        option snat_ip '19.0.7.7'
        option src 'wan'
        list proto 'all'

18.06.4 draws a distinction between the real source (the internal host), the translated source (the public IP address), and the destination (the outside world), and shows this distinction with its src, src_dip and dest directives. This makes sense to me: where did the traffic originate (a host on the LAN), where is it going to (somwhere in the outside world), and what source IP address will the packets have when they sally bravely forth from the router (the translated public IP address)?

19.07.7, on the other hand, does not have a dest directive, and instead shows the source of the traffic as the outside world (src 'wan'). This does not make sense to me. If I ask myself, "where did the traffic originate?" I still come back with the answer: the internal host.

Indeed, if I try to "correct" the configuration to what I think it ought to be (src 'lan' and dest 'wan'), /etc/init.d/firewall whines at me that "Option @nat[0].dest is unknown", and the corresponding SNAT rule moves from the zone_wan_postrouting chain to the zone_lan_postrouting chain.

If the end result is that iptables shows a sensible SNAT rule, then I guess it's all working properly. But the files and pages to administer that SNAT rule look, well, just weird.

I've looked at the v19 changelogs to see if there's anything obvious which might explain this, but without success. Either there's nothing obvious there, or there is but I'm missing it.

So, am I being dim and misunderstanding something fundamental about the latest incarnation of OpenWRT? Or is there genuinely an error in the code used to manage and display that SNAT configuration to the intrepid administrator?

1 Like

I can see the confusion here. However let me say a couple of things.
The SNAT is applied in postrouting. At this point it makes no sense to take into account the source zone. Whether it was allowed or not, this has been decided in the filtering.
The src 'wan' is indeed confusing, since in the Luci it is mentioned as Outbound zone, so one would expect the option to be dest or something more intuitive.

3 Likes

As long as it works, I guess! :smiley:

I can keep a note for reference, so that I don't get confused again in the future...

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.