Bookmark

DNS over TLS trên OpenWrt với Unbound: cấu hình và kiểm tra rò rỉ DNS

Mục tiêu của bài này là đưa DNS từ router tới upstream bằng DNS over TLS (DoT) thông qua Unbound. Tôi phải quyết định trước dnsmasq sẽ bị tắt vai trò DNS hay tiếp tục nghe ở port 53 và forward sang Unbound; hai mô hình này không dùng cùng một đoạn cấu hình.[27]

Mục tiêu và điều kiện

Trang OpenWrt mô tả DoT để mã hóa DNS, giảm nguy cơ DNS leak/hijack và tùy chọn dùng provider công cộng. Tôi cần truy cập LuCI hoặc SSH, quản lý package/service/log, và có phương án console nếu thay đổi DNS làm mất phân giải.[27]

Phương án A: Unbound làm resolver chính

Tắt vai trò DNS của dnsmasq (có thể vẫn giữ DHCP bằng odhcpd), rồi cài Unbound:[27]

1
2
3
4
5
6
7
8
9
# Install packages
opkg update
opkg install unbound-daemon

# Enable DNS encryption
uci set unbound.fwd_google.enabled="1"
uci set unbound.fwd_google.fallback="0"
uci commit unbound
service unbound restart

Trong mô hình này, LAN clients và hệ thống cục bộ dùng Unbound làm resolver chính, với giả định dnsmasq đã không còn giữ port 53.[27]

Kiểm tra resolver và giao thức

Kiểm tra phân giải qua localhost:[27]

1
nslookup openwrt.org localhost

Nguồn liệt kê các bài test provider như Cloudflare, AdGuard, NextDNS, Mullvad, Quad9, OpenDNS, cùng DNS Leak Test và DNSSEC Test. Có thể kiểm tra bằng CLI:[27]

1
2
3
4
dig +short txt proto.on.quad9.net.
# should print: doh. or dot. or doq.

curl -SL https://test.nextdns.io/

Kết quả NextDNS hợp lệ có thể cho thấy "status": "ok""protocol": "DOT". Tôi không coi một lần nslookup thành công là đủ; cần xem provider test và đường đi thực tế.[27]

Xử lý lỗi và audit runtime

Khi DNS không hoạt động, restart log/Unbound rồi thu thập runtime và persistent config:[27]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Restart services
service log restart; service unbound restart

# Log and status
logread -e unbound; netstat -l -n -p | grep -e unbound

