根据本地用户 ID 设置源 IP 的 iptables 规则

根据本地用户 ID 设置源 IP 的 iptables 规则

我有两个用户,alpha (uid 500) 和 beta (uid 501),以及两个分配为 eth0 和 eth0:1 的 IP 地址。我希望由用户 alpha 启动的进程发出的所有传出数据包都标记为 eth0 的源 IP 地址,而来自用户 beta 进程的所有数据包都标记为 eth0:1 的源 IP 地址。

通过搜索本论坛和其他地方提供的答案,我发现我应该做这样的事情:

# 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

上述方法有效吗?是否有更简单的设置(一步而不是两步)?我该如何使用tcpdump来验证它确实有效?

答案1

不幸的是,由于工作方式的原因netfilter,您无法进行“一步式”设置。

  • 数据包所有者只能在 OUTPUT 链中检测到,但是
  • SNAT只能在POSTROUTING链中执行

也就是说,我建议不要使用 SNAT,而是使用netfilter和的组合iproute2,例如:

为了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

为了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

答案2

现在(iptables v1.4.21)只需一步即可完成:

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

并且 uid 为 1030 的用户将从 10.0.0.85 发起所有连接(如果 ip 位于传出接口上)。

相关内容