我有一个简单的场景,其中工作站连接到网关(模拟防火墙),并且该网关可以访问互联网。因此,为了澄清起见,网关有两个接口,eth0 用于工作站,eth1 用于访问互联网。
在 WKS 中,我们定义了 3 个用户,user1 的 ID 为 999,user2 的 ID 为 998,root 的 ID 为 0。我们想使用 iptables 过滤他们的流量。例如,我们不希望 user1 连接到互联网。
一开始我只是通过过滤 WKS 上的数据包来实现这一点:
iptables -A OUTPUT -m owner --uid-owner 999 -j DROP
确实成功了,但教授并不希望采用这种方式。他希望我做的是:在 WKS 中按用户标记数据包,然后,当网关收到数据包时,根据之前的标记进行过滤。总结一下:我必须根据用户在 WKS 中标记数据包,然后在网关中过滤该标记。
我尝试了很多方法,但似乎都没有用,标记没有被传播,例如:
On the WKS:
iptables -t mangle -A OUTPUT -m owner --uid-owner 999 -j MARK --set-mark 1
On the Gateway:
iptables -A FORWARD -m mark --mark 1 -j DROP
我也尝试过这样使用 CONNMARK:
On the WKS:
iptables -t mangle -A OUTPUT -m owner --uid-owner 999 -j CONNMARK --set-mark 1
iptables -t mangle -A OUTPUT -m owner --uid-owner 999 -j CONNMARK --save-mark
On the Gateway:
iptables -t mangle -A FORWARD -j CONNMARK --restore-mark
iptables -A FORWARD -m mark --mark 1 -j DROP
我也尝试了许多其他解决方案,但都没有奏效。你能帮助我吗?
PD:所有机器都是 Debian 容器,并具有到其应在位置的默认路由,并且网关已激活转发 IP 数据包。
答案1
Iptables 标记实际上从未在网络上发送。它们仅存在于本地内核的网络堆栈中(无论如何,它们都是 Linux 特有的机制 - 没有可以保存此类标记的标准 IP 选项)。这适用于数据包级标记和 connmark。
也许你的教授把 iptables 标记与 DiffServ 混淆了(数据保护协议(以前称为 ToS)标记?它们不是为了安全而是为了确定优先级(例如交互式流量与批量流量),但它们是包含在 IP 标头中,并且您有 ~64 个不同的值可供选择。
或者,如果你的系统有 SELinux,那么你可以应用秒分数。虽然这些分数也不会直接发送,但可以将它们转换为“西普索”IP 选项专门用于在主机之间传输安全标识符。(不过,不要忘记在出口处再次删除它们,因为有些 ISP 会直接丢弃包含选项的 IP 数据包。)
仅适用于 IPv4,数据包也可以使用“邪恶”一点但是 iptables 只能匹配它而不能设置它。(不过,使用 nftables 可以设置它。)
最后,您可以为工作站分配多个 IP 地址,并将不同的用户通过 SNAT 映射到他们自己的 IP 地址,这样网关就可以匹配源 IP。