DNSは広く公開するサービスであるため、その運用には細心の注意が要求される。BINDを攻撃者から守るには何をすればよいか。今回はBINDで行うべきセキュリティ対策を紹介する。(編集局)
もともとがパブリックなサービスであるDNSは、ゾーン情報を広く知らしめるための手段であり、そこへアクセスする対象も不特定多数です。一方キャッシュサービスは利用対象者を限定することができます。セキュアなサービスを提供するには、まずBINDの働きを整理し、それに応じた方策と万が一の場合の善後策を準備する必要があります。
キャッシュサーバとゾーンサーバとでは、セキュリティに対するアプローチもサービスを利用する対象も違います。サーバを物理的に、できればキャッシュサーバはNAT配下などのクローズドな環境で利用することが望ましいといえます(図1)。
ゾーンサーバでキャッシュサービスを提供しないのであれば、named.confを次のように設定し、一切の再帰問い合わせを無効にします。
options { |
ゾーンサーバのnamed.conf |
●専用ユーザーとchrootの利用
rootをはじめとするユーザー権限の奪取は、ソースコードに潜むバッファオーバーフローを突くことで行われます。ユーザーには、ソースコードそのものの脆弱性を是正することは簡単にはできません。もしバッファオーバーフロー脆弱性が報告されたら、問題のBINDのアップデートを行う以外にすべはありません。
そこで、ユーザー権限が奪取されてしまった場合を前提とした策として、最小権限のユーザーでnamedプロセスを起動することが考えられます。本連載では第1回以降、一貫してnamedプロセスの起動はnamedユーザー、namedグループを使用しており、この方法はすでに導入済みのはずです。
今回はもう一歩踏み込んで、chrootを導入します。chrootはファイルシステムのルートディレクトリの位置を変更する機能で、特定のプロセスに対して任意のディレクトリをルートディレクトリに見せかけることができます。あるディレクトリへchrootすると、そのプロセスとその子プロセスは、chrootしたディレクトリより上の階層のファイルにアクセスできなくなります(注)。もしユーザー権限が奪われてしまっても、jail(牢獄)に幽閉してしまおうというわけです(編注)。
BINDはchrootを考慮した実装がすでに行われており、named起動時のオプションの1つとして指定可能です。後は、chrootでルートディレクトリに見せかけるディレクトリを準備するだけです。では、/var/namedをjailとする場合を例に手順を見ていきましょう(注)。
まず、jailに以下のファイルを用意します。
/var/named($jail) | |||||||||||||||
├ | dev | ||||||||||||||
| | ├ | null | |||||||||||||
| | └ | random | |||||||||||||
├ | etc | ||||||||||||||
| | ├ | localtime | |||||||||||||
| | └ | named.conf | |||||||||||||
└ | var | ||||||||||||||
├ | log(注) | ||||||||||||||
├ | named | ||||||||||||||
| | ├ | named.ca | |||||||||||||
| | ├ | local.zone | |||||||||||||
| | └ | そのほかのゾーンファイル…… | |||||||||||||
└ | run | ||||||||||||||
└ | named | ||||||||||||||
└ | named.pid(起動時に作成される) | ||||||||||||||
注:すぐに必要になることはありませんが、この後紹介する「BIND 9のログで利用状況を把握する」で使用します。 |
ゾーンファイルの保存先として使用していた/var/namedは、整理しやすいようにリネームして新たな/var/namedを用意します。
# mv /var/named /var/named_org |
$jail下に移動し、必要なディレクトリを用意します。mkdir実行の際は「-p」オプションを指定し、一気に親ディレクトリとサブディレクトリを作成します(参考:親ディレクトリとサブディレクトリを同時に作成するには)。
# cd /var/named |
$jail/etc下に、named.confファイルとlocaltimeファイルを用意します。localtimeファイルは、namedプロセスが日付時間関数を使用する場合にローカルなタイムゾーンを取得し、正しい時刻を得るのに必要です。$jail/etc/named.confを用意する際は、オリジナルの/etc/named.confをリネームしておきます。
# cd /var/named/etc/ |
次に、ゾーンファイルを用意します。ここでは、以前/var/namedで使用していたものをそのまま使用します。
# cd /var/named/var/named/ |
ここで、ファイルのパーミッション/オーナー/グループを整えます。$jail下はnamedユーザー/namedグループで、/var/namedへのアクセスを限定します。
# cd /var/ |
最後に、mknodコマンドを使用して$jail/dev下にデバイスファイルを作成します。
# cd /var/named/dev/ |
namedの起動の際は、「-t」オプションで$jailを指定します。
#/usr/local/sbin/named -u named -t /var/named |
注:namedのパスはインストール状況に合わせて変更してください。 |
/etc/init.d下の起動スクリプトを使用している場合も、スクリプトを編集してnamedに「-t /var/named」の指定を行います。Red Hat Linuxは、起動スクリプトを編集しなくても、/etc/sysconfig/namedファイルに下記の行を追加するだけで構いません。
ROOTDIR="/var/named" |
jail利用時は、$jail/etc/named.conf(/var/named/etc/named.conf)がデフォルトで使用されます。しかし、起動スクリプトの多くは、named起動の条件として/etc/named.confの有無を確認するため、以下のような修正を加えます(注)。
[ -f /etc/named.conf ] || exit 0 |
/etc/init.d/named(修正前) |
[ -f /var/named/etc/named.conf ] || exit 0 |
/etc/init.d/named(修正後) |
named.confファイルの修正は特に必要ありません。-tオプションを指定することで、設定ファイル中の各ルート(/)ディレクトリは$jailに変換されます。
options { |
/var/named/etc/named.conf例 |
本稿では、named.confに「include」を用いた外部ファイルの読み込みは紹介しませんが、includeを使用する場合もファイルパスは$jailをルートディレクトリに見立てるため、外部ファイルは$jailに合わせてコピーや移動しておきます。
(省略) |
/var/named/etc/named.conf例 注:このような場合は、rndc.keyファイルを/var/named/etc/に置く必要があります。 |
設定したら、/var/log/messagesに出力されるメッセージやdigコマンドなどを利用して、正常に動作しているかどうかを確認します。treeコマンドが使えるなら、
$ tree /var/named |
を実行し、先に紹介したファイル一覧がすべて用意されているか確認しましょう。
使用しているBINDのバージョンは、外部からでも簡単に引き出すことができます。
$ dig @対象のDNSサーバ version.bind chaos txt |
バージョンが分かることで、バージョン特有の脆弱性を攻撃される可能性があるため、意図的にバージョン名を隠ぺいまたは置き換えます。
options { |
named.conf |
DoS(Denial of Service)やDDoS(Distributed Denial of Service)攻撃は、サーバそのものに及ぶ被害より、DNSとして正常なサービスを提供できなくなることに留意する必要があります。DNSサーバやネットワーク中継装置に対して、ICMP PingやAckなどの不特定で大量のパケットを送り付けるため、未然に防ぐことは困難です。
そこで、DoS/DDoS攻撃を早期に発見し、攻撃元および攻撃対象を特定して中継装置でのフィルタリングやサーバ自身でのiptablesなどを用いたパケット制限(Linuxで作るファイアウォール[パケットフィルタリング設定編])を実施します。
●blackholeの設定
DoSのように攻撃元が絞れる場合は、BIND 9でも対応可能です。named.confのoptionsステートメント中のblackholeで攻撃元のIPを指定し、一切の問い合わせ要求を無視するようにします。
options { |
named.conf |
●rndcを使った利用状況の把握
肝心なのは、現在攻撃を受けているのか、被害が出ている場合はどこから攻撃を受けているかを一刻も早く察知することです。そのためにも、普段からDNSに対する問い合わせ要求数をチェックしたりBIND 9のロギング機能を有効にするなど、日ごろの運用監視が重要になります。
運用監視については回を改めて紹介しますが、ここではrndcを使った統計情報の取得方法と、BIND 9のロギング機能を有効にする方法について説明します。
rndcの設定および使用方法については、第5回を参照してください。次にrndcの引数にstatsを指定し、/var/named/下(jailを使用している場合は$jail/var/named/下)に統計情報を出力させます。
# /usr/local/sbin/rndc stats |
/var/named/named.stats例 |
新しいデータは、ファイルの末尾に追加されます。crontabなどを利用して、必ず等間隔で統計情報を出力するようにし、異常な増加が見られないか確認するようにしましょう。
rndcの統計情報は貴重な情報ですが、数字のままで確認するのはあまり効率が良くありません。そこで、数値を基にMRTGなどのグラフ化ユーティリティで視覚的にとらえられるデータを作成するなどの工夫が必要です。これについては、今後BIND 9の運用管理の紹介で取り上げます。
●BIND 9のログで利用状況を把握する
次に、BIND 9のロギングを有効にする方法を見ていきます。これまでに紹介してきた設定では、BIND 9が出力するログはsyslogdを通して/var/log/messagesに記録されます。ところが/var/log/messagesには、BIND以外にも/etc/syslog.confの設定によってさまざまなサービスのログが出力されており、あまり可読性が良いとはいえません。また、BINDのログももう少しきめ細かいものが望まれます。そこで、named.confにloggingセクションを追加してさまざまなログを出力するようにします。
logging { |
/etc/named.conf(jailを導入している際には$jail/etc/named.conf) |
攻撃元を簡単に特定するため、問い合わせクエリーをすべて記録することもできます。ただし全クエリーが出力されるため、サーバリソースの消費に注意します。
logging { |
/etc/named.conf(jailを導入している際には$jail/etc/named.conf) |
categoryにはdefault/security/clien以外にもgeneral/configなどが指定できますが、ここでは上記にとどめ、詳細については次回以降「BIND 9の運用監視」で紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.