SSD Nodes Learn 🎉 VPS từ $5.50/tháng
Hướng dẫn Matt ConnorBởi Matt Connor

DNS là gì? Cách trỏ domain đến VPS

DNS quyết định domain có đến được VPS hay không. Xem record, nameserver, TTL và cache khiến thay đổi DNS trông như bị lỗi, kèm cách kiểm tra bằng dig.

DNS là gì và vì sao domain của bạn chưa trỏ đến VPS

DNS (domain name system) chuyển một tên như example.com thành địa chỉ IP (internet protocol) như 203.0.113.10. Trình duyệt không thể kết nối trực tiếp đến tên. Nó kết nối đến một địa chỉ, nên mỗi lần tải trang đều bắt đầu bằng một câu hỏi DNS và một câu trả lời. Nếu bạn vừa mua một domain và một VPS riêng, nhưng không tải được gì, thì một trong hai trường hợp sau đang xảy ra: chưa có record nào kết nối tên đó với địa chỉ của server, hoặc đã có record nhưng một thành phần nào đó trên đường truyền vẫn đang cung cấp câu trả lời cũ.

Cả hai trường hợp đều bình thường và không có nghĩa là hệ thống bị lỗi. Các phần bên dưới trình bày từng thành phần theo đúng thứ tự bạn sẽ gặp, bắt đầu với vấn đề thường làm mất nhiều thời gian nhất: control panel nào thực sự đang lưu các record của bạn.

Mọi bước kiểm tra trong bài này đều dùng dig. Công cụ này không được cài sẵn trên máy Ubuntu hoặc Debian mới.

sudo apt update && sudo apt install -y bind9-dnsutils

Registrar, nameserver, DNS host: bạn cần chỉnh ở đâu

Ba khái niệm này chỉ các vai trò khác nhau. Nhầm lẫn giữa chúng là lý do phổ biến nhất khiến một thay đổi không có tác dụng.

  • Registrar là công ty nơi bạn mua domain. Nhiệm vụ quan trọng của registrar là delegation: thông báo cho registry quản lý TLD của bạn (top-level domain, phần .com) biết những nameserver nào có thẩm quyền đối với domain đó.
  • Authoritative nameserver lưu các record thực tế của zone. Zone là domain của bạn và các tên nằm bên dưới domain đó.
  • DNS host là đơn vị vận hành các nameserver đó. Đó có thể là registrar, một nhà cung cấp riêng, hoặc bind9 chạy trên server do bạn sở hữu.

Bạn mua domain tại registrar. Bạn chỉnh DNS tại DNS host. Nếu bạn đã chuyển domain sang nameserver của nhà cung cấp khác, DNS panel của registrar vẫn hiển thị một zone, vẫn lưu các thay đổi của bạn, nhưng không ai trên Internet hỏi zone đó. Các record vẫn tồn tại. Chỉ là chúng không bao giờ được sử dụng.

Hãy xác định nơi Internet đang gửi truy vấn:

dig example.com NS +short
dig +trace example.com

Lệnh đầu tiên in ra các nameserver đang trả lời cho domain ở thời điểm hiện tại. Lệnh thứ hai lần theo chuỗi bắt đầu từ root server và in ra referral mà các TLD server cung cấp. Đây là delegation do registrar của bạn quản lý. Nếu các tên đó thuộc về một nhà cung cấp mà bạn không nhận ra, bạn cần chỉnh tại panel của nhà cung cấp đó.

Một truy vấn đơn lẻ di chuyển như thế nào

Có 4 bên tham gia. Mỗi bên đều lưu một bản sao của thông tin mà nó biết được.

  1. Stub resolver trên máy của bạn. Nó không tự tìm kiếm. Nó hỏi một server đã cấu hình và tin vào câu trả lời. Trên Ubuntu, /etc/resolv.conf thường là symlink đến /run/systemd/resolve/stub-resolv.conf và trỏ tới 127.0.0.53, tức là systemd-resolved đang chạy cục bộ với cache riêng.
  2. Recursive resolver. Đây là resolver do ISP (nhà cung cấp dịch vụ Internet) vận hành, chẳng hạn như 1.1.1.1, hoặc do bạn tự vận hành. Nó thực hiện công việc tìm câu trả lời.
  3. Root server và TLD server. Recursive resolver hỏi một root server. Root server không biết địa chỉ của bạn, nhưng trả về referral đến các server .com. Các server này trả về referral đến nameserver của bạn.
  4. Authoritative nameserver. Nó không hỏi server nào khác. Nó trả lời từ zone của bạn và đánh dấu câu trả lời là authoritative.