# Runtime configuration
pgrep -f -a unbound
head -v -n -0 /etc/resolv.* /tmp/resolv.* /tmp/resolv.*/*

# Persistent configuration
uci show unbound

Tôi kiểm tra port đang listen, resolver file và uci show unbound trước khi thay thêm rule firewall; nếu port đã bị service khác chiếm, đổi cấu hình mù sẽ làm khó khôi phục.[27]

Quản lý qua LuCI

Cài integration:[27]

1
2
3
4
# Install packages
opkg update
opkg install luci-app-unbound
service rpcd restart

Sau đó vào LuCI → Services → Recursive DNS để cấu hình Unbound.[27]

Đổi provider sang Cloudflare

1
2
3
4
5
6
# Configure DoT provider
uci set unbound.fwd_google.enabled="0"
uci set unbound.fwd_cloudflare.enabled="1"
uci set unbound.fwd_cloudflare.fallback="0"
uci commit unbound
service unbound restart

Dùng provider khác hoặc Cloudflare Family

Tắt hai preset rồi thêm một forward_zone cho root zone:[27]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Configure DoT provider (example: "Cloudflare Family Protection")
uci set unbound.fwd_google.enabled="0"
uci set unbound.fwd_cloudflare.enabled="0"
while uci -q del unbound.@zone[4]; do :; done
uci add unbound zone
uci set unbound.@zone[-1].enabled="1"
uci set unbound.@zone[-1].fallback="0"
uci set unbound.@zone[-1].zone_type="forward_zone"
uci add_list unbound.@zone[-1].zone_name="."
uci add_list unbound.@zone[-1].server="1.1.1.3"
uci add_list unbound.@zone[-1].server="1.0.0.3"
uci add_list unbound.@zone[-1].server="2606:4700:4700::1113"
uci add_list unbound.@zone[-1].server="2606:4700:4700::1003"
uci set unbound.@zone[-1].tls_upstream="1"
uci set unbound.@zone[-1].tls_index="family.cloudflare-dns.com"
uci commit unbound
service unbound restart

Dùng nhiều resolver giúp fault tolerance, nhưng provider, địa chỉ IPv4/IPv6 và hostname TLS phải khớp với dịch vụ thật; không thay tls_index tùy tiện.[27]

Bật DNSSEC

1
2
3
4
# Enforce DNSSEC validation
uci set unbound.@unbound[0].validator="1"
uci commit unbound
service unbound restart

Nguồn cảnh báo cần cân bằng fault tolerance và hiệu năng. Tôi bật DNSSEC sau khi đường DoT cơ bản đã kiểm tra được, để nếu có lỗi còn biết lớp nào gây ra.[27]

Phương án B: giữ dnsmasq ở port 53 và forward sang Unbound:5353

Nếu muốn dnsmasq tiếp tục làm resolver nội bộ cho LAN, đổi port Unbound và cấu hình dnsmasq:[27]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Change unbound port to 5353, because dnsmasq is running already on port 53
sed -i "s/option listen_port '53'/option listen_port '5353'/g" /etc/config/unbound
sed -i "s/option add_local_fqdn '2'/option add_local_fqdn '0'/g" /etc/config/unbound

# configure dnsmasq to forward to localhost 5353
service dnsmasq stop
uci set dhcp.@dnsmasq[0].noresolv="1"
uci set dhcp.@dnsmasq[0].cachesize='0'
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#5353"
uci add_list dhcp.@dnsmasq[0].server="::1#5353"
uci commit dhcp
service dnsmasq start
service unbound restart

Các bước tùy chọn trong mô hình forward

Nếu NTP cần hoạt động trước khi DNS sẵn sàng:[27]

1
2
3
4
5
6
7
# Optional - ensure, that the NTP server can work without DNS
uci del system.ntp.server
uci add_list system.ntp.server='194.177.4.1'    # 0.openwrt.pool.ntp.org
uci add_list system.ntp.server='213.222.217.11' # 1.openwrt.pool.ntp.org
uci add_list system.ntp.server='80.50.102.114'  # 2.openwrt.pool.ntp.org
uci add_list system.ntp.server='193.219.28.60'  # 3.openwrt.pool.ntp.org
uci commit system

Tắt DNS peer từ ISP:[27]

1
2
3
4
# Optional: Disable ISP's DNS server
uci set network.wan.peerdns='0'
uci set network.wan6.peerdns='0'
uci commit network

Ép client LAN không đi thẳng ra DNS công cộng:[27]

1
2
3
4
5
6
7
8
# Optional: Force LAN clients to send DNS queries to dnsmasq (that later will be going to unbound):
uci add firewall rule
uci set firewall.@rule[-1].name='Block-Public-DNS'
uci set firewall.@rule[-1].src='lan'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].dest_port='53 853 5353'
uci set firewall.@rule[-1].target='REJECT'
uci commit firewall

Nếu có DNS server nội bộ nghe port khác, source có thêm redirect mẫu. Không dùng nếu hệ thống có mDNS:[27]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
## 2. Optional: Redirect queries for DNS servers running on non-standard ports. For example: 5353
## Warning: don't use this one if you run an mDNS server
uci add firewall redirect
uci set firewall.@redirect[-1].dest='lan'
uci set firewall.@redirect[-1].target='DNAT'
uci set firewall.@redirect[-1].name='Divert-DNS, port 5353'
uci set firewall.@redirect[-1].src='lan'
uci set firewall.@redirect[-1].src_dport='5353'
uci set firewall.@redirect[-1].dest_port='53'
uci commit firewall

# On the end
/etc/init.d/firewall reload

Kết luận thực hành

Tôi chọn một trong hai mô hình: Unbound chiếm vai trò resolver chính, hoặc dnsmasq giữ port 53 rồi forward sang Unbound ở 5353. Sau mọi thay đổi, kiểm tra nslookup, provider protocol, log Unbound, port listen, uci show unbound và firewall. Nếu redirect DNS, rule chặn public DNS hoặc DNSSEC làm mất truy cập, dùng console để revert từng nhóm thay đổi thay vì reset toàn bộ.[27]

Nguồn

Tài liệu gốc: [DoT with Unbound]1, đăng/cập nhật 2025-02-28.[27]

[27] https://openwrt.org/docs/guide-user/services/dns/dot_unbound — OpenWrt Wiki: DoT with Unbound


0 Bình luận

Góp Ý / Bình Luận / Đánh giá