2014年7月13日日曜日

BIND 9.10 をソースから入れてみる

以前パッケージを使ってBINDを入れてみたが、今回セキュリティも考慮しつつ、ソースから構築してみる。
セキュリティを考慮すると、迅速に対応できるソースで扱えるとよい。と思いやってみた。

■環境
 ・CentOS 6.4(x64) on VirtualBox
 ・Bind 9.10

1.ソースの入手

  このサイトから最新のソースを入手し、展開する。
 # mkdir /tmp/bind;cd /tmp/bind
 # wget http://www.isc.org/downloads/file/bind-9-10-0b1-2/?version=tar.gz -O bind-9.10.0-P2.tar.gz
 # tar xvfz bind-9.10.0-P2.tar.gz
 # cd bind-9.10.0-P2
2.ビルド&インストールをする

 opensslのライブラリを使うため、なるべく最新のモジュールを使う。その後にビルドする。
 # ./configure --prefix=/usr --exec_prefix=/usr --localstatedir=/var --sysconfdir=/etc --enable-threads --enable-chroot

 "--enable-threads"はマルチスレッドでビルドをするオプション。
 # make
 # make install
 モジュールは、/usr/local/binと/usr/local/sbinに配置される。/usr/sbinを参照する
 仕組みもある可能性があるらしいので、リンクを貼っておくとよいらしい。
 # ln -s /usr/local/sbin/named /usr/sbin/named
 # ln -s /usr/local/sbin/named-checkconf /usr/sbin/named-checkconf
 # ln -s /usr/local/sbin/named-checkzone /usr/sbin/named-checkzone
 # ln -s /usr/local/sbin/named-checkzone /usr/sbin/named-compilezone
 configureにて、以下の設定を入れるのもありか。
 # ./configure --prefix=/usr --exec_prefix=/usr --localstatedir=/var --sysconfdir=/etc --enable-threads --enable-chroot

3.設定をする

 次にbindの設定をする。設定ファイルはnamed.conf。以下のステートメントについて説明を記載

 aclステートメント

 ネットワークの定義をする。optionsの中で、この定義を使う。
acl hayachi617net {
    192.168.0.0/24;
    127.0.0.1;
    !192.168.1.0/24;
};
 上記は、192.168.0.0/24と127.0.0.1は許可し、192.168.1.0/24は許可しない、という設定になる
またaclのデフォルトでは以下が定義されている。
any全てのアドレス
none全てのアドレスを否定
localhostDNSホストに実装された全てのネットワーク・インタフェイスに割り当てられたIPアドレス(IPv4, IPv6)
localnetsDNSホストに実装された全てのネットワーク・インタフェイスに割り当てられたネットワーク(IPv4, IPv6)
 BIND 9ではGeoIPをSupportしているらしい。面白い。でも今のところ使うことはなさそうだけど。。
includeステートメント
 外部ファイルを取り込む。
inculde "filename";

controlsステートメント
 リモートやローカルのbindを制御するツールrndcを受け付ける設定。
controls {
    inet 192.168.0.2 port 953 allow { 192.168.0/24; } keys { "rndckey"; };
};
 上記の設定は、IPは192.168.0.2、PORTは53でリスンし、192.168.0/24からのみアクセス
 を受け付け、使用する共通鍵名は"rndckey"ということを示している。この行を複数設定
 することも可能。

 rndckeyは以下のコマンドで作成してみる
# rndc-confgen -a -b 512 -k rndctest
 が待てども待てどもレスポンスがない。以前何かの時に乱数発生の処理でうまくいかないことがあった。ということで、
# rndc-confgen -a -b 512 -k rndctest -r /dev/urandom
としてみたら、さくっと返ってきた。
loggingステートメント
 loggingステートメントの文法は以下の通り。
