7/08/2010

VPSでDNS

格安のVPS出現のおかげで、固定グローバルIPv4アドレスとIPv6アドレスが使えるようになったので、ついに念願のMyDNSを立てました。
でも、格安VPSのなかでも更に一番安いプランなので、メモリは256MBと非常に厳しい状況。
まあ。なんとでもなるんですけどね、1つでも固定グローバルさえ手に入れてしまえば。。。。

ということで、どこから繋いでも名前解決できるように、Dynamic DNSを利用します。

namedの起動オプション
で、借りたVPSですが論理CPUが16個と非常に多いためデフォルト状態でnamedをstartさせると、200MBぐらいメモリを確保してしまい、他のサービスに影響が出てしまうので、まずはnamedが使用するCPCの数を制限することによりメモリの節約を行います。

借りているVPSはCentOSなので、下記のファイルの最後の行にnamed起動時のOPTIONの設定を追加します。
# tail -1 /etc/sysconfig/named
OPTIONS="-n 2"

これで、50MBぐらいになりました。

TSIG鍵の生成
DNSへ登録要求してくるLinuxは、ISPに接続するたびにIPアドレスが変わってしまうので、DNS Sec用の鍵を作って、信頼関係を築いた方が良いでしょう。

# /usr/sbin/dnssec-keygen -a HMAC-MD5 -b 512 -n HOST xxxxxxx.com

こんなファイルが2つ作られます。
Kxxxxxxx.com.+xxx+xxxxx.key
Kxxxxxxx.com.+xxx+xxxxx.private

named.confの設定
master serverのnamed.confにkey項目の追加と、動的にレコードを追加したいzoneにupdateの許可を設定します。key項目のsecretには、TGIS鍵で作成した"Kxxxxxxx.com.+xxx+xxxxx.key"ファイル内のBase64風なゴチャゴチャした文字列を設定します。
下の例では、update-policyにより、www.xxxxxxx.comだけ更新を行えるように設定しています。

# cat Kxxxxxxx.com.+xxx+xxxxx.key
xxxxxxx.com. IN KEY 512 3 157 xxxxsecretxxxx

key "xxxxxxx.com" {
        algorithm hmac-md5;
        secret "xxxxsecretxxxx";
};
zone "xxxxxxx.com" in {
        file "master/xxxxxxx.com";
        type master;
        allow-transfer { localnets; };
#       allow-update {
#               key xxxxxxx.com;
#       };
        update-policy {
                grant xxxxxxx.com name www.xxxxxxx.com. A;
        };
};

slave serverも変更します。
key "xxxxxxx.com" {
        algorithm hmac-md5;
        secret "xxxxsecretxxxx";
};
zone "xxxxxxx.com" in {
        allow-transfer { localnets; };
        masters { xxx.xxx.xxx.xxx; };
        file "slave/xxxxxxx.com";
        type slave;
        allow-update-forwarding {
                key xxxxxxx.com;
        };
};

PPPoE接続されたときにUpdateする場合
Bフレッツを使用したISPへPPPoE接続する場合は、PPPインタフェースがUPした時にDNSレコードの登録を行うように設定します。下記の例はUbuntsu910を使用している場合です(SUSEでもFedoraでもCentOSでも同じになると思います)。PPPのIPCPにより得られたIPアドレスは、PPPのip-upスクリプトの第四引数に渡されますので、そのアドレスをnsupdateします。
#cat /etc/ppp/ip-up.d/nsupdate
#/bin/sh
FQDN=www.xxxxxxx.com.
KEY=/usr/local/etc/dnsseckey/Kxxxxxxx.com.+xxx+xxxxx.private
LOCALIP=$4
NSUPDATE=/tmp/nsupdate$$.conf
echo "update delete $FQDN IN A" > $NSUPDATE
echo "update add $FQDN 3600 IN A $LOCALIP" >> $NSUPDATE
echo "" >> $NSUPDATE
nsupdate -k $KEY $NSUPDATE
rm $NSUPDATE

DHCPでIPアドレスが振られたときにUpdateする場合
YahooBBなどやUsenのISPを利用している場合は、多くがDHCPでアドレスが振られますので、if-upスクリプトが実行される時にDNSレコードの登録を行うように設定します。下記の例はUbuntsu910を使用している場合です。IPv6の場合はアドレスを決定するのが微妙なので、レコード追加してません。悩みどころですね。

# cat /etc/network/if-up.d/nsupdate
#! /bin/sh

set -e
env > /tmp/env.log

# Don't bother to restart sshd when lo is configured.
if [ "$IFACE" = lo ]; then
    exit 0
fi

# Only run from ifup.
if [ "$MODE" != start ]; then
    exit 0
fi

if [ "$ADDRFAM" != inet ] && [ "$ADDRFAM" != inet6 ]; then
    exit 0
fi

FQDN=www.xxxxxxx.com.
KEY=/usr/local/etc/dnsseckey/Kxxxxxxx.com.+xxx+xxxxx.private
LOCALIP="`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"
NSUPDATE=/tmp/nsupdate$$.conf
echo "update delete $FQDN IN A" > $NSUPDATE
echo "update add $FQDN 3600 IN A $LOCALIP" >> $NSUPDATE
echo "" >> $NSUPDATE
nsupdate -k $KEY $NSUPDATE
rm $NSUPDATE

named rootのパーミッション確認
DNSサーバはupdateを受け取ると、ルートディレクトリにジャーナルファイルを作成しますので、書き込みできるパーミッションを設定してください。
#chown -R named:named /var/lib/named

DNSへの登録が行われると、下記のようなジャーナルファイルが作られます。
/var/lib/named/master/xxxxxxx.com.jnl
/var/lib/named/slave/xxxxxxx.com.jnl