はじめに
SELinux (Security-Enhanced Linux) は、Linuxのセキュリティ機能を改善するために作られたシステムで、米国国家安全保障局 (NSA) が開発した無料のオープンソースソフトウェアです。 SELinuxは、Red Hat系のLinux (CentOS, RHEL, Fedora) では標準で有効化されていますが、理論的には全てのLinuxにインストールすることが可能です。 SELinuxは、Linuxカーネルモジュールのコードと拡張ファイル属性 (xattr) を使用して、許可されたユーザーとプロセスのみが機密ファイルまたはシステムリソースにアクセスできるようにします。 この仕組みによって、ゼロデイ攻撃などの一般に公開されていない脆弱性を利用したシステムへの攻撃を緩和することができます。
残念ながら、SELinuxは操作が難しいことや情報が少ないことで、多くのシステム管理者が無効化しているのが現状です。 実際、多くの入門書やチュートリアルでは、最初にSELinuxを無効化する手順が含まれています。 しかし、セキュリティの歴史を振り返ってみると、世界には多くの脅威と脆弱性があふれています。 より複雑化したソフトウェア、サードパーティライブラリの使用、増大するネットワーク接続、モバイルコードの使用、ゼロデイの存在 などです。 そして、これらはパッチ管理でパッチを適切に当てていたとしても、システムを保護できない可能性があります。 なぜパッチを当てるだけでは不十分なのか、どのようなセキュリティモデルが情報資産の保護に有効なのか、なぜデフォルトで安全側に設定されて有効化されているのか、などの問いは全てSELinuxにつながっているのです。 この本を通して、SELinuxの仕組みや使い方を説明しますので、SELinuxがすごい仕組みであることを認識してくださると幸いです。
情報資産のセキュリティ
情報セキュリティとは、価値の高い情報資産の機密性・完全性・可用性を脅威から保護することです。 情報資産を保護するには、まず資産とは何かを明確に定義するところから始まります。 セキュリティ対策費用の面から全ての資産を守ることはできません。 定量的評価では価値の高い資産から順に、定性的評価では発生可能性と影響を考慮して、優先順位を付けて守ることが重要です。 そして、組織は保護すべき全ての情報資産がどこにあるかを認識し、情報資産を保護するために分類とカテゴリ化をして、適切なセキュリティコントロールを導入します。 つまり、分類とカテゴリ化をしないで情報資産を保護することはできません。
分類は、アクセス権を分類する作業のことです。 例えば、情報資産に対して 最高機密 / 機密 / 部外秘 / 非機密 の分類でラベル付けをし、データが侵害されたときの被害の大きさを表します。 カテゴリ化は、データの使用に関するセキュリティ要件を満たすために、情報の種類をラベル付けする作業のことです。 例えば、あるデータを「個人情報」にカテゴリ化しておくと、同じレベルの職員でもプロジェクトXに従事している職員は個人情報にアクセスできる、というようなルールやセキュリティ要件を実現することができます。
この分類やカテゴリ化は、データやシステムリソースなどの情報資産だけでなく、人やプロセスなどの情報資産にアクセスするものに対してもラベル付けをすることができます。 政府や軍において人 (職員や隊員) にラベル付けした、アクセスできる機密レベルを「クリアランス」と呼びます。 また、SELinuxではプロセスにラベル付けした、アクセスできるカテゴリのレベルを「ドメイン」と呼びます。
組織は人やプロセスにラベル付けをすることで、その人やプロセスのクリアランスが決まります。 アクセス制御システムは、分類とカテゴリ化が適切に行われると、人やプロセスが情報資産にアクセスできるかを検証できるようになります。 アクセス制御システムは、人やプロセスのクリアランスとその情報を知る必要性を検証した上でアクセスを許可します。 人やプロセスへのラベル付けによって、権限の基本原則である最小権限 (Least privilege) や、知る必要性 (Need to know) を実現することができます。
また、脆弱性への対応は「エクスプロイト防御」「影響範囲特定」「インシデント対応」の3つのプロセスから成ります。 影響範囲を特定するために、脆弱性のある資産を特定する必要がありますが、構成管理をしていない場合は情報の収集に時間がかかってしまいます。 そこで、その前段であるエクスプロイト防御で、パッチを適用するまでの間にツールを使った攻撃が失敗するようにする対策が必要です。 SELinux はエクスプロイト防御の1つの対策として導入することができます。
アクセス制御
アクセス制御は、許可されたユーザとプロセスが、ファイルやシステムリソースにアクセスできるように制御する仕組みのことです。 識別とラベリングが適切にできていれば、アクセス制御を導入することができます。 アクセス制御では、「オブジェクト」と「サブジェクト」と「アクセス」という3つのキーワードが出てきます。
- オブジェクトは、情報資産やシステムリソースのことです。例えば、ファイルやメモリ、CPU、ネットワークインターフェースなどは全てオブジェクトです。
- サブジェクトは、オブジェクトにアクセスする人やプロセスなどのことです。例えば、パソコンを扱う管理者はサブジェクトですが、DBにアクセスするそのパソコンはサブジェクトになります。つまり、オブジェクトは文脈によってはサブジェクトにもなります。
- アクションは、オブジェクトに対する操作のことです。アクセスとも呼びます。
文法的には、サブジェクトは主語、オブジェクトは目的語、アクションは動詞です。 一般的なアクセス制御の概念は、次の図のようになります。
リファレンスモニタ (参照モニター) は、サブジェクトとオブジェクトの間でセキュリティを強制するコンポーネントです。 リファレンスモニタは、サブジェクトからオブジェクトへのアクセスを監視し、アクセス制御ポリシーに基づいてアクセス許可・拒否を決めます。 このアクセス制御ポリシーには、サブジェクトのラベル、オブジェクトのラベル、アクション の3つの要素から成るルールが複数定義されています。 サブジェクトやオブジェクトへのラベル付けが完了していない環境では、アクセス制御を有効活用することはできないので、分類とカテゴリ化を先に実施する必要があります。 リファレンスモニタがアクセスを拒否した場合、その結果はログに記録されます。アカウンタビリティ (説明責任) のために、許可も拒否も全てログに記録する場合もあります。
アクセス制御モデル
アクセス制御にはいくつかのモデルがありますが、ここでは SELinux に関連する3つのアクセス制御モデルについて説明します。
- DAC : 自分が所有するオブジェクトへのアクセス権を誰に与えるかをオーナーが決定するアクセス制御システムです。
- MAC : アクセス制御ポリシーの決定を中央機関が行うアクセス制御システムです。
- RBAC : 職務や認可に応じて個別にロールを設定し、情報システムへのアクセスを許可されたユーザに限定するアクセス制御システムです。
DAC
DAC (Discretionary Access Control) は、自分が所有するオブジェクトへのアクセス権を誰に与えるかをオーナーが決定するアクセス制御システムです。 Linuxのアクセス制御には、DAC が使用されています。 LinuxのDACは、サブジェクトのユーザとグループの情報を、オブジェクトのユーザとグループの情報と比較して、アクセスが許可されているかを確認します。 DACはオブジェクトの所有者がオブジェクトに対してアクセス制御するための権限を設定します。 例えば、ファイル /etc/passwd は所有者が root で、DACの権限は 644 になっている場合、その他のユーザは読み取りのみ許可されています。
~]$ ls -l /etc/passwd
-rw-r--r--. 1 root root 2004 Feb 11 12:00 /etc/passwd
LinuxのDACによるアクセス制御の問題点は、高い権限を必要とするプログラムやサービスが稼働しているとき、そのプログラムやサービスを利用して権限昇格をされる可能性がある点です。
MAC
MAC (Mandatory Access Control) は、アクセス制御ポリシーの決定を中央機関が行うアクセス制御システムです。 SELinuxを有効にした場合、Linuxのアクセス制御に MAC が追加されます。 アクセス許可を確認する順番は、LinuxのDACで権限を検証した後に、SELinuxのMACで権限を検証します。 DAC はリソースオーナーがアクセス権を設定できるのに対して、MAC はすべてのアクセス権を一か所で管理します。 中央機関が全てのアクションを必ず検証するという点が「強制 (Mandatory)」という名前の由来になっています。 アクセス制御におけるリファレンスモニターというモデルを実装したものがセキュアカーネルです。
SELinuxの特徴として、SELinuxのMACはプロセスに対してアクセス制御するための権限(セキュリティコンテキスト)を設定します。 SELinuxはセキュリティコンテキストに基づいて、アクセスの許可を決定します。 この仕組みを利用することで、たとえ root に権限昇格されても、自由にファイルシステムを操作できないようにすることができます。
例えば、SELinuxが有効な環境で以下のように、user1 から root ユーザに昇格しても /etc/passwd に書き込みできません。
~]$ id
uid=1001(user1) gid=1001(user1) groups=1001(user1),10(wheel) context=staff_u:staff_r:staff_t:s0-s0:c0.c1023
~]$ sudo su -
[sudo] password for user1: (ここでパスワードを入力する)
~]# id
uid=0(root) gid=0(root) groups=0(root) context=staff_u:staff_r:staff_t:s0-s0:c0.c1023
~]# echo "test" >> /etc/passwd
-bash: /etc/passwd: Permission denied
一方で、user2 から root ユーザに権限昇格した場合は、/etc/passwd に書き込むことができます。
~]$ id
uid=1002(user2) gid=1002(user2) groups=1002(user2),10(wheel) context=sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
~]$ sudo su -
[sudo] password for user2: (ここでパスワードを入力する)
~]# id
uid=0(root) gid=0(root) groups=0(root) context=sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
~]# echo "test" >> /etc/passwd
~]# tail -1 /etc/passwd
test
2つのユーザの違いは、ログイン時のセキュリティコンテキストにあります。 user1 は staff_u というSELinuxユーザに対応付けされているため「staff_t」ドメインで動作しています。 一方、user2 は sysadm_u というSELinuxユーザのため「sysadm_t」ドメインで動作しています。 SELinuxを使うことで、su などでユーザを切り替えても、ユーザやプロセスに割り当てられるSELinuxのセキュリティコンテキストは維持されます。 そのため、適切なドメインでプロセスを動作させれば、MACによるアクセス制御を行うことができ、ソフトウェアの脆弱性などによる権限昇格からシステムを保護することができます。
RBAC
RBAC (Role-Based Access Control) は、ユーザをロールに所属させて、ロールごとにアクセス制御を行う仕組みです。 RBACは、ロールに基づくアクセス制御とも呼ばれます。 RBACの仕組みは、Linux を含む一般的な OS で使用されています。 例えば Linux では、全てのユーザは必ず /etc/group に書かれている1つ以上のグループに所属しており、Linux の DAC は所有者、グループ、その他の3種類のサブジェクトに対してアクセスの許可を決定しています。 SELinux システムにもロールが存在します。 例えば、SELinuxユーザである sysadm_u と staff_u はどちらも sysadm_r に所属しています。 よって、どちらも sysadm_t ドメインに遷移することができます (staff_u は条件付きです)。