こんふまにあ

インターネットサーバの構築経験を生きた証として残すブログ

¥980のVPSを2つ契約して専用DNSを構築

こんにちは。野又でございます。

「さくらのVPS」でサーバー収容拠点を選択可能に、石狩/大阪リージョン -INTERNET Watch

これを読んで専用DNS(ゾーンサーバ)立ててみたくなりました。拠点を石狩と大阪それぞれ契約すればDR対策のレベルも一つ上がります。ゾーン情報の提供だけが目的ならVPSとの相性が非常にいいと思います。

で、やってみたのでログをまとめます。

今回は さくらのVPS(CentOS 6)で構築することを前提に

  • サーバ1台目のFQDNは ns1.example.jp / VPSのIPは 192.0.2.1
  • サーバ2台目のFQDNは ns2.example.jp / VPSのIPは 198.51.100.2

という環境を仮定します。
また、このネームサーバを指定するドメインが後からどんどん増えるつもりで構築します。
 

[step 1] BINDインストール(ものぐさ対応)

1台目と2台目両方で行う。
bind-chroot で動かす場合、インストールだけではディレクトリ構成がちょっと甘いので、そのままでは動かない。必要なファイルの移動やディレクトリの作成を行う。

[root@www999xx ~]# yum -y install bind-chroot
[root@www999xx ~]# mv -f /etc/named* /var/named/chroot/etc/
[root@www999xx ~]# mv -f /var/named/{d,n,s}* /var/named/chroot/var/named/
[root@www999xx ~]# mkdir -p /var/named/chroot/var/{run/named,named/keys,log}
[root@www999xx ~]# rndc-confgen -a -c /etc/rndc.key -b 512 -k rndckey -u named -r /dev/urandom
[root@www999xx ~]# cat /etc/rndc.key > /var/named/chroot/etc/rndc.key

 

[step 2] 起動とチェック

1台目と2台目両方で行う。

[root@www999xx ~]# service named start
[root@www999xx ~]# chkconfig named on
[root@www999xx ~]# rndc status
[root@www999xx ~]# tail -100 /var/named/chroot/var/named/data/named.run
[root@www999xx ~]# tail -100 /var/log/messages

ステータスやログはデフォルトで上記の場所に出力される。
IPv6のインタフェースを持たないVPSでは以下のようなエラーが出るが、これは後でnamed.confを修正するときに解決させる。

error (network unreachable) resolving './DNSKEY/IN': 2001:500:2f::f#53

 

[step 3] ファイヤーウォール(ものぐさ対応)

1台目と2台目両方で行う。
これも最低限。SSHポート変更などは各自のセキュリティポリシに応じて要修正。

[root@www999xx ~]# iptables -A INPUT -i lo -j ACCEPT
[root@www999xx ~]# iptables -A INPUT -s 192.0.2.1/32 -j ACCEPT        #1台目のサーバIP
[root@www999xx ~]# iptables -A INPUT -s 198.51.100.2/32 -j ACCEPT     #2台目のサーバIP
[root@www999xx ~]# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
[root@www999xx ~]# iptables -A INPUT -f -j DROP
[root@www999xx ~]# iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
[root@www999xx ~]# iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
[root@www999xx ~]# iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
[root@www999xx ~]# iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset
[root@www999xx ~]# iptables -A INPUT -j DROP
[root@www999xx ~]# service iptables save
[root@www999xx ~]# service iptables start
[root@www999xx ~]# chkconfig iptables on

 

[step 4] サーバ間で同期するための準備

1台目と2台目両方で行う。
BIND にはスレーブに同期させる機能があるが、今回はそれを使わずssh+rsyncでよりセキュアに行う。言い方を変えれば、1台目も2台目もマスターとして動作させる。さすがにrootでは通信させたくないのでnamedユーザによる鍵認証で行う。

[root@www999xx ~]# mkdir -p /var/named/chroot/{home/named/.ssh,bin,usr/bin}
[root@www999xx ~]# cp ~/.bash* /var/named/chroot/home/named
[root@www999xx ~]# which --skip-alias {bash,ls,touch,mkdir,cp,mv,rm,pwd,chmod,cat,vi,rsync,ssh,ssh-keygen} | xargs -i% cp -fp % /var/named/chroot%
[root@www999xx ~]# chown -R named:named /var/named/chroot/
[root@www999xx ~]# usermod -s /bin/bash -d /var/named/chroot/home/named named
[root@www999xx ~]# passwd named
Changing password for user named.
New password: ********
Retype new password: ********
passwd: all authentication tokens updated successfully.
[root@www999xx ~]#

