Dynamic DNS là dịch vụ mạng để ánh xạ tên miền thành địa chỉ IP động (tạm thời, thường xuyên thay đổi). Dịch vụ này được sử dụng để truy cập vào các máy tính không có địa chỉ IP tĩnh, chẳng hạn như các máy tính trong mạng SOHO (Văn phòng nhỏ/Văn phòng tại nhà) và thường được sử dụng kết hợp với chuyển tiếp cổng để truy cập vào các hệ thống nằm sau tường lửa NAT. Bài viết này sẽ hướng dẫn bạn thiết lập hoàn chỉnh máy chủ Dynamic DNS trong vùng chứa Docker trên hệ thống Debian 10, bao gồm thiết lập các bản ghi DNS cần thiết, đặt API quản lý sau proxy ngược Nginx HTTPS và tự động cập nhật bản ghi DNS phía máy khách.
Máy chủ DNS động của bạn sẽ xử lý tất cả các bản ghi trong ddns.your_domain. Bản ghi thứ ba, loại AAAA, là tùy chọn. Các bản ghi tương ứng trông như sau:
Bạn nên tạo các bản ghi này trong bảng điều khiển của cơ quan đăng ký tên miền. Xin lưu ý rằng có thể mất tới 24 giờ để các bản ghi này lan truyền tốt, nhưng thường chỉ mất vài phút.
Sau khi khởi động lại, hãy cài đặt các gói phần mềm cần thiết cho thiết lập này:
Cài đặt kho lưu trữ docker:
Cập nhật bộ nhớ đệm kho lưu trữ của Debian rồi cài đặt docker và các phần phụ thuộc của nó:
Sau khi cài đặt hoàn tất, hãy đảm bảo dịch vụ docker được bật và chạy như sau:
Đợi quá trình hoàn tất, có thể mất một lúc, sau đó mở tệp envfile bằng trình soạn thảo văn bản:
Và nhập lệnh sau:
Bí mật được chia sẻ là mật khẩu sẽ được sử dụng để xác thực với API quản lý. ZONE cho biết vùng DNS nào mà máy chủ của bạn sẽ chịu trách nhiệm và TTL của bản ghi chỉ định thời gian lưu trữ bộ nhớ đệm các bản ghi DNS. TTL 60 giây được khuyến nghị cho các IP động thường xuyên thay đổi.
Nếu cần, bạn có thể tạo chuỗi 40 ký tự ngẫu nhiên cho bí mật bằng lệnh sau:
Bây giờ chúng ta có thể tạo container:
Lệnh này sẽ tạo một container có tên là ddns-server từ hình ảnh chúng ta đã xây dựng trước đó và sẽ ánh xạ các cổng 8080/tcp, 53/tcp và 53/udp từ máy chủ sang container. Nó cũng sẽ gắn thư mục /mnt/ddns-data từ máy chủ, trên /var/cache/bind trong hệ thống tệp của vùng chứa. Điều này được sử dụng để lưu trữ dữ liệu DNS trong quá trình tạo lại vùng chứa.
Xác minh rằng vùng chứa đã được tạo bằng lệnh:
Một mục nhập duy nhất sẽ được xuất ra với tên ddns-server.
Để có thể quản lý container này như một dịch vụ hệ thống, chúng ta sẽ gói nó trong một đơn vị systemd. Tạo tệp /etc/systemd/system/ddns-server-ct.service bằng trình soạn thảo văn bản của bạn:
Và thêm nội dung sau:
Lưu và thoát, sau đó đặt quyền chính xác cho tệp đơn vị này:
Tải tệp dịch vụ mới bằng lệnh sau:
Bây giờ bạn có thể khởi động và dừng vùng chứa này bằng systemctl như bất kỳ dịch vụ hệ thống nào khác.
Nếu bạn muốn máy chủ DDNS tự động khởi động khi khởi động hệ thống, hãy thực hiện lệnh sau:
Gửi yêu cầu GET đến API để tạo bản ghi mới:
LƯU Ý: Hiện tại, API chỉ có thể truy cập cục bộ (tức là từ máy chủ cục bộ).
Curl sẽ trả về phản hồi sau:
LƯU Ý: Miền test1 tham chiếu đến test1.ddns.your_domain. vì máy chủ đang xử lý vùng ddns.your_domain..
Thực hiện tra cứu DNS để xác minh rằng bản ghi thực sự đã được tạo và để kiểm tra độ phân giải DNS:
Đầu ra phải là 1.1.1.1.
Quyền sở hữu tên miền của bạn sẽ được xác minh và chứng chỉ sẽ được cấp. Tiếp theo, cài đặt Nginx và đảm bảo rằng nó được bật và đang chạy:
Sau đó, vô hiệu hóa tệp khối máy chủ mặc định vì nó không cần thiết:
Bây giờ chúng ta sẽ tạo một tệp cấu hình mới cho proxy ngược, ví dụ:
Và dán nội dung sau, đảm bảo rằng bạn thay thế địa chỉ IP và tên miền bằng tên miền của riêng bạn:
Tùy chọn: Nếu bạn muốn API có thể truy cập qua IPv6, hãy thêm dòng sau sau chỉ thị listen hiện có:
Bật tùy chọn này cấu hình và áp dụng các thay đổi bằng cách tải lại Nginx:
Bây giờ, API có thể truy cập được qua internet và chỉ chấp nhận kết nối HTTPS. Để kiểm tra, hãy đưa ra lệnh:
Nó sẽ trả về thông tin sau:
Bạn cũng có thể cập nhật bản ghi của nhiều tên miền phụ bằng một yêu cầu duy nhất. Ví dụ: để tạo/cập nhật bản ghi cho sub1.ddns.your_domain và sub2.ddns.your_domain có địa chỉ IP 198.51.100.100, bạn sẽ gửi yêu cầu GET đến URL này:
https://ns1.your_domain:8080/update?secret=your_secret&domain=sub1,sub2&addr=198.51.100.100
Tham số addr cũng có thể chứa địa chỉ IPv6 để tạo/cập nhật bản ghi DNS AAAA, ví dụ:
Để tự động hóa các cập nhật trên máy khách Linux, hãy lưu tập lệnh bash sau đây dưới dạng /opt/ddns-update.sh:
Tập lệnh này sử dụng vòng lặp while bao quanh lệnh dig để lấy địa chỉ IP công khai của máy khách và lưu trữ trong một biến. Vòng lặp đảm bảo rằng IP công khai được lấy chính xác. Sau đó, cURL được sử dụng để gửi yêu cầu API để cập nhật bản ghi DNS bằng IP mới lấy này. Đảm bảo bạn thay thế các giá trị cho your_secret và your_subdomain.
Tiếp theo, hãy thực thi tập lệnh này:
Sau đó, khởi chạy trình chỉnh sửa crontab:
Thêm dòng sau vào cuối crontab của bạn:
Lưu và thoát. Bây giờ, tập lệnh sẽ chạy sau mỗi hai phút, giúp bản ghi DNS động của bạn luôn cập nhật với địa chỉ IP công khai mới nhất của máy khách.
Yêu cầu
- Một máy chủ Debian 10 duy nhất, tùy chọn có kết nối IPv6. (192.0.2.2 và 2001:0db8::0db9 sẽ được sử dụng làm trình giữ chỗ cho IPv4 và IPv6 của máy chủ tương ứng.)
- Truy cập vào người dùng gốc hoặc người dùng có quyền sudo.
- Cổng tcp/53 và udp/53 phải có sẵn trên máy chủ.
- Tên miền đã đăng ký và quyền truy cập vào máy chủ tên/tệp vùng của tên miền đó. Tạo bản ghi DNS cho tên miền này như được hiển thị trong phần tiếp theo.
- Biến môi trường $EDITOR phải được đặt.
- Tùy chọn, bất kỳ hệ thống máy khách Linux/Unix nào để thiết lập cập nhật bản ghi DNS tự động.
Tạo bản ghi DNS.
Bạn sẽ cần tạo ít nhất 2 bản ghi DNS để máy chủ DNS động của bạn hoạt động. Đầu tiên, hãy chọn một tên miền phụ như ns1.your_domain sẽ trỏ đến địa chỉ IPv4 của máy chủ của bạn. Thứ hai, hãy chọn một tên miền phụ như ddns.your_domain sẽ được chuyển giao cho ns1.your_domain.Máy chủ DNS động của bạn sẽ xử lý tất cả các bản ghi trong ddns.your_domain. Bản ghi thứ ba, loại AAAA, là tùy chọn. Các bản ghi tương ứng trông như sau:
Mã:
ns1.your_domain A 192.0.2.2
Mã:
ddns.your_domain NS ns1.your_domain
Mã:
ns1.your_domain AAAA 2001:0db8::0db9 (tùy chọn)
Mã:

