NFT IPv6 SNAT configuration - proper syntax needed

Need help with IPv6 SNAT rules using nftables

I’m working on setting up source NAT for IPv6 traffic on my home router. The goal is to have all outbound packets going through interface eth0 get translated to a specific IPv6 address.

Here are the different commands I’ve attempted along with their errors:

Attempt 1:

nft add rule ip6 nat postrouting oifname "eth0" snat to 2001:db8:85a3::8a2e:370:7334

This gives me: “table does not exist” error

Attempt 2:

nft add rule inet filter postrouting oifname "eth0" snat ip6 to 2001:db8:85a3::8a2e:370:7334/128

Result: “syntax error, unexpected snat”

Attempt 3:

nft add rule ip6 filter postrouting oifname eth0 snat to 2001:db8:85a3::8a2e:370:7334

Gets: “table ‘ip6’ does not exist in family filter”

I’m clearly missing something about the correct table and chain setup for IPv6 SNAT rules. What’s the proper way to structure this command?

Oh wow, classic nftables table creation issue! Been there :sweat_smile:

You’re trying to add rules to tables that don’t exist yet. Unlike iptables, nftables won’t create tables automatically - you have to make them first.

Run this before your commands:

nft add table ip6 nat
nft add chain ip6 nat postrouting { type nat hook postrouting priority 100; }

Then your first attempt should work! Quick question though - you sure about that IPv6 address? 2001:db8:85a3 is from the documentation range and won’t route on the real internet.

What’s your setup? OpenWrt or regular Linux? And do you have IPv6 forwarding enabled in /proc/sys/net/ipv6/conf/all/forwarding?

Sometimes it’s not just nftables syntax but the whole IPv6 routing setup. Have you confirmed eth0 actually has that IPv6 address assigned?

yeah, you’re missing the nat table. run nft add table ip6 nat first, then add your postrouting chain. your syntax in attempt 1 is actually correct once the table exists - just drop the /128 subnet mask for the snat destination.

Your issue is with table and chain creation order in nftables. Unlike iptables, you’ve got to create the ip6 nat table and postrouting chain first before adding any rules. I’d suggest starting with basic rules to test your setup - there might be hook priority conflicts with existing rules. If you run into problems, try setting priority to 0. Also check if your kernel actually supports IPv6 NAT. Some minimal setups don’t include this. Run lsmod | grep ip6table_nat or check /proc/net/ip6_tables_names to verify. And make sure the IPv6 address you’re using for SNAT is actually configured on your outbound interface - otherwise return traffic won’t work.