ここまでが、1台目と2台目共通で必要な作業となります。 


[step 5] named.external.zones を作成する

1台目で作業する。
名前解決させたいドメインを列挙するファイル。

[root@www999xx ~]# vi /var/named/chroot/etc/named.external.zones

その内容

zone "example.jp" IN {
	type master;
	file "example.jp.zone";
};

 

[step 6] example.jp.zone を作成する

1台目で作業する。
ゾーンファイルは1ドメイン毎に1ファイル作ることになる。ファイル名はドメイン.zoneにする。

[root@www999xx ~]# vi /var/named/chroot/var/named/example.jp.zone

その内容(最低限ns2の行まででOK)*1

$TTL 300
@	IN	SOA	ns1.example.jp. postmaster.example.jp. (
				2012010100	; Serial
				28800	; Refresh
				14400	; Retry
				86400	; Expire
				3600	; Negative Cache
				)
	IN	NS	ns1.example.jp. ; FQDN. for the primary
	IN	NS	ns2.example.jp. ; FQDN. for the secondary

ns1	IN	A	192.0.2.1	; IP address on the primary
ns2	IN	A	198.51.100.2	; IP address on the secondary

@	IN	A	203.0.113.3
@	IN	MX	10 mail	
@	IN	TXT	"v=spf1 +a +mx ~all"

mail	IN	A	203.0.113.3
blog	IN	CNAME	hatenablog.com.

この例では 203.0.113.3 のIPで別のサーバが稼動していて、それとは別に blog.example.jp をはてなブログProの独自ドメイン用にする、なんていうケースを想定。 


[step 7] named.conf を編集する

1台目で作業する。

[root@www999xx ~]# cp /var/named/chroot/etc/named.conf /var/named/chroot/etc/named.conf.bak
[root@www999xx ~]# vi /var/named/chroot/etc/named.conf

その内容(ここまでの流れを踏襲している場合はコピペで良い)

//
// named.conf
//

options {
	listen-on	port 53 { any; };
	listen-on-v6	port 53 { any; };
	directory		"/var/named";
	dump-file		"/var/named/data/cache_dump.db";
	statistics-file 	"/var/named/data/named_stats.txt";
	memstatistics-file	"/var/named/data/named_mem_stats.txt";
	managed-keys-directory	"/var/named/dynamic";
	bindkeys-file		"/etc/named.iscdlv.key";
	allow-query		{ any; };
	allow-query-cache	{ none; };
	dnssec-enable yes;
	dnssec-validation yes;
	dnssec-lookaside auto;
	recursion no;
	notify no;
	version "unknown";
};

logging {
	channel "queries" {
		file "data/query.log" versions 5 size 20M;
		severity info;
		print-time yes;
		print-severity yes;
		print-category yes;
	};
	channel "default" {
		file "data/named.run" versions 5 size 20M;
		severity dynamic;
		print-time yes;
		print-severity yes;
		print-category yes;
	};
	category queries {
		"queries";
	};
	category lame-servers {
		"default";
#		"null";
	};
	category default {
		"default";
	};
};

server	::1		{ bogus no; };
server	fe80::/16	{ bogus no; };
server	::ffff:0:0/96	{ bogus no; };
server	::/0		{ bogus yes; };

controls {
	inet 127.0.0.1 allow { localhost; } keys { rndckey; };
};

include "/etc/rndc.key";
include "/etc/named.root.key";
include "/etc/named.rfc1912.zones";
include "/etc/named.external.zones";

作業が終わったらリロードする

[root@www999xx ~]# service named reload

 

[step 8] 同期を取るための作業

2台目のサーバが1台目の設定を真似するようにします。
まず2台目で以下を実行

[root@www999xx ~]# su - named
[named@www999xx ~]$ ssh-keygen -b 2048 -t rsa -N "" -C "named@ns2.example.jp" -f ~/.ssh/id_rsa

