2

I have two users, alpha (uid 500) and beta (uid 501), and two IP addresses assigned as eth0 and eth0:1. I would like all outgoing packets originated by processes started by user alpha to be marked with the source IP address of eth0, and all packets from user beta's processes to be marked with the source IP address of eth0:1.

From searching the available answers on this forum and elsewhere, I found that I should do something like this:

# mark packets with 11 or 12 depending which user they came from:
iptables -A OUTPUT -m owner --uid-owner 500 -j MARK --set-mark 11
iptables -A OUTPUT -m owner --uid-owner 501 -j MARK --set-mark 12

# now, for a packet having mark 11 (or 12), set source IP to  192.168.1.1 (or .2) 
iptables -t nat -I POSTROUTING -m connmark  --mark 11 -j SNAT --to-source 192.168.1.1
iptables -t nat -I POSTROUTING -m connmark  --mark 12 -j SNAT --to-source 192.168.1.2

Would the above work? Is there a simpler (one-step, instead of two-step) setup? How can I use tcpdump to verify that it works, indeed?

mario
  • 21
  • 1
  • 2
  • The rules in the question won't work because the connmark checks the `ctmark` value, that is stored in a conntrack entry, not the firewall mark from the socket buffer structure. So the `-m connmark --mark` matches from the nat rules return a false match and rules won't be hit, and, consequencally, the `SNAT` action won't be done. – Anton Danilov May 31 '19 at 17:04

2 Answers2

2

Now (iptables v1.4.21) it's works in one step:

iptables -t nat -A POSTROUTING ! -o lo -m owner --uid-owner 1030 -j SNAT --to-source 10.0.0.85

And the user with uid 1030 will be originating all connections from the 10.0.0.85 (if the ip is on the outgoing interface).

1

Unfortunately, due to the way netfilter works, you can't do a 'one-step' setup.

  • Packet owners can only be detected in the OUTPUT chain, but
  • SNAT can only be performed in the POSTROUTING chain

That said, instead of using SNAT, I recommend using a combination of netfilter and iproute2, e.g.:

For netfilter:

iptables -A OUTPUT -m owner --uid-owner 500 -j MARK --set-mark 500
iptables -A OUTPUT -m owner --uid-owner 501 -j MARK --set-mark 501

For iproute2:

ip rule add fwmark 500 table 500
ip rule add fwmark 501 table 501

ip route add default via $gateway dev eth0 src $ip_eth0   table 500
ip route add default via $gateway dev eth0 src $ip_eth0_1 table 501
pepoluan
  • 4,918
  • 3
  • 43
  • 71