Назад | Перейти на главную страницу

Как заблокировать DNS через HTTPS с помощью IPtables

Недавно я впервые начал использовать iptables на моем маршрутизаторе на базе OpenWrt, Linux. Изначально брандмауэр OpenWrt очень хорош, однако, после того, как захотелось сделать с брандмауэром более сложные вещи, такие как принудительный DNS, iptables выглядел так, как будто это был единственный выход.

Итак, что я пытаюсь сделать, так это заставить весь DNS-трафик проходить через маршрутизатор, чтобы пользователи, подключенные к сети, не могли переопределить DNS-серверы, установив ручные настройки DNS на своих устройствах. Я успешно сделал это для стандартного трафика порта 53, используя правило перенаправления.

Я проверил это, установив DNS на моем маршрутизаторе OpenWrt и используя dnsleaktest.com, чтобы узнать, какие DNS были обнаружены. Как и ожидалось, я использовал DNS, установленный в OpenWrt. Затем в Windows я установил DNS вручную, отличный от openwrt, снова провел тест на «dnsleaktest.com» и начал видеть некоторые из переопределенных DNS. Наконец, я применил правило перенаправления iptables и провел тест в третий раз, и действительно, на этот раз ручной DNS, установленный на клиенте, не отображался, а вместо этого проходили DNS маршрутизатора.

Кроме того, я также заблокировал DNS через TLS (DoT), отбросив порт 853. Однако у меня возникли проблемы с DNS через HTTPS (DoH).

Я читал в нескольких местах, что единственный способ остановить DoH - это заблокировать IP на порту 443 (SSL). Имея это в виду, я составил полный список общедоступных DNS-серверов через HTTPS, таких как Google, Adguard и Cloudflare. Я поместил IP-адреса в ipset и загрузил их в iptables, но, похоже, он не работает.

Для тестирования DoH я установил флажок «Включить DNS через HTTPS» в настройках сети Mozilla Firefox и протестировал с помощью «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.

То, что вы хотите, как хорошо говорит @hardillb, невозможно сделать. В качестве вашего ответа, с моей точки зрения, у него нет решения, потому что это разные протоколы, я думаю, единственное, что вы можете сделать, это отфильтровать порт. Например, создайте свой собственный DNS и разрешите запросы только для своих DNS и заблокируйте все остальные запросы. В следующем примере (bash iptables) используется DNS-адрес Google, но вы должны сделать это со своим 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`

Другой альтернативой является фильтрация трафика с помощью инструментов, например пи-отверстие или ipset, но такая фильтрация сильно замедляет трафик