Fedora 28: SELinuxで強制アクセス制御

SELinuxの使い方を記載します。

1 SELinuxの状態を確認する

sestatusとgetenforceでSELinuxの状態を確認できます。有効はEnforcing、無効はPermissiveです。SELinuxはデフォルトで有効です。

$ sudo 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
Max kernel policy version:      30
$ sudo getenforce
Enforcing

2 setenforceでSELinuxを有効・無効にする(非推奨)

setenforceでSELinuxを有効・無効にすることができます。onは1、offは0でも代用できます。

$ sudo setenforce on   # Enable SELinux.
$ sudo setenforce off  # Disable SELinux.

ただし、setenforce offでSELinuxを無効にするのは古い方法です。今はsetroubleshoot-serverを使ってbooleanを設定したりポリシーを追加するのが正しい方法です。

3 setseboolでSELinuxのbooleanを設定する

SELinuxには各種機能を制御するbooleanが用意されています。例えば、httpdのmod_userdirがユーザのホームディレクトリへ読み込みできるかを決めるhttpd_read_user_contentがあります。

getseboolでbooleanの値を表示します。

$ sudo getsebool <name> # Show key value
$ sudo getsebool -a    # Show all key value

setseboolでbooleanの値を設定します。-Pをつけると恒久的に設定されます。onは1、offは0でも代用できます。

$ sudo setsebool -P <name> on  # Enable <name>
$ sudo setsebool -P <name> off # Disable <name>

setroubleshoot-serverを使えばbooleanの名前を覚える必要はありません。

4 semoduleでSELinuxのポリシーを追加する

setseboolでは対処できない場合はsemoduleでSELinuxのポリシーを追加する必要があります。

  • テキストの.teファイルを作成します。
  • .teファイルから.modファイルを作成します。
  • .modファイルからバイナリの.ppファイルを作成します。
  • .ppファイルをsemoduleに読み込ませてSELinuxのポリシーを追加します。
$ # create my-policy.te
$ checkmodule -M -m -o my-policy.mod my-policy.te
$ semodule_package -m my-policy.mod -o my-policy.pp
$ sudo semodule -i my-policy.pp

setroubleshoot-serverを使えば.teファイルの内容を提案してもらえます。

5 setroubleshoot-serverでSELinuxの設定方法を取得する

SELinuxが拒否した内容から、setseboolやsemoduleによるSELinuxの設定方法をjournaldへログ出力するパッケージです。

5.1 setseboolの例

httpdでmod_userdirを動かすとmod_userdirはSELinuxによって拒否されます。

$ sudo journalctl
<snip>
Jun 11 22:15:59 yourhost setroubleshoot[20931]: Deleting alert
4d17868b-f30d-4719-9bbd-997a38f61807, it is dontaudit'd in current policy
Jun 11 22:16:00 yourhost setroubleshoot[20931]: SELinux is preventing
httpd from read access on the directory public_html. For complete
SELinux messages. run sealert -l 50efa2e4-2f95-40f3-ba54-114a9a44b4c2
Jun 11 22:16:00 yourhost python3[20931]: SELinux is preventing httpd
from read access on the directory public_html.
  *****  Plugin catchall_boolean (32.5 confidence) suggests  ***************

  If you want to allow httpd to read user content
  Then you must tell SELinux about this by enablin the
  'httpd_read_user_content' boolean.

  Do
  setsebool -P httpd_read_user_content 1
<snip>

Do以下のコマンドを実行すればSELinuxによって拒否されなくなります。

$ sudo setsebool -P httpd_read_user_content 1

5.2 semoduleの例

Nagiosを動かすとsocketの作成がSELinuxによって拒否されます。

$ sudo journalctl
Jun 11 23:22:42 yourhost setroubleshoot[9871]: SELinux is preventing
nagios from create access on the sock_file nagios.qh. For complete
SELinux messages. run sealert -l 3221abf3-4aae-4451-9d57-267a78ef12fe
Jun 11 23:22:42 yourhost python3[9871]: SELinux is preventing nagios
from create access on the sock_file nagios.qh.

  *****  Plugin catchall (100. confidence) suggests  ***********************

  If you believe that nagios should be allowed create access on the
  nagios.qh sock_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 'nagios' --raw | audit2allow -M my-nagios
  # semodule -X 300 -i my-nagios.pp

auserchとaudit2allowで.ppファイルと.teファイルが作成されます。ausearchは一度SELinuxで拒否された状態でないと結果を返しません。

$ sudo ausearch -c 'nagios' --raw | audit2allow -M my-nagios
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i my-nagios.pp
$ ls my-nagios.*
my-nagios.pp  my-nagios.te

.ppファイルでSELinuxのポリシーを追加します。

$ sudo semodule -X 300 -i my-nagios.pp

SELinuxに拒否される前にSELinuxのポリシーを追加するにはteファイルを作成しておく必要があります。

  • テスト環境にて一度SELinuxに拒否されておき、auserchとaudit2allowで.ppファイルと.teファイルを作成します。
  • 本番環境にてSELinuxに拒否される前に、テスト環境で作成した.teファイルから.ppファイルを作成してSELinuxのポリシーを追加します。
$ cat my-nagios.te

module my-nagios 1.0;

require {
        type nagios_log_t;
        type nagios_t;
        class sock_file create;
}

#============= nagios_t ==============
allow nagios_t nagios_log_t:sock_file create;