---
id: networking-dns
title: "DNS records"
shortTitle: "DNS records"
track: networking
trackTitle: "Networking"
order: 3
level: core
status: published
estimatedMinutes: 35
prerequisites:
  - networking-cli-tools
next: networking-http
reviewedAgainst: 2026-10-12
sources:
  - title: "RFC 1035"
    url: https://www.rfc-editor.org/rfc/rfc1035
  - title: "RFC 1912"
    url: https://www.rfc-editor.org/rfc/rfc1912
---

# DNS records

DNS đổi tên miền thành địa chỉ IP trước khi có connection TCP nào. App không bao giờ thấy bản ghi DNS; nó chỉ nhận được IP, hoặc một lỗi resolve.

## Để làm gì

Sau bài này, bạn chọn đúng loại bản ghi, đọc được TTL, và biết vì sao không đặt CNAME ở apex của zone.

## Gồm những gì

- `A`, `AAAA`, `CNAME`, `MX`, `TXT`, `NS`.
- TTL, và một bản ghi cũ còn nằm trong cache bao lâu.
- Apex và bản ghi alias của nhà cung cấp DNS.

Bài này không đi sâu vào DNSSEC. Bạn chỉ cần biết zone có thể được ký số; chưa cần tự ký ở đây.

## Dùng khi nào

Bạn đụng tới DNS khi trỏ domain vào load balancer, chứng minh quyền sở hữu domain để lấy certificate, hoặc cấu hình mail. Nếu đổi IP server mà quên sửa bản ghi `A`, client vẫn đi tới máy cũ cho đến khi TTL hết hạn.

Đừng hạ TTL xuống 60 giây rồi để vậy mãi, vì lượng query lên resolver và tiền bill sẽ tăng. Hãy hạ TTL trước khi đổi IP, đổi xong thì trả về giá trị bình thường.

## Kiến thức cốt lõi

`A` map tên sang IPv4, `AAAA` map sang IPv6. Một tên có thể có nhiều bản ghi `A`; client nhận cả danh sách và tự chọn.

`CNAME` trỏ tên này sang một tên khác, nên resolver phải hỏi tiếp tên đích. Theo RFC 1912, một tên đã có `CNAME` thì không được có bản ghi loại khác. Apex của zone, tức tên gốc như `example.com`, luôn có `SOA` và `NS`, nên không thể đặt `CNAME` ở đó. Để giải quyết, nhiều nhà cung cấp DNS có bản ghi `ALIAS` hoặc `ANAME`. Đây là tính năng riêng của họ chứ không phải loại bản ghi trong RFC 1035; khi client hỏi, họ trả về bản ghi `A`.

`MX` chỉ máy nhận mail, kèm số ưu tiên; số nhỏ hơn được thử trước. `TXT` chứa chuỗi tự do, thường dùng cho SPF và bước xác minh domain khi cấp certificate. `NS` ủy quyền một zone con cho nameserver khác.

TTL tính bằng giây, và resolver cache câu trả lời trong suốt khoảng đó. Vì vậy bạn sửa bản ghi xong, điện thoại của user chưa chắc thấy ngay.

## Lệnh và code mẫu

```bash
dig example.com A +noall +answer
dig example.com AAAA +noall +answer
dig example.com NS +noall +answer
```

Nếu không có `dig`, dùng PowerShell:

```powershell
Resolve-DnsName example.com -Type A
```

## Thực hành

1. Hỏi bản ghi `A` của `example.com` và ghi lại TTL ở cột thứ hai.
2. Hỏi bản ghi `NS`. Kết quả là nameserver của zone, không phải IP của web.
3. Đừng sửa DNS của domain thật trong lab này.

## Kết quả mong đợi

`example.com` có bản ghi `A`, và cột TTL là một số giây. `NS` trả về tên các máy chủ DNS, thường kết thúc bằng dấu `.`

## Checklist

- [ ] Khi đổi IP, hạ TTL từ trước, đừng đợi tới lúc user đã cache bản cũ.
- [ ] Apex dùng `A` hoặc alias của nhà cung cấp, không dùng `CNAME`.
- [ ] Sau khi xác minh domain bằng `TXT`, xóa bản ghi đó nếu bên cấp certificate cho biết chỉ cần lúc cấp.

## Thẻ ôn

### networking-dns-ttl
kind: decide
cue: Sắp đổi IP thì hạ TTL từ trước và đợi bản cũ hết cache, rồi mới sửa bản ghi. Đừng hạ xuống 60 giây rồi để vậy mãi.