dig +trace example.com cho bạn thấy quá trình này vì nó bắt đầu ngay từ root và in ra từng referral thay vì hỏi cache. Đây là cách nhanh nhất để kiểm tra delegation và zone có khớp nhau hay không.

Các bản ghi DNS quan trọng khi chạy server

  • A: ánh xạ tên sang địa chỉ IPv4. example.com. A 203.0.113.10. Đây là bản ghi trỏ domain đến VPS của bạn.
  • AAAA: ánh xạ tên sang địa chỉ IPv6, chẳng hạn 2001:db8::10. Chỉ công bố bản ghi này khi service thực sự lắng nghe trên địa chỉ đó. Client trên mạng IPv6 sẽ thử câu trả lời AAAA trước, nên một địa chỉ không có service phản hồi sẽ làm mọi lượt truy cập bị chậm.
  • CNAME: alias từ tên này sang tên khác. www.example.com. CNAME example.com. đưa người truy cập của www đến nơi mà bare domain phân giải. CNAME không thể được đặt tại apex (example.com, tức bare domain), vì apex phải có SOA (start of authority) và bản ghi NS riêng, còn CNAME không được dùng chung tên với bất kỳ bản ghi nào khác. Các nhà cung cấp có workaround với những tên như ALIAS, ANAME hoặc CNAME flattening.
  • MX: nơi mail của domain được chuyển đến. Bản ghi này chứa một hostname và một số preference; số nhỏ hơn được thử trước. MX phải trỏ đến một tên có bản ghi địa chỉ. Trỏ MX đến CNAME là không hợp lệ và một số sending server sẽ từ chối.
  • TXT: văn bản tự do, dùng để xác minh và khai báo policy. Các bản ghi xác thực mail (SPF, DKIM, DMARC) nằm ở đây, cũng như token ACME (automatic certificate management environment) dùng để cấp wildcard certificate.
  • NS: các nameserver phục vụ zone. Bản ghi quyết định nơi Internet truy vấn nằm trong parent zone và được lấy từ delegation của registrar, không phải bản sao bên trong zone của bạn.

Hai chi tiết này gây nhầm lẫn nhiều hơn bản thân các loại record. Tên kết thúc bằng dấu chấm là tên tuyệt đối, nên www.example.com. có nghĩa chính xác như vậy và không có phần nào khác. Hầu hết panel đều yêu cầu tên tương đối và tự nối domain vào tên đó, nên nhập www.example.com vào ô name sẽ tạo ra www.example.com.example.com, nhưng tên này không phân giải được cho ai. Chi tiết còn lại là @, trong gần như mọi panel đều có nghĩa là apex: domain đứng một mình, không có subdomain.

Trỏ một bản ghi A đến VPS của bạn

Trước tiên, lấy địa chỉ mà Internet nhìn thấy của server:

curl -4 https://ifconfig.me
ip -brief -4 address show

Sau đó, tạo một record tại DNS host của bạn: type A, name @, value là địa chỉ đó, TTL (time to live) 300. Thêm một record thứ hai cho www, có thể là một A khác với cùng địa chỉ hoặc một CNAME trỏ đến apex.

Bây giờ xác nhận tên miền phân giải được, tốt nhất là từ laptop thay vì chính server:

dig example.com A +short
dig @1.1.1.1 example.com A +short
dig @ns1.your-dns-host.net example.com A +short

Lệnh đầu tiên sử dụng đường dẫn thông thường của máy bạn, bao gồm cả cache. Lệnh thứ hai bỏ qua cache cục bộ và truy vấn một public recursive resolver. Lệnh thứ ba truy vấn trực tiếp authoritative nameserver của bạn, nên kết quả là trạng thái hiện tại và không có cache nào trên đường đi. Khi lệnh thứ ba trả về địa chỉ của bạn còn lệnh đầu tiên thì không, DNS của bạn đã được cấu hình đúng và bạn chỉ đang chờ bản sao kết quả cũ trong cache hết hạn.

