Sổ tay kỹ thuật

DNS trên Linux không phân giải – dig, resolvectl, systemd-resolved

troubleshooting#linux#dns#systemd· cập nhật 2026-11-06

Dùng khi gặp Temporary failure in name resolution, SERVFAIL, tên nội bộ không phân giải được, hoặc kết quả DNS cũ trên Ubuntu dùng systemd-resolved.

Sửa trang này
Mục lục

Triệu chứng chính: Temporary failure in name resolution, Could not resolve host, dig ra SERVFAIL/NXDOMAIN, tên nội bộ (split DNS) không phân giải được trong khi tên public thì được, hoặc đã đổi record mà máy vẫn trả IP cũ.

Trên Ubuntu, app gọi glibc → /etc/nsswitch.conf (hosts: files ... dns) → /etc/hosts rồi /etc/resolv.conf → stub 127.0.0.53 (systemd-resolved) → DNS server thật theo từng link. Khoanh vùng = hỏi từng tầng.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
dig @198.51.100.53 được, dig example.com không resolved không có DNS server cho link nào resolvectl status; cấu hình nameservers trong netplan
/etc/resolv.conf bị ghi đè, nội dung lạ Có công cụ khác (DHCP client, VPN, cloud-init) ghi file Giữ symlink tới /run/systemd/resolve/stub-resolv.conf; cấu hình DNS ở netplan/resolved
Tên nội bộ *.corp.example.com không phân giải khi bật VPN Query đi sai link, thiếu routing domain resolvectl domain tun0 '~corp.example.com' (bền: cấu hình ở VPN/netplan)
SERVFAIL chỉ với một số domain DNSSEC validate lỗi, hoặc upstream lỗi dig +cd (bỏ validate) để so; resolvectl query --validate=no; xem DNSSEC=
Đã sửa record, máy vẫn trả IP cũ Cache của resolved (theo TTL) hoặc cache ở app/JVM resolvectl flush-caches; kiểm tra TTL bằng dig
getent hosts khác dig /etc/hosts hoặc nsswitch đè grep name /etc/hosts; dig bỏ qua /etc/hosts, getent thì không
Container Docker không phân giải Docker không dùng được 127.0.0.53, lấy DNS từ /run/systemd/resolve/resolv.conf Kiểm tra file đó có server thật; hoặc "dns": [...] trong daemon.json
Port 53 bị chiếm khi chạy dnsmasq/bind/Pi-hole Stub listener của resolved giữ 127.0.0.53:53 DNSStubListener=no (xem bên dưới)
Query chậm đúng 5 giây rồi mới có kết quả Server đầu tiên chết, timeout rồi mới chuyển server sau Bỏ server chết khỏi cấu hình; resolvectl status xem Current DNS Server
Tên ngắn host1 không phân giải Thiếu search domain resolvectl domain eth0 example.com hoặc search: trong netplan

Các bước khoanh vùng

flowchart TD A["App lỗi resolve"] --> B{"getent hosts name OK?"} B -->|Có| C["Lỗi ở app: cache, proxy, container"] B -->|Không| D{"resolvectl query name OK?"} D -->|Có| E["Kiểm tra nsswitch, /etc/resolv.conf"] D -->|Không| F{"dig @server-thật name OK?"} F -->|Có| G["resolved: link, routing domain, DNSSEC"] F -->|Không| H["Lỗi ở DNS server / zone / firewall"]

1. Cấu hình hiện tại

ls -l /etc/resolv.conf                     # nên là -> ../run/systemd/resolve/stub-resolv.conf
cat /run/systemd/resolve/resolv.conf       # DNS server thật mà resolved đang dùng
resolvectl status                          # server + domain theo từng link, Current DNS Server
grep ^hosts /etc/nsswitch.conf

2. Hỏi từng tầng

getent hosts app.example.com                     # đúng đường app đi (gồm /etc/hosts)
resolvectl query app.example.com                 # qua resolved, cho biết link nào trả lời
resolvectl query --cache=no app.example.com      # bỏ qua cache
dig app.example.com                              # qua 127.0.0.53
dig @198.51.100.53 app.example.com               # hỏi thẳng server, bỏ qua resolved
dig +tcp @198.51.100.53 app.example.com          # nghi UDP 53 bị chặn / response lớn

3. Phía server / zone

Mục đích Lệnh
Chỉ lấy kết quả dig +short example.com A
Đi từ root xuống, thấy delegation hỏng ở đâu dig +trace example.com
Serial SOA trên mọi NS (NS lệch dữ liệu) dig +nssearch example.com
Hỏi authoritative, không đệ quy dig +norecurse @ns1.example.com example.com
Reverse lookup dig -x 203.0.113.5
Xem TTL còn lại trong cache dig example.com (cột thứ 2), chạy lại thấy giảm
Bỏ kiểm tra DNSSEC để so SERVFAIL dig +cd example.com

4. Log của resolved

sudo resolvectl log-level debug
journalctl -u systemd-resolved -f
sudo resolvectl log-level info            # nhớ trả lại
resolvectl statistics                     # cache hit/miss, DNSSEC verdict

Cấu hình đúng

Đặt DNS bền qua netplan (nameservers:). Cấu hình chung cho resolved đặt ở drop-in:

/etc/systemd/resolved.conf.d/10-local.conf
[Resolve]
# Split DNS: chỉ gửi *.corp.example.com tới server nội bộ
DNS=198.51.100.53
Domains=~corp.example.com
# Tắt stub 127.0.0.53 khi chạy DNS server riêng trên port 53
#DNSStubListener=no
sudo systemctl restart systemd-resolved
# Nếu tắt stub: trỏ resolv.conf sang file chứa server thật
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

resolvectl dns / resolvectl domain chỉ là runtime, mất khi link up/down hoặc reboot. Dùng để thử, sau đó đưa vào netplan hoặc resolved.conf.d.

Kiểm tra nhanh

resolvectl status | grep -E 'Link|Current DNS|DNS Servers|DNS Domain'
getent hosts example.com; resolvectl query example.com; dig +short example.com
dig +short @198.51.100.53 example.com
resolvectl flush-caches && resolvectl statistics | grep -i 'current cache size'

Lệnh DNS cơ bản khác: Linux network cheatsheet.