DNS設定 · 2 min read · Oct 02, 2025
Debian 10でDockerを使用して動的DNSサーバーをデプロイする方法

動的DNSは、ドメイン名を動的(一時的、頻繁に変化する)IPアドレスにマッピングするためのネットワークサービスです。これは、静的IPアドレスを持たないコンピュータ(SOHO(小規模オフィス/ホームオフィス)ネットワーク内のものなど)にアクセスするために使用され、NATファイアウォールの背後にあるシステムにアクセスするためにポートフォワーディングと組み合わせて使用されることがよくあります。この記事では、Debian 10システム上のDockerコンテナ内で動的DNSサーバーを完全にセットアップする方法を説明します。必要なDNSレコードの設定、Nginx HTTPSリバースプロキシの背後に管理APIを配置し、クライアント側のDNSレコードの更新を自動化することを含みます。
要件
- 単一のDebian 10サーバー、オプションでIPv6接続。 (192.0.2.2および2001:0db8::0db9は、それぞれサーバーのIPv4およびIPv6のプレースホルダーとして使用されます。)
- rootユーザーへのアクセス、またはsudo権限を持つユーザー。
- ホスト上でtcp/53およびudp/53ポートが利用可能である必要があります。
- 登録済みのドメイン名とそのネームサーバー/ゾーンファイルへのアクセス。このドメインのDNSレコードを次のセクションに示すように作成します。
- $EDITOR環境変数が設定されている必要があります。
- オプションで、自動DNSレコード更新を設定するためのLinux/Unixクライアントシステム。
DNSレコードの作成
動的DNSサーバーが機能するためには、少なくとも2つのDNSレコードを作成する必要があります。まず、ns1.your_domainのようなサブドメインを選択し、これがサーバーのIPv4アドレスを指すようにします。次に、ddns.your_domainのようなサブドメインを選択し、これがns1.your_domainに委任されます。
動的DNSサーバーは、ddns.your_domainの下のすべてのレコードを処理します。タイプAAAAの3番目のレコードはオプションです。対応するレコードは次のようになります:
ns1.your_domain A 192.0.2.2ddns.your_domain NS ns1.your_domainns1.your_domain AAAA 2001:0db8::0db9 (オプション)
これらのレコードは、ドメインレジストラのコントロールパネルで作成する必要があります。これらのレコードが正しく伝播するまでに最大24時間かかる場合がありますが、通常は数分で済みます。
インストール
rootユーザーを使用していない場合は、ほとんどのコマンドが特権を必要とするため、一時的なrootシェルを開始することをお勧めします。rootシェルを起動するには、次のいずれかのコマンドを使用します:
sudo su - rootsudo -sステップ1:依存関係の更新とインストール
最初にシステムを更新することは常に良い習慣です:
apt updateapt upgrade -yreboot再起動後、このセットアップに必要なソフトウェアパッケージをインストールします:
- 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ステップ2:Docker CEのインストール
Dockerの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"Debianのリポジトリキャッシュを更新し、dockerとその依存関係をインストールします:
apt updateapt install -y docker-ce docker-ce-cli containerd.ioインストールが完了したら、dockerサービスが有効で実行中であることを確認します:
systemctl enable --now docker.serviceステップ3:docker-ddnsのダウンロードとビルド
私たちの動的DNSサーバーは、BindをDNSサーバーとして使用し、Goで書かれた管理APIを使用するdockerコンテナによって動かされます。まず、Githubリポジトリをクローンし、次のコマンドでコンテナイメージをビルドします:
git clone https://github.com/dprandzioch/docker-ddns.gitcd docker-ddnsmake 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は現在、ローカル(つまりlocalhostから)でのみアクセス可能です。
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を使用してLet’s EncryptからSSL証明書を取得します:
certbot certonly --standalone --agree-tos -m [email protected] -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.serviceAPIは現在インターネット経由でアクセス可能で、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"}ステップ7:クライアント設定
Pfsenseなどのカスタム動的DNSプロバイダーをサポートするルーターで自動レコード更新を設定できます。また、オフィスや家庭のネットワーク内のほとんどの他のデバイスでも設定できます。レコードを更新または作成するには、次のエンドポイントにGETリクエストを送信する必要があります:
https://ns1.your_domain:8080/update?secret=your_secret&domain=your_subdomain&addr=your_ip_address1つのリクエストで複数のサブドメインのレコードを更新することもできます。例えば、sub1.ddns.your_domainとsub2.ddns.your_domainのレコードをIPアドレス198.51.100.100で作成/更新するには、次のURLにGETリクエストを送信します:
https://ns1.your_domain:8080/update?secret=your_secret&domain=sub1,sub2&addr=198.51.100.100
addrパラメータには、AAAA DNSレコードを作成/更新するためにIPv6アドレスを持たせることもできます。例えば:
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}"このスクリプトは、クライアントのパブリックIPアドレスを取得し、変数に格納するdigコマンドをラップしたwhileループを使用します。ループは、パブリックIPが正しく取得されることを保証します。その後、cURLを使用してこの新しく取得したIPでDNSレコードを更新するAPIリクエストを送信します。your_secretとyour_subdomainの値を置き換えることを忘れないでください。
次に、このスクリプトを実行可能にします:
chmod +x /opt/ddns-update.sh次に、crontabエディタを起動します:
crontab -ecrontabの最後に次の行を追加します:
*/2 * * * * /opt/ddns-update.sh保存して終了します。これで、スクリプトは2分ごとに実行され、クライアントの最新のパブリックIPアドレスで動的DNSレコードを最新の状態に保ちます。
さらなる読み物
- 動的DNS Wikipedia記事
- docker-ddns on Github
新しい投稿を受信箱で受け取る
スパムはありません。いつでも購読を解除できます。