DNS over TLS trên OpenWrt với Unbound: cấu hình và kiểm tra rò rỉ DNS
MỤC LỤC BÀI VIẾT (Nhấn để xem)
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. Mình 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. Mình 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]
# 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]
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]
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" và "protocol": "DOT". Mình 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]
# 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
Mình 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]
# 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
# 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]
# 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
# 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. Mình 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]
# 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]
# 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]
# 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]
# 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]
## 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
Mình 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
https://openwrt.org/docs/guide-user/services/dns/dot_unbound — DoT with Unbound. ↩︎
OpenWRT
- Chia sẻ ổ USB qua Samba trên OpenWrt: cấu hình, firewall và xử lý lỗi
- DNS over TLS trên OpenWrt với Unbound: cấu hình và kiểm tra rò rỉ DNS Đang đọc
- Dùng USB làm bộ nhớ ngoài cho OpenWrt: driver, phân vùng và automount
- LuCI essentials trên OpenWrt: cài đặt, HTTPS, port thay thế và offline
- Sao lưu và khôi phục cấu hình OpenWrt bằng LuCI và SSH
Bình luận & Thảo luận 0
Chia sẻ thắc mắc, phản hồi hoặc kinh nghiệm thực chiến của bạn