我最近开始在基于 Linux 的 OpenWrt 路由器上首次使用 iptables。开箱即用的 OpenWrt 防火墙非常好,但是,在想使用防火墙执行更高级的操作(例如强制 DNS)后,iptables 似乎是唯一的选择。
因此,我尝试强制所有 DNS 流量通过路由器,以便连接到网络的用户无法通过在其设备上设置手动 DNS 设置来覆盖 DNS 服务器。我已使用重定向规则成功对标准端口 53 流量执行此操作。
我通过在 OpenWrt 路由器上设置 DNS 并使用“dnsleaktest.com”查看已获取的 DNS 来测试这一点。正如预期的那样,我使用的是 OpenWrt 中设置的 DNS。接下来,在 Windows 上,我设置了一个手动 DNS(不同于 openwrt DNS),并在“dnsleaktest.com”上再次进行测试,并开始看到一些被覆盖的 DNS 出现。最后,我应用了 iptables 重定向规则并进行了第三次测试,确实这一次客户端上的手动 DNS 设置没有显示,而是路由器的 DNS 正在显示。
此外,我还通过删除端口 853 阻止了 DNS over TLS (DoT)。但是,我遇到困难的是 DNS over HTTPS (DoH)。
我在一些地方读到,阻止 DoH 的唯一方法是阻止端口 443(SSL)上的 IP。考虑到这一点,我制作了一份完整的公共 DNS over HTTPS 服务器列表,例如 Google、Adguard 和 Cloudflare。我已将 IP 放入 ipset 并将它们加载到 iptables 中,但似乎不起作用。
为了测试 DoH,我一直在 Mozilla Firefox 的网络设置下启用“启用 HTTPS 上的 DNS”复选框,并使用“dnsleaktest.com”进行测试。
/etc/Block_DoH.txt (ipset)
create Block_DoH hash:ip,port
add Block_DoH 8.8.4.4,443
add Block_DoH 8.8.8.8,443
add Block_DoH 149.112.112.112,443
add Block_DoH 9.9.9.9,443
add Block_DoH 149.112.112.9,443
add Block_DoH 9.9.9.10,443
add Block_DoH 149.112.112.10,443
add Block_DoH 9.9.9.11,443
add Block_DoH 149.112.112.11,443
add Block_DoH 104.28.1.106,443
add Block_DoH 104.28.0.106,443
add Block_DoH 45.90.28.0,443
add Block_DoH 45.90.30.0,443
add Block_DoH 176.103.130.131,443
add Block_DoH 176.103.130.130,443
add Block_DoH 176.103.130.132,443
add Block_DoH 176.103.130.134,443
add Block_DoH 96.113.151.147,443
add Block_DoH 185.228.168.9,443
add Block_DoH 185.228.169.9,443
add Block_DoH 185.228.168.168,443
add Block_DoH 185.228.169.168,443
add Block_DoH 185.228.168.10,443
add Block_DoH 185.228.169.11,443
add Block_DoH 1.1.1.1,443
add Block_DoH 1.0.0.1,443
# Force DNS to router's DNS
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT
iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT
# Block DNS over TLS
iptables -I INPUT -p tcp --sport 853 -j DROP
iptables -I INPUT -p udp --sport 853 -j DROP
iptables -I OUTPUT -p tcp --dport 853 -j DROP
iptables -I OUTPUT -p udp --dport 853 -j DROP
# Block DNS over HTTPS
iptables -I OUTPUT -m set --match-set Block_DoH src -j DROP
iptables -I INPUT -m set --match-set Block_DoH dst -j DROP
# Tried blocking Cloudflare with IPtables directly
iptables -I INPUT -s 1.1.1.1 -j DROP
iptables -I INPUT -s 1.0.0.1 -j DROP
iptables -I OUTPUT -d 1.1.1.1 -j DROP
iptables -I OUTPUT -d 1.0.0.1 -j DROP
# Tried to redirect to DNS running on router
iptables -t nat -I OUTPUT -p tcp -s 1.1.1.1 --sport 443 -d 192.168.1.1 --dport 53 -j REDIRECT
iptables -t nat -I OUTPUT -p udp -s 1.1.1.1 --sport 443 -d 192.168.1.1 --dport 53 -j REDIRECT
iptables -t nat -I OUTPUT -p tcp -s 1.0.0.1 --sport 443 -d 192.168.1.1 --dport 53 -j REDIRECT
iptables -t nat -I OUTPUT -p udp -s 1.0.0.1 --sport 443 -d 192.168.1.1 --dport 53 -j REDIRECT
有任何想法吗?
提前谢谢了。
更新 1
@hardillb 我关注的是#Block DNS over HTTPS
。我明确地试图阻止 DoH,以便客户端将回退到标准 DNS。
答案1
在路由器上阻止 DoH 协议非常困难,甚至不可能。DoH 无法轻易被阻止,因为它使用 TCP 端口 443,而这恰好是用于 HTTPS 的同一端口。您可以阻止此类 IP:443,但其中一些服务器将其用于 DoH 和内容。例如,DoH 服务器 dns.cloudflare.com 具有与 cdnjs.cloudflare.com 相同的 IP,后者用于提供一些脚本,由多个网站使用,例如 linuxquestions.org
所以你可以只阻止一些 DoH 服务器。
作为一种选择,您可以使用 dnscrypt2 / H2O / Simple AdBlock 等在局域网中设置自己的 DoH 服务器。但应用程序可能想使用它,也可能不想使用它。
由于加密保护,强制将流量重定向到自己的 DoH 服务器将不起作用
答案2
正如@hardillb所说,你想要的无法实现。正如你的回答,从我的角度来看,它没有解决方案,因为它们是不同的协议,我认为你唯一能做的就是过滤端口。例如,创建你自己的dns并只允许查询你的dns并阻止所有其他请求。以下示例(bash iptables)使用google dns,但你必须使用你的dns(替换变量)执行此操作:
PS:这不是一个好的解决方案,但最终可以有所帮助
# UDP: DNS Public (53) and DNS over TLS (853)
dns="8.8.8.8 8.8.4.4"
# local interface
lan=enp2s0
# internet interface
internet=enp2s1
for ip in $dns; do
iptables -A INPUT -s $ip -i $internet -p udp -m multiport --sports 53,853 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d $ip -o $internet -p udp -m multiport --dports 53,853 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -A FORWARD -i $lan -p udp -m multiport --dports 53,853 -d $ip -o $internet -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
done
iptables -A INPUT -i $lan -p udp -m multiport --dports 53,853 -j DROP
iptables -A FORWARD -i $lan -p udp -m multiport --dports 53,853 -j DROP`
答案3
请用ipset, 看https://ipset.netfilter.org/。对于如此庞大的列表,您不需要有那么多规则,即每个 IP 一个规则。
答案4
你需要这样的清单 https://raw.githubusercontent.com/jpgpi250/piholemanual/master/DOHipv4.txt https://raw.githubusercontent.com/jpgpi250/piholemanual/master/DOHipv6.txt
然后将 IP 放入 ipset 列表,最后就可以通过 iptables 来阻止它。
ipset create blacklist4 hash:ip
while read line
do
ipset add blacklist4 "$line"
done < /tmp/file_from_website
iptables -I forwarding_lan_rule -m set --match-set blacklist4 dst -j drop