我正在尝试根据原始进程的 uid 来路由数据包。
我知道 PREROUTING 不会影响传出数据包。iptables 中有一个 MANGLE 表,您可以将这些规则放在 OUTPUT 链中。nftables 没有 MANGLE 钩子之类的东西。只有 OUTPUT 钩子。
这是 nftables 的限制吗?在路由决策之前,没有办法标记源自主机的传出数据包?
nftables v0.7 (Scrooge McDuck)
Linux 4.14.5-1-ARCH #1 SMP PREEMPT Sun Dec 10 14:50:30 UTC 2017 x86_64 GNU/Linux
答案1
nftables 中的命名约定可能会误导您认为该功能不存在。
路线,用于在任何相关 IP 报头字段或数据包标记被修改时重新路由数据包。如果您熟悉 iptables,此链类型提供与曼格尔 表,但仅适用于输出钩子(对于其他钩子使用类型筛选 而不是)。ip 和 ip6 表系列支持此功能。
因此,从 LXC 容器执行所有这些操作,使用 debian stretch 的内核4.9.0-4-amd64 #1 SMP Debian 4.9.65-3 (2017-12-03)
,我将使 uid 1001 成为唯一能够连接到互联网的用户(这里是使用 TCP 的 Google 公共 DNS):
# IP 路由 默认通过 10.0.3.1 dev eth0 10.0.3.0/24 dev eth0 proto 内核范围链接 src 10.0.3.66 # pkill -9 dhclient # ip 路由删除默认值 # ip route add default via 10.0.3.2 dev eth0 # 10.0.3.2 不存在,但是路由代码需要默认路由才能触发 fwmark 规则,否则会直接出现“网络不可达”并且不会生成数据包。 # ip route 添加默认通过 10.0.3.1 表 10 # ip 规则添加 fwmark 1 表 10
可以在下面找到 mangle 的规范命名这里(或 /usr/share/doc ...)。-150 是NF_IP_PRI_MANGLE
# nft 添加表 ip mangle # nft‘添加链 ip mangle 输出 { 类型路由钩子输出优先级 -150; }’ # nft 添加规则 ip mangle 输出 skuid 1001 计数器标记设置 1 # ID uid=0(根) gid=0(根) groups=0(根) # nc -v -n -z 8.8.8.8 53 # 对 10.0.3.2 的 ARP 请求将超时 nc:连接到 8.8.8.8 端口 53 (tcp) 失败:没有到主机的路由 # su-测试 $id 复制代码 uid=1001(测试) gid=1001(测试) groupes=1001(测试) $ nc -v -n -z 8.8.8.8 53 连接8.8.8.8 53端口[tcp/*]成功!
最后一点。有一条评论是关于使用网络命名空间来简化配置的,我只能表示同意:如果没有容器(具有自己的网络命名空间),给出这个示例会更加困难。例如,如果有一个 suid root 命令使用网络,则根据命令的工作方式,它可能会触发或不触发标记和路由。
更新:用户连接发起的一些数据包不再属于用户。这可能发生在连接结束时最后一次ACK
确认数据包时,并且当连接过早中止时,数据包更常出现这种情况。这些数据包将与所有者不匹配,因此不会收到标记,不会被重新路由,这可能会导致传输结束时超时。为了避免这种情况,应将其与其他功能(如/ (相当于' ))结合使用。有关 conntrack 标记和等效 iptables 问题及解决方案的更多信息,请参阅:FIN
RST
ct mark set mark
mark set ct mark
iptables
CONNMARK
Iptables:将传出流量与 conntrack 和所有者进行匹配。适用于奇怪的丢包
是否可以在任意 TCP 回复数据包中强制 fwmark 反射?
在上述“成功”的测试中确实发生了超时nc
,但由于命令已返回,因此没有网络捕获则无法看到它。超时发生在对等服务器端。要解决此问题,请保留相同的路由命令,但将上面的 nft 规则替换为:
# nft add table ip mangle
# nft 'add chain ip mangle output { type route hook output priority -150; }'
# nft flush chain ip mangle output
# nft add rule ip mangle output mark set ct mark counter
# nft add rule ip mangle output mark ne 0 counter accept
# nft add rule ip mangle output skuid 1001 counter mark set 1
# nft add rule ip mangle output ct mark set mark counter
scounter
仅用于调试。
答案2
nft add rule inet filter output meta skuid 1004 drop
或者:
chain output {
type filter hook output priority 0; policy accept;
meta skuid t drop
}