Bạn nên tạo các bản ghi này trong bảng điều khiển của cơ quan đăng ký tên miền. Xin lưu ý rằng có thể mất tới 24 giờ để các bản ghi này lan truyền tốt, nhưng thường chỉ mất vài phút.
Cài đặt
Nếu bạn không sử dụng người dùng root, chúng tôi khuyên bạn nên khởi động một shell root tạm thời, vì hầu hết các lệnh được hiển thị trong hướng dẫn này đều yêu cầu các đặc quyền nâng cao. Để khởi chạy root shell, hãy sử dụng một trong các lệnh sau:
Mã:
sudo su - root
Mã:
sudo -s
Bước 1: Cập nhật và cài đặt các dependency.
Luôn luôn là một thói quen tốt khi cập nhật hệ thống của bạn trước:
Mã:
apt update
Mã:
apt upgrade -y
Mã:
reboot
- certbot sẽ được sử dụng để lấy chứng chỉ SSL/TLS.
- make là lệnh bắt buộc để xây dựng hình ảnh docker mà máy chủ DDNS sẽ chạy.
- apt-transport-https, ca-certificates, curl, gnupg2 và software-properties-common là cần thiết để cài đặt kho lưu trữ Docker và khóa GPG tương ứng của nó.
- dnsutils cung cấp dig, sẽ được sử dụng để thử nghiệm.
Mã:
apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils
Bước 2: Cài đặt Docker CE.
Thêm khóa GPG của Docker:
Mã:
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
Mã:
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"
Mã:
apt update
Mã:
apt install -y docker-ce docker-ce-cli containerd.io
Mã:
systemctl enable --now docker.service
Bước 3: Tải xuống và xây dựng docker-ddns
Máy chủ DNS động của chúng tôi sẽ được hỗ trợ bởi một vùng chứa docker sử dụng Bind làm máy chủ DNS và API quản lý được viết bằng Go. Đầu tiên, hãy sao chép kho lưu trữ Github và xây dựng hình ảnh container bằng các lệnh sau:
Mã:
git clone https://github.com/dprandzioch/docker-ddns.git
Mã:
cd docker-ddns
Mã:
make image
Mã:
$EDITOR envfile
Mã:
SHARED_SECRET=your_secret
ZONE=ddns.your_domain
RECORD_TTL=60
Nếu cần, bạn có thể tạo chuỗi 40 ký tự ngẫu nhiên cho bí mật bằng lệnh sau:
Mã:
cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 40 | head -1
Mã:
docker create -it -p 127.0.0.1:8080:8080 -p 53:53 -p 53:53/udp --env-file envfile -v /mnt/ddns-data:/var/cache/bind --name ddns-server davd/docker-ddns
Xác minh rằng vùng chứa đã được tạo bằng lệnh:
Mã:
docker container ls -a
Bước 4: Dịch vụ Systemd (tùy chọn)
Bước này giúp quản lý đơn giản hơn nhưng không bắt buộc. Nếu bạn chọn không sử dụng dịch vụ systemd, bạn sẽ phải quản lý vùng chứa theo cách thủ công hoặc sử dụng giải pháp quản lý khác. Xin lưu ý rằng đối với các triển khai vùng chứa lớn hơn, phức tạp hơn, giải pháp phối hợp như Kubernetes hoặc Docker Swarm được khuyến nghị. Trong trường hợp này, dịch vụ systemd hoàn toàn phù hợp vì chúng ta chỉ chạy một container duy nhất.Để có thể quản lý container này như một dịch vụ hệ thống, chúng ta sẽ gói nó trong một đơn vị systemd. Tạo tệp /etc/systemd/system/ddns-server-ct.service bằng trình soạn thảo văn bản của bạn:
Mã:
$EDITOR /etc/systemd/system/ddns-server-ct.service
Mã:
[Unit]
Description=DDNS Server Docker Container
After=docker.service
Requires=docker.service
Requires=network.target
[Service]
Type=oneshot
TimeoutStartSec=240
Restart=no
RemainAfterExit=yes
ExecStart=/usr/bin/docker start ddns-server
ExecStop=/usr/bin/docker stop ddns-server
[Install]
WantedBy=multi-user.target
Mã:
chmod 664 /etc/systemd/system/ddns-server-ct.service
Mã:
systemctl daemon-reload
Nếu bạn muốn máy chủ DDNS tự động khởi động khi khởi động hệ thống, hãy thực hiện lệnh sau:
Mã:
systemctl enable ddns-server-ct.service
Bước 5: Kiểm tra máy chủ của bạn
Trước khi tiến hành thiết lập, chúng tôi sẽ kiểm tra API quản lý cục bộ. Khởi động container:
Mã:
systemctl start ddns-server-ct.service
LƯU Ý: Hiện tại, API chỉ có thể truy cập cục bộ (tức là từ máy chủ cục bộ).
Mã:
curl "http://127.0.0.1:8080/update?secret=your_secret&domain=test1&addr=1.1.1.1"
Mã:
{"Success":true,"Message":"Đã cập nhật bản ghi A cho test1 thành địa chỉ IP 1.1.1.1","Domain":"test1","Domains":["test1"],"Address":"1.1.1.1","AddrType":"A"}
Thực hiện tra cứu DNS để xác minh rằng bản ghi thực sự đã được tạo và để kiểm tra độ phân giải DNS:
Mã:
dig +short -t A test1.ddns.your_domain @127.0.0.1
Bước 6: Proxy ngược
Vì API hoạt động qua HTTP, nên bí mật xác thực của bạn có khả năng bị đánh hơi bất cứ khi nào bạn gửi yêu cầu qua mạng. Sau đó, kẻ tấn công có thể thao túng các bản ghi DNS của bạn bằng bí mật của bạn. Chúng tôi sẽ thiết lập proxy ngược bằng Nginx và bảo mật nó bằng HTTPS. Trước tiên, hãy lấy chứng chỉ SSL từ Let's Encrypt bằng certbot:
Mã:
certbot certonly --standalone --agree-tos -m [emailprotected] -d ns1.your_domain
Mã:
apt install -y nginx systemctl enable --now nginx.service
Mã:
unlink /etc/nginx/sites-enabled/default
Mã:
$EDITOR /etc/nginx/sites-available/ddns-api-proxy.conf
Mã:
server {
listen 192.0.2.2:8080;
server_name ns1.your_domain;
ssl on;
ssl_certificate /etc/letsencrypt/live/ns1.your_domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ns1.your_domain/privkey.pem;
location /update {
proxy_pass http://127.0.0.1:8080;
}
location / {
return 404;
}
access_log /var/log/nginx/ddns-api-access.log;
error_log /var/log/nginx/ddns-api-error.log;
}
Mã:
listen [2001:0db8::0db9]:8080;
Mã:
ln -s /etc/nginx/sites-available/ddns-api-proxy.conf /etc/nginx/sites-enabled/
Mã:
systemctl reload nginx.service
Bây giờ, API có thể truy cập được qua internet và chỉ chấp nhận kết nối HTTPS. Để kiểm tra, hãy đưa ra lệnh:
Mã:
curl "https://ns1.your_domain:8080/update?secret=your_secret&domain=test2&addr=1.1.1.2"
Mã:
{"Success":true,"Message":"Updated A record for test2 to IP address 1.1.1.2","Domain":"test2","Domains":["test2"],"Address":"1.1.1.2","AddrType":"A"}
Bước 7: Cấu hình máy khách
Bạn có thể thiết lập cập nhật bản ghi tự động trên bất kỳ bộ định tuyến nào hỗ trợ nhà cung cấp DNS động tùy chỉnh, chẳng hạn như Pfsense. Bạn cũng có thể thiết lập chúng trên hầu hết các thiết bị khác trong mạng văn phòng hoặc gia đình của mình. Để cập nhật hoặc tạo bản ghi, yêu cầu GET phải được gửi đến điểm cuối sau:
Mã:
https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=your_ip_address
https://ns1.your_domain:8080/update?secret=your_secret&domain=sub1,sub2&addr=198.51.100.100
Tham số addr cũng có thể chứa địa chỉ IPv6 để tạo/cập nhật bản ghi DNS AAAA, ví dụ:
Mã:
https://ns1.your_domain:8080/update?secret=your_secret&domain=cheese&addr=2001:0db8:aaaa::
Mã:
#!/bin/bash
while [ -z $CURRENTIP ]do
CURRENTIP=`dig -r +short myip.opendns.com @resolver1.opendns.com 2>/dev/null`
sleep 1
done
curl -s "https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=${CURRENTIP}"
Tiếp theo, hãy thực thi tập lệnh này:
Mã:
chmod +x /opt/ddns-update.sh
Mã:
crontab -e
Mã:
*/2 * * * * /opt/ddns-update.sh