我是 iptables 新手,我想阻止除“用户”和 root 之外的所有用户的网络访问。我按如下方式设置 iptables:
$ sudo iptables -L OUTPUT
target prot opt source destination
ACCEPT all -- anywhere anywhere owner UID match user
ACCEPT all -- anywhere anywhere owner UID match root
ACCEPT all -- anywhere anywhere owner socket exists
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
然后我以“其他”身份登录并执行以下操作(使用 Google 的一个 IP 地址):
$ whoami
other
$ wget http://172.217.19.36
--2020-06-25 18:43:16-- http://172.217.19.36/
Connecting to 172.217.19.36:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://www.google.com/ [following]
--2020-06-25 18:43:16-- http://www.google.com/
Resolving www.google.com (www.google.com)... failed: Name or service not known.
wget: unable to resolve host address 'www.google.com'
换句话说,iptables 允许非“用户”或非 root 用户使用 wget 访问 Google。
我究竟做错了什么?
答案1
问题在于你的规则-m owner --socket-exists
你可以通过这个例子看到:
iptables -A OUTPUT -m owner --uid-owner 0 -j LOG --log-prefix UID_ROOT
iptables -A OUTPUT -m owner --uid-owner 1000 -j LOG --log-prefix UID_1000
iptables -A OUTPUT -m owner --socket-exists -j LOG --log-prefix OWN_SOCKETS
iptables -A OUTPUT -m owner --uid-owner 1000 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner 0 -j ACCEPT
iptables -A OUTPUT -j LOG --log-prefix WILL-REJECT
iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable
并且iptables-save -c | grep OUTPUT
,您可以看到数据包计数器。
因此通过序列你就可以看到发生了什么。
sudo iptables -Z ;
sudo iptables-save -c | grep OUTPUT ;
/usr/bin/wget http://172.217.19.36 ;
sudo iptables-save -c | grep OUTPUT
在文件 /var/log/kern.log 中,你可以使用以下命令
tail -200f /var/log/kern.log | grep -e WILL_ -e OWN_ -e UID_ /var/log/kern.log
您可能需要允许另一个用户使用 DNS,这取决于您当前的机制。
在常规 Ubuntu 上您使用的是 systemd-resolve ,因此您需要添加 uid systemd-resolve
。
答案2
根据 EchoMike444 的帮助建议,我现在有以下规则:
iptables -A OUTPUT -m owner --uid-owner user -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner systemd-resolve -j ACCEPT
iptables -A OUTPUT -o lo -p icmp -j ACCEPT
iptables -A OUTPUT -j REJECT
这似乎可以解决问题:我仍然可以访问外部世界,其他用户则不能,但是由于规则 4,规则 5 中的 ICMP 拒绝消息仍然可以通过。