Khởi Động Nhanh: Chạy Unbound Trong 5 Phút
Bạn có bao giờ thắc mắc tại sao các truy vấn DNS nội bộ lại phải đi qua Cloudflare hay Google trước khi được phân giải? Hay tại sao một upstream bị sập lại kéo theo cả hệ thống mạng của bạn? Unbound giải quyết cả hai vấn đề trên. Nó chạy như một recursive resolver ngay trên phần cứng của bạn — tự duyệt cây DNS từ root server xuống đến authoritative nameserver cho từng truy vấn. Không cần resolver bên thứ ba. Không có log nào bị gửi đi nơi khác.
Cách nhanh nhất để cài đặt trên Ubuntu/Debian:
# Cài đặt Unbound
sudo apt update && sudo apt install -y unbound
# Bật và khởi động dịch vụ
sudo systemctl enable --now unbound
# Kiểm tra nhanh
dig @127.0.0.1 google.com
Nếu dig trả về A record, Unbound đã hoạt động và đang phân giải được. Đó là nền tảng cơ bản. Tất cả những phần bên dưới giúp bạn đưa nó vào môi trường production.
Tìm Hiểu Sâu: Unbound Hoạt Động Như Thế Nào
Recursive vs. Forwarding vs. Caching — Khác Nhau Ở Điểm Gì?
Hầu hết router gia đình dùng resolver kiểu forwarding — chúng chuyển tiếp truy vấn của bạn đến 8.8.8.8 rồi cache kết quả. Unbound cũng có thể làm vậy, nhưng điểm mạnh thật sự của nó là đệ quy hoàn toàn: bắt đầu từ root DNS server, theo các referral xuống theo phân cấp, và đến thẳng authoritative nameserver. Ba lợi ích cụ thể từ cách này:
- Không có upstream nào có thể ghi log hay can thiệp vào truy vấn của bạn
- DNSSEC validation diễn ra cục bộ, không ủy thác cho bên thứ ba
- Bạn kiểm soát hoàn toàn cache TTL và hành vi negative caching
File Cấu Hình Chính
File cấu hình chính của Unbound nằm tại /etc/unbound/unbound.conf. Mặc định rất tối giản. Dưới đây là điểm xuất phát tốt cho homelab hoặc văn phòng nhỏ — bao gồm access control, DNSSEC, tối ưu hiệu năng và bảo mật cơ bản:
sudo nano /etc/unbound/unbound.conf
server:
# Giao diện mạng để lắng nghe
interface: 0.0.0.0
port: 53
# Cho phép truy vấn từ mạng nội bộ
access-control: 127.0.0.1/32 allow
access-control: 192.168.0.0/16 allow
access-control: 10.0.0.0/8 allow
access-control: 0.0.0.0/0 refuse
# Xác thực DNSSEC
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# File root hints (cập nhật định kỳ)
root-hints: "/var/lib/unbound/root.hints"
# Tối ưu hiệu năng
num-threads: 2
cache-max-ttl: 86400
cache-min-ttl: 300
neg-cache-size: 4m
prefetch: yes
prefetch-key: yes
# Bảo vệ quyền riêng tư
hide-identity: yes
hide-version: yes
qname-minimisation: yes
# Ghi log (điều chỉnh mức độ chi tiết: 0=tối thiểu, 2=debug)
verbosity: 1
log-queries: no
logfile: "/var/log/unbound/unbound.log"
Tải File Root Hints
File root hints cho Unbound biết nơi tìm 13 cụm root nameserver. File này hiếm khi thay đổi, nhưng hints lỗi thời có thể gây ra lỗi phân giải khó phát hiện trong các giai đoạn chuyển đổi hạ tầng:
sudo mkdir -p /var/lib/unbound
sudo curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
sudo chown unbound:unbound /var/lib/unbound/root.hints
Bật DNSSEC Validation
DNSSEC có lẽ là lý do lớn nhất để bạn tự chạy resolver riêng. Khi bật, Unbound xác minh chữ ký mã hóa trên mọi phản hồi DNS. Một upstream bị xâm phạm không thể chèn A record giả mạo — đây chính là kiểu tấn công DNS cache poisoning kinh điển. Nếu không có DNSSEC, bạn sẽ không bao giờ biết điều đó đã xảy ra.
Khởi tạo trust anchor (khóa công khai của root zone):
sudo unbound-anchor -a /var/lib/unbound/root.key
sudo chown unbound:unbound /var/lib/unbound/root.key
Xác minh bằng hai bài kiểm tra:
# Phải trả về cờ AD (Authenticated Data)
dig @127.0.0.1 dnssec-failed.org +dnssec
# Domain này cố ý có DNSSEC bị lỗi — phải trả về SERVFAIL
dig @127.0.0.1 www.dnssec-failed.org
Nhận được SERVFAIL trên www.dnssec-failed.org là kết quả đúng. Unbound đã từ chối trả về câu trả lời giả mạo. Đó chính xác là điều bạn muốn.
Khởi Động Lại và Xác Minh
sudo systemctl restart unbound
sudo systemctl status unbound
# Kiểm tra cú pháp cấu hình trước khi khởi động lại trên production
sudo unbound-checkconf
Sử Dụng Nâng Cao
Split-Horizon DNS cho Domain Nội Bộ
Đang dùng hostname nội bộ như nas.home.lab hay vpn.internal? Bạn muốn Unbound phân giải chúng cục bộ mà không cần đụng đến internet công cộng. Thêm các chỉ thị local-zone và local-data vào cấu hình:
server:
# Định nghĩa zone nội bộ
local-zone: "home.lab." static
# Thêm A record cho các máy nội bộ
local-data: "nas.home.lab. IN A 192.168.1.10"
local-data: "router.home.lab. IN A 192.168.1.1"
local-data: "vpn.home.lab. IN A 192.168.1.20"
# Tra cứu ngược (PTR records)
local-data-ptr: "192.168.1.10 nas.home.lab"
Chuyển Tiếp Zone Cụ Thể Đến Resolver Khác
Môi trường Active Directory và cấu hình VPN với split-DNS thường cần một zone được xử lý bởi nameserver nội bộ trong khi mọi thứ còn lại được phân giải đệ quy. Một khối forward-zone là đủ:
forward-zone:
name: "corp.internal."
forward-addr: 10.0.0.53 # DNS server AD nội bộ của bạn
Rate Limiting để Ngăn Chặn Lạm Dụng
Nếu bạn mở resolver ra ngoài LAN — chẳng hạn trên VPS — thì rate limiting là bắt buộc. Không có nó, bạn đang chạy một DNS amplifier mở:
server:
ratelimit: 1000 # Số truy vấn tối đa mỗi giây trên mỗi IP
ratelimit-size: 4m
ip-ratelimit: 2000 # Giới hạn theo từng IP
DNS-over-TLS (DoT) Upstream cho Chế Độ Forwarding
Muốn chuyển tiếp đến upstream nhưng vẫn muốn mã hóa lưu lượng? Unbound hỗ trợ DNS-over-TLS ở phía client. Đây là góc nhìn khác so với hướng dẫn DoH/DoT server trên blog này — ở đây Unbound đóng vai client gửi truy vấn đã mã hóa lên upstream, không phải endpoint phục vụ chúng:
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 9.9.9.9@853#dns.quad9.net
Giám Sát với unbound-control
Unbound đi kèm giao diện thống kê thực sự hữu ích để chẩn đoán phân giải chậm hoặc tỷ lệ cache hit thấp. Trước tiên, bật nó lên:
# Bật remote control trong cấu hình
# remote-control:
# control-enable: yes
# Thiết lập TLS keys cho unbound-control
sudo unbound-control-setup
# Xem thống kê trực tiếp
sudo unbound-control stats_noreset | grep -E 'total|cache|num'
# Xóa một bản ghi đã cache (hữu ích khi debug)
sudo unbound-control flush www.example.com
# Xuất toàn bộ cache
sudo unbound-control dump_cache
Kinh Nghiệm Thực Tế
Tự Động Cập Nhật Root Hints
Root hints hiếm khi thay đổi, nhưng giữ chúng luôn mới là thói quen tốt. Một cron job hàng tháng xử lý việc này mà không cần can thiệp thủ công:
sudo crontab -e
# Thêm dòng này:
0 3 1 * * curl -s -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.root && systemctl reload unbound
Trỏ Client Về Unbound
Trên chính server:
# Chỉnh sửa /etc/resolv.conf hoặc dùng systemd-resolved stub
nameserver 127.0.0.1
Để áp dụng cho toàn mạng, cấu hình DHCP server (router hoặc dnsmasq) để phát IP của máy chạy Unbound làm DNS server. Mọi thiết bị trong mạng sẽ tự nhận — không cần cấu hình từng máy.
Kiểm Tra Trạng Thái DNSSEC cho Bất Kỳ Domain Nào
# Tìm cờ "ad" (authenticated data) trong phần flags
dig @127.0.0.1 github.com +dnssec | grep flags
# Dò trace chuỗi DNSSEC chi tiết
dig @127.0.0.1 github.com +sigchase +trusted-key=/var/lib/unbound/root.key
Định Dạng Log để Debug
Có gì đó không phân giải được? Tăng verbosity tạm thời thay vì lục tung log tĩnh:
sudo unbound-control verbosity 2
# Theo dõi trực tiếp
sudo tail -f /var/log/unbound/unbound.log
# Đặt lại khi xong
sudo unbound-control verbosity 1
Kinh Nghiệm Chạy Thực Tế của Tôi
Tôi đã chạy Unbound trên homelab 15 thiết bị hơn một năm nay. Nó xử lý khoảng 8.000–12.000 truy vấn DNS mỗi ngày với tỷ lệ cache hit luôn trên 70%. Độ trễ phân giải mới là con số đáng nói thật sự: ~30ms khi chuyển tiếp lên upstream giảm xuống dưới 5ms cho các hit trong cache, và các lần tra cứu đệ quy lạnh đến root server dưới 150ms. Đó là cải thiện 6 lần trên luồng xử lý phổ biến nhất.
Điều thú vị hơn: DNSSEC validation đã phát hiện hai phản hồi bị giả mạo thực sự trong giai đoạn tôi đang thử nghiệm với một upstream cấu hình sai. Nếu chỉ dùng forwarding thông thường, cả hai đã bị chấp nhận im lặng. Bạn sẽ không bao giờ biết điều đó xảy ra.
Một lưu ý trên Ubuntu hiện đại: systemd-resolved đã chiếm port 53, nên Unbound sẽ không khởi động được. Có hai cách xử lý:
# Cách 1: Tắt stub listener của systemd-resolved
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
# Cách 2: Chạy Unbound trên port 5335 và trỏ systemd-resolved vào đó
# Trong unbound.conf: port: 5335
# Trong /etc/systemd/resolved.conf: DNS=127.0.0.1:5335
Danh Sách Kiểm Tra Bảo Mật
- Đặt
access-control: 0.0.0.0/0 refuselàm catch-all — chỉ cho phép các subnet cụ thể của bạn - Bật
hide-identity: yesvàhide-version: yesđể chặn fingerprinting phiên bản - Dùng
qname-minimisation: yes— Unbound chỉ gửi số nhãn tối thiểu cần thiết đến mỗi nameserver, giảm đáng kể rò rỉ dữ liệu - Trên VPS công cộng, chặn hoàn toàn port 53 từ internet bằng ufw hoặc iptables
- Giữ Unbound luôn được cập nhật —
sudo apt update && sudo apt upgrade unbound
Việc cài đặt đơn giản hơn bạn nghĩ. Hai mươi phút cấu hình là bạn có được phân giải đệ quy hoàn toàn, DNSSEC validation, không có log bên thứ ba, và các tra cứu đã cache cảm giác tức thì. Khó mà lập luận ngược lại với sự đánh đổi đó cho bất kỳ homelab hay môi trường production nhỏ nào.

