无法让 iptables 所有者模块 (gid-owner) 工作

无法让 iptables 所有者模块 (gid-owner) 工作

在我的 ubuntu 16.04 笔记本电脑上,我尝试设置规则,iptables以便默认情况下拒绝所有应用程序的互联网访问,并且只允许一个名为internet.我不会将该组添加到我自己的登录中,而是在需要时使用sudo -gsg访问互联网。例如:

sudo -g internet firefox

或者

sg internet -c "firefox"

然而,这种方法并不奏效。以下是iptables我添加的规则:

/sbin/iptables -A OUTPUT -p tcp --dport 80  -m owner --gid-owner internet   -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport 443  -m owner --gid-owner internet   -j ACCEPT
/sbin/iptables -A OUTPUT -p udp --dport 53  -m owner --gid-owner internet   -j ACCEPT

我已经测试了上述规则,当我删除所有者模块时,它工作正常并且所有应用程序都允许互联网。但是当我添加所有者模块和gid-owner过滤器时,没有应用程序能够访问互联网(即使使用提到​​的sgsudo -g命令)。

我究竟做错了什么?

答案1

已经标记为已解决,但为了其他遇到此问题的人的理智,我想我应该在这里详细说明并解释您发现的问题的实际原因。问题在于iptables。具体来说,它并不像我们人类期望的那样处理组 ID 过滤。我不确定这是 WAD 还是 bug。恕我直言,这是一个错误iptables -m owner扩展代码。

问题在于 的处理--gid-owner。看来iptables 扩展代码不会按字面过滤组ID(即用户是否在该组中,是还是否?)。从该模块的行为可以明显看出,它会更深入地挖掘并检查用户名设置,然后根据用户的主要组成员身份做出决定。这与对小组成员列表的字面检查(我自己和其他遇到此问题的人所期望的)不同。此行为未记录在任何相关手册页中。

也就是说,Ubuntu 的 iptables 实现只检查主要群体当前网络数据包的所有者。假设您希望创建一个拆分 VPN,其中特定用户组VPN将其流量强制发送到 VPN 接口。

如果您要指定每个所有者,则扩展--uid-owner下的参数-m owner将按预期工作。然后,假设您有多个要分支的用户名,并且用户列表可能会随着时间的推移而改变。因此,您认为使用组 ID 过滤会更有效 ( --gid-owner)。您将所有 VPN 流量用户放入一个名为VPN并将 iptables 参数更改为--gid-owner vpn。正如您所看到的,在许多情况下,过滤器无法按预期运行。为什么?

仅比较数据包所有者的主要/默认组。因此,您添加到的任何用户名VPN创建用户后的组将在VPN组作为辅助用户,并且即使他们是该团体的成员,他们也不会被分支!

“root”用户对您不起作用的原因是它的主要/默认组是“root”。

举例说明

假设您有用户名VPN在初级组VPN和用户名测试假人在初级组测试测试假人也是该组织的成员VPN团体。到测试假人,VPN是一个次要群体。

该 iptables 规则将标记属于VPN用户但不是测试假人用户,即使本能地认为来自两个用户的数据包都会被标记,因为它们都属于组VPN

iptables -t mangle -A OUTPUT ! -d 192.168.1.1 -m owner --gid-owner vpn -j MARK --set-mark 0x1

要解决该问题,您必须创建另一个规则,例如以下解决方案:

iptables -t mangle -A OUTPUT ! -d 192.168.1.1 -m owner --gid-owner vpn -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT ! -d 192.168.1.1 -m owner --uid-owner testdummy -j MARK --set-mark 0x1

答案2

经过多次尝试和错误,我找到了自己问题的答案。问题不在于 iptables 或我使用的 Ubuntu/Linux 版本,而在于第三条规则:

/sbin/iptables -A OUTPUT -p udp --dport 53  -m owner --gid-owner internet   -j ACCEPT

由于udp/53端口用于 DNS 名称解析,因此后台服务dnsmasq可能会使用它们,因此当我尝试在该组中运行程序时,不会发生名称解析,internet因为这些其他服务不在该组中。然而,理想情况下,这些服务仍然应该有权访问该端口,因为它们在 root 帐户下运行(并且 root 可以做任何事情!),但 iptables 所有者模块的设计似乎不尊重这种 root 权限。

当我从最后一条规则中删除所有者模块检查后,互联网就开始工作:

/sbin/iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

编辑

另一个不直接链接但相关的问题是使用根组的所有者模块。我们倾向于分配根组对互联网的访问权限(除了internet组之外或代替组),如下所示:

/sbin/iptables -A OUTPUT -p tcp --dport 80  -m owner --gid-owner root   -j ACCEPT

然而,这在实践中行不通,因为出于安全原因,很多应用程序不使用 root 用户连接到互联网。例如,即使执行了上述操作,以下命令也将不起作用:

sudo apt-get update

这是因为出于安全原因apt,程序内部使用_apt用户下载包。

答案3

您可以--suppl-groups为此使用,添加在EA6CC2FD。从iptables-extensions(8)

   --suppl-groups
          Causes group(s) specified with --gid-owner to be also checked in
          the supplementary groups of a process.

也可以看看iptables组匹配:修改用户的主要组

答案4

/sbin/iptables -A OUTPUT -p tcp --dport 80  -m owner ! --gid-owner root -j DROP

相关内容