Ngừng điều hướng người dùng đi nửa vòng trái đất: Xây dựng GeoDNS với PowerDNS

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

Tại sao DNS tĩnh đang làm giảm hiệu năng của bạn

DNS tĩnh là một “kẻ sát nhân thầm lặng” đối với hiệu năng. Tôi đã dành nhiều năm kiểm thử các hệ thống toàn cầu, nơi một người dùng ở Singapore bị điều hướng đến máy chủ tại New York chỉ vì đó là IP duy nhất được cấu hình. Điều này làm tăng khoảng 250ms độ trễ không đáng có cho mỗi yêu cầu. Trong một thế giới mà 40% người dùng rời bỏ trang web nếu tải quá ba giây, những mili giây đó thực sự rất tốn kém.

Các “ông lớn” thương mại như AWS Route53 hay Cloudflare Load Balancing có thể giải quyết vấn đề này, nhưng chúng đi kèm với hóa đơn hàng tháng và sự phụ thuộc vào nhà cung cấp (vendor lock-in). Nếu bạn muốn toàn quyền kiểm soát mà không phải trả “thuế đám mây”, PowerDNS chính là câu trả lời. Tôi đã triển khai mô hình này trong các môi trường production xử lý hàng triệu truy vấn. Nó hoạt động cực kỳ hiệu quả. Hướng dẫn này sẽ chỉ cho bạn cách trả về các địa chỉ IP khác nhau dựa trên vị trí phát sinh truy vấn.

Bắt đầu nhanh: Triển khai trong 5 phút

Bạn không cần một cụm cluster đồ sộ cho việc này. Một VPS cấu hình nhẹ với 1GB RAM chạy Ubuntu 22.04 hoặc 24.04 là quá đủ để xử lý hàng ngàn yêu cầu mỗi giây. Chúng ta sẽ tập trung vào PowerDNS Authoritative Server và backend GeoIP của nó.

1. Cài đặt PowerDNS và GeoIP Backend

Đầu tiên, hãy cài đặt server cốt lõi và module backend cụ thể. Chúng có sẵn trong kho lưu trữ chuẩn của Ubuntu.

sudo apt update
sudo apt install pdns-server pdns-backend-geoip -y

2. Tải cơ sở dữ liệu GeoIP

PowerDNS cần một bản đồ để liên kết các IP với vị trí vật lý. MaxMind cung cấp phiên bản miễn phí gọi là GeoLite2. Hãy đăng ký tài khoản miễn phí trên trang web của họ, lấy mã bản quyền và tải về các tệp City và Country định dạng .mmdb. Sau đó, hãy đặt chúng vào một thư mục riêng biệt.

# Thư mục của bạn sẽ trông như thế này:
ls /var/lib/GeoIP/
# GeoLite2-City.mmdb  GeoLite2-Country.mmdb

3. Cấu hình cơ bản

Mở tệp /etc/powerdns/pdns.conf. Chúng ta cần vô hiệu hóa backend bind mặc định và kích hoạt GeoIP. Điều này cho PowerDNS biết chính xác nơi tìm dữ liệu vị trí và các quy tắc điều hướng tùy chỉnh của bạn.

launch=geoip
geoip-database-files=/var/lib/GeoIP/GeoLite2-City.mmdb /var/lib/GeoIP/GeoLite2-Country.mmdb
geoip-zones-file=/etc/powerdns/geoip-zones.yaml

Đi sâu chi tiết: Cách PowerDNS ánh xạ IP tới vị trí

Tệp geoip-zones.yaml chính là bộ não của hệ thống. Không giống như các tệp Bind kiểu cũ cứng nhắc và lộn xộn, PowerDNS sử dụng YAML cho GeoIP. Nó sạch sẽ, dễ đọc và dễ quản lý phiên bản (version control).

Khi một truy vấn gửi đến máy chủ, PowerDNS sẽ kiểm tra IP của người gửi đối chiếu với cơ sở dữ liệu MaxMind. Nó xác định mã châu lục hoặc quốc gia và khớp với các quy tắc YAML của bạn. Nếu không có kết quả khớp, nó sẽ trả về bản ghi mặc định. Đó là logic đơn giản cho một vấn đề phức tạp.

Cấu hình Zone File

Tạo tệp /etc/powerdns/geoip-zones.yaml. Dưới đây là cấu trúc đã được kiểm chứng qua thực tế cho một dịch vụ toàn cầu với các node tại Châu Á, Châu Âu và Bắc Mỹ:

domains:
  - domain: example.com
    ttl: 300
    records:
      example.com:
        - a: 1.2.3.4 # IP dự phòng mặc định
      
      app.example.com:
        - a: 1.2.3.4 
    
    services:
      app.example.com:
        # Node Singapore cho Châu Á
        as.continent.geo.example.com: ["103.1.2.3"]
        # Node Frankfurt cho Châu Âu
        eu.continent.geo.example.com: ["185.1.2.3"]
        # Node New York cho Bắc Mỹ
        na.continent.geo.example.com: ["192.1.2.3"]

