我知道这不是最好的解决方案,而且它也不是生产服务器,但是,如果它与域字符串不匹配,我仍会尝试删除对域的请求。
到目前为止,如果我单独应用该规则,它会起作用,但它与其他规则结合使用时不起作用。我猜是因为 Iptables 对顺序很敏感。
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Allow unlimited traffic on loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow full outgoing connection but no incomming stuff
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -o eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# Block sites
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT 1 -p tcp --dport 80 -m string --string ! "sub.domain.com" --algo kmp -j DROP
iptables -A INPUT -i eth0 -j DROP
iptables -A OUTPUT -j DROP
答案1
Iptables 对规则排序非常敏感。第一个匹配的规则决定了数据包的命运。
可能发生的情况是,在字符串 DROP 规则之前,您有一个匹配并接受 ESTABLISHED 数据包的规则。ESTABLISHED 规则成为 iptables 设置中的第一条规则之一的情况非常常见。
如果我没记错的话,连接在第一个 SYN 数据包之后立即获得 ESTABLISHED 状态。并且 SYN 数据包不包含带有“sub.domain.com”的主机头名称。只有带有 GET 请求的数据包才会包含该名称,并且它已经匹配 ESTABLISHED 规则。
解决方案是将字符串 DROP 放在 ESTABLISHED 之前。
话虽如此,您的解决方案非常不寻常,如果这些被阻止的请求数量恰好很高,甚至可能会给服务器带来一些麻烦。连接已建立,但客户端随后安静下来。服务器将等待,直到某个超时终止该过程。我不知道会发生什么,但要小心。
我猜你出于某种原因无法更改服务器配置来阻止那里的特定连接。在 Apache 中,设置这种控制是小菜一碟。
答案2
这不会达到您想要的效果。您可以使用 iptables 有效地限制对主机的访问。在您的情况下,限制对托管站点的服务器 IP 地址的访问。这仍然会允许访问该服务器托管的其他域。
您可以使用类似透明代理模式的代理squid
,并在其中使用 ACL 来限制对您允许的站点的访问。使用 DNAT 规则将所有 HTTP 访问重定向到您的代理。类似这样的规则应将 Web 流量重定向到端口 3129 上的代理:
iptables -t nat -A PREROUTING -p tcp --dport 80 ! -d 127.0.0.1 -j DNAT --to-destination $SQUID:3129
答案3
使用squid来限制http协议上你想要的所有域名,配置简单
对于 https 协议使用:iptables -A FORWARD -m string --string "facebook.com" --algo bm --from 1 --to 600 -j REJECT