![如何使用 iptables 过滤 DNS 请求](https://linux22.com/image/753786/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20iptables%20%E8%BF%87%E6%BB%A4%20DNS%20%E8%AF%B7%E6%B1%82.png)
我正在尝试过滤来自本地网络的 DNS 请求。仅授权对特定 DNS 的请求并拒绝其余的请求,但这对我来说不起作用。这是我的规则(以 dns google 为例):
internal=enp2s1
external=enp2s0
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward # default 0
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6 # default 0
echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6 # default 0
echo 1 > /proc/sys/net/ipv6/conf/lo/disable_ipv6 # default 0
iptables -A INPUT -p all -i lo -j ACCEPT
iptables -A INPUT -s 192.168.0.10 -j ACCEPT
iptables -A OUTPUT -p all -o lo -j ACCEPT
iptables -A OUTPUT -p all -s 127.0.0.1 -j ACCEPT
iptables -t mangle -A PREROUTING -p all -i lo -j ACCEPT
iptables -t mangle -A PREROUTING -p all -s 127.0.0.1 -j ACCEPT
iptables -t nat -A PREROUTING -p all -i lo -j ACCEPT
iptables -t mangle -A PREROUTING -i lo -s 127.0.0.0/8 -j ACCEPT
iptables -t mangle -A PREROUTING -i lo -d 127.0.0.0/8 -j ACCEPT
iptables -t mangle -A PREROUTING -i $internal -s 255.255.255.0/32 -j ACCEPT
iptables -t mangle -A PREROUTING -i $internal -d 255.255.255.0/32 -j ACCEPT
iptables -t mangle -A PREROUTING -i $internal -s 192.168.0.0/24 -j ACCEPT
iptables -t mangle -A PREROUTING -i $internal -d 192.168.0.0/24 -j ACCEPT
iptables -t mangle -A PREROUTING -p udp --dport 853 -j DROP
iptables -t mangle -A PREROUTING -p tcp --dport 853 -j DROP
dns="8.8.8.8 8.8.4.4"
for ip in $dns; do
iptables -A INPUT -s $ip -p udp --sport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
done
iptables -A FORWARD -p udp --dport 53 -j REJECT
例如,如果我在本地网络 (1.1.1.1 1.0.0.1) 上的 PC 上手动设置 cloudflare dns,则该 PC 可以访问互联网
PD:
规则“-m state --state RELATED,ESTABLISHED”位于这个问题被选为正确的阻止规则位于这个问题被选为正确的- 我尝试在所有链(INPUT、Mangle、OUTPUT、FORWARD)上使用相同的阻止规则,并将 REJECT 更改为 DROP,但并没有阻止
- 我为 src 添加了额外的阻止规则,它也没有阻止。例如:
iptables -A FORWARD -s $ip -p udp --sport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
# and block
iptables -A FORWARD -p udp --sport 53 -j DROP
笔记:这些规则也适用于 TCP(但为了不重复,我就不放了)
更新:
我将 DNS 规则更改为:
dns="8.8.8.8 8.8.4.4"
for ip in $dns; do
iptables -A INPUT -s $ip -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -d $ip -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d $ip -p udp --dport 53 -j ACCEPT
done
iptables -A INPUT -p udp --sport 53 -j DROP
iptables -A OUTPUT -p udp --dport 53 -j DROP
iptables -A FORWARD -p udp --dport 53 -j DROP
但它也没有正确地进行阻止
笔记:输入规则是否带有“-m state --state RELATED,ESTABLISHED -j ACCEPT”无关紧要,因为我感兴趣的是阻止连接,而这并没有发生
谢谢
答案1
简短的摘要
iptables -A OUTPUT -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d $ip -p udp --dport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
规则应该是:
iptables -A OUTPUT -d $ip -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d $ip -p udp --dport 53 -j ACCEPT
解释
我将使用客户端 IP192.168.100.100
和端口12345
作为示例。
当您网络中的客户端(192.168.100.100)发送 DNS 请求时,它会从端口 12345 发送一个 UDP 数据包到 DNS 服务器的端口 53。
当数据包通过 Linux 路由器时,路由器会为 DNS 查询创建一个连接跟踪条目。此连接跟踪条目有多个状态,其中之一就是ESTABLISHED
。
现在,在您的原始规则中,您需要ESTABLISHED
第一个传出的 DNS 查询数据包的状态。在示例中,客户端从端口向端口192.168.100.100
发送 UDP 数据包,没有该五元组的条目。因此防火墙会丢弃该数据包。12345
8.8.8.8
53
ESTABLISHED
当从传出规则中删除匹配状态时,则所有到 DNS 服务器端口 53 的传出数据包都将被批准,并且连接跟踪条目将被正确创建。
然后您可以使用 匹配返回方向-m state --state ESTABLISHED
,因为连接跟踪条目存在。