8.2. カスタムアプリケーション用の SELinux ポリシーの作成および実施
SELinux によってアプリケーションを制限することで、ホストシステムとユーザーのデータのセキュリティーを強化できます。各アプリケーションには特定の要件があるため、ユースケースに応じてこの手順を変更してください。ここでは例として、単純なデーモンを制限する SELinux ポリシーを作成します。
前提条件
-
selinux-policy-devel
パッケージとその依存関係がシステムにインストールされている。
手順
この手順例では、
/var/log/messages
ファイルを開いて書き込みを行う簡単なデーモンを準備します。新しいファイルを作成して、選択したテキストエディターで開きます。
$ vi mydaemon.c
以下のコードを挿入します。
#include <unistd.h> #include <stdio.h> FILE *f; int main(void) { while(1) { f = fopen("/var/log/messages","w"); sleep(5); fclose(f); } }
ファイルをコンパイルします。
$ gcc -o mydaemon mydaemon.c
デーモンの
systemd
ユニットファイルを作成します。$ vi mydaemon.service [Unit] Description=Simple testing daemon [Service] Type=simple ExecStart=/usr/local/bin/mydaemon [Install] WantedBy=multi-user.target
デーモンをインストールして起動します。
# cp mydaemon /usr/local/bin/ # cp mydaemon.service /usr/lib/systemd/system # systemctl start mydaemon # systemctl status mydaemon ● mydaemon.service - Simple testing daemon Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; vendor preset: disabled) Active: active (running) since Sat 2020-05-23 16:56:01 CEST; 19s ago Main PID: 4117 (mydaemon) Tasks: 1 Memory: 148.0K CGroup: /system.slice/mydaemon.service └─4117 /usr/local/bin/mydaemon May 23 16:56:01 localhost.localdomain systemd[1]: Started Simple testing daemon.
新しいデーモンが SELinux によって制限されていないことを確認します。
$ ps -efZ | grep mydaemon system_u:system_r:unconfined_service_t:s0 root 4117 1 0 16:56 ? 00:00:00 /usr/local/bin/mydaemon
デーモンのカスタムポリシーを生成します。
$ sepolicy generate --init /usr/local/bin/mydaemon Created the following files: /home/example.user/mysepol/mydaemon.te # Type Enforcement file /home/example.user/mysepol/mydaemon.if # Interface file /home/example.user/mysepol/mydaemon.fc # File Contexts file /home/example.user/mysepol/mydaemon_selinux.spec # Spec file /home/example.user/mysepol/mydaemon.sh # Setup Script
直前のコマンドで作成した設定スクリプトを使用して、新しいポリシーモジュールでシステムポリシーを再構築します。
# ./mydaemon.sh Building and Loading Policy + make -f /usr/share/selinux/devel/Makefile mydaemon.pp Compiling targeted mydaemon module Creating targeted mydaemon.pp policy package rm tmp/mydaemon.mod.fc tmp/mydaemon.mod + /usr/sbin/semodule -i mydaemon.pp ...
restorecon
コマンドを使用して、設定スクリプトがファイルシステムの対応する部分の再ラベル付けを行うことに注意してください。restorecon -v /usr/local/bin/mydaemon /usr/lib/systemd/system
デーモンを再起動して、SELinux が制限のあるデーモンを実行していることを確認します。
# systemctl restart mydaemon $ ps -efZ | grep mydaemon system_u:system_r:mydaemon_t:s0 root 8150 1 0 17:18 ? 00:00:00 /usr/local/bin/mydaemon
デーモンは SELinux によって制限されているため、SELinux はこのデーモンが
/var/log/messages
にアクセスできないようにします。対応する拒否メッセージを表示します。# ausearch -m AVC -ts recent ... type=AVC msg=audit(1590247112.719:5935): avc: denied { open } for pid=8150 comm="mydaemon" path="/var/log/messages" dev="dm-0" ino=2430831 scontext=system_u:system_r:mydaemon_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ...
sealert
ツールを使用して追加情報を取得することもできます。$ sealert -l "*" SELinux is preventing mydaemon from open access on the file /var/log/messages. ***** Plugin catchall (100. confidence) suggests ************************** If you believe that mydaemon should be allowed open access on the messages file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # ausearch -c 'mydaemon' --raw | audit2allow -M my-mydaemon # semodule -X 300 -i my-mydaemon.pp Additional Information: Source Context system_u:system_r:mydaemon_t:s0 Target Context unconfined_u:object_r:var_log_t:s0 Target Objects /var/log/messages [ file ] Source mydaemon …
audit2allow
ツールを使用して、変更を提案します。$ ausearch -m AVC -ts recent | audit2allow -R require { type mydaemon_t; } #============= mydaemon_t ============== logging_write_generic_logs(mydaemon_t)
audit2allow
が提案するルールは特定のケースでは正しくない可能性があるため、出力の一部のみを使用して対応するポリシーインターフェイスを見つけます。macro-expander
ツールを使用してlogging_write_generic_logs (mydaemon_t)
マクロを検査し、マクロが提供するすべての許可ルールを確認します。$ macro-expander "logging_write_generic_logs(mydaemon_t)" allow mydaemon_t var_t:dir { getattr search open }; allow mydaemon_t var_log_t:dir { getattr search open read lock ioctl }; allow mydaemon_t var_log_t:dir { getattr search open }; allow mydaemon_t var_log_t:file { open { getattr write append lock ioctl } }; allow mydaemon_t var_log_t:dir { getattr search open }; allow mydaemon_t var_log_t:lnk_file { getattr read };
ここでは、提案されたインターフェイスを使用できます。このインターフェイスは、ログファイルとその親ディレクトリーへの読み取りおよび書き込みアクセスのみを提供するためです。Type Enforcement ファイルに対応するルールを追加します。
$ echo "logging_write_generic_logs(mydaemon_t)" >> mydaemon.te
または、インターフェイスを使用する代わりに、このルールを追加することもできます。
$ echo "allow mydaemon_t var_log_t:file { open write getattr };" >> mydaemon.te
ポリシーを再インストールします。
# ./mydaemon.sh Building and Loading Policy + make -f /usr/share/selinux/devel/Makefile mydaemon.pp Compiling targeted mydaemon module Creating targeted mydaemon.pp policy package rm tmp/mydaemon.mod.fc tmp/mydaemon.mod + /usr/sbin/semodule -i mydaemon.pp ...
検証
アプリケーションが SELinux によって制限されて実行されていることを確認します。以下に例を示します。
$ ps -efZ | grep mydaemon system_u:system_r:mydaemon_t:s0 root 8150 1 0 17:18 ? 00:00:00 /usr/local/bin/mydaemon
カスタムアプリケーションが SELinux 拒否を生じさせないことを確認します。
# ausearch -m AVC -ts recent <no matches>
関連情報
-
システムの
sepolgen(8)
、ausearch(8)
、audit2allow(1)
、audit2why(1)
、sealert(8)
、およびrestorecon(8)
の man ページ - ナレッジベースの記事 Quick start to write a custom SELinux policy