Không tải được dù phân giải tên thành công

Phân giải tên thành công chứng minh DNS hoạt động. Nó không chứng minh gì về web server của bạn. Sau khi dig trả về đúng địa chỉ, hãy kiểm tra kết nối:

curl -I http://example.com

curl: (6) Could not resolve host: example.com là vấn đề DNS. curl: (7) Failed to connect to example.com port 80 after 21 ms: Connection refused không phải vấn đề DNS: tên đã được phân giải và packet đã đến nơi, nên vấn đề là không có tiến trình nào listening trên port đó. Request bị treo rồi timeout thường có nghĩa là firewall đã âm thầm drop packet thay vì từ chối kết nối. Từ đây DNS không còn là vấn đề cần kiểm tra; port và listening socket cùng các rule của firewall ufw trên VPS mới là phần cần xem. Sau khi kết nối hoàn tất, phần còn lại của quá trình tải trang là HTTP xử lý request.

Vì sao trình duyệt vẫn hiển thị host cũ

Không có gì được lan truyền. Không có server nào đẩy thay đổi của bạn ra bên ngoài đến người khác. Authoritative nameserver giữ giá trị mới ngay khi bạn lưu, còn mọi bản sao đã cache của câu trả lời cũ vẫn hợp lệ cho đến khi timer riêng của chúng hết hạn. Timer đó là TTL, tính bằng giây, mà record có tại thời điểm được trả về.

Bản sao tồn tại ở nhiều nơi hơn mọi người thường nghĩ: cache ngắn hạn của chính trình duyệt, stub resolver trên máy, recursive resolver được mạng đó sử dụng và bất kỳ resolver nào do VPN cài trên client. Mỗi thành phần giữ bản sao trong thời gian tối đa bằng TTL đã nhận. Hai người dùng trên hai mạng khác nhau có thể thấy hai câu trả lời khác nhau trong nhiều giờ, và cả hai máy đều đang hoạt động đúng.

Theo dõi thời gian đếm ngược trên một caching resolver:

dig @1.1.1.1 example.com +noall +answer

Chạy lệnh này 2 lần, cách nhau vài giây. TTL trong câu trả lời sẽ giảm xuống. Khi TTL về 0, resolver xóa record và hỏi lại nameserver của bạn.

Có một cache thứ hai mà hầu như không ai tính đến: câu trả lời phủ định. Khi resolver được báo rằng một name không tồn tại, nó cũng cache NXDOMAIN đó trong khoảng thời gian được đặt bởi trường cuối cùng trong record SOA của zone.

dig example.com SOA +short

Con số cuối cùng trên dòng đó là negative TTL, thường là 3600. Vì vậy, nếu tra cứu staging.example.com trước khi tạo, bạn có thể không thấy record trong cả 1 giờ sau khi tạo. Hãy tạo record trước, rồi mới query.

Thay đổi nameserver chậm hơn thay đổi record vì nguyên nhân nằm ở cơ chế hoạt động. Các delegation record trong zone .com được phục vụ với TTL là 172800 giây, tức 2 ngày. Vì vậy, resolver đã cache nameserver cũ có thể tiếp tục hỏi chúng trong khoảng thời gian đó. Đây là lý do có khuyến nghị “cho phép tối đa 48 giờ”. Khuyến nghị này áp dụng cho việc thay đổi nameserver, không áp dụng cho việc chỉnh sửa record thông thường.

Hãy lập kế hoạch migration theo TTL thay vì cố chống lại cơ chế này:

  1. Giảm TTL của record xuống 300 rồi lưu lại.
  2. Chờ lâu hơn TTL cũ để mọi bản sao đã cache giá trị cũ đều hết hạn.
  3. Thay đổi địa chỉ.
  4. Sau khi traffic đã chuyển sang địa chỉ mới, tăng TTL trở lại 3600 hoặc cao hơn, vì TTL thấp khiến mọi resolver hỏi nameserver của bạn thường xuyên hơn nhiều.

Để xóa dữ liệu mà chính máy của bạn đang giữ:

resolvectl flush-caches
resolvectl statistics