logging {
        [ channel channel_name {
                ( file path_name | syslog syslog_facility | stderr | null );
                [ severity ( critical | error | warning | notice | info | debug | dynamic ); ]
                [ print-category ( yes | no ); ]
                [ print-severity ( yes | no ); ]
                [ print-time ( yes | no ); ]
        }; ]

        [ category category_name {
                channel_name; [ channel_name; ....]
        }; ]
};
 Channelフェーズでは、出力方法、フォーマットのオプション、重大度レベルを設定し、
 Categoryフェーズにて、どの種類のログをどのChannelに出力するか?を指定する。
 loggingステートメントが指定されていない場合は、デフォルトで以下の設定が適用される
logging {
    category default { default_syslog; default_debug; };
    category unmatched { null; };
};
 Channelフェーズの各設定値は以下の通り。
( file path_name | syslog syslog_facility | stderr | null );
fileファイルに出力する。引数には出力先を指定する。またversionsオプションを指定するとログの世代数と、1ファイルあたりのサイズを指定できる。
channel an_example_channel {
    file "example.log" versions 3 size 20m;
};
上記は、ログファイルを20MBで切り替え、3世代保持をするという設定になる。
syslogsyslogに直接出力をする設定。引数にfacilitiyを指定できる。
stderr標準エラー出力に出力する。これはデーモン起動ではなく、直接 起動時に使用する。主にデバッグ時に使用する
nullログは全て捨てる
 それ以外のChannelのオプションは以下の通り。
severity重大度レベルを指定する
print-categoryカテゴリ情報を出力するかどうか?指定する
print-severitySeverity情報を出力するかどうか?指定する
print-time時刻を出力するかどうか?指定する
 また以下の4つのChannelがデフォルトで定義されている
channel default_syslog {
    // send to syslog’s daemon facility
    syslog daemon;
    // only send priority info and higher
    severity info;
};

channel default_debug {
    // write to named.run in the working directory
    // Note: stderr is used instead of "named.run" if
    // the server is started with the ’-f’ option.
    file "named.run";
    // log at the server’s current debug level
    severity dynamic;
};
channel default_stderr {
    // writes to stderr
    stderr;
    // only send priority info and higher
    severity info;
};
channel null {
    // toss anything sent to this channel
    null;
};
 categoryフェーズで選択できるログの種類のうち、いくつかを以下に記載。
defaultデフォルトのログ
general全てのログ
securityリクエストの承認と否認のログ
update動的更新のログ

 optionsステートメント
 optionsステートメントの文法はたくさんありすぎるので、とりあえず使いそうなもの
 を中心に記録しておく。
versionバージョン情報。セキュリティを考慮し"UNKNOWN"やブランクにするなどを検討
version version_string;
hostnameDNSサーバのホスト名問い合わせ時のレスポンス値。省略された場合は、OSホスト名が返される。 負荷分散などでホスト名がバラならなときに使ったりする。
directorynamed.confの中で相対パスが指定されいた場合の、起点になるディレクトリのパス情報。 基本はフルパスで記載する。/var/namedが一般的らしい。
directory path_name;
pid-filenamedのpidファイルの場所。デフォルトは/var/run/named.pid
pid-file filename;
listen-on portDNSサービスをリスンするIPおよびポートの指定。特に複数 のネットワークインタフェイスが実装されたホストや、IPエリアスでネットワークインタ フェイスに複数のIPアドレスが割り当てられているホストで、DNSサービスを特定のアドレス に限定したい場合に設定する。省略した場合、namedはホストに割り当てられたすべてのアドレス をリッスンする。
listen-on [ port ip_port ] { address_match_list; };
recursion再帰的クエリーに関する設定。yesの場合、自分がマスターでないゾーンについて リクエストを受けた場合、該当ゾーンのSOAである他のDNSサーバーに問い合わせて回答する。noの場合は、 自分がSOAのゾーンについてのみ回答する。あるいはキャッシュにあれば回答する(らしい)。キャッシュになく 自身のゾーンでない場合は、次に問い合わせすべきネームサーバーを返す。
内部LANのDNSサーバーの場合は、内部サーバーからのリクエストのみ再帰的クエリーを許可する場合は、 allow-recursionをセットで使う。
allow-recursion再帰的クエリーを許可するネットワークの指定。
allow-recursion { localnets; };
forwardforwardersとセットで使う。firstを指定した場合は、まず最初にforwardersのリストの 宛先にクエリを投げ、解決しない場合は自身で探す。onlyはforwardersのリストに転送するのみ。
forward ( only | first );
forwarders問い合わせを転送する先のネットワークを指定。デフォルトは空で、 クエリの転送はされない。またこの指定は、ゾーンの設定にて上書き可能。
forwarders { ip_addr; [ ip_addr; ... ] };

 viewsステートメント

 イントラ向けとインターネット向けに返送するゾーンを分ける際に使う。viewsステートメントの文法は以下の通り。
