SELinuxシリーズ
本記事は、SELinuxシリーズの1記事目です。
- Linuxプロセスアクセス制御の概要 ←今ココ
- SELinuxの概要
- SELinux Type Enforcement
- SELinuxの実践
- (参考) SELinuxのRBAC、UBAC、MLS、MCS
- (参考) SELinux Module Policyのソースコード読解、ビルド
- 参考URL
1〜3記事目は、4記事目を理解するための前提知識をカバーしています。
4記事目が最も重要で、SELinuxの具体的な操作方法やコマンド、トラブルシューティング手順を紹介しています。
5記事目以降は参考情報です。
SELinuxの関連記事は、SELinuxタグから探せます。
一連の記事はFedora環境を前提として書いています。
FedoraやRHELに類するディストリビューションであればほぼ同等の挙動になると思いますが、他のディストリビューションでは挙動に差異がある可能性があるのでご注意ください。
お伝えしたいこと
本記事では、SELinuxの位置づけを明確にするために、Linuxプロセスのアクセス制御技術を分類します。
SELinux自体の具体的な特徴は次の記事に譲りますが、SELinuxの上位概念であるMAC (Mandatory Access Control) の特徴はSELinuxにも当てはまるので、これを理解しておくことはSELinuxを理解する上で重要です。
本記事では、以下のようなトピックを扱います。
Linuxプロセスのアクセス概要
SELinuxはプロセスのアクセス制御を実装するセキュリティ技術の一つです。
Linuxのディストリビューションではありません (お約束)。
SELinuxの役割を具体的にイメージするために、本セクションではプロセスが何に対してどうアクセスしているかを図解します。
プロセスは実行ファイルの実行などによって生成し、様々なリソースに対してアクセス、操作します。
例えばユーザーによるCLI操作は、シェル (Process) を介して実行ファイル (File) を実行 (execute) し、別のプロセス (Process) を起動することで様々な処理を実行します。
別の例として、Linuxのブート時にはsystemd (Process) が起動し、systemdが様々なプロセス (Process) を起動します。
各種デーモンプロセス (Process) は設定ファイル (File) を読み込み (read)、アーキテクチャによっては子プロセスを複数起動し (fork)、特定のポート番号 (Network Socket) で通信を待ち受けます (listen)。
このように、プロセスは様々なリソースにアクセスして処理を実行します。
そして、プロセスからリソースへのアクセスを細かく制御するのがSELinuxという機能です。
例えば、あるプロセスに「File Aを開いて (open) 追記する (append) はできるが、他の書き込み (write) は許可しない」といった制御が可能です。
制御対象となるアクセス先はFileだけでなく、Process (IPC: Inter-Process Communication), Network Socket (ネットワーク通信), Database, Filesystem, Device, Kernel, ...など多岐に渡ります。
Linuxプロセスのアクセス制御
アクセス制御の分類
Linuxのアクセス制御技術は、DACとMACに大別されます。
MACのことをnon-discretionary access controlと呼ぶことも稀にあります1。
- DAC (Discretionary Access Control): File access permissionsとPOSIX ACLのこと
- MAC (Mandatory Access Control): SELinuxのこと
DACとMACは、いずれもSubjectがObjectに対して何のActionを実行できるかを制御します。
Subjectとは、アクションを実行するもののことです。
Objectとは、Subjectによって何か操作をされる対象のことです。
そしてActionとは、SubjectがObjectに対して実行する操作のことです。
Subjectとは、具体的にはLinuxのプロセスを指します。
Object, Actionが何を指すかは、アクセス制御の種類によって異なります。
詳細は後続のセクションで、DACとMACの意味や特徴も含めつつ説明します。
DACとMACは両方使われる
DACとMACはどちらか片方が動作するというものではありません。
Linuxにおいてプロセスがファイルアクセスをする際、DAC→MACの順に処理されます2。
アクセス先がファイルではない場合、DACは関係ないのでMACのみ処理されます。
1と2のどちらか片方がNGであれば、多くのプログラムではPermission Deniedエラーになります。
詳しくは次のセクションで触れますが、DACはFile access permissions、MACはSELinuxと読み替えてほぼ差し支えありません。
最後に補足ですが、DAC→MACという処理順序を理解しておくことは実務上でも重要です。
SELinuxでエラーが発生したときは監査ログ (/var/log/audit/audit.log
) が発生します。
しかし、仮にSELinuxでアクセス許可されていなくても、先にFile access permissionsで拒否されていた場合には監査ログが発生しません。
アクセス拒否の原因を正確に切り分けるためにも、DACの後にMACという処理順序を理解しておくことが重要です。
DAC (Discretionary Access Control)
DACはMACと同様、Linuxプロセスのアクセス制御の一種です。
広義のDACは、以下の全て、または一部が可能であるという特徴を持つアクセス制御を指します3。
広義の場合、LinuxやWindowsのファイルアクセス制御に限定されない語義となっています。
- 他のSubjectやObjectに対するデータの受け渡し
- 他のSubjectに対する権限の付与 (例: chmod)
※Discretionary = (非rootユーザーであっても) 裁量を持つ - セキュリティ属性の変更 (例: setuid, setgid)
- 新規作成されたObjectのセキュリティ属性の指定 (例: umask)
- アクセス制御のルールの変更
しかし実際には、SELinuxの文脈においては狭義のDACで解説されることがほとんどです。
したがって、本ブログにおいても狭義のDACに基づいてこの後の解説を続けます。
狭義のDACは、Linuxにおけるプロセスからファイルへのアクセス制御技術を指します4。
DACは、UID (User ID), GID (Group ID) に基づいてLinuxプロセスのファイルアクセスを制御します。
より具体的には、狭義のDACはFile access permissionsとPOSIX ACLという2つの機能を指します。
「SubjectがObjectに対して何のActionを実行できるか」という観点で整理すると、Subject、Object、Actionは以下が該当します。
- Subject = プロセス
- Object = ファイル
- Action = read, write, execute, setuid, setgid, deletion (sticky bit)
File access permissionsは、皆さん馴染みがあると思います。
File access permissionsはPOSIXの言い回しですが5、他にもLinux permissionsやUnix permissions、File permissionsなどと呼ばれることもあります。
プロセスを実行したユーザー/グループのID (EUID: Effective UID, EGID: Effective GID) とファイルのオーナー (UID/GID) を突き合わせてUser/Group/Othersを判定し、file mode bits (※) に基づいてアクセス制御する機能です。
(※) 644
やrwxrw-rw-
など、権限を表現するビット列
関連するコマンドとしては、以下が挙げられます。
コマンド | 意味 |
---|---|
ls -l | ファイルのUID/GID, File mode bits の確認 |
ps -ef | プロセスのEUID、PID、コマンドなどを表示 (※) |
chmod | File mode bitsの変更。 root、またはオーナーユーザーが実行可 |
chown | ファイルのUID/GIDの変更。 rootが実行可 |
(※) ps
については、ps -eo user,group,pid,ppid,command
のように列を指定することで、Groupも含めて確認できます。詳細はman ps
を参照してください
EUID/EGIDという用語は聞き慣れないかもしれませんが、要するにプロセスを実行したユーザーのUID/GIDです。
例外として、setuid/setgid属性が付与されたファイルを実行したり、rootユーザーの特権を行使することでEUID/EGIDが変わることもあります。
ちなみに、プロセスは他にも2種類のIDを持ちます (SUID/SGID, RUID/RGID)。
このあたりの仕組みに興味のある方は、以下の参考URLもご覧ください。
- Processが持つ3種類のUID/GIDの話 → Wikipedia - User identifier
- setuid, setgidの話 → Red Hat - Enable Sysadmin - Linux permissions: SUID, SGID, and sticky bit
File Permissionsは、「ログインユーザーとファイルのUID/GIDを比較する」と説明されることもありますが、これは実は正確ではありません。
ログインユーザーが実行したプロセスは、「結果的に」上記の説明でも矛盾はありません。
しかし、実際にはLinux起動時にrootユーザー名義 (EUID=0) で実行されるデーモンプロセスなどもあり、これらのプロセスがファイルにアクセスする際もFile Permissionsによって評価されます。
EUIDという言葉を知っていると、デーモンプロセスによるアクセスも本質的にはユーザープロセスと変わらず制御されることを理解できます。
また、ここでEUID/EGIDという小難しい用語に触れたのにはもう一つ理由があります。
それは、DACが「プロセスの」アクセス制御であることを強調するためです。
DACもMACも「プロセスから各種リソースへのアクセス制御」という点では同じカテゴリに属する技術です。
その観点でDACとMACを対比して考えるとSELinuxの必要性について理解が深まるので、ここで改めて意識いただけますと幸いです。
少し話が飛躍しますが、「DACだけではセキュリティに穴があるので、MACによって補完しよう」というのがSELinuxを含むMACの基本的な考え方です。
POSIX ACLは、File access permissionの高機能版です。
Linuxの文脈では単にACL (Access Control List) と呼ばれることが多いです。
User/Group/Othersに関わらず、特定のユーザーやグループ1つに対して権限を割り当てることができます。
setfacl
で設定を変更し、getfacl
で設定を確認します。
プロセスとファイルのUID/GIDを対比し、file mode bitsによってアクセス制御するという基本動作は、File access permissionsと同様です。
最後に、冒頭の広義のDACの定義も参考にしつつ、File access permissionsとPOSIX ACLに共通するDACの特徴をまとめます。
次のセクションでDACとMACの特徴を対比することで、MAC (つまりSELinux) の必要性を理解するための布石です。
- ファイルのオーナーユーザーは、一般ユーザーであっても他ユーザーに対して
chmod
やsetfacl
で任意の権限を与えることができる (Discretion、つまり裁量を持っている) - アクセス制御の粒度は読み書き実行 + Sticky bitによる削除の制御
- ファイルに対するアクセス制御のみ
- UID/GIDを利用する
- rootのEUID (EUID=0) を持っていればアクセス制御の対象にならず、何でもできる
MAC (Mandatory Access Control)
SELinuxはMAC (Mandatory Access Control) を実装する技術の一つです。
したがって、本セクションで触れる内容は全てSELinuxについても当てはまります。
MACはDACと同様にLinuxプロセスから各種リソースへのアクセスを制御します。
MACは、DACでは許可されている以下の挙動を制限することが特徴です。
これにより、MACはDACと比較してより高いセキュリティを提供します。6,7
- 他のSubjectやObjectに対するファイルデータの受け渡し
- 他のSubjectに対する権限の付与
- セキュリティ属性の変更
- 新規作成されたObjectのセキュリティ属性の指定
- アクセス制御のルールの変更
MACにおいては特権を持たないリソースオーナーの裁量 (Discretion) によって、chmod
のような仕組みで権限を譲渡することはできません。
Kernel Spaceにアクセス制御ルールの定義情報を持ち、EUID=0を持つプロセスであっても例外なく強制的に (Mandatorily) アクセス制御ルールが適用されます。
具体例として、EUID=0を持つデーモンプロセスがゼロデイ攻撃によって脆弱性を付かれ、操作権限を奪われたとします。
DACの場合、EUID=0を持つ限りは権限を絞る手立てはありません。
最悪の場合はroot権限のshellを起動され、任意の操作を実行されます。
例えば、データ取得、バックドアの設置、他のシステムに侵入するための踏み台として利用するなどが考えられます。
一方でMACが実装されていれば、EUIDに関わらず、MACが付与したプロセスを識別するメタデータに基づいてアクセス制御されます(※)。
(※) SELinuxの場合は、Security Contextと呼ばれる識別子をプロセスやファイル、ポート番号などに付与します。そして識別子に基づいてアクセス制御します。プロセスが持つEUIDは、SELinuxにおいては意味を持ちません
例えば、侵入されたプロセスがrsyslogdだとすると、実施できる操作がrsyslogサーバーとして必要なアクセスの範囲に限定されます。
MACは侵入を検知したり防いだりすることはできませんが、侵入後の被害を限定することができます。
MACを実装しているセキュリティ技術は、SELinux以外にも存在します。
以下のMAC実装技術のうち、複数を同じLinux上で同時起動することはできません。
したがって、SELinuxのみを使う場合は他のMACを意識する必要はありません。
(参考) LSM (Linux Security Module)
本セクションは興味のある方向けの補足情報です。
SELinuxを理解する上では、読み飛ばしても問題ありません。
MACはLSM (Linux Security Module) という形でLinux Kernelに組み込まれます。8,9,10
MACを実装しているソフトウェアはSELinuxやAppArmorなど複数存在しますが、LSM Hookというインターフェースを介して共通した方法でLinux Kernelとやり取りします。
単一のLinuxマシンにMAC機能を提供するソフトウェアを複数インストールし、OS起動時に切り替えて使用することは可能です。
しかし、同時に動作できるMACは1つのみです (※)。
したがって、SELinuxを動作するマシンにおいてAppArmorなどの他のMACが同時に動作することはありません。
(※) 厳密には、LSMにはnon-exclusive modules (minor modules) というものがあり、SELinux以外にもyamaやcapabilitiesなどいくつか同時に起動しています。SELinuxやAppArmorはexclusive modules (major modules) と呼ばれ、exclusive modulesが2つ同時に動くことはありません11,12
LSMの切り替えについてはLinux Security Module Usageに詳細が書かれています。
いくつか、Fedora35上で実行した関連ログも添えておきます。
↓ActiveなLSMを表示しています。
SELinuxだけでなく、他にもいくつかのLSMが起動していることがわかります。
cat /sys/kernel/security/lsm
# lockdown,capability,yama,selinux,bpf,landlock
↓Kernelのビルドオプションにより、デフォルトで起動するmajor LSM を指定できます。
自力でLinux Kernelをビルドしているのでなければ、Linux Distributionによってデフォルトで使用するmajor LSMが決まると考えて良いと思います。
以下の出力では、SELinuxがデフォルトにセットされていることがわかります。
grep CONFIG_DEFAULT_SECURITY /boot/config-`uname -r` # CONFIG_DEFAULT_SECURITY_SELINUX=y
↓現在のkernel command line argumentを確認しています。
kernel command line argumantにsecurity=selinux
のようにMACを指定することで、上記のデフォルト挙動を上書きすることができます。
以下の出力にはsecurity=...
という指定がないため、Kernelのビルドオプションの設定に従ってSELinuxで起動することがわかります。
cat /proc/cmdline
# BOOT_IMAGE=(hd0,gpt2)/vmlinuz-5.14.18-300.fc35.x86_64 root=/dev/mapper/fedora_pc-root ro rd.lvm.lv=fedora_pc/root rhgb quiet
まとめ
Linuxのアクセス制御技術を分類し、SELinuxの位置づけを示しました。
Linuxプロセスのアクセス制御技術はDACとMACに分類され、SELinuxはMACの一種です。
MACはDACよりも高いセキュリティを実現できる技術ですが、DACと比較して設計や設定変更に労力がかかります。
DACとMACをうまく併用し、運用性とセキュリティの良いバランスを検討することが重要です。
具体的には、MACはLinuxインストール時の初期値として必要なアクセスを、細かい粒度で許可します。
初期値としてルール設定されているので、ある意味万人向けに、広くアクセス許可されています。
しかし、攻撃でなければ絶対発生し得ないようなアクセスパターンは確実に遮断します。
プロセスの基本動作に変更があった場合に、実情に併せて「root権限を以て慎重に、稀に」アクセス許可設定を変更します。
一方、DACは非rootユーザーでも手軽に変更できる点を活かし、運用者の裁量によって重要なファイルに対して細かく権限を設計し、実情にあわせてこまめにメンテナンスする使い方をします。