resolvectl statistics in một phần cache kèm bộ đếm hit và miss. Vì vậy, ngay sau khi flush, lần lookup tiếp theo sẽ được ghi nhận là miss. Trình duyệt giữ một cache riêng, nên Chrome vẫn có thể dùng câu trả lời cũ sau khi system cache đã trống. Hãy xóa cache đó tại chrome://net-internals/#dns. Đồng thời kiểm tra /etc/hosts, vì một dòng còn sót lại ở đó sẽ được ưu tiên hơn DNS trên máy này, và chỉ trên máy này. getent hosts example.com hiển thị câu trả lời mà hệ thống thực sự sẽ sử dụng, bao gồm cả /etc/hosts.

Chứng chỉ wildcard được xác thực bằng bản ghi TXT

CA (certificate authority) kiểm tra quyền kiểm soát một tên trước khi cấp chứng chỉ. Thử thách HTTP-01 cung cấp một file qua cổng 80 trên đúng hostname đó, phù hợp khi chỉ có một tên. Chứng chỉ wildcard áp dụng cho *.example.com, một tập hostname không giới hạn mà CA không thể truy cập file, nên Let's Encrypt chỉ cấp wildcard thông qua thử thách DNS-01. Bạn tạo một bản ghi TXT tại _acme-challenge.example.com và đặt vào đó token do CA cung cấp. Quyền kiểm soát zone là bằng chứng xác thực.

Điều này khiến DNS host trở thành một phần của quy trình gia hạn chứng chỉ. Certbot phải tự tạo và xóa bản ghi TXT đó trong mỗi lần gia hạn, nên cần có API và plugin tương ứng với provider của bạn. Khi xác thực thất bại, thông báo thường gặp là DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com. Điều đó có nghĩa là CA đã kiểm tra trước khi bản ghi được cập nhật: bản ghi chưa từng được lưu hoặc câu trả lời phủ định vẫn còn trong cache. Toàn bộ quy trình có trong hướng dẫn về chứng chỉ wildcard với thử thách DNS-01.

Khi VPN thay resolver của hệ thống

Client VPN (virtual private network) thường thay resolver của hệ thống trong thời gian kết nối, vì gửi truy vấn phân giải tên đến mạng cục bộ sẽ làm lộ cho mạng đó tên của mọi site bạn truy cập. Đây là hành vi đúng, nhưng có thể lỗi theo 2 hướng.

Nếu tunnel kết nối và tên không còn phân giải được trong khi địa chỉ vẫn hoạt động, resolver mà client cài đặt không thể truy cập từ bên trong tunnel. ping 1.1.1.1 thành công và curl https://example.com trả về curl: (6) Could not resolve host: example.com. Nếu tunnel kết nối nhưng truy vấn vẫn được gửi đến mạng bạn đang sử dụng, traffic của bạn đi qua tunnel còn resolver cục bộ vẫn nhìn thấy mọi tên bạn truy vấn.

resolvectl status

Lệnh này in ra resolver đang được sử dụng cho từng link, để bạn xác định tunnel đã cài resolver nào và đó có phải resolver bạn muốn dùng hay không. WireGuard lấy giá trị này từ dòng DNS = trong cấu hình client, còn sửa lỗi DNS khi WireGuard thay resolver trình bày chi tiết các trường hợp dùng systemd-resolved và resolvconf.

Mã phản hồi và ý nghĩa của từng mã

  • NXDOMAIN: máy chủ authoritative xác nhận rằng tên này không tồn tại. Kiểm tra chính tả, kiểm tra xem hậu tố domain có bị lặp không, và kiểm tra bạn đã sửa đúng zone mà delegation trỏ đến chưa.
  • NOERROR kèm ANSWER SECTION trống: tên này tồn tại, nhưng không có record thuộc type bạn yêu cầu. Nếu yêu cầu AAAA trong khi chỉ có A, bạn sẽ nhận đúng kết quả này.
  • SERVFAIL: resolver đã thử nhưng không thể tạo câu trả lời. Hai nguyên nhân thường gặp là các máy chủ authoritative không phản hồi và quá trình xác thực DNSSEC (domain name system security extensions) thất bại. Kiểm tra bằng dig @1.1.1.1 example.com A +cd, tùy chọn này tắt xác thực. Nếu khi tắt xác thực bạn nhận được +cdSERVFAIL, thì vấn đề nằm ở các chữ ký. Tình huống này thường xảy ra sau khi chuyển nameserver nhưng parent vẫn công bố record DS (delegation signer) cũ.
  • REFUSED: máy chủ bạn truy vấn sẽ không trả lời câu hỏi đó, thường là vì bạn trỏ dig đến một máy chủ authoritative của domain mà máy chủ đó không phục vụ.
  • ;; connection timed out; no servers could be reached: dig chưa kết nối được đến resolver. Đây là vấn đề về network hoặc resolver ở phía bạn, không phải vấn đề của domain.

