SELinux and AppArmor

SELinux と AppArmor 完全ガイド

目次

  1. はじめに
  2. 強制アクセス制御(MAC)の基礎
  3. SELinux 詳細解説
  4. AppArmor 詳細解説
  5. SELinux vs AppArmor 比較
  6. 実践シナリオ
  7. トラブルシューティング総合ガイド
  8. ベストプラクティス
  9. 参考文献

1. はじめに

SELinux(Security-Enhanced Linux)と AppArmor は、Linux カーネルに組み込まれた強制アクセス制御(MAC: Mandatory Access Control)セキュリティモジュールである。従来の任意アクセス制御(DAC: Discretionary Access Control)では、ファイルの所有者がアクセス権を管理するが、MAC ではシステム管理者がセキュリティポリシーを一元的に管理し、プロセスの権限をより厳密に制御する。

対象読者

  • Linux システム管理者
  • セキュリティエンジニア
  • SRE / DevOps エンジニア

2. 強制アクセス制御(MAC)の基礎

2.1 DAC と MAC の違い

特性DAC(任意アクセス制御)MAC(強制アクセス制御)
制御主体リソースの所有者システムポリシー
権限変更所有者が自由に変更可能管理者のみ変更可能
root の権限無制限ポリシーにより制限可能
粒度ユーザー/グループ/その他プロセス/ファイル/ポート等
実装例chmod, chownSELinux, AppArmor

2.2 Linux Security Modules (LSM)

LSM は Linux カーネルのフレームワークで、SELinux や AppArmor などのセキュリティモジュールをカーネルにフックする仕組みを提供する。

# 利用可能なLSMの確認
$ cat /sys/kernel/security/lsm
lockdown,capability,landlock,yama,apparmor

# カーネルコンフィグの確認
$ grep -i "config_security" /boot/config-$(uname -r) | head -20
CONFIG_SECURITY=y
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_APPARMOR=y

3. SELinux 詳細解説

3.1 SELinux の概念

SELinux は NSA(米国国家安全保障局)が開発した MAC 実装であり、主に RHEL/CentOS/Fedora 系ディストリビューションで使用される。

SELinux の基本原則

  1. デフォルト拒否: 明示的に許可されていないアクセスは全て拒否
  2. 最小権限: プロセスに必要最小限の権限のみを付与
  3. タイプエンフォースメント: プロセスのタイプ(ドメイン)がアクセスできるリソースのタイプを制御

3.2 コンテキストとラベル

SELinux は全てのプロセス、ファイル、ポートにセキュリティコンテキスト(ラベル)を付与する。

コンテキストの形式

user:role:type:level
要素説明
userSELinux ユーザーsystem_u, unconfined_u
roleSELinux ロールsystem_r, object_r
typeSELinux タイプ(最も重要)httpd_t, httpd_sys_content_t
levelMLS/MCS レベルs0, s0:c0.c1023

コンテキストの確認

# ファイルのコンテキスト
$ ls -Z /var/www/html/
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

# プロセスのコンテキスト
$ ps auxZ | grep httpd
system_u:system_r:httpd_t:s0    root  1234  0.0  0.5  ... /usr/sbin/httpd

# ユーザーのコンテキスト
$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# ポートのコンテキスト
$ sudo semanage port -l | grep http
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

# 現在のコンテキスト
$ cat /proc/self/attr/current
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

コンテキストの変更

# ファイルのコンテキストを変更(一時的)
$ sudo chcon -t httpd_sys_content_t /var/www/html/newfile.html

# ファイルのコンテキストを変更(再帰的)
$ sudo chcon -R -t httpd_sys_content_t /var/www/html/

# デフォルトコンテキストに復元
$ sudo restorecon -v /var/www/html/newfile.html
$ sudo restorecon -Rv /var/www/html/

# ファイルのデフォルトコンテキストを確認
$ matchpathcon /var/www/html
/var/www/html   system_u:object_r:httpd_sys_content_t:s0

3.3 SELinux のモード

モード説明用途
Enforcingポリシーを強制実行し、違反を拒否・ログ本番環境
Permissiveポリシー違反をログのみ記録(拒否しない)デバッグ・ポリシー開発
DisabledSELinux を完全に無効化非推奨
# 現在のモードを確認
$ getenforce
Enforcing

# 詳細なステータス
$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

