目次
背景
時間がない人は読み飛ばして下さい
私は苦労してbind9でDNSサーバーを建てたわけですが、もちろんそれには目的がありました。動的にレコードを変更できるDNSを低コストに用意するということです。自宅のIPアドレスが動的であるため、レコードを動的に更新する作業は必須でありますし、 Let’s encrypt でワイルドカード証明書を取得する際にもドメインの所有を確認するための作業としてDNSのレコードに Let’s encrypt から渡された文字列をTXTレコードにセットする必要があります。Google Cloud DNS や Cloud flare 、Amazon Route53 などを使用してもよかったのですが、貧乏だった私は無料に拘りGCPのAlwaysFreeインスタンスにbind9でDNSサーバーを構築することとしたわけです。構築してから1年以上経つわけですが、まだギリギリ思い出せるうちにDDNS設定を書き残したいと思います。
鍵の設定
DNSレコードの更新のために鍵を使います。鍵がないと誰でも更新できてしまうので非常に危険です。IPアドレスで制限を加えることもできますが、私は現状固定IPを持っていませんし自宅のWiFiに友達が接続した場合なんかに弄ることができてしまいます。(そんなことする友達は居ませんが…) この章では鍵の設定を行っていきます。
鍵生成
dnssec-keygen と呼ばれるコマンドを使って動的更新に使う鍵の生成を行います。 鍵の生成は以下のように行います。 kusshie.comの部分は自身のドメイン名や任意の文字列を指定して下さい。
$ dnssec-keygen -a hmac-md5 -b 512 -n host kusshie.com
Kkusshie.com.+XXX+XXXXX
$ ls
Kkusshie.com.+XXX+XXXXX.key Kkusshie.com.+XXX+XXXXX.private
Xで表している部分はコマンドを実行する度に異なる数字が入ります。
named.conf.optionsの設定
以下のように追記して下さい。 kusshie.comの部分は自身のドメイン名を指定して下さい。
key "kusshie.com" {
algorithm hmac-md5;
secret "fdsfasFAsdfaSFa35Afasf3fafsdAfdsehjyhdDFGHds456hSgDadsf==";
};
algorithm
先ほどのコマンドでhamac-md5を指定しましたので、同じものを記述しています。
secret
Kkusshie.com+XXX+XXXXX.keyに記載されている文字列を指定して下さい。
こんな風になっていますので後ろ2つをくっつけてsecretへ入れて下さい。
kusshie.com. IN KEY 512 3 XXX fdsfasFAsdfaSFa35Afasf3fafsdAfdsehjy hdDFGHds456hSgDadsf==
注意) secretの部分は分かりやすいように通常より短めの超でたらめな値を書いています。
named.conf.external-zonesの設定
以下のように書き加えて下さい。 named.conf.options の key と同じ名前になるよう記述します。 この設定をいれることで、鍵を使った動的レコード操作が許可されます。
view "external" {
zone "kusshie.com" {
type master;
file "kusshie.com.wan";
allow-transfer {
# セカンダリのIPアドレス
163.44.76.202;
};
allow-notify {
# セカンダリのIPアドレス
163.44.76.202;
};
# ここから追記
allow-update {
key "kusshie.com";
};
# 追記ここまで
};
~ 省略 ~
};
ここまでは以下のサイトを参考にしました。ありがとうございました。
nsupdate:Masashi
動的更新操作
更新操作はnsupdateコマンドを使って行います。
nsupdate
$ nsupdate -k Kkusshie.com.+XXX+XXXXX.key
>
これで更新操作が可能となります。基本的には対話的に操作しますが自動化もできます。それはあとで説明します。
nsupdateの使い方
以下のように操作します。
>server XXX.XXX.XXX.XXX ←DNSサーバーのIPアドレスを指定します。(入力したらもちろんEnter)
>update add kusshie.com 300 A YYY.YYY.YYY.YYY ←addでレコード追加です 300はTTL AはAレコードという意味
>update delete kussshie.com ←レコードを消すというそのままの意味です
>send ←私の場合これがないと上記コマンドが反映されませんでした。忘れずに!
自動化
以下のようなスクリプトを作ります。 ドメイン名などは私のものなので自分のに置き換えて下さい。
nsupdate.sh
#!/bin/bash
REGISTERD_IP=`dig @自分のDNSサーバーアドレス kusshie.com +short`
LATEST_EXTERNAL_IP=`curl inet-ip.info`
DATE=`date --date "9 hours" "+%Y/%m/%d %H:%M"`
if [ ${REGISTERD_IP} = ${LATEST_EXTERNAL_IP} ]; then
echo "[ ${DATE} ] Latest executed time." > /root/bin/log.txt
exit 0
else
nsupdate -k /root/bin/Kkusshie.com.+XXX+XXXXX.key << EOS
server 自分のDNSサーバーアドレス
update delete kusshie.com
update delete vpn.kusshie.com
update delete storage.kusshie.com
update delete blog.kusshie.com
update add kusshie.com 300 A ${LATEST_EXTERNAL_IP}
update add vpn.kusshie.com 300 A ${LATEST_EXTERNAL_IP}
update add storage.kusshie.com 300 A ${LATEST_EXTERNAL_IP}
update add blog.kusshie.com 300 A ${LATEST_EXTERNAL_IP}
send
EOS
echo "[ ${DATE} ] Updated" >> /root/bin/log.txt
fi
このスクリプトを毎日まわしてIPアドレスが変わっていたら更新処理を行うようにしています。が、実際のところ半固定IPなせいでまだIPが変わったことがなく正しく機能するのかわかりません。おかしかったらTwitterのDMで教えて下さい。
ここまでは以下のサイトを参考にしました。ありがとうございました。
Dynamic DNSの基礎とnsupdateコマンド
まとめ
bind9の構築に比べればそこまで難しくなにのではと思います。メンテがだるいのでGoogleとかにDNSサーバーを変更したいのですがそれも面倒で最近放置しています。しかし、Let’s encrypt の認証に使う動的更新は機能しているのでなかなか便利です。このままでいいかなと思ったりも。ぜひ一度試してみて下さい。