I am trying to build a multi-WAN router based on Debian Buster (kernel version 4.19). It has multiple 'LAN-side' network interfaces (e.g. lan0, lan1, ... lanM), and also multiple 'WAN-side' interfaces (e.g. wan0, wan1, ... wanN). I have each WAN-side interface configured to masquerade outgoing traffic, like so:

iptables -t nat -I POSTROUTING -o wan0 -j MASQUERADE
iptables -t nat -I POSTROUTING -o wan1 -j MASQUERADE

Now my problem is that I find (using 'tshark' packet capture) that some outgoing packets 'escape' the masquerade, and egress a WAN-side interface with a source-IP that is different from the IP of that WAN interface. I was able to catch and drop some of these packets with the rule

iptables -t filter -I FORWARD -m state --state INVALID -j DROP

... but unfortunately not all such packets. (I even found packets that have the source-IP equal to that of wan0 trying to egress through wan1.)

My Question: Is there a way I can inspect and drop packets after they have passed the MASQUERADE operation? I understand that the 'nat' table's POSTROUTING chain is the last thing I can do with 'iptables', but is there anything I can do with, for example, nftables, or eBPF?


1 Answer 1


I have figured out a way to do this, and it involves tc.

Here is how we can configure interface ${ifc} to drop, on egress, any packet that does not have ${ip} in its source address field.

h_ip=$(ip_to_hex ${ip})

tc qdisc add dev ${ifc} root handle 1: htb
tc filter add dev ${ifc} parent 1: prio 1 protocol ip basic match 'not u32( u32 '${h_ip}' 0xFFFFFFFF at 12 )' action drop


function ip_to_hex {
        IFS='.'; read -ra AD <<< "$1"; unset IFS
        printf '0x%02x%02x%02x%02x' ${AD[0]} ${AD[1]} ${AD[2]} ${AD[3]}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .