こちらの記事では、BINDを使用したDNSサーバーにchroot環境を構築する方法について解説します。BINDの基礎的な概念については、以下の記事で紹介していますので必要に応じてご参照ください。
https://envader.plus/article/212
また、実際に手を動かしながら学びたいという方は、以下の記事でBINDを使用したDNSサーバーにchroot環境を構築する方法をハンズオン形式で紹介していますのでご参照ください。
https://envader.plus/article/229
本記事の解説事項
本記事では以下の項目について解説します。
- chroot環境の構築とは
- なぜchroot環境を構築するのか
- chroot環境の隔離
- BINDをchroot環境内で設定する際の明示的なファイルパス指定
- デバイスファイルの作成
- BINDが読み込むnamed.confの変更
- セキュリティ制限の定義の追加
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.conf
でbind.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が記録されるファイルです。.pid
はPID(Process 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/named
にOPTIONS
を定義し、named.service
でそれを読み込むアプローチが採用されています。
ここまでを踏まえ、BINDの読み込み元のnamed.conf
の変更方法は、以下の2通りの方法があります。
-
/etc/default/named
のOPTIONS
を変更する(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. セキュリティ制限の定義の追加
AppArmor(Application 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, |
C | capabilityの許可。特定のカーネル機能へのアクセスを許可する | 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を学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。
関連記事
2020.02.25
完全未経験からエンジニアを目指す爆速勉強法
USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
- キャリア・学習法
- エンジニア
2024.09.28
Trivyで実現するTerraformのセキュリティ強化 IaC脆弱性スキャンの方法
インフラのコード化による効率化が進みましたが、一方でコードに潜むセキュリティリスクも拡大しています。これらのリスクを管理するためには、適切なセキュリティスキャンを導入し、脆弱性を早期に発見することが重要です。
- サイバーセキュリティ
- インフラエンジニア
- Terraform
2023.03.27
未経験からのインフラエンジニアのロードマップ
今回は未経験の方に向けて、インフラエンジニアのロードマップについて解説します。ぜひ参考にしてください。
- インフラエンジニア
- キャリア・学習法
2023.07.28
Terraformのinput変数の基本的な定義方法 Variableとは
こちらの記事では、Terraformにおけるinput変数、Variableについて解説します。Terraformとは、IaC(Infrastructure as Code)を実現するための構成管理ツールの一つです。
- インフラエンジニア
- AWS