Hãy lưu ý rằng các truy vấn DNS thường đến từ các resolver của ISP thay vì trực tiếp từ người dùng. Tuy nhiên, PowerDNS hỗ trợ EDNS Client Subnet (ECS). Điều này cho phép resolver truyền tải subnet thực tế của người dùng, giúp việc điều hướng địa lý của bạn trở nên cực kỳ chính xác.

Sử dụng nâng cao: Kiểm soát chi tiết và Dự phòng

Điều hướng ở cấp độ châu lục là một khởi đầu tốt, nhưng bạn có thể đi sâu hơn. Ví dụ, bạn có thể muốn người dùng ở Việt Nam truy cập vào node tại TP. Hồ Chí Minh trong khi phần còn lại của Châu Á vẫn tiếp tục sử dụng Singapore.

Điều hướng theo quốc gia cụ thể

Sử dụng mã quốc gia ISO 3166-1 alpha-2 để đạt được độ chính xác tuyệt đối. Điều này hoàn hảo để tuân thủ các luật dữ liệu địa phương hoặc tối ưu hóa cho các thị trường cụ thể.

services:
  app.example.com:
    vn.country.geo.example.com: ["45.1.2.3"] # Node Việt Nam
    as.continent.geo.example.com: ["103.1.2.3"] # Phần còn lại của Châu Á

Điều hướng trọng số và Dự phòng

Nếu bạn có hai máy chủ trong cùng một khu vực, hãy liệt kê cả hai. PowerDNS sẽ trả về cả hai IP, cho phép client tự lựa chọn. Đây là một cách cơ bản nhưng hiệu quả để phân phối tải giữa nhiều máy chủ trong cùng một trung tâm dữ liệu.

services:
  app.example.com:
    eu.continent.geo.example.com: ["185.1.2.3", "185.1.2.4"]

Lời khuyên thực tiễn từ kinh nghiệm thực tế

Tự vận hành hạ tầng DNS là một cam kết nghiêm túc. Tôi đã rút ra được một vài bài học xương máu khi quản lý các hệ thống này trong môi trường lưu lượng cao.

1. Tự động cập nhật cơ sở dữ liệu

MaxMind cập nhật dữ liệu GeoLite2 của họ hai lần một tuần. Cơ sở dữ liệu lỗi thời sẽ dẫn đến điều hướng sai—chẳng hạn như gửi một người dùng ở London đến máy chủ tại Tokyo. Hãy sử dụng công cụ geoipupdate với một cron job đơn giản để giữ cho các tệp của bạn luôn mới nhất mà không cần can thiệp thủ công.

2. Kiểm tra trạng thái (Health Check) là bắt buộc

PowerDNS không tự động kiểm tra xem các máy chủ ứng dụng của bạn có đang hoạt động hay không. Nếu node tại Frankfurt gặp sự cố, PowerDNS vẫn sẽ tiếp tục gửi người dùng Châu Âu đến một IP “chết”. Tôi khuyên bạn nên dùng một script Python hoặc Go đơn giản để giám sát các node và cập nhật tệp YAML (sau đó chạy pdns_control reload) nếu có lỗi xảy ra.

3. Bảo mật DNS chống lại các cuộc tấn công

Các máy chủ DNS mở là mục tiêu của các cuộc tấn công khuếch đại DDoS (DDoS amplification). Hãy thắt chặt bảo mật. Sử dụng firewall để giới hạn tỷ lệ truy vấn và đảm bảo bạn chỉ cho phép lưu lượng trên cổng UDP/53 và TCP/53. Việc giám sát các đột biến trong lưu lượng truy vấn có thể cứu máy chủ của bạn khỏi việc bị lợi dụng làm công cụ tấn công.

4. Giữ chỉ số TTL thấp

Đối với GeoDNS, hãy sử dụng TTL trong khoảng từ 60 đến 300 giây. Nếu một node khu vực gặp sự cố và bạn cần chuyển hướng lưu lượng, TTL cao (như 86400 giây) sẽ khiến người dùng bị kẹt ở IP lỗi trong cả ngày trời. TTL thấp đảm bảo các thay đổi của bạn được lan truyền nhanh chóng trên internet.

Xây dựng GeoDNS của riêng bạn với PowerDNS mang lại khả năng kiểm soát hoàn toàn luồng lưu lượng. Đây là một chiến lược hiệu quả về chi phí và hiệu suất cao, đảm bảo người dùng của bạn có được trải nghiệm nhanh nhất có thể, bất kể họ đang ở đâu trên bản đồ.

Share: