1. ホーム
  2. 記事一覧
  3. 【BIND高度】chroot環境を構築する際の必要知識について解説

2023.09.29

【BIND高度】chroot環境を構築する際の必要知識について解説

こちらの記事では、BINDを使用したDNSサーバーにchroot環境を構築する方法について解説します。BINDの基礎的な概念については、以下の記事で紹介していますので必要に応じてご参照ください。

https://envader.plus/article/212

また、実際に手を動かしながら学びたいという方は、以下の記事でBINDを使用したDNSサーバーにchroot環境を構築する方法をハンズオン形式で紹介していますのでご参照ください。

https://envader.plus/article/229

本記事の解説事項

本記事では以下の項目について解説します。

  1. chroot環境の構築とは
  2. なぜchroot環境を構築するのか
  3. chroot環境の隔離
  4. BINDをchroot環境内で設定する際の明示的なファイルパス指定
  5. デバイスファイルの作成
  6. BINDが読み込むnamed.confの変更
  7. セキュリティ制限の定義の追加

1. chroot環境の構築とは

chroot(change root)環境の構築とは、特定のプログラムやプロセスが動作する際に、そのプログラムやプロセスが利用できる「ファイルシステムのルートディレクトリを変更する操作」のことを指します。この技術はUNIX系のオペレーティングシステムにおいて長い間利用されてきました。

chroot自体はBINDや特定のアプリケーションに限ったものではありません。多くのUNIXベースのプログラムやデーモンで使用され、一時的な作業環境の作成やパッケージのビルド、リカバリ作業などの多岐にわたる用途で利用されています。

2. なぜchroot環境を構築するのか

chroot環境の構築は、システム全体のセキュリティと信頼性を向上させるのに役立ちます。特に、サーバー上で動作するデーモンやサービスを隔離することで、セキュリティのリスクを低減できます。もし特定のサービスが攻撃を受けた場合でも、chroot環境の壁が攻撃者の動きを制限し、システム全体へのアクセスを難しくすることができます。

また、chroot環境はセキュリティの向上やプロセスの隔離、開発・テスト環境の分離、依存関係の管理などの様々な目的で使用されます。

しかし、chroot環境の構築は難易度が高いです。設定やセキュリティポリシーの管理が正しく行われていない場合、脆弱性を産む結果になりかねません。そのためにも正しい知識を身につける必要があります。

3. chroot環境の隔離

chroot環境を設定する際、単に領域を構築するだけでは十分ではありません。chroot環境は外部とのアクセスを制限し、環境を隔離することを目的としています。そのため、chroot環境の領域を構築後、chrootと外部を繋ぐディレクトリには正しい所有者・権限の設定が非常に重要です。

以下はchroot環境のイメージ図です。

chroot環境は、指定されたディレクトリ(図でいうとnamedディレクトリ)を新しいルートとして設定し、そのディレクトリをルートディレクトリとして扱う隔離された環境を作成します。この環境では、指定されたディレクトリがルートディレクトリであるように見えます。

また、上記図のPOINTで記載したように「chroot環境を現行のシステム環境と同じように構築する」ことでchroot環境が現実のシステム環境に近くなり、より多くのアプリケーションやサービスが正常動作するようになります。

4. BINDをchroot環境内で設定する際の明示的なファイルパス指定

上記の図で説明すると、通常のシステムのルートは/ですが、chroot環境内のBINDのルートは/namedになります。例えば、/etc/bindというファイルパスがあった場合、BINDにとっては/named/etc/bindというファイルパスで認識します。

そのため、chroot環境内のプログラムはchroot環境内のファイルパスを正しく認識するためにも、ファイルパスを明示的に指定することは非常に重要です。また、ファイルパスを指定する際のルートは指定したディレクトリであることを意識することも大切です。

以下に、明示的にファイルパスを指定する必要のあるファイルの一例を紹介します。

4-1. bind.keys

bind.keysには、一般的にはルートゾーンの公開鍵(トラステッドキーまたは信頼アンカー)が格納されています。DNSSECの検証プロセスにおいて、署名されたDNS情報を検証する際の信頼の起点として使用されます。このため、bind.keysは非常に重要なファイルです。

指定方法は以下の2通りです。

  • named.confbind.keysをincludeする

    include "/etc/keys/bind.keys";
  • named.conf.optionsなどでkey-directoryディレクティブを使用する

    options {
    	# BINDが管理する信頼アンカーを格納するディレクトリを指定
    	# 指定ディレクトリには、`bind.keys`を含む、BINDによって管理される信頼アンカーが格納される
    	key-directory "/etc/keys";
    }

4-2. named.pid

named.pidは、BINDのプロセスIDが記録されるファイルです。.pidPIDProcess ID)のことで、実行中のプロセスを一意に識別するための番号のことを指します。PIDは通常、システムがサーバーのプロセスを管理する際に使用されます。

named.pidはBINDが自動で生成するファイルです。そのため、生成するディレクトリを用意し、ファイルパスを指定する必要があります。

4-3. session.key

session.keyは、ダイナミックDNSの認証キーを保存するファイルです。ダイナミックDNSは、DNSの変更を許可する際にセキュリティキーが必要であり、そのキーがダイナミックDNSの認証キーとなります。

session.keyもBINDが自動で生成するファイルです。そのため、生成するディレクトリを用意し、ファイルパスを指定する必要があります。

5. デバイスファイルの作成