# モードの一時的な変更(再起動でリセット)
$ sudo setenforce 0    # Permissive に変更
$ sudo setenforce 1    # Enforcing に変更

# モードの永続的な変更
$ sudo vi /etc/selinux/config
# SELINUX=enforcing
# SELINUX=permissive
# SELINUX=disabled

# 注意: disabled から enforcing への変更時は再ラベリングが必要
$ sudo touch /.autorelabel
$ sudo reboot

特定のドメインのみ Permissive にする

# httpd_t ドメインのみ Permissive に設定
$ sudo semanage permissive -a httpd_t

# Permissive ドメインの一覧
$ sudo semanage permissive -l

# Permissive を解除
$ sudo semanage permissive -d httpd_t

3.4 SELinux のタイプとドメイン

タイプエンフォースメント(TE)は SELinux の中核メカニズムである。

主要なタイプの例

タイプ説明
httpd_tApache/nginx プロセスのドメイン
httpd_sys_content_tWeb コンテンツ(読み取り専用)
httpd_sys_rw_content_tWeb コンテンツ(読み書き可能)
httpd_sys_script_exec_tCGI スクリプト
mysqld_tMySQL/MariaDB プロセスのドメイン
mysqld_db_tMySQL データベースファイル
sshd_tSSH デーモンのドメイン
user_home_tユーザーのホームディレクトリ
tmp_t/tmp ディレクトリ
var_log_tログファイル

タイプ遷移

# プロセスのドメイン遷移を確認
$ sudo sesearch -T -s init_t -t httpd_exec_t
type_transition init_t httpd_exec_t : process httpd_t;
# init_t が httpd_exec_t を実行すると、httpd_t ドメインに遷移する

# 許可されるアクセスを確認
$ sudo sesearch -A -s httpd_t -t httpd_sys_content_t
allow httpd_t httpd_sys_content_t : file { getattr ioctl lock open read };
allow httpd_t httpd_sys_content_t : dir { getattr ioctl lock open read search };

3.5 ロールとユーザー

SELinux ユーザー

# SELinux ユーザーの一覧
$ sudo semanage user -l
                Labeling   MLS/       MLS/
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles
guest_u         user       s0         s0                             guest_r
root            user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
staff_u         user       s0         s0-s0:c0.c1023                 staff_r sysadm_r
sysadm_u        user       s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r unconfined_r
unconfined_u    user       s0         s0-s0:c0.c1023                 system_r unconfined_r
user_u          user       s0         s0                             user_r

# Linux ユーザーと SELinux ユーザーのマッピング
$ sudo semanage login -l
Login Name           SELinux User         MLS/MCS Range        Service
__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *

# マッピングの追加
$ sudo semanage login -a -s user_u webuser

SELinux ロール

ロール説明許可されるドメイン
unconfined_r制限なしunconfined_t 等
system_rシステムプロセスhttpd_t, sshd_t 等
sysadm_rシステム管理者sysadm_t
staff_rスタッフstaff_t
user_r一般ユーザーuser_t
guest_rゲストguest_t

3.6 ブーリアン値の管理

SELinux ブーリアンは、ポリシーの特定の機能をオン/オフするスイッチである。

# 全ブーリアンの一覧
$ sudo getsebool -a
abrt_anon_write --> off
abrt_handle_event --> off
allow_console_login --> on
...
httpd_can_network_connect --> off
httpd_can_network_connect_db --> off
httpd_can_sendmail --> off
httpd_enable_cgi --> on
httpd_enable_homedirs --> off
...

# 特定のブーリアンの確認
$ getsebool httpd_can_network_connect
httpd_can_network_connect --> off

# ブーリアンの変更(一時的)
$ sudo setsebool httpd_can_network_connect on

# ブーリアンの変更(永続的)
$ sudo setsebool -P httpd_can_network_connect on

# httpd 関連のブーリアン一覧
$ getsebool -a | grep httpd
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> on
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_read_user_content --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off

# semanage でのブーリアン管理
$ sudo semanage boolean -l | grep httpd_can_network
httpd_can_network_connect      (on   ,   on)  Allow httpd to can network connect
httpd_can_network_connect_db   (off  ,  off)  Allow httpd to can network connect db

よく使用されるブーリアン