view view_name
    [class] {
    match-clients { address_match_list };
    match-destinations { address_match_list };
    match-recursive-only yes_or_no ;
    [ view_option; ...]
    [ zone_statement; ...]
};
match-clientsソースIPの条件を記載。指定がなければany
match-destinations宛先IPの条件を記載。指定がなければany
match-recursive-only上記条件に合致するクライアントからのリクエストを再帰的クエリーのみ処理するオプション
view_optionoptionステートメントのものが記載できる
zone_statementzoneステートメントのものが記載できる

 zoneステートメント

 zoneステートメントの文法はたくさんありすぎるので、とりあえずサンプルをベース記載しておく。
 ・キャッシュサーバーの設定。再帰的クエリーを許可する場合に設定。
zone "." {
    type hint;               (*1)
    file "named.ca";         (*2)
    allow-update { none; };  (*3)
};
(*1)キャッシュサーバーとしての設定
(*2)named.caはルートヒントの情報が入ったファイル。named.ca は
ftp://ftp.rs.internic.net/domain/named.root
から入手できる。
(*3) namedが起動した際にルートサーバーから自動更新できるが、セキュリティ上無効化したほうがよいらしい。
※実際に設定すると、「option 'allow-update' is not allowed in 'hint' zone '.'」というエラーが出てしまう。  あまり詳細な情報が見つからなかったが、無効化したら、起動できた。バージョン差異なのか。。とりあえず、進める。
 ・hayachi.jpドメインに対する正引き用の設定
zone "hayachi.jp" IN {
        type master;
        file "zones_master_forward/hayachi.jp.zone";
};
 マスターゾーンサーバーとしての設定になる。hayachi.jp.zoneの中身は以下の通り
   hayachi.jp.zone
$ORIGIN hayach.jp.                    (*1)
$TTL 3600       ; 1 hour              (*2)
@   IN SOA  ns1.hayachi.jp. postmaster.hayachi.jp. (    (*3)
        2009082401 ; serial                             (*4)
        3600       ; refresh (1 hour)                   (*5)
        1200       ; retry (20 min.)                    (*6)
        1209600    ; expire (2 weeks)                   (*7)
        900        ; minimum (15 min.)                  (*8)
        )
@       IN  NS      ns1.hayachi.jp.                     (*9)
@       IN  NS      ns2.hayachi.jp. 
@       IN  MX      10  mail.hayachi.jp.                (*10)
@       IN  TXT     "v=spf1 mx ~all"    ; SPF record    (*11)