/dev/null, /dev/random, および /dev/urandom のデバイスファイルの作成は必ずしも必須ではありませんが、BINDの正常な動作のために推奨されます。

各種デバイスファイルがBINDの動作に関与する部分を以下に説明します。

/dev/null

BINDは多くのログやエラーメッセージを出力する可能性があります。特定のメッセージを無視するために、これらのメッセージを/dev/nullにリダイレクトするのが一般的です。この処理を行うことにより、不要なメッセージがシステムのログファイルに記録されるのを防ぐことができます。

/dev/randomおよび/dev/urandom

DNSの処理では。クエリや応答などの特定の操作において、安全で予測できないIDや署名が必要です。これらのランダムな値を作るために、/dev/random/dev/urandomという特別な場所からデータを取得します。

/dev/randomはランダムなデータを生成するのに時間がかかることがあります。一方、/dev/urandomはすぐにランダムなデータを提供してくれます。

6. BINDの読み込み元のnamed.confの変更

chroot環境を構築するためには、chroot環境下に定義したnamed.conf(BIND設定ファイル)を読み込む必要があります。Ubuntuのnamedに関する設定は、/lib/systemd/system/named.serviceに定義されています。この、named.serviceを変更することで読み込み元のnamed.confを変更することができます。

/lib/systemd/system/named.serviceの中身が以下になります。

$ cat /lib/systemd/system/named.service

[Unit]
Description=BIND Domain Name Server
Documentation=man:named(8)
After=network.target
Wants=nss-lookup.target
Before=nss-lookup.target

[Service]
EnvironmentFile=-/etc/default/named
ExecStart=/usr/sbin/named -f $OPTIONS
ExecReload=/usr/sbin/rndc reload
ExecStop=/usr/sbin/rndc stop
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=bind9.service

ExecStartはnamedの起動時の設定オプションで、$OPTIONSと記述されています。このOPTIONSは、EnvironmentFileで記述されている/etc/default/namedに定義されたOPTIONSを参照しています。

/etc/default/namedの中身が以下になります。

$ cat /etc/default/named

#
# run resolvconf?
RESOLVCONF=no

# startup options for the server
OPTIONS="-u bind"

このように、Ubuntuでは/etc/default/namedOPTIONSを定義し、named.serviceでそれを読み込むアプローチが採用されています。

ここまでを踏まえ、BINDの読み込み元のnamed.confの変更方法は、以下の2通りの方法があります。

  • /etc/default/namedOPTIONSを変更する(Ubuntuのアプローチに則る)

    # chroot環境下のnamed.confを使用
    OPTIONS="-u bind -t /chroot/named -c /etc/named.conf"
  • /lib/systemd/system/named.serviceを直接変更する

    ExecStart=/usr/sbin/named -f -u bind -t /chroot/named -c /etc/named.conf

named.serviceを変更した際には、新しい設定をsystemdに反映させる必要があります。反映させるためには、以下のコマンドを実行します。

$ sudo systemctl daemon-reload

7. セキュリティ制限の定義の追加

AppArmorApplication Armor)は、アプリケーションごとのアクセス制御を提供するセキュリティツールです。

BINDに関するセキュリティ制限の定義は、AppArmorのポリシー設定ファイルの一部として/etc/apparmor.d/usr.sbin.namedというプロファイルが存在します。このプロファイルに、BINDに対するアクセス制限を定義することで、BINDのセキュリティを強化することができます。

AppArmorの権限指定方法に関しては、以下の表にまとめました。

権限説明
r読み込み許可/etc/named.conf r,
w書き込み許可/var/cache/** w,
rw読み書き両方の許可/var/cache/** rw,
mメモリマップファイルの許可/usr/sbin/named m,
kファイルのロックの許可/var/lock/bind.lock k,
ix実行許可(継承)。子プロセスが親のプロファイルを継承する/usr/sbin/named ix,
Pxプロファイルの変更を許可せずに実行。子プロセスは指定されたプロファイルで実行される/usr/bin/some-binary Px,
Ux実行時にunconfinedになる。子プロセスは制限なしで実行される/usr/bin/unconfined-binary Ux,
Ccapabilityの許可。特定のカーネル機能へのアクセスを許可するcapability net_bind_service,

具体的なアクセス制限の定義の手順は以下の通りです。

7-1. プロファイルの内容の編集

以下の内容をプロファイルに追加します。(/chroot/named以下がchroot環境下とした場合)

$ sudo vim /etc/apparmor.d/usr.sbin.named

/usr/sbin/named {
    # ... 既存の内容 ...

    # chroot環境へのアクセス許可
    /chroot/named/** r,
}

7-2. AppArmorの再起動

設定を反映させるために、AppArmorを再起動します。

$ sudo systemctl restart apparmor

まとめ

こちらの記事では、BINDにおけるchroot環境を構築する際の必要知識について解説しました。BINDの設定や運用を適切に行うためには、今回紹介した中で登場したデバイスファイルの理解やセキュリティツールなどの知識が必要になります。

chroot環境は要件や用途に合わせて柔軟に設定が行えるため、必要な環境を柔軟にカスタマイズできるようになるためにも幅広い知識を身につけていきましょう。

【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

IT未経験者必見 USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。

「フリーランスエンジニア」

近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。

「成功する人とそうでない人の違いは何か?」

私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。

比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。

多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、

note記事3000いいね超えの殿堂記事 今すぐ読む

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事