ブーリアンデフォルト説明
httpd_can_network_connectoffhttpd がネットワーク接続を許可
httpd_can_network_connect_dboffhttpd がデータベースへの接続を許可
httpd_can_sendmailoffhttpd がメール送信を許可
httpd_enable_homedirsoffhttpd がユーザーのホームディレクトリにアクセス
httpd_use_nfsoffhttpd が NFS マウントにアクセス
ftpd_anon_writeoffFTP の匿名書き込みを許可
samba_enable_home_dirsoffSamba がホームディレクトリを共有
virt_use_nfsoff仮想化がNFSを使用

3.7 semanage コマンド

semanage は SELinux ポリシーの管理コマンドである。

ファイルコンテキストの管理

# デフォルトのファイルコンテキストを確認
$ sudo semanage fcontext -l | grep "/var/www"
/var/www(/.*)?          all files   system_u:object_r:httpd_sys_content_t:s0
/var/www/cgi-bin(/.*)?  all files   system_u:object_r:httpd_sys_script_exec_t:s0

# カスタムディレクトリにコンテキストを設定
$ sudo semanage fcontext -a -t httpd_sys_content_t "/opt/myapp/www(/.*)?"
$ sudo restorecon -Rv /opt/myapp/www/

# コンテキストの変更
$ sudo semanage fcontext -m -t httpd_sys_rw_content_t "/opt/myapp/www/uploads(/.*)?"
$ sudo restorecon -Rv /opt/myapp/www/uploads/

# コンテキストの削除
$ sudo semanage fcontext -d "/opt/myapp/www(/.*)?"

ポートの管理

# ポートのコンテキスト一覧
$ sudo semanage port -l | grep http
http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

# カスタムポートの追加
$ sudo semanage port -a -t http_port_t -p tcp 8090

# ポートの変更
$ sudo semanage port -m -t http_port_t -p tcp 8090

# ポートの削除
$ sudo semanage port -d -t http_port_t -p tcp 8090

ネットワークインターフェースの管理

# インターフェースの一覧
$ sudo semanage interface -l

# インターフェースの追加
$ sudo semanage interface -a -t netif_t eth0

3.8 ポリシーモジュール管理

# ロード済みモジュールの一覧
$ sudo semodule -l
abrt    1.4.1
accountsd       1.1.0
acct    1.6.0
...

# モジュールの無効化
$ sudo semodule -d httpd

# モジュールの有効化
$ sudo semodule -e httpd

# モジュールの削除
$ sudo semodule -r mymodule

# モジュールのインストール
$ sudo semodule -i mymodule.pp

# ポリシーの再構築
$ sudo semodule -B

カスタムポリシーモジュールの作成

# audit2allow で拒否ログからポリシーを生成
$ sudo ausearch -m AVC -ts recent | audit2allow -M mymodule

# 生成されたファイル
# mymodule.te  - タイプエンフォースメントファイル(ソース)
# mymodule.pp  - コンパイル済みポリシーパッケージ

# ポリシーの内容を確認
$ cat mymodule.te
module mymodule 1.0;

require {
    type httpd_t;
    type var_t;
    class file { read open getattr };
}

#============= httpd_t ==============
allow httpd_t var_t:file { read open getattr };

# モジュールのインストール
$ sudo semodule -i mymodule.pp

3.9 SELinux 拒否のトラブルシューティング

AVC(Access Vector Cache)ログの確認

# audit.log での AVC 拒否の確認
$ sudo ausearch -m AVC -ts today
----
time->Thu Apr 10 10:00:00 2026
type=AVC msg=audit(1712739600.123:456): avc:  denied  { read } for  pid=1234 comm="httpd" name="config.php" dev="sda1" ino=789012 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

# audit2why で拒否の理由を分析
$ sudo ausearch -m AVC -ts today | audit2why
type=AVC msg=audit(1712739600.123:456): avc:  denied  { read } for  pid=1234 comm="httpd" name="config.php" dev="sda1" ino=789012 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

    Was caused by:
        Missing type enforcement (TE) allow rule.

        You can use audit2allow to generate a loadable module to allow this access.

# sealert で詳細な分析(setroubleshoot-server がインストールされている場合)
$ sudo sealert -a /var/log/audit/audit.log

# 最近の拒否を確認
$ sudo ausearch -m AVC --start recent

# 特定のプロセスの拒否を確認
$ sudo ausearch -m AVC -c httpd

一般的な対処フロー

# 1. 拒否ログを確認
$ sudo ausearch -m AVC -ts today

# 2. 原因を分析
$ sudo ausearch -m AVC -ts today | audit2why

# 3a. ファイルコンテキストが間違っている場合
$ sudo restorecon -Rv /path/to/files

# 3b. ブーリアンで対応できる場合
$ sudo setsebool -P httpd_can_network_connect on

# 3c. ポートの追加が必要な場合
$ sudo semanage port -a -t http_port_t -p tcp 8090

# 3d. カスタムポリシーが必要な場合
$ sudo ausearch -m AVC -ts today | audit2allow -M mypolicy
$ sudo semodule -i mypolicy.pp

# 4. 変更後のテスト
$ sudo ausearch -m AVC -ts recent

4. AppArmor 詳細解説

4.1 AppArmor の概念

AppArmor はパス名ベースの MAC 実装であり、主に Debian/Ubuntu/SUSE 系ディストリビューションで使用される。SELinux がラベルベースであるのに対し、AppArmor はファイルパスに基づいてアクセス制御を行う。

# AppArmor の状態確認
$ sudo apparmor_status
apparmor module is loaded.
56 profiles are loaded.
56 profiles are in enforce mode.
   /snap/snapd/14978/usr/lib/snapd/snap-confine
   /usr/bin/evince
   /usr/bin/man
   /usr/sbin/cups-browsed
   /usr/sbin/cupsd
   /usr/sbin/mysqld
   /usr/sbin/ntpd
   ...
0 profiles are in complain mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

# または aa-status
$ sudo aa-status

4.2 プロファイルとモード

プロファイルのモード

モード説明用途
Enforceプロファイルのルールを強制し、違反を拒否・ログ本番環境
Complain違反をログのみ記録(拒否しない)プロファイル開発・テスト
Unconfinedプロファイルが読み込まれていない制限なし

プロファイルの配置

# プロファイルの格納場所
/etc/apparmor.d/
├── abstractions/           # 共有ルールの抽象化
│   ├── base
│   ├── nameservice
│   └── ...
├── cache/                  # コンパイル済みプロファイルのキャッシュ
├── force-complain/         # 強制 complain モード
├── disable/                # 無効化されたプロファイル
├── local/                  # ローカルオーバーライド
├── tunables/               # 変数定義
│   ├── global
│   └── home
├── usr.sbin.mysqld         # MySQL のプロファイル
├── usr.sbin.ntpd           # NTP のプロファイル
├── usr.sbin.sshd           # SSH のプロファイル
└── usr.lib.apache2.mpm-prefork.apache2  # Apache のプロファイル

プロファイルの基本構造

# /etc/apparmor.d/usr.sbin.nginx
#include <tunables/global>

/usr/sbin/nginx {
    #include <abstractions/base>
    #include <abstractions/nameservice>
    #include <abstractions/openssl>

    # ネットワークアクセス
    network inet stream,
    network inet6 stream,

    # 能力(capability)
    capability net_bind_service,
    capability setuid,
    capability setgid,
    capability dac_override,

    # 実行ファイル
    /usr/sbin/nginx mr,

    # 設定ファイル
    /etc/nginx/** r,
    /etc/nginx/nginx.conf r,

    # ログファイル
    /var/log/nginx/** rw,
    /var/log/nginx/ r,

    # Web コンテンツ
    /var/www/** r,
    /var/www/html/** r,

    # PID ファイル
    /run/nginx.pid rw,
    /run/nginx/ rw,

    # 一時ファイル
    /tmp/** rw,
    /var/lib/nginx/** rw,

    # SSL 証明書
    /etc/ssl/certs/** r,
    /etc/ssl/private/** r,
    /etc/letsencrypt/** r,

    # ローカルのカスタマイズを読み込み
    #include <local/usr.sbin.nginx>
}

アクセス権限の記号

記号説明
r読み取り
w書き込み
a追記
kファイルロック
lリンク
mメモリマップ(実行可能)
x実行(汎用)
ix実行(現在のプロファイルを継承)
cx実行(子プロファイルに遷移)
px実行(指定プロファイルに遷移)
ux実行(制限なし)
Ux実行(制限なし、環境をクリーン化)
Px実行(指定プロファイルに遷移、環境をクリーン化)

4.3 プロファイル管理コマンド

# プロファイルを enforce モードに設定
$ sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Setting /etc/apparmor.d/usr.sbin.nginx to enforce mode.

# プロファイルを complain モードに設定
$ sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
Setting /etc/apparmor.d/usr.sbin.nginx to complain mode.

# プログラム名でモード変更
$ sudo aa-enforce /usr/sbin/nginx
$ sudo aa-complain /usr/sbin/nginx

# プロファイルを無効化
$ sudo aa-disable /etc/apparmor.d/usr.sbin.nginx
# または
$ sudo ln -s /etc/apparmor.d/usr.sbin.nginx /etc/apparmor.d/disable/

# プロファイルの再読み込み
$ sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx

# 全プロファイルの再読み込み
$ sudo systemctl reload apparmor

# プロファイルの削除(アンロード)
$ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.nginx

4.4 カスタムプロファイルの作成

aa-genprof(自動プロファイル生成)

# 1. プロファイル生成を開始
$ sudo aa-genprof /usr/local/bin/myapp
Writing updated profile for /usr/local/bin/myapp.
Setting /usr/local/bin/myapp to complain mode.

Before you begin, you may wish to check if a
profile already exists for the application you
wish to confine. See the following wiki page for
more information:
https://gitlab.com/apparmor/apparmor/wikis/Profiles

Profiling: /usr/local/bin/myapp

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below
for AppArmor to detect the events.

[(S)can system log for AppArmor events] / (F)inish

# 2. 別のターミナルでアプリケーションを実行
$ /usr/local/bin/myapp

# 3. S を入力してスキャン
# AppArmor が検出したアクセスについて許可/拒否を選択

# 4. F を入力して完了
# プロファイルが /etc/apparmor.d/ に保存される

aa-logprof(ログからプロファイルを更新)

# ログに記録された拒否イベントからプロファイルを更新
$ sudo aa-logprof
Reading log entries from /var/log/syslog.
Updating AppArmor profiles in /etc/apparmor.d.

Profile:  /usr/sbin/nginx
Path:     /var/cache/nginx/proxy_temp/
New Mode: rw

 [1 - #include <abstractions/base>]
  2 - /var/cache/nginx/proxy_temp/ rw,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish

手動でのプロファイル作成

# /etc/apparmor.d/usr.local.bin.myapp
#include <tunables/global>

/usr/local/bin/myapp {
    #include <abstractions/base>
    #include <abstractions/nameservice>

    # プログラム自身の読み取り
    /usr/local/bin/myapp mr,

    # 設定ファイル
    /etc/myapp/ r,
    /etc/myapp/** r,

    # データディレクトリ
    /var/lib/myapp/ rw,
    /var/lib/myapp/** rw,

    # ログファイル
    /var/log/myapp/ rw,
    /var/log/myapp/** rw,

    # PID ファイル
    /run/myapp.pid rw,

    # 一時ファイル
    /tmp/myapp-* rw,

    # ネットワーク
    network inet stream,
    network inet dgram,

    # 能力
    capability net_bind_service,

    # シグナル
    signal send set=(term, kill) peer=/usr/local/bin/myapp,

    # 子プロセス
    /usr/bin/python3 cx -> myapp_python,

    profile myapp_python {
        #include <abstractions/base>
        #include <abstractions/python>
        /usr/bin/python3 mr,
        /usr/local/lib/python3/myapp/** r,
    }

    # ローカルカスタマイズ
    #include <local/usr.local.bin.myapp>
}

# プロファイルを読み込み
$ sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.myapp

4.5 AppArmor のトラブルシューティング

ログの確認

# AppArmor の拒否ログ(kern.log / syslog)
$ sudo dmesg | grep -i apparmor
[12345.678901] audit: type=1400 audit(1712739600.123:456): apparmor="DENIED" operation="open" profile="/usr/sbin/nginx" name="/var/www/custom/index.html" pid=1234 comm="nginx" requested_mask="r" denied_mask="r" fsuid=33 ouid=0

# journalctl でのフィルタ
$ sudo journalctl -k | grep -i apparmor

# audit.log でのフィルタ
$ sudo ausearch -m APPARMOR

問題の切り分け

# 1. プロファイルを complain モードに変更
$ sudo aa-complain /usr/sbin/nginx

# 2. 問題の操作を再実行

# 3. ログを確認
$ sudo dmesg | grep -i "apparmor.*ALLOWED"

# 4. aa-logprof でプロファイルを更新
$ sudo aa-logprof

# 5. プロファイルを enforce モードに戻す
$ sudo aa-enforce /usr/sbin/nginx

# 6. 動作を確認

5. SELinux vs AppArmor 比較

5.1 機能比較

特性SELinuxAppArmor
アクセス制御モデルラベルベース(タイプエンフォースメント)パスベース
主な対象ディストリビューションRHEL/CentOS/FedoraDebian/Ubuntu/SUSE
粒度非常に細かい中程度
学習曲線緩やか
MLS/MCS サポート完全サポート限定的
ネットワーク制御ポートラベリングネットワークルール
ファイル移動時の動作ラベルがファイルに付随パスが変わると制御が変わる
ポリシーの複雑さ高い低い
パフォーマンスへの影響わずかに大きいわずかに小さい
デフォルトポリシーtargeted(主要サービスのみ制限)一部のプロファイルのみ

5.2 選択基準

基準SELinux を選ぶ場合AppArmor を選ぶ場合
ディストリビューションRHEL/CentOS/FedoraUbuntu/Debian/SUSE
セキュリティ要件非常に高い(政府・軍事等)中~高程度
管理の容易さ専門知識があるチームより少ないスキルセット
カスタムポリシー複雑なポリシーが必要シンプルなポリシーで十分
コンプライアンスDISA STIG 等の要件CIS Benchmark 等

5.3 操作コマンド比較

操作SELinuxAppArmor
状態確認sestatus, getenforceaa-status, apparmor_status
強制モードに設定setenforce 1aa-enforce <profile>
許容モードに設定setenforce 0aa-complain <profile>
無効化/etc/selinux/configaa-disable <profile>
ファイルコンテキスト確認ls -ZN/A(パスベース)
ファイルコンテキスト変更chcon, semanage fcontextN/A
コンテキスト復元restoreconN/A
ポリシー自動生成audit2allowaa-genprof, aa-logprof
ブーリアン管理getsebool, setseboolN/A
ログ確認ausearch -m AVCdmesg | grep apparmor
ログ分析audit2why, sealertaa-logprof

6. 実践シナリオ

6.1 Web サーバーの SELinux 設定

# Apache/nginx が非標準ポートで動作する場合
$ sudo semanage port -a -t http_port_t -p tcp 8080

# Web コンテンツのディレクトリを変更した場合
$ sudo semanage fcontext -a -t httpd_sys_content_t "/opt/website(/.*)?"
$ sudo restorecon -Rv /opt/website/

# アップロードディレクトリに書き込みを許可
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/opt/website/uploads(/.*)?"
$ sudo restorecon -Rv /opt/website/uploads/

# バックエンドへのネットワーク接続を許可
$ sudo setsebool -P httpd_can_network_connect on

# データベースへの接続を許可
$ sudo setsebool -P httpd_can_network_connect_db on

# NFS 上のコンテンツを許可
$ sudo setsebool -P httpd_use_nfs on

6.2 Web サーバーの AppArmor 設定

# /etc/apparmor.d/usr.sbin.nginx
#include <tunables/global>

/usr/sbin/nginx {
    #include <abstractions/base>
    #include <abstractions/nameservice>
    #include <abstractions/openssl>
    #include <abstractions/ssl_certs>

    capability net_bind_service,
    capability setuid,
    capability setgid,
    capability dac_override,

    network inet stream,
    network inet6 stream,

    /usr/sbin/nginx mr,

    /etc/nginx/** r,
    /var/log/nginx/** rw,
    /var/www/** r,
    /opt/website/** r,
    /opt/website/uploads/** rw,
    /run/nginx.pid rw,
    /var/lib/nginx/** rw,
    /proc/*/io r,

    #include <local/usr.sbin.nginx>
}

