# Different gateway per user with nftables

## JSheridan

While switching from iptables to nftables i ran into an issue with my per user based gateway setup.

The machine has just one ethernet port.

Before switching to nftables I used the following setup to split the traffic based on the source ip (or username if local traffic) to different gateways.

iptables:

iptables -t mangle -I OUTPUT ! -d "localnetwork" -m owner --uid-owner "username_a" -j MARK --set-mark 0x1

iptables -t mangle -I OUTPUT ! -d "localnetwork" -m owner --uid-owner "username_b" -j MARK --set-mark 0x2

iptables -t mangle -I PREROUTING -m iprange --src-range "range for user a" -j MARK --set-mark 0x1

iptables -t mangle -I PREROUTING -m iprange --src-range "range for user b" -j MARK --set-mark 0x2

iptables -t nat -A POSTROUTING -o eth0 -s "localnetwork" ! -d "localnetwork" -j MASQUERADE

ip route:

ip rule add from all fwmark 0x1 lookup "user_table_a" priority 90

ip rule add from all fwmark 0x2 lookup "user_table_b" priority 95

rt_tables:

90      user_table_a

91      user_table_b

each lookup table has a different default gw entry for eth0.

Now i thought switching to nftables would be ease because I should just have to replace the iptables rules with nftables ones. So I removed the iptables support from the kernel and wrote this small rule test for nftables.

table ip nat {

  chain pre {

    type nat hook prerouting priority -150;

    ip saddr >= "..." ip saddr <= "..." ip daddr != "localnetwork" mark set 0x1;

    ip saddr >= "..." ip saddr <= "..." ip daddr != "localnetwork" mark set 0x2;

  }

chain post {

    type nat hook postrouting priority -150;

    ip daddr != "localnetwork" snat "ip of eth0"

  }

}

table ip filter {

  chain output {

    type filter hook output priority -150;

    meta skuid "username_a" ip daddr != "localnetwork" mark set 0x1;

    meta skuid "username_b" ip daddr != "localnetwork" mark set 0x2;

  }

}

Now while this worked fine with iptables it doesn't with nftables. I suspect that the response packets get lost. If I remove the ip rules which matches the mark the connection works, but of course all connections / packets use the default gateway.

For now I had to switch back to my old iptables setup but maybe someone here encountered the same issue and can give me a hint what is or might be wrong with this solution.

Thanks in advance!

J

----------