Q: Tối nay bạn cắt server sang IP mới và định sửa bản ghi `A` đúng lúc bấm công tắc. Như vậy đã đủ để mọi client tới máy mới chưa? TTL nên xử lý thế nào, và vì sao không để TTL 60 giây vĩnh viễn?

A: Chưa đủ. Resolver và client đang giữ bản ghi cũ cho đến khi TTL hết hạn. Trong khoảng đó họ vẫn đi tới IP cũ, dù zone đã sửa. Hạ TTL từ trước, đợi ít nhất bằng TTL cũ để bản cache hết hạn, rồi mới đổi IP. Lúc ấy bản mới lan nhanh. Đừng hạ TTL xuống 60 giây rồi quên tăng lại. Mỗi lần hết hạn là một lần query, lượng hỏi tới authoritative tăng và ở lại mức đó mãi.

### networking-dns-apex
kind: trap
cue: Không đặt `CNAME` cho tên gốc của zone. Apex đã có `SOA` và `NS`. Dùng bản ghi `A`, hoặc alias của nhà cung cấp nếu họ có.

Q: Bạn muốn `example.com`, tên gốc của zone, trỏ sang một tên khác nên thêm `CNAME`. Được không, và nếu nhà cung cấp có `ALIAS` hoặc `ANAME` thì đó có phải bản ghi trong RFC 1035 không?

A: Không đặt `CNAME` ở apex. Tên gốc của zone luôn có `SOA` và `NS`. Một tên đã có `CNAME` thì không được có bản ghi loại khác cùng hiệu lực, nên `CNAME` ở apex đụng ngay hai bản ghi bắt buộc đó. Apex dùng bản ghi `A` trỏ thẳng IP. Một số nhà cung cấp có `ALIAS` hoặc `ANAME` để trông giống `CNAME` ở apex. Đó là cơ chế của họ, không phải loại bản ghi trong RFC 1035. Đọc tài liệu của đúng nhà cung cấp, đừng ghi chữ `CNAME` vào apex rồi hy vọng nó hợp lệ.

### networking-dns-mx
kind: trap
cue: Cùng một tên vừa `CNAME` vừa `MX` thì vừa sai chuẩn vừa làm hỏng mail. `www` mới dùng `CNAME`. Apex giữ `A` và `MX`.

Q: Bạn đặt `www` và tên gốc giống nhau cho tiện, rồi để cùng một tên vừa là `CNAME` vừa có `MX`. Mail còn đáng tin không, và nên tách thế nào?

A: Không nên. Tên có `CNAME` không được kèm bản ghi loại khác, và `MX` chính là bản ghi khác. Vừa sai chuẩn DNS, vừa làm máy gửi mail không biết tin bản ghi nào. Tách tên. `www` có thể là `CNAME` sang tên đích. Apex, nơi đặt `MX` và thường cả `A`, giữ các bản ghi đó và không làm `CNAME`. Mail và web không bắt buộc dùng chung một kiểu bản ghi trên cùng một nhãn.

### networking-dns-loop
kind: trap
cue: `a` CNAME sang `b` và `b` CNAME lại sang `a` thì resolver bỏ cuộc, `dig` không ra IP. Sửa một phía thành bản ghi `A`.

Q: Bản ghi `a` là `CNAME` sang `b`, và `b` là `CNAME` sang lại `a`. `dig` không in ra IP. Resolver đang làm gì, và sửa một phía thế nào?

A: Resolver đi theo `CNAME` để tới một bản ghi có địa chỉ. Ở đây hai tên trỏ vòng, không có điểm dừng, nên nó bỏ cuộc và không có IP để trả. `dig` trống địa chỉ không phải vì mạng chết. Sửa một phía thành bản ghi `A` trỏ tới IP thật. Phía kia có thể tiếp tục là `CNAME` sang tên đã có `A`. Vòng phải được phá ở một đầu.

## Lỗi thường gặp

**Đặt CNAME và MX trên cùng một tên.** Vừa sai chuẩn DNS, vừa làm hỏng mail. Hãy tách tên: ví dụ `www` dùng CNAME, còn apex giữ `A` và `MX`.

**CNAME trỏ vòng: `a` sang `b`, `b` lại sang `a`.** Resolver bỏ cuộc và `dig` không ra IP nào. Sửa một phía thành bản ghi `A`.

## Nguồn

1. [RFC 1035](https://www.rfc-editor.org/rfc/rfc1035) — bản ghi `A`, `NS`, `CNAME`, `MX`.
2. [RFC 1912](https://www.rfc-editor.org/rfc/rfc1912) — `CNAME` không đứng cùng bản ghi khác.

## Tiếp theo

[HTTP và HTTPS](./05-http.md)