6.3 カスタムアプリケーションのプロファイル作成

# SELinux: カスタムポリシーの作成

# 1. Permissive モードでアプリケーションを実行
$ sudo semanage permissive -a myapp_t

# 2. アプリケーションの全機能をテスト

# 3. AVC ログからポリシーを生成
$ sudo ausearch -m AVC -c myapp | audit2allow -M myapp_policy

# 4. ポリシーを確認・インストール
$ cat myapp_policy.te
$ sudo semodule -i myapp_policy.pp

# 5. Permissive を解除
$ sudo semanage permissive -d myapp_t

# AppArmor: プロファイルの作成

# 1. aa-genprof でプロファイルを生成
$ sudo aa-genprof /usr/local/bin/myapp

# 2. 別ターミナルでアプリケーションの全機能をテスト

# 3. スキャン・許可/拒否を選択

# 4. プロファイルの微調整
$ sudo vi /etc/apparmor.d/usr.local.bin.myapp

# 5. プロファイルの再読み込み
$ sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.myapp

7. トラブルシューティング総合ガイド

7.1 SELinux トラブルシューティングフローチャート

アプリケーションが動作しない
         │
         ├─ getenforce で確認
         │   └─ Enforcing の場合 → ausearch -m AVC で拒否を確認
         │       │
         │       ├─ ファイルコンテキストの問題
         │       │   └─ restorecon -Rv / semanage fcontext
         │       │
         │       ├─ ブーリアンの問題
         │       │   └─ setsebool -P
         │       │
         │       ├─ ポートの問題
         │       │   └─ semanage port -a
         │       │
         │       └─ その他
         │           └─ audit2allow でカスタムポリシー作成
         │
         └─ Permissive / Disabled の場合
             └─ SELinux 以外の問題