Generating public/private rsa key pair.
Your identification has been saved in /var/named/chroot/home/named/.ssh/id_rsa.
Your public key has been saved in /var/named/chroot/home/named/.ssh/id_rsa.pub.
The key fingerprint is:
ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff named@ns2.example.jp
The key s randomart image is:
+--[ RSA 2048]----+
|                 |
 :
|                 |
+-----------------+

[named@www999xx ~]$ exit
[root@www999xx ~]$ scp /var/named/chroot/home/named/.ssh/id_rsa.pub root@192.0.2.1:/var/named/chroot/home/named/.ssh/authorized_keys

The authenticity of host '192.0.2.1 (192.0.2.1)' cannot be established.
RSA key fingerprint is 09:1a:2b:3c:4d:5e:6f:70:81:92:a3:b4:c5:d6:e7:f8.
Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '192.0.2.1' (RSA) to the list of known hosts.
root@192.0.2.1''s password: ********

id_rsa.pub           100%  400     0.4KB/s   00:00
[root@www999xx ~]$

1台目に戻ってきて以下を実行(これで、2台目のマシンは1台目にパスなしで入れる)

[root@www999xx ~]# chown -R named:named /var/named/chroot/
[root@www999xx ~]# chmod 755 /var/named/chroot/home/named
[root@www999xx ~]# chmod 700 /var/named/chroot/home/named/.ssh
[root@www999xx ~]# chmod 600 /var/named/chroot/home/named/.ssh/authorized_keys

こんどは2台目にログインして、1台目からnamed.confなどの設定を頂いてくるスクリプトを作成する

[root@www999xx ~]# su - named
[named@www999xx ~]# vi ~/sync.sh

その内容

#!/bin/sh
rsync -gptv -e ssh named@192.0.2.1:/var/named/chroot/var/named/* /var/named/chroot/var/named/
rsync -gptv -e ssh named@192.0.2.1:/var/named/chroot/etc/named.conf /var/named/chroot/etc/
rsync -gptv -e ssh named@192.0.2.1:/var/named/chroot/etc/named.external.zones /var/named/chroot/etc/
rndc reload

実行権限を与えて、ためしに実行してみる。

[named@www999xx ~]# chmod 755 ~/sync.sh
[named@www999xx ~]# ./sync.sh

これで同期がとれていれば、完了! 


外部からの動作チェック

Windowsクライアントから作業している場合は、コマンド プロンプトから以下の作業を試してみる。
(最近はnslookupコマンドが無いエディションがあるので要注意)

C:\>nslookup 
Default Server:  ********
Address:  ********

> server 192.0.2.1
Default Server:  www999xx.sakura.ne.jp
Address:  192.0.2.1

> ns2.example.jp
Server:  www999xx.sakura.ne.jp
Address:  192.0.2.1

Name:    ns2.example.jp
Address:  198.51.100.2

> server 198.51.100.2
Default Server:  www999xx.sakura.ne.jp
Address:  198.51.100.2

> ns1.example.jp
Server:  www999xx.sakura.ne.jp
Address:  198.51.100.2

Name:    ns2.example.jp
Address:  192.0.2.1

> exit

C:\>exit

 

この後の作業

  • レジストラでホスト作成を行ったあと、ここで作ったネームサーバを指定する。
  • さくらのVPSはIPアドレスを逆引きしたときのホスト名を変更できるため、コンパネで変更する。
  • セキュリティポリシに応じた各種変更

これでゾーンサーバの構築は終わりです。あとはログを見つつ TTL を長めに(更新予定が無ければ86400程度に)しておけばより負荷が減るかと思います。 


ゾーン更新時の運用について

  • 1台目はnamedアカウントでログインして色々編集したあと rndc reload します。
  • 2台目はnamedアカウントでログインしてsync.shをキックして同期を取ります。

ちゃんとスクリプト組めば2台目にログインする必要が無くなるのかもしれません。
また、sync.shを1台目にも作ることで、マルチマスター型のゾーンサーバとして運用できます(ns2に変更を加えてns1から同期しに行くことが出来る)。障害発生時からの回復を考えると、どちらかが必ずプライマリにならなければいけないというのは少々面倒です。

それでは、野又でした。 


*1:ところでbindzoneのシンタックスハイライトが美しすぎる。びっくりする。