ns1     IN  A       124.34.146.121                      (*12)
ns2     IN  A       124.34.146.122
mail    IN  A       124.34.146.123
srv1    IN  A       124.34.146.124
www     IN  CNAME   srv1                                (*13)
(*1)$ORINGディレクティブ。SOAレコード、Aレコード、PTRレコード等の定義で最後に「.」が つかない場合に、付加される文字列を定義。また「@」で置き換えすることができる。 一つのゾーンファイルの中で複数回使用できる。
(*2)該当ゾーンの各レコードの寿命(秒単位)。$ORIGINでゾーンの定義をした直後に必ず$TTLを 指定する必要がある。DHCPなどでDynamicDNS環境にする場合は5分などにすることもあるらしい。
(*3)SOAレコードの記載。「@」は$ORIGINディレクティブで設定されたゾーン名を表している。$ORIGINが ない場合は、named.confで設定されたゾーン名が採用される。
この行の書式は
@ IN SOA <MNAME> <RNAME> (
となる。
MNAMEにはこのゾーンのプライマリのDNSサーバーをFQDNで指定(IPはダメ)。末尾に「.」が必須 であり、Aレコードで定義されている必要がある(CNAMEはダメ)。
RNAMEは、このゾーンの管理者のメールアドレスで、「@」を「.」にに置き換えたもの。末尾に「.」 が必須(ないと、$ORIGINの定義が付加される)
(*4)SERIALは1から始まる連番。運用面でYYYYMMDDnn(nnは連番)で見立てて設定することを推奨しているらしい。 ただし、DynamicDNSの環境では、この体系は無視されて1ずつ追加される。
(*5)REFRESHは、スレーブネームサーバーがSERIALが増えたかどうかをチェックするインターバル秒。
(*6)RETRYは、ポーリングが失敗した時の再試行までの時間(秒)。原則はREFRESHの整数分の1の値。
(*7)EXIREは、マスターサーバーがダウンした場合、ここで指定された時間の間はゾーン情報が有効なものとして扱うが、 過ぎると、無効として廃棄する。RFC1912は、2~4週間(1209600~2419200)を推奨しているらしい。
(*8)各リソースレコード(A, MX, TXT etc.)のデフォルトのTTL(秒)
(*9)NSレコード。ドメインのDNSサーバーを指定。
(*10)MXレコード。ドメインのメールサーバーを指定。
(*11)TXTレコード。この例はSPFレコード。以下SPFレコードのルール(簡易)。
v=spf1 [+送出MTAリスト] [送出MTAリスト以外から送出された場合の判定all]

[+送出MTAリスト]
  MXを指定           "+mx"
  IPアドレスを指定   "+ip4:x.x.x.x"
  ネットワークを指定 "+ip4:x.x.x.x/x"
  ※複数のMTAを指定する際には、半角スペースでつなぐ。

[送出MTAリスト以外から送出された場合の判定all]
  創出MTAリスト以外から送られた場合の判定
   Fail     "-all"  
   SoftFail "~all"
   Neutral  "?all"
  詳細は、ここを参照。
(*12)Aレコード
(*13)CNAMEレコード
 ・192.168.0.0/24アドレスの逆引き用の設定
zone "0.168.192.in-addr.arpa" {
        type master;
        file "zones_master_rev/rev_192.168.0.0_24.zone";
};
   rev_192.168.0.0_24.zone
$ORIGIN 0.168.192.in-addr.arpa.
$TTL 3600       ; 1 hour
@ IN SOA  ns1.hayachi.jp. postmaster.hayachi.jp. (
        2009082401 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
        IN  NS      dns1.hayachi.jp.                 (*1)
        IN  NS      dns2.hayachi.jp.                 (*1)
50      IN  PTR     dns1.hayachi.jp.                 (*2)
51      IN  PTR     dns2.hayachi.jp.

(*1)逆引きを管理するDNSサーバー
(*2)PTRレコード。この例の場合、192.168.0.5はdns1.hayachi.jpであることを示す
 ・192.168.0.0/16アドレスの逆引き用の設定
zone "168.192.in-addr.arpa" { (*1)
        type master;
        file "zones_master_rev/rev_192.168.0.0_16.zone";
};
   rev_192.168.0.0_16.zone
$ORIGIN 168.192.in-addr.arpa.
$TTL 3600       ; 1 hour
@ IN SOA  ns1.hayachi.jp. postmaster.hayachi.jp. (
        2009082401 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
        IN  NS      ns1.hayachi.jp.
        IN  NS      ns2.hayachi.jp.
50.0    IN  PTR     ns1.hayachi.jp.                 (*1)
50.1    IN  PTR     ns2.hayachi.jp.

(*1)末尾8ビット分を記載する(逆順に)
 ・192.168.0.0/28アドレスの逆引き用の設定
    管理は4ビット単位になっているのでちょっと工夫が必要になるらしい。例えば、
  192.168.0.0/24を4つに分けて管理をする場合を考える。
zone "0.168.192.in-addr.arpa" { (*1)
        type master;
        file "zones_master_rev/rev_192.168.0.zone";
};
   rev_192.168.0.zone
$ORIGIN 168.192.in-addr.arpa.
$TTL 3600       ; 1 hour
@ IN SOA  ns1.hayachi.jp. postmaster.hayachi.jp. (
        2009082401 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
        IN  NS      ns1.hayachi.jp.
        IN  NS      ns2.hayachi.jp.
;
; 192.168.0.0/26用
;
0-26  IN NS     ns1.hayachi1.jp.
      IN NS     ns2.hayachi1.jp.
1     IN CNAME  1.0-26.0.168.192.in-addr.arpa.
2     IN CNAME  2.0-26.0.168.192.in-addr.arpa.
3     IN CNAME  3.0-26.0.168.192.in-addr.arpa.    (*1)
...
63    IN CNAME  63.0-26.0.168.192.in-addr.arpa.
;
; 192.168.0.64/26用
;
64-26 IN NS     ns1.hayachi2.jp.
      IN NS     ns2.hayachi2.jp.
65    IN CNAME  65.64-26.0.168.192.in-addr.arpa.
66    IN CNAME  66.64-26.0.168.192.in-addr.arpa.
67    IN CNAME  67.64-26.0.168.192.in-addr.arpa.
...
127   IN CNAME  127.64-26.0.168.192.in-addr.arpa.
;
; 192.168.0.128/26用
;
128-26 IN NS     ns1.hayachi3.jp.
       IN NS     ns2.hayachi3.jp.
129    IN CNAME  129.128-26.0.168.192.in-addr.arpa.
130    IN CNAME  130.128-26.0.168.192.in-addr.arpa.
131    IN CNAME  131.128-26.0.168.192.in-addr.arpa.
...
191    IN CNAME  191.128-26.0.168.192.in-addr.arpa.
;
; 192.168.0.192/26用
;
192-26 IN NS     ns1.hayachi4.jp.
       IN NS     ns2.hayachi4.jp.
193    IN CNAME  193.192-26.0.168.192.in-addr.arpa.
194    IN CNAME  194.192-26.0.168.192.in-addr.arpa.
195    IN CNAME  195.192-26.0.168.192.in-addr.arpa.
...
255    IN CNAME  255.192-26.0.168.192.in-addr.arpa.
   rev_192.168.0.0-64.zone
$ORIGIN 0-64.0.168.192.in-addr.arpa.
$TTL 3600       ; 1 hour
@ IN SOA  ns1.hayachi1.jp. postmaster.hayachi1.jp. (
        2009082401 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
        IN  NS      ns1.hayachi1.jp.
        IN  NS      ns2.hayachi1.jp.

3      IN  PTR     ns1.hayachi1.jp.      (*2)
4      IN  PTR     ns2.hayachi1.jp.
5      IN  PTR     svr1.hayachi1.jp.
 例えば、192.168.0.3の逆引きをすると、「rev_192.168.0.zone」の中にある(*1)がヒットする。
  該当レコードは3.0-26.0.168.192.in-addr.arpaのCNAMEレコードとなっているので、
  0-26.0.168.192.in-addr.arpaに問い合わせが行われる。そこで、rev_192.168.0.0-64.zoneの
 中の(*2)がヒットし、ns1.hayachi1.jpが返ってくる。ということらしい。
 上記を踏まえた、named.conの設定例を以下にUPしてみた。
   named.conf
acl "net-client" {
       192.168.0.0/24;
};

controls {
    inet 127.0.0.1 port 953
        allow { 127.0.0.1; } keys { "rndc-key"; };
};
include "/etc/rndc.key";

logging {

    channel queries-log {
        file "/var/named/queries.log" versions 4 size 10m;
        severity info;
        print-category yes;
        print-severity yes;
        print-time yes;
    };

    channel "default syslog" {
        syslog daemon;
        severity info;
    };

    channel "default debug" {
        file "named.run";
        severity dynamic;
    };

    channel "null" {
        null;
    };

    category edns-disabled { null; };
    category lame-servers { null; };
    category resolver { null; };
    category queries { queries-log; };
    category security { "default syslog"; };
    category general { "default syslog"; };
    category default { "default syslog"; };
};

options { 
    version "unknown";
    hostname "hayachi617.jp";
    directory "/var/named/"; 
    statistics-file "/var/named/data/named stats.txt"; 
    pid-file "/var/run/named/named.pid";
      
    listen-on port 53 {
        127.0.0.1;
        192.168.0.50;
    };

    allow-query { localnets; net-client; };
    recursion yes;
    allow-recursion { localnets; net-client; };
    forward only;
    forwarders { 192.168.0.1; };
};

view internal {
    match-clients { localnets; net-client; };  
    match-recursive-only no;
    include "zones/myzones.zones";
};

   zones/myzones.zones
zone "." IN {
    type hint;
    file "named.ca";
};
zone "hayachi617.jp" IN {
        type master;
        file "zones_master_forward/hayachi617.jp.zone";
};
zone "0.168.192.in-addr.arpa" {
        type master;
        file "zones_master_rev/rev_192.168.0.zone";
};
   zones_master_forward/hayachi617.jp.zone
$ORIGIN hayach617.jp.
$TTL 3600       ; 1 hour
@ IN SOA  dns1.hayachi617.jp. postmaster.hayachi617.jp. (
        2009082401 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
@       IN  NS      dns1.hayachi617.jp.

dns1    IN  A       192.168.0.50
srv1    IN  A       192.168.0.51
www     IN  CNAME   srv1
   zones_master_rev/rev_192.168.0.zone
$ORIGIN 0.168.192.in-addr.arpa.
$TTL 3600       ; 1 hour
@ IN SOA  dns1.hayachi617.jp. postmaster.hayachi617.jp. (
        2009082401 ; serial
        3600       ; refresh (1 hour)
        1200       ; retry (20 min.)
        1209600    ; expire (2 weeks)
        900        ; minimum (15 min.)
        )
        IN  NS      dns1.hayachi617.jp.
50      IN  PTR     dns1.hayachi617.jp.
51      IN  PTR     svr1.hayachi617.jp.
 上記を設定して、namedサービスを起動してみたが、動かない。。
 # named-checkconf -z /etc/named.conf
 zone hayachi617.jp/IN: loaded serial 2009082401
 zone 0.168.192.in-addr.arpa/IN: loaded serial 2009082401

 # echo $?
 1

 # /usr/sbin/named-checkzone hayachi617.jp /var/named/zones_master_forward/hayachi617.jp.zone
 zone hayachi617.jp/IN: loaded serial 2009082401
 OK

 # /usr/sbin/named-checkzone 0.168.192.in-addr.arpa /var/named/zones_master_rev/rev_192.168.0.zone
 zone 0.168.192.in-addr.arpa/IN: loaded serial 2009082401
 OK
 となる。named-checkzoneはOKだけど、named-checkconfがエラーになる。でも
 エラーメッセージも出ず、何がエラーなのかわからない。で、straceで見てみたら、、
 # strace named-checkconf -z /etc/named.conf
 <中略> 
 open("named.ca", O_RDONLY)              = -1 ENOENT (No such file or directory)
 <中略> 
 とでた。あっ。。
 # wget ftp://ftp.rs.internic.net/domain/named.root -o /var/named/named.ca
 # mv named.root /var/named/named.ca
 # named-checkconf -z /etc/named.conf
 zone hayachi617.jp/IN: loaded serial 2009082401
 zone 0.168.192.in-addr.arpa/IN: loaded serial 2009082401

 # echo $?
 0
 うーん、、凡ミス。

0 件のコメント:

コメントを投稿