如何在 Debian 10 上使用 Docker 部署动态 DNS 服务器如何在 Debian 10 上使用 Docker 部署动态 DNS 服务器如何在 Debian 10 上使用 Docker 部署动态 DNS 服务器如何在 Debian 10 上使用 Docker 部署动态 DNS 服务器
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何在 Debian 10 上使用 Docker 部署动态 DNS 服务器

在此页

  1. 要求
  2. 创建 DNS 记录。
  3. 安装
    1. 第 1 步:更新和安装依赖项。
    2. 第 2 步:安装 Docker CE。
    3. 第 3 步:下载并构建 docker-ddns
    4. 第 4 步:Systemd 服务(可选)
    5. 第 5 步:测试您的服务器
    6. 第 6 步:反向代理
    7. 第 7 步:客户端配置

    动态 DNS 是一种将域名映射到动态(临时的、经常变化的)IP 地址的网络服务。它用于访问没有静态 IP 地址的计算机,例如 SOHO(小型办公室/家庭办公室)网络中的计算机,并且通常与端口转发结合使用以访问 NAT 防火墙后面的系统。本文将指导您在 Debian 10 系统上的 Docker 容器中完成动态 DNS 服务器的完整设置,包括设置所需的 DNS 记录,将管理 API 置于 Nginx HTTPS 反向代理后面,以及自动化客户端 DNS记录更新。

    要求

    • 一台 Debian 10 服务器,可选 IPv6 连接。 (192.0.2.2 和 2001:0db8::0db9 将分别用作服务器 IPv4 和 IPv6 的占位符。)
    • 访问 root 用户或具有 sudo 权限的用户。
    • 端口 tcp/53 和 udp/53 必须在主机上可用。
    • 注册的域名和对其名称服务器/区域文件的访问权限。如下一节所示为此域创建 DNS 记录。
    • 必须设置 $EDITOR 环境变量。
    • 可选,任何 Linux/Unix 客户端系统设置自动 DNS 记录更新。

    创建 DNS 记录。

    您需要为动态 DNS 服务器创建至少 2 个 DNS 记录才能工作。首先,选择一个子域,例如 ns1.your_domain,它将指向您的服务器 IPv4 地址。其次,选择一个子域,例如 ddns.your_domain,它将被委托给 ns1.your_domain。

    您的动态 DNS 服务器将处理 ddns.your_domain 下的所有记录。第三条记录,类型为 AAAA,是可选的。相应的记录如下所示:

    ns1.your_domain A 192.0.2.2
    ddns.your_domain NS ns1.your_domain
    ns1.your_domain AAAA 2001:0db8::0db9 (optional)

    您应该在您的域注册商控制面板中创建这些记录。请注意,这些记录最多可能需要 24 小时才能正常传播,但通常需要几分钟。

    安装

    如果您不使用 root 用户,我们建议您启动一个临时的 root shell,因为本指南中显示的大多数命令都需要提升权限。要启动 root shell,请使用以下命令之一:

    sudo su - root
    sudo -s

    第 1 步:更新和安装依赖项。

    最好先更新您的系统:

    apt update
    apt upgrade -y
    reboot

    重新启动后,安装此设置所需的软件包:

    • certbot 将用于获取 SSL/TLS 证书。
    • 需要 make 来构建运行 DDNS 服务器的 docker 镜像。
    • 需要 apt-transport-https、ca-certificates、curl、gnupg2 和 software-properties-common 来安装 Docker 存储库及其相应的 GPG 密钥。
    • dnsutils 提供dig,将用于测试。

    apt install -y certbot make apt-transport-https curl ca-certificates software-properties-common gnupg2 dnsutils

    第二步:安装Docker CE。

    添加 Dockers GPG 密钥:

    curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

    安装 docker 存储库:

    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian buster stable"

    更新 Debians 存储库缓存然后安装 docker 及其依赖项:

    apt update
    apt install -y docker-ce docker-ce-cli containerd.io

    安装完成后,确保 docker 服务已启用并运行,如下所示:

    systemctl enable --now docker.service

    第 3 步:下载并构建 docker-ddns

    我们的动态 DNS 服务器将由一个使用 Bind 作为 DNS 服务器的 docker 容器和一个用 Go 编写的管理 API 提供支持。首先,克隆 Github 存储库并使用以下命令构建容器镜像:

    git clone https://github.com/dprandzioch/docker-ddns.git
    cd docker-ddns
    make image

    等待该过程完成,这可能需要一段时间,然后使用文本编辑器打开文件 envfile:

    $EDITOR envfile

    并输入以下内容:

    SHARED_SECRET=your_secret 
    ZONE=ddns.your_domain
    RECORD_TTL=60

    共享机密是一个密码,将用于通过管理 API 进行身份验证。 ZONE 指示您的服务器将负责哪个 DNS 区域,记录 TTL 指定 DNS 记录可以缓存多长时间。对于频繁更改的动态 IP,建议使用 60 秒的 TTL。

    如果需要,您可以使用以下命令为密钥生成一个随机的 40 个字符的字符串:

    cat /dev/urandom | tr -dc "a-zA-Z0-9" | fold -w 40 | head -1

    我们现在可以创建容器:

    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

    此命令将从我们之前构建的映像创建一个名为 ddns-server 的容器,并将端口 8080/tcp、53/tcp 和 53/udp 从主机映射到容器。它还将从主机挂载目录 /mnt/ddns-data 到容器文件系统中的 /var/cache/bind 上。这用于跨容器重新创建持久化 DNS 数据。

    使用以下命令验证容器是否已创建:

    docker container ls -a
    

    应输出一个名为 ddns-server 的条目。

    第 4 步:Systemd 服务(可选)

    此步骤是为了简化管理,但并非严格要求。如果您选择不使用 systemd 服务,则必须手动管理容器或使用其他管理解决方案。请注意,对于更大、更复杂的容器部署,建议使用 Kubernetes 或 Docker Swarm 等编排解决方案。在这种情况下,systemd 服务非常合适,因为我们只运行一个容器。

    为了能够将此容器作为系统服务进行管理,我们将其包装在一个 systemd 单元中。使用文本编辑器创建文件 /etc/systemd/system/ddns-server-ct.service:

    $EDITOR /etc/systemd/system/ddns-server-ct.service
    

    并添加以下内容:

    [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

    保存退出,然后对该单元文件设置正确的权限:

    chmod 664 /etc/systemd/system/ddns-server-ct.service

    使用以下命令加载新的服务文件:

    systemctl daemon-reload

    您现在应该能够像使用任何其他系统服务一样使用 systemctl 启动和停止此容器。

    如果您希望 DDNS 服务器在系统启动时自动启动,请执行以下命令:

    systemctl enable ddns-server-ct.service

    第 5 步:测试您的服务器

    在继续设置之前,我们会在本地测试管理 API。启动容器:

    systemctl start ddns-server-ct.service

    向 API 发送 GET 请求以创建新记录:

    注意:该 API 目前只能在本地访问(即从本地主机)。

    curl "http://127.0.0.1:8080/update?secret=your_secret&domain=test1&addr=1.1.1.1"

    Curl 应返回以下响应:

    {"Success":true,"Message":"Updated A record for test1 to IP address 1.1.1.1","Domain":"test1","Domains":["test1"],"Address":"1.1.1.1","AddrType":"A"}

    注意:域 test1 指的是 test1.ddns.your_domain。因为服务器正在处理 ddns.your_domain。区。

    执行 DNS 查找以验证记录确实已创建并测试 DNS 解析:

    dig +short -t A test1.ddns.your_domain @127.0.0.1

    输出应为 1.1.1.1。

    第 6 步:反向代理

    由于 API 通过 HTTP 工作,因此无论何时您通过网络发送请求,您的身份验证密码都可能被嗅探。然后,攻击者可以使用您的密码操纵您的 DNS 记录。很好地使用 Nginx 设置反向代理并使用 HTTPS 保护它。首先,使用 certbot 从 Lets Encrypt 获取 SSL 证书:

    certbot certonly --standalone --agree-tos -m  -d ns1.your_domain

    您的域的所有权将得到验证并颁发证书。接下来,安装 Nginx 并确保它已启用并正在运行:

    apt install -y nginx systemctl enable --now nginx.service

    然后禁用默认服务器块文件,因为它不需要:

    unlink /etc/nginx/sites-enabled/default

    我们现在将为反向代理创建一个新的配置文件,例如:

    $EDITOR /etc/nginx/sites-available/ddns-api-proxy.conf

    并粘贴以下内容,确保将 IP 地址和域名替换为您自己的:

    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;
    }

    可选:如果您希望 API 可通过 IPv6 访问,请在现有的 listen 指令后添加以下行:

    listen [2001:0db8::0db9]:8080;

    启用此配置并通过重新加载 Nginx 来应用更改:

    ln -s /etc/nginx/sites-available/ddns-api-proxy.conf /etc/nginx/sites-enabled/
    systemctl reload nginx.service

    API 现在应该可以通过互联网访问,并且只接受 HTTPS 连接。要测试它,请发出命令:

    curl "https://ns1.your_domain:8080/update?secret=your_secret&domain=test2&addr=1.1.1.2"

    它应该返回以下内容:

    {"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"}

    第七步:客户端配置

    您可以在任何支持自定义动态 DNS 提供商(例如 Pfsense)的路由器上设置自动记录更新。您还可以在办公室或家庭网络中的大多数其他设备上设置它们。要更新或创建记录,应将 GET 请求发送到以下端点:

    https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=your_ip_address

    您还可以使用单个请求更新多个子域的记录。例如,要为 IP 地址为 198.51.100.100 的 sub1.ddns.your_domain 和 sub2.ddns.your_domain 创建/更新记录,您可以向此 URL 发送 GET 请求:

    addr 参数还可以保存一个 IPv6 地址来创建/更新 AAAA DNS 记录,例如:

    https://ns1.your_domain:8080/update?secret=your_secret&domain=cheese&addr=2001:0db8:aaaa::

    要在 Linux 客户端上自动执行这些更新,请将以下 bash 脚本保存为 /opt/ddns-update.sh:

    #!/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}"

    该脚本使用一个 while 循环环绕 dig 命令,该命令获取客户端公共 IP 地址并将其存储在变量中。该循环可确保正确获取公共 IP。然后,cURL 用于发送 API 请求以使用这个新获取的 IP 更新 DNS 记录。确保替换 your_secret 和 your_subdomain 的值。

    接下来,使这个脚本可执行:

    chmod +x /opt/ddns-update.sh

    然后启动 crontab 编辑器:

    crontab -e

    将以下行添加到您的 crontab 的末尾:

    */2 * * * * /opt/ddns-update.sh

    保存并退出。该脚本现在每两分钟运行一次,使您的动态 DNS 记录与客户端最新的公共 IP 地址保持同步。

    进一步阅读

    • 动态 DNS 维基百科文章
    • Github 上的 docker-ddns

©2015-2025 艾丽卡 support@alaica.com