ping: example.com: Temporary failure in name resolution là cùng một loại lỗi, nhưng được glibc báo cáo thay vì dig.

Có nên chạy nameserver trên VPS của bạn không?

Bạn có thể làm vậy. bind9, knot hoặc nsd sẽ phục vụ zone của bạn từ máy chủ, đồng thời giúp bạn hiểu về DNS nhiều hơn bất kỳ panel nào. Các vấn đề cần cân nhắc chủ yếu là thực tế. Một domain nên có ít nhất 2 nameserver trên các network riêng biệt, vì một VPS duy nhất sẽ trở thành điểm lỗi duy nhất cho mọi dịch vụ trên domain, bao gồm cả mail. Nameserver có tên nằm bên trong chính domain mà nó phục vụ cần có glue record tại registrar. Glue record là địa chỉ của ns1.example.com được lưu trong parent zone; nếu không có record này, quá trình lookup không có cách nào bắt đầu. Khi resolver không thể kết nối đến nameserver của bạn, nó không chuyển sang website: toàn bộ domain sẽ biến mất đối với người dùng đó. Với đa số người dùng, DNS được host kèm API là lựa chọn ít rủi ro hơn. Chạy caching resolver trên VPS cho các máy của riêng bạn là một công việc khác và có mức cam kết thấp hơn nhiều.

FAQ

Vì sao thay đổi DNS của tôi vẫn chưa được cập nhật?

Không có gì được “propagate”. Authoritative nameserver giữ giá trị mới ngay khi bạn lưu, còn mọi resolver đã hỏi trước đó vẫn giữ bản sao trong cache cho đến khi TTL mà chúng nhận được hết hạn. Hỏi trực tiếp authoritative server bằng dig @ns1.your-dns-host.net example.com A +short. Nếu lệnh trả về địa chỉ mới, thay đổi đã có hiệu lực và phần còn lại chỉ là vấn đề cache. Nếu bạn thay nameserver thay vì thay record, hãy dự kiến thời gian lâu hơn nhiều, vì TLD delegation được cấp với TTL 2 ngày.

Làm thế nào để biết domain của tôi thực sự đang dùng nameserver nào?

dig example.com NS +short in ra nameserver hiện đang trả lời cho domain, còn dig +trace example.com hiển thị chuỗi referral từ root, bao gồm delegation mà TLD server cấp. Nếu các tên đó không phải là provider có panel mà bạn đang chỉnh sửa, đó là nguyên nhân lỗi. Hãy chỉnh record tại provider được nêu trong delegation, hoặc thay delegation tại registrar để trỏ đến nơi bạn muốn.

Domain đã resolve nhưng site vẫn không tải được. Tôi phải làm gì?

DNS hoàn tất ngay khi dig example.com A +short trả về địa chỉ của server. Sau đó, vấn đề nằm ở kết nối. Nếu curl -I http://example.com trả về Connection refused, không có tiến trình nào đang listening trên cổng đó. Request bị treo cho đến khi timeout thường có nghĩa là firewall đã drop packet. Kiểm tra web server đang chạy và bind vào địa chỉ public, sau đó kiểm tra firewall trên server và network firewall riêng trong control panel của provider.

Vì sao tôi không thể đặt CNAME cho root domain?

CNAME cho biết một name là alias của name khác, và một name có CNAME không được phép chứa bất kỳ record nào khác. Root domain phải có record SOA và NS để tồn tại dưới dạng zone, nên không thể đồng thời là CNAME. Hãy dùng record A chứa địa chỉ tại root, hoặc dùng tính năng của provider được cung cấp dưới tên ALIAS, ANAME hoặc CNAME flattening. Tính năng này lưu một name và trả lời query bằng địa chỉ mà name đó đang resolve đến.