Cannot see iptables masquerade rule since 21.11

On NixOS 21.05, when setting IPMasquerade = "yes"; on my WireGuard interface via option systemd.network.networks.<name>.networkConfig , I could see the result of this settings by running:

# iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 1 packets, 60 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 1 packets, 60 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 17 packets, 1504 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 17 packets, 1504 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  any    any     10.201.0.0/24        anywhere

Since NixOS 21.11 however, altought the masquerade works, I cannot see anything with iptables commands:

# iptables -t nat -L -v
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

# iptables-legacy -t nat -L -v
Chain PREROUTING (policy ACCEPT 3 packets, 296 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 1 packets, 176 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 2 packets, 120 bytes)
 pkts bytes target     prot opt in     out     source               destination

Is this linked to the following change in NixOS 21.11?

iptables now uses nf_tables backend.

How can I visualise the masquerade rule under NixOS 21.11?

1 Like

what does nft list ruleset

give you?

1 Like

After setting IPMasquerade = "yes";, the command nft list ruleset add the following to the output (in comparison to not setting IPMasquerade = "yes";):

table ip io.systemd.nat {
        set masq_saddr {
                type ipv4_addr
                flags interval
                elements = { 10.201.0.0/24 }
        }

        map map_port_ipport {
                type inet_proto . inet_service : ipv4_addr . inet_service
        }

        chain prerouting {
                type nat hook prerouting priority dstnat + 1; policy accept;
                fib daddr type local dnat ip to meta l4proto . th dport map @map_port_ipport
        }

        chain output {
                type nat hook output priority -99; policy accept;
                ip daddr != 127.0.0.0/8 oif "lo" dnat ip to meta l4proto . th dport map @map_port_ipport
        }

        chain postrouting {
                type nat hook postrouting priority srcnat + 1; policy accept;
                ip saddr @masq_saddr masquerade
        }
}
table ip6 io.systemd.nat {
        set masq_saddr {
                type ipv6_addr
                flags interval
        }

        map map_port_ipport {
                type inet_proto . inet_service : ipv6_addr . inet_service
        }

        chain prerouting {
                type nat hook prerouting priority dstnat + 1; policy accept;
                fib daddr type local dnat ip6 to meta l4proto . th dport map @map_port_ipport
        }

        chain output {
                type nat hook output priority -99; policy accept;
                ip6 daddr != ::1 oif "lo" dnat ip6 to meta l4proto . th dport map @map_port_ipport
        }

        chain postrouting {
                type nat hook postrouting priority srcnat + 1; policy accept;
                ip6 saddr @masq_saddr masquerade
        }
}

So I guess that is it, nft allows me to see that.

For information:

# iptables -t io.systemd.nat -L -v
iptables v1.8.7 (nf_tables): table 'io.systemd.nat' does not exist
Perhaps iptables or your kernel needs to be upgraded.

# iptables-legacy -t io.systemd.nat -L -v
iptables v1.8.7 (legacy): can't initialize iptables table `io.systemd.nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

However, I had to install nftables to be able to run the nft command. Would it not make sense that this program is installed by default if it is the new tool to manage the firewall?

Could you raise an issue for this. If you feeling nice even a PR! :slight_smile:

Quickly scanning, it seems that the old iptables commands have to be sym linked to the new nft commands, this may or may not be happening.

scroll down to the section Two variants of the iptables command`

Thanks for taking the time to the report the issue.

1 Like

What would you like me to open an issue for? You answered my question so I am not sure I understand.
Is it an issue for the fact that we cannot see the rule with iptables -t nat -L -v?

Well if you’ve asked this question and are confused, then others will more likely be confused.

So, it either needs patching, options are (there are more options)

  • the nft tools are brought in with nft subsystem, however devops type people like there system ultra light without external tools!!! .

  • iptables need integrating with nft to work as legacy commands

  • iptables needs to give you a warning to use nft tools, if nft subsystem is enabled

This might be on the tracker already, i’ve not checked yet.

But its not always about answering your question, it’s about making nixos better for the fame , the glory (and potentially fortune) that comes with it.

:slight_smile: