えんでぃの技術ブログ

えんでぃの技術ブログ

ネットワークエンジニアの視点で、IT系のお役立ち情報を提供する技術ブログです。

SELinuxの概要

SELinux_logo

SELinuxシリーズ

本記事は、SELinuxシリーズの2記事目です。

  1. Linuxプロセスアクセス制御の概要
  2. SELinuxの概要 ←今ココ
  3. SELinux Type Enforcement
  4. SELinuxの実践
  5. (参考) SELinuxのRBAC、UBAC、MLS、MCS
  6. (参考) SELinux Module Policyのソースコード読解、ビルド
  7. 参考URL

1〜3記事目は、4記事目を理解するための前提知識をカバーしています。
4記事目が最も重要で、SELinuxの具体的な操作方法やコマンド、トラブルシューティング手順を紹介しています。

5記事目以降は参考情報です。

SELinuxの関連記事は、SELinuxタグから探せます。

一連の記事はFedora環境を前提として書いています。
FedoraRHELに類するディストリビューションであればほぼ同等の挙動になると思いますが、他のディストリビューションでは挙動に差異がある可能性があるのでご注意ください。

お伝えしたいこと

前回のアクセス制御の一般論に続き、本記事ではSELinuxの概要を紹介します。
アクセス制御ルールについては、ボリュームがあるので次の記事に回します。

本記事でカバーする主なトピックは、以下のとおりです。

SELinuxとは

SELinux (Security Enhanced Linux) とは、MAC (Mandatory Access Control) を実装するアクセス制御技術の1つです。
RHELFedoraなどいくつかのLinuxディストリビューションにおいてデフォルトで有効化されています。

アメリカのUtah大学とアメリカ国防総省が開発したFLASK (Flux Advanced Security Kernel) というセキュリティフレームワークSELinuxの原型です。
その後、FLASKのフレームワークを引き継いでNSA (National Security Agency = アメリカ国家安全保障局) が開発を進め、SELinuxというOSSとしてリリースされたという経緯があります1

MACの特徴については既に前回記事のMAC (Mandatory Access Control)にて紹介しましたが、SELinuxにもMACの特徴が当てはまります。
以降のセクションでは、MACの特徴から更に踏み込み、SELinuxのより具体的な特徴やアーキテクチャに触れていきます。

SELinuxのアクセス制御

SELinuxのアクセス制御の概要を下図に示します。
図は「SubjectがObjectに対してActionを実行する」システムにおいて、SELinuxがどのようなアクセスパターンを制御対象にしているかを表しています。2,3,4

selinux_summary

上図からもわかるように、SELinuxによるアクセス制御は以下の特徴を持ちます。

  • プロセスのアクセス制御技術である (Subject = process)
  • アクセス制御対象がファイルに限らず、多岐にわたる (Object = file, socket, process, device, database, ...)
  • 許可するアクセスの粒度が細かい (Action = read, write, execute, create, open, append, link, ...)

ファイルのみを対象として読み書き実行を中心にアクセス制御を実装するDAC (Discretionary Access Control) と比較すると、SELinuxは細かい粒度でアクセス制御します。
(※) 本記事において、DACという用語は狭義で使用しており、LinuxのFile Access PermissionsとACLのことを指しています

もちろん、SELinuxMACと同様に以下の特徴も持ちます。

  • EUID=0を持つ特権プロセスであってもアクセス制御対象とする
  • アクセス制御ルールを書き換えられるのは基本rootユーザーのみ

仮にEUID=0を持つデーモンプロセスを脆弱性などで乗っ取られたとしても、SELinuxは自身が許可しているアクセス以外を全て拒否します。
EUID=0であれば無条件にアクセスを許可するDACと比較すると、プロセスのアクセスをより厳格に管理するSELinuxは、ゼロデイ攻撃などによってシステムに侵入された後の防御策としてより強力であると言えます。

DACMACに関するより詳細な説明は、前回記事を参照してください。

SELinuxアーキテクチャ

本セクションでは、SELinuxを構成する主なコンポーネントを紹介します。

SELinuxを操作する中で、AVC (Access Vector Cache) という用語は#SELinuxの監査ログに出てきます。
本セクションの内容からは、最低限 「AVCはアクセス制御可否を返すプログラムである」と理解いただければ十分です。

OM (Object Manager) やSecurity Serverについては、用語を覚えなくても問題はありません。
ただ、AVCとやり取りするプログラムですので、これらも併せて理解することでSELinuxの動作を理解する助けになると思います。

システム構成図

以下の図は、SubjectがObjectに対してActionを実行しようとしたとき、SELinuxが許可/拒否を判断するまでの内部動作を示したものです5

component1

処理は以下の流れで進みます。

  • (1) SubjectのプロセスがSELinuxのアクセス許可を得るため、OMにアクセスする
  • (2) OMは、AVCにアクセス権限の有無を問い合わせる
  • (3)〜(4) AVCのキャッシュ上にデータがなければ、AVCからSecurity Serverに問い合わせる。Security Serverは、アクセス制御ルール定義 (Security Policy) の内容に基づいて応答を返す
  • (5) AVCからOMに応答を返す
  • (6)〜(7) 応答に応じて、OMはSubjectにActionの実行を許可または拒否する

図中のSecurity Policyは、単一のバイナリファイルです。
/etc/selinux/SELINUXTYPE/policy/policy.NNに格納されています。
このファイルの中には、アクセス制御ルールの定義情報が入っています。

Security Policyのファイルパスについて補足します。

SELINUXTYPEは/etc/selinux/configに書かれている値で、デフォルトはtargetedです6
SELINUXTYPEは、単にpolicyと呼ばれることもあります。
Security policyとは別の意味なので、ややこしいですが文脈によってどちらのことを指しているか判断する必要があります。

NNはpolicyのバージョンを表し、値が大きいほどSELinuxとして多くの機能をサポートします7
SELinuxを運用する上でこのバージョン番号を意識することはほぼありません。

例えば、Fedora35の場合は以下のファイルパスにSecurity Policyが配置されています。

file /etc/selinux/targeted/policy/policy.33
# /etc/selinux/targeted/policy/policy.33: SE Linux policy v33 8 symbols 9 ocons

(参考) より詳細なシステム構成図

The SELinux Notebook - Core SELinux Componentsにより詳細な図があるので、そちらも添付いたします。

component2

こちらの図を全て理解するのは難しいですが、わかる範囲でポイントを箇条書きにします。

  • 図の上半分がUserSpace、下半分がKernelSpaceになっている
  • UserSpaceのプロセスは、/sys/fs/selinux配下のファイルを通してKernelと連携している
  • /sysはsysfsと呼ばれる疑似ファイルシステムをメモリ上で構成し、UserSpaceからKernelにアクセスするためのインターフェースをファイルという形で提供する (man 5 sysfs)
  • OMとAVCはUserSpaceとKernelSpaceのどちらにも存在しうる。SELinuxと連携するアプリの実装次第
  • Security Serverが読み込んでいるLoaded Policyとは、/etc/selinux/SELINUXTYPE/policy/policy.NNをメモリ上に読み込んだファイルのこと。/sys/fs/selinux/policy

/sys/fs/selinux配下にどのようなファイルがあるかは、以下のリンクに説明があります。
The SELinux Notebook - Linux Security Module and SELinux - #SELinux Filesystem

SELinuxの監査ログ

SELinuxによってアクセスが拒否された場合、Auditdに連携されて監査ログ (/var/log/audit/audit.log) が出力されます8

監査ログは以下のコマンドで確認できます。

sudo ausearch -m avc,user_avc

# ----
# time->Sun Nov 21 17:29:41 2021
# type=AVC msg=audit(1637483381.836:583): avc:  denied  { read } for  pid=10602 comm="mandb" name="anki.1" dev="dm-0" ino=919333 scontext=system_u:system_r:mandb_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

このログは、SELinuxによって拒否されたアクセスの詳細を表現しています。
今回の場合はSubjectがscontext (source context)、Objectはtcontext (target context)、Actionは{ read }として表示されています。
#SELinuxのアーキテクチャで触れたAVCというキーワードは、この監査ログで登場します。

setroubleshoot-server RPMパッケージがインストールされている場合、上記監査ログの発生をトリガーとして追加のログが/var/log/messagesに出力されます。
setroubleshoot-serverは、Fedoraにはデフォルトでインストールされていました。
追加のログは、以下のコマンドで確認できます。

journalctl -qen all -t setroubleshoot --no-pager
# (一部抜粋)

# Nov 21 17:29:45 pc setroubleshoot[11309]: SELinux is preventing mandb from read access on the file /usr/local/share/man/man1/anki.1. For complete SELinux messages run: sealert -l 5fe15040-2828-45d4-9e8c-ba8ef5781937

# Nov 21 17:29:45 pc setroubleshoot[11309]: SELinux is preventing mandb from read access on the file /usr/local/share/man/man1/anki.1.
 
#   *****  Plugin restorecon (99.5 confidence) suggests   *****
#   # /sbin/restorecon -v /usr/local/share/man/man1/anki.1
  
#   *****  Plugin catchall (1.49 confidence) suggests   *****
#   # ausearch -c 'mandb' --raw | audit2allow -M my-mandb
#   # semodule -X 300 -i my-mandb.pp

上記ログは、発生したエラー内容と問題解決のためのヒント情報を含みます。
エラーメッセージから「/sbin/restorecon -v /usr/local/share/man/man1/anki.1を実行すれば直る」と読み取れます。

setroubleshootが提示する解決策は、最適な解決方法とは限りません。
あくまで「ヒント」として活用し、最終的には自分で判断することが重要です。

SELinuxのログの読み方については、後続記事のSELinuxの実践で改めて説明します。

監査ログが出ないケース

DACで拒否された場合

SELinuxのルールが評価されるより手前の段階でエラーになった場合、当然ながらSELinuxの監査ログは発生しません。

特にファイルアクセスについて言うと、SELinuxを含むMACよりもDACが先に評価されます。

したがって、File Permissionの不足が原因でアクセスに失敗した場合は、SELinuxの監査ログは出ないのでご注意ください。

dontauditルールに該当した場合

SELinuxのアクセス制御ルールで、dontaudit ruleというものがあります9
条件に該当したアクセスは、SELinuxによってアクセスを拒否されても監査ログを出力しなくなります。

dontauditルールは拒否されても問題ないアクセスパターンに対して指定するものですが、稀に拒否されてほしくない条件が含まれているかもしれません。
そういった場合には、一時的にdontauditを無効化する切り分けが有効です。
以下のコマンドで一時的に無効化できます。
この無効化状態は、SELinuxのSecurity Policy (アクセス制御のルール定義) が再読込みされるまで継続します。

sudo semodule -DB

再び有効化するには、以下のコマンドでSecurity Policyを再読込みします。

sudo semodule -B

この切り分けが有効なのは、「dontauditルールが不適切に定義されている場合」のみです。
もちろん、こういったことはレアケースで、私はこういった状況にあたったことはありません。

dontauditについては、頭の片隅に入れておく程度で良いと思います。

(参考) 何でもいいので監査ログを出力させる方法

余談ですが、sudo semodule -DBSELinuxの監査ログのサンプルを得たいときにも有効です。
以下の手順で監査ログを得られます。

  • sudo semodule -DBでdontauditを一時的に無効化する
  • journalctl -fでログ監視しながらしばらく待つ
  • 監査ログを確認できたら、sudo semodule -Bでdontauditを再度有効化する

裏を返すと、dontauditを無効化するだけで不要な監査ログが大量に出力されるということなので、何らかの詳細調査のために無効化する時は大量のログ調査する覚悟をしてください。

(参考) その他のトピック

本セクションでは、SELinuxに関して気になりそうなトピックをいくつかピックアップしてカジュアルにまとめます。

本セクションの内容はエビデンスが少なめです。
信憑性についてはそれほど高くないという前提で、気になる部分があれば拾い読みいただければと思います。

SELinuxはどの程度エラーを出すのか

SELinuxは、デフォルトで6万行以上のアクセス許可設定が定義されています。
これらのアクセス許可設定は、デフォルト構成でLinuxを使い続けている限り、必要なアクセスを全て許可するように作られています。

例えば、私はFedoraをメインPCとしてブラウジング、ネットワーク設定、KVMによる仮想マシン起動、各種ソフトウェアのインストール、プログラミングなど行っていますが、SELinuxによる拒否が発生したのは3年間で1回のみです。
その1回も、あるフリーソフトインストーラの動きに癖があったことが原因であり、SELinuxのアクセス許可ルールが足りていなかったわけではありません。

SELinuxを有効化すると色々とうまくいかなくなるのは、RHEL6ぐらいまでの話だと思います。
今はSELinuxにエラーを出させようとするほうが逆に大変です。

SELinuxは、デフォルトのまま使っても十分に運用できる品質になっています。

確かにサーバーの設定ファイルを書き換えてファイルパスやポート番号周りを変えるとエラーが発生しますが、これも正しい知識を持っていれば簡単に対処できます。

アクセス制御ルールの設計方針

SELinuxのアクセス制御ルールは以下の特徴を持ちます。

  • allowルールを追加することでアクセス許可する
  • allowルールに記載のないアクセスは拒否される
  • denyルールは存在しない
  • 既存のallowルールの削除はできない

したがって、既存のアクセス許可ルールを更に厳しくする手段は原則ありません (※)
(※) 厳密にはCustom Policyの追加によって元々アクセス制御対象外だったプロセスをアクセス制御対象に加えることができます。mls policyと呼ばれる設定を有効化することで、セキュリティをガチガチにすることも可能です。しかしいずれも特殊な要件でのみ使われる非常に難易度の高い技術なので、私達が使うことはほぼありません

このことから、アクセス拒否されたときにallowルールを中心に必要な設定を追加することSELinuxの基本的な運用となります。
デフォルトで定義されている6万行以上のアクセス制御ルールを把握する必要はありません。
アクセス拒否が発生したときに、関連するアクセス制御ルールをいくつか検索するためのコマンドを知っていれば十分です。

言い方を考えると、SELinuxはエラーが発生したときに適切な方法で修正できれば十分だと思います。
SELinuxを使うだけであれば、長い時間を割いてSELinuxの奥深くまで理解する必要はありません。

SELinux有効化のメリット

前回記事のMAC (Mandatory Access Control)にて述べたMACの特徴を再掲します。
これらの特徴はSELinuxにも当てはまり、有効化のメリットに繋がります。

  • EUID=0を持つ特権プロセスも特別扱いされない
    • アクセス制御の対象となる
    • アクセス制御ルールを変更できない (※)
  • ファイルアクセス以外も制御される
    • プロセス、ファイル、ポート番号、データベース、カーネル、...

(※) rootユーザーのみ、アクセス制御ルールの変更やSELinuxの無効化操作が可能です。root権限を持つrsyslogなどのプロセスの操作権限を得たとしても、これらの操作はできません

具体的なメリットとしては、以下が挙げられます。

  • 攻撃されたときの被害を「緩和」する10
  • プロセスを乗っ取られたとき、SELinuxの許可範囲でしか操作ができない (※)
  • 特に、未知の脆弱性を利用するゼロデイ攻撃に対して有効

特にコンテナ技術との相性が良いようです。

他にも、少々特殊な設計ではあるものの工夫によって価値を出している事例もあります。
SELinuxによって、file access permissionsでは難しかったきめ細やかな制御を可能としています。
SELinuxによってセキュリティ問題を解決し、セキュリティ観点だけでなく運用観点でもメリットを出せている事例です。

  • ssh秘密鍵sshプロセスは読めるが、人間には読めないようにできる12

SELinuxの守備範囲

SELinuxは、プロセスのアクセス制御技術です。
DACとセットで使われることが想定されています。

あるプロセスが通常動作として必要と想定されたアクセスについては、デフォルトで許可されるようルール定義されています。
仮にデータベースの管理プロセスが乗っ取られたとすると、データベースのクエリや破壊の不正実行は、SELinux観点では許可されます。
バックドアとしてLinuxユーザーと侵入用のポート番号を開くことはデータベースの想定用途に反するため、拒否されます。

世の中には様々なセキュリティ技術がありますが、SELinuxは以下を代替するものではありません。
Linuxカーネルレイヤーにおけるプロセスのアクセス制御」を実装するSELinuxとは、そもそもの役割が異なるためです。

もちろん、SELinuxがプロセスの役割範囲を超えたアクセスを制限することで、万が一システムに侵入された際のリスクを大幅に減らすことは可能です。
したがってSELinuxを有効化する意義はあるのですが、他のセキュリティも併せて実装する必要があるということです。

SELinuxの無効化は非推奨

SELinuxは、デフォルトで有効化されているOS標準のセキュリティ機能です。
そして、無効化することは非推奨とRed Hat社のマニュアルにも書いてあります13

SELinuxが有効であることによって、不正アクセスによるシステム乗っ取りの被害を「軽減」できます (侵入を防ぐことはないと思いますが)
SELinuxを無効化するのは、このメリットを失くすということです。

無効化を検討するのは、SELinuxの有効化がよほど大変な場合なときだと思います。
例えば、SELinux無効化前提の既存設計を変更するのに多大な労力やコストがかかる場合などが考えられます。

しかし、SELinuxの維持管理のシンプルさについては他セクションで既に述べたとおりです。

  • SELinuxはデフォルトで必要なアクセス許可設定が定義済み
  • ポート番号やファイルパスをデフォルトから変えない限り、ほとんどエラーは出ない
  • エラーが出た場合、そこだけを修正すれば良い

以上より、原則としてはSELinuxをデフォルトの有効状態のまま運用するのが良いと考えています。

まとめ

前回記事のMAC (Mandatory Access Control) の特徴から更に踏み込んで、SELinuxの特徴を紹介しました。

SELinuxによるアクセス制御の詳細な仕組みについては、次回記事にて扱います。

次の記事

SELinuxによるアクセス制御のコアとなるType Enforcement (TE) について詳しく説明します。
SELinuxを扱う上で最も重要な知識の理論部分をカバーします。

endy-tech.hatenablog.jp