このページの目次
LSM とアクセス制御
カバー範囲: Linux Security Modules アーキテクチャ → SELinux/AppArmor/SMACK → LSM フック機構 → BPF LSM → キャパビリティ → キーリング → IMA/EVM カーネルバージョン: 2.6 ~ 6.x
概要
従来の Unix DAC(Discretionary Access Control)では、所有者/グループ/その他という3段階の権限しか表現できず、「この Web サーバーは /var/www のみを読み取り可能で、/home/user/.ssh にはアクセス不可」といったきめ細かなポリシーを表現できません。LSM は、重要なシステムコールのパスにフックを挿入することで、セキュリティモジュールが追加のアクセス制御判断を行えるようにします。
現在、主要な2つの LSM は、SELinux(型強制に基づく強制アクセス制御)と AppArmor(パスマッチングに基づくプロファイルポリシー)です。
LSM フックアーキテクチャ
// include/linux/lsm_hooks.h
// 200以上のフックがすべての機微な操作をカバーします:
;
// 呼び出しチェーン:
// security_file_open(file) → call_void_hook(file_open, file)
// → 登録されているすべてのモジュールのフックを走査 → いずれかがエラーを返すと → 操作を拒否
フックの挿入ポイント
SELinux: 型強制
コア概念:
- すべてにラベル (label) が付与される: ファイル、プロセス、ソケットなど
→ ls -Z: system_u:object_r:httpd_sys_content_t:s0
- ポリシーは「どのソース型が、どのターゲット型の、どのクラスにアクセスできるか」を定義する
→ ホワイトリストモデル: デフォルトは拒否、明示的に許可されたもののみが許可
- AVC (Access Vector Cache): ポリシー照会結果のキャッシュ (パフォーマンスの要)
SELinux モード:
/sys/fs/selinux/enforce
Enforcing (1): 拒否 + ログ記録
Permissive (0): 許可 + ログ記録 (デバッグ用)
Disabled: 完全にロードしない
ラベルの保存:
ext4/xfs: xattr security.selinux
tmpfs/procfs: 実行時に生成 (genfscon)
AppArmor: パスマッチング
パスプロファイルモデル:
セキュリティポリシーは型に基づかず、パスマッチングに基づきます:
/usr/bin/nginx {
/var/www/** r,
/var/log/nginx/* w,
/run/nginx.pid w,
/tmp/** rw,
capability net_bind_service,
}
利点:
- SELinux より直感的 (パスを見ればポリシーがわかる)
- ポリシーファイルが独立している (プログラムごとに1つ)
欠点:
- パスで回避可能 (ハードリンク、bind mount)
- 複雑なグローバル制約の表現が困難
SMACK: 簡略化された型強制
SELinux に似ているが 90% 簡略化:
- ラベルのみ、ロール/ユーザー/MLS はなし
- ルール: 「subject label が object label にアクセス」
- 用途: Tizen (サムスン)、Automotive Grade Linux
カーネルコンパイル: CONFIG_SECURITY_SMACK
BPF LSM (5.7以降)
// BPF プログラムで LSM フックを実装:
// bpf(BPF_PROG_LOAD, BPF_PROG_TYPE_LSM, ...)
// attach: bpf(BPF_RAW_TRACEPOINT_OPEN, lsm/file_mprotect)
// カーネルモジュール相比の利点:
// - カーネルモジュールをコンパイルする必要がない
// - verifier により安全性が保証される (パニックしない)
// - 配布と更新が容易
キャパビリティ: ルート権限の分割
// include/uapi/linux/capability.h
// ルートの全能力をきめ細かなビットに分割:
CAP_SYS_ADMIN // システム管理
CAP_NET_RAW // raw socket
CAP_NET_BIND_SERVICE // 1024未満のポートへのバインド
CAP_SYS_PTRACE // 他のプロセスの ptrace
CAP_KILL // 他のユーザーのプロセスへのシグナル送信
// ... 40以上のキャパビリティ
// コンテナセキュリティの重要ポイント:
// docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE
// → コンテナ内の root はポートバインドのみ可能、モジュールの読み込みは不可
IMA/EVM: ファイル整合性
IMA (Integrity Measurement Architecture):
測定: ファイルが読み込まれるたびにハッシュを計算 → TPM に記録
評価: ファイルハッシュを検証 → 改ざんされたファイルを拒否
EVM (Extended Verification Module):
ファイルのメタデータ (xattr, モード, オーナー) が改ざんされないよう保護
HMAC (TPM キー使用) またはデジタル署名に基づく
デバッグ
# SELinux
# AppArmor
# キャパビリティ
参考
- ソースコード:
security/(lsm, selinux, apparmor, smack, integrity)、include/linux/lsm_hooks.h - カーネルドキュメント:
Documentation/admin-guide/LSM/ - LWN: 「The LSM hook interface」、「BPF LSM」
キーワード: LSM, SELinux, AppArmor, BPF LSM, キャパビリティ, IMA, EVM, 型強制, AVC