我正在尝试iptables
在本地机器上创建一个 Web 过滤器,该过滤器将网站列表列入白名单,并将每个用户的其他所有内容列入黑名单。因此,一个用户可以完全访问 Web,而另一个用户只能访问白名单中的网站。
我可以针对每个用户阻止所有传出的网络流量,但似乎无法将某些网站列入白名单。我当前的FILTER
表格设置为:
Chain INPUT (policy ACCEPT 778 packets, 95768 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 777 packets, 95647 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 176.32.98.166 0.0.0.0/0 owner UID match 1000
0 0 ACCEPT all -- * * 176.32.103.205 0.0.0.0/0 owner UID match 1000
0 0 ACCEPT all -- * * 205.251.242.103 0.0.0.0/0 owner UID match 1000
677 73766 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 1000 reject-with icmp-port-unreachable
它是使用以下命令创建的:
sudo iptables -A OUTPUT -s amazon.com -m owner --uid-owner <USERNAME> -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner <USERNAME> -j REJECT
我的理解是,这iptables
将使用与数据包匹配的第一个规则,但这里似乎并非如此。所有网络流量都会被阻止,而其他所有用户都可以访问。还有其他方法可以设置吗?
答案1
泰罗·基尔卡宁是正确的。这是一种脆弱的白名单方式,因为大多数(如果不是全部)主要网站都在使用 CDN。看看当我尝试解析并插入 REJECT 规则时会发生什么:
$ host www.amazon.com
www.amazon.com is an alias for tp.47cf2c8c9-frontier.amazon.com.
tp.47cf2c8c9-frontier.amazon.com is an alias for d3ag4hukkh62yn.cloudfront.net.
d3ag4hukkh62yn.cloudfront.net has address 13.227.254.68
$ sudo iptables -A OUTPUT -d www.amazon.com -j REJECT
$ sudo iptables -L OUTPUT -n
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
REJECT all -- 0.0.0.0/0 13.227.254.68 reject-with icmp-port-unreachable
大约 2 分钟后,我再次解析了域名,并且获得了不同的 IP 地址:
$ host www.amazon.com
www.amazon.com is an alias for tp.47cf2c8c9-frontier.amazon.com.
tp.47cf2c8c9-frontier.amazon.com is an alias for www.amazon.com.edgekey.net.
www.amazon.com.edgekey.net is an alias for e15316.e22.akamaiedge.net.
e15316.e22.akamaiedge.net has address 23.213.141.104
对于这种情况,我使用的最佳解决方案是使用DNS 解析器--ipset
中的功能dnsmasq
。首先创建 ipset,我们将其命名为amazon
:
$ sudo ipset create amazon hash:ip
$ sudo ipset -L amazon
Name: amazon
Type: hash:ip
Revision: 2
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 128
References: 0
Members:
在您dnsmasq.conf
定义域名时,当解析为 IP 地址时,将被添加到 ipset:
ipset=/amazon.com/amazon
amazon.com
上面定义的规则也适用于所有子域,即*.amazon.com
。重启服务后,在规则中dnsmasq
使用set
iptables 中的模块(参见):man iptables-extensions
$ sudo iptables -A OUTPUT -m set --match-set amazon dst -j REJECT
现在尝试www.amazon.com
再次解析并查看其 IP 地址是否添加到 ipset 中:
$ host www.amazon.com
www.amazon.com is an alias for tp.47cf2c8c9-frontier.amazon.com.
tp.47cf2c8c9-frontier.amazon.com is an alias for www.amazon.com.edgekey.net.
www.amazon.com.edgekey.net is an alias for e15316.e22.akamaiedge.net.
e15316.e22.akamaiedge.net has address 23.208.241.77
$ sudo ipset -L amazon
Name: amazon
Type: hash:ip
Revision: 2
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 176
References: 0
Members:
23.208.241.77
再次,但使用amazon.com
:
$ host amazon.com
amazon.com has address 205.251.242.103
amazon.com has address 176.32.103.205
amazon.com has address 54.239.28.85
amazon.com mail is handled by 5 amazon-smtp.amazon.com.
$ sudo ipset -L amazon
Name: amazon
Type: hash:ip
Revision: 2
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 320
References: 0
Members:
205.251.242.103
176.32.103.205
23.208.241.77
54.239.28.85
通过运行几个请求来确认 iptables 规则是否正常工作curl
:
$ curl https://www.amazon.com
curl: (7) Failed to connect to www.amazon.com port 443: Connection refused
$ curl https://amazon.com
curl: (7) Failed to connect to amazon.com port 443: Connection refused
$ curl https://aws.amazon.com
curl: (7) Failed to connect to aws.amazon.com port 443: Connection refused
答案2
好的,多亏了 @MichaelHampton 的问题,我才明白。白名单网站应按如下方式添加:
sudo iptables -A OUTPUT -d amazon.com -m owner --uid-owner <USERNAME> -j ACCEPT
您还必须打开 UDP 端口 53 以允许 DNS 主机解析:
sudo iptables -A OUTPUT -p udp --dport 53 -m owner --uid-owner <USERNAME> -j ACCEPT
最终规则应该是:
sudo iptables -A OUTPUT -m owner --uid-owner <USERNAME> -j REJECT