使用 nftables 根据 UID 做出路由决策

使用 nftables 根据 UID 做出路由决策

我正在尝试根据原始进程的 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 中的命名约定可能会误导您认为该功能不存在。

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 问题及解决方案的更多信息,请参阅:FINRSTct mark set markmark set ct markiptablesCONNMARK

nftables 的标记和 conntrack 标记

Netfilter 连接标记

Iptables:将传出流量与 conntrack 和所有者进行匹配。适用于奇怪的丢包

是否可以在任意 TCP 回复数据包中强制 fwmark 反射?

没有 uid 的 iptables 数据包

在上述“成功”的测试中确实发生了超时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
}

相关内容