7.2 共通の問題パターン

症状SELinux での対処AppArmor での対処
ファイルが読めないrestorecon または semanage fcontextプロファイルにパスを追加
ポートにバインドできないsemanage port -aプロファイルに network ルールを追加
他のサービスに接続できないsetsebool -Pプロファイルに network ルールを追加
ファイルに書き込めないhttpd_sys_rw_content_t に変更プロファイルに w 権限を追加
CGI が実行できないhttpd_sys_script_exec_t に変更プロファイルに ix 権限を追加

8. ベストプラクティス

8.1 一般的な原則

  1. MAC を無効にしない: SELinux や AppArmor を無効にせず、問題を適切にトラブルシューティングする
  2. 段階的な導入: まず Permissive/Complain モードで動作を確認してから Enforcing/Enforce に移行
  3. 最小権限: 必要最小限のアクセス権のみを付与
  4. ログの監視: 拒否ログを定期的に確認し、セキュリティイベントを把握
  5. ポリシーの文書化: カスタムポリシーの変更理由を文書化

8.2 SELinux のベストプラクティス

# 1. Enforcing モードを維持
$ sudo setenforce 1
$ grep SELINUX=enforcing /etc/selinux/config

# 2. setroubleshoot をインストール
$ sudo yum install setroubleshoot-server

# 3. 定期的な監査
$ sudo ausearch -m AVC -ts today --raw | aureport -a

# 4. 不要な permissive ドメインがないか確認
$ sudo semanage permissive -l

# 5. ファイルコンテキストの整合性チェック
$ sudo restorecon -Rvn /  # dry-run で確認

8.3 AppArmor のベストプラクティス

# 1. 重要なサービスに enforce モードを適用
$ sudo aa-enforce /etc/apparmor.d/*

# 2. 新しいプロファイルの開発手順
#    a. complain モードで開始
#    b. aa-logprof で繰り返し調整
#    c. テスト後に enforce モードに移行

# 3. 抽象化(abstractions)を活用
#include <abstractions/base>
#include <abstractions/nameservice>

# 4. ローカルオーバーライドの使用
#include <local/usr.sbin.nginx>

9. 参考文献

  1. SELinux Project Wiki: https://selinuxproject.org/
  2. Red Hat SELinux Guide: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/using_selinux/
  3. SELinux Notebook: https://github.com/SELinuxProject/selinux-notebook
  4. AppArmor Wiki: https://gitlab.com/apparmor/apparmor/-/wikis/home
  5. Ubuntu AppArmor Guide: https://ubuntu.com/server/docs/apparmor
  6. SUSE AppArmor Guide: https://documentation.suse.com/sles/15-SP4/html/SLES-all/part-apparmor.html
  7. CIS Benchmarks: https://www.cisecurity.org/cis-benchmarks
  8. DISA STIG: https://public.cyber.mil/stigs/
  9. Arch Linux Wiki - SELinux: https://wiki.archlinux.org/title/SELinux
  10. Gentoo Wiki - SELinux: https://wiki.gentoo.org/wiki/SELinux

本ドキュメントは 2026年4月時点の情報に基づいて作成されています。