Hệ thống DNS tôi đang dùng – AdGuard Home + NPMplus

Triển khai AdGuard Home và NPMplus bằng mô hình hai stack Docker tách biệt, hỗ trợ đầy đủ DoH, DoT và DoQ. Ghi chép cá nhân.

Dạo gần đây tôi làm lại toàn bộ hệ thống DNS ở nhà và văn phòng.
Tôi muốn một hệ thống:

Cuối cùng tôi chọn mô hình:


🌐 1. Tạo network chung

1docker network create reverse_proxy

🧩 2. NPMplus – cổng HTTPS cho toàn hệ thống

 1services:
 2  npmplus:
 3    container_name: npmplus
 4    image: docker.io/zoeyvid/npmplus:latest
 5    restart: unless-stopped
 6    ports:
 7      - 80:80
 8      - 443:443
 9    volumes:
10      - ./npmplus-data:/data
11      - ./npmplus-ssl:/etc/letsencrypt
12    networks:
13      - reverse_proxy
14    environment:
15      - TZ=Asia/Ho_Chi_Minh
16
17networks:
18  reverse_proxy:
19    external: true

NPM xử lý DoH, dashboard AdGuard, chứng chỉ Let’s Encrypt (cho DoH) và reverse proxy.


🛡️ 3. AdGuard Home – DNS + DoT/DoQ

 1services:
 2  adguardhome:
 3    container_name: adguardhome
 4    image: adguard/adguardhome:latest
 5    restart: unless-stopped
 6    ports:
 7      - 53:53/tcp
 8      - 53:53/udp
 9      - 853:853/tcp
10      - 853:853/udp
11    volumes:
12      - ./workdir:/opt/adguardhome/work
13      - ./confdir:/opt/adguardhome/conf
14      - /opt/certbot/live/dns.example.com:/opt/adguardhome/certs:ro
15    networks:
16      - reverse_proxy
17    environment:
18      - TZ=Asia/Ho_Chi_Minh
19
20networks:
21  reverse_proxy:
22    external: true

Dashboard chạy nội bộ port 8080 và chỉ NPM truy cập.


🔐 4. Cấp chứng chỉ TLS cho DoT/DoQ bằng Certbot

Wildcard không bao gồm root domain, nên tôi xin hai SAN:

4.1 Container Certbot

1services:
2  certbot:
3    container_name: certbot
4    image: certbot/certbot:latest
5    restart: unless-stopped
6    volumes:
7      - /opt/certbot:/etc/letsencrypt
8    command: sleep infinity

4.2 Xin chứng chỉ SAN (DNS-01 tự động)

Tôi dùng DNS-01 tự động để Certbot tự thêm TXT record qua API của DNS provider (ví dụ Cloudflare → certbot-dns-cloudflare, Porkbun → certbot-dns-porkbun, …).

Ví dụ với Cloudflare:

1docker exec -it certbot bash
1certbot certonly \
2  --dns-cloudflare \
3  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
4  -d dns.example.com \
5  -d '*.dns.example.com'

Certbot tự tạo TXT → tự xác thực → tự ra cert → không phải thao tác thủ công.

Cert (trên container) nằm tại:

1/etc/letsencrypt/live/dns.example.com/

Cert (trên host) nằm tại:

1/opt/certbot/live/dns.example.com/

4.3 Mount cert vào AdGuard

1volumes:
2  - /opt/certbot/live/dns.example.com:/opt/adguardhome/certs:ro

4.4 Cấu hình HTTP / TLS trong AdGuard

 1http:
 2  address: 0.0.0.0:8080
 3
 4dns:
 5  bind_hosts:
 6    - 0.0.0.0
 7  port: 53
 8
 9tls:
10  enabled: true
11  certificate_path: /opt/adguardhome/certs/fullchain.pem
12  private_key_path: /opt/adguardhome/certs/privkey.pem
13  port_dns_over_tls: 853
14  port_dns_over_quic: 853
15  port_https: 0

4.5 Gia hạn chứng chỉ

10 */12 * * * docker exec certbot certbot renew

🔁 5. Reverse proxy cho DoH + Dashboard trong NPM

 1location ~ ^/dns-query(/.*)?$ {
 2    set $clientid "";
 3    if ($1 != "") { set $clientid $1; }
 4    proxy_pass http://adguardhome:8080/dns-query;
 5    proxy_set_header X-Client-ID $clientid;
 6    proxy_set_header X-Real-IP  $remote_addr;
 7}
 8
 9location / {
10    proxy_pass http://adguardhome:8080;
11}

DoH: https://dns.example.com/dns-query/my-device
Dashboard: https://dns.example.com/


🧬 6. Định danh thiết bị trong AdGuard

 1clients:
 2  persistent:
 3    - name: Windows YogaDNS (Hanoi)
 4      ids: [100.68.0.11, hn-p1]
 5
 6    - name: iPhone15
 7      ids: [my-ip15]
 8
 9    - name: Android ZTE
10      ids: [my-zte]
11
12    - name: Laptop Dell3558
13      ids: [my-d58]

📱 7. Cách tôi cấu hình DNS trên từng thiết bị

Thiết bị Giao thức Endpoint
Windows Plain DNS udp://192.168.2.2 hoặc udp://100.68.x.x
iPhone DoH https://dns.example.com/dns-query/my-ip15
Android DoH https://dns.example.com/dns-query/my-zte
Linux DoQ quic://my-d58.dns.example.com:853

LAN/Tailscale → Plain DNS
Internet → DoH/DoQ


🧪 8. Kiểm tra nhanh

1doggo example.com @udp://192.168.2.2 --time

🎯 Kết luận

Dựng một lần và gần như không phải đụng vào nữa.

#AdGuard Home   #NPMplus   #DNS   #DoH   #DoT   #DoQ   #docker   #Certbot