SELinuxてなに?

今回はSELinuxについてです。

SELinuxはファイルやプロセスにラベルを付けることでアクセス制御を行います。ラベルはプロセスとファイルにふることができます。ラベルの種類には次のようなものがあり、

  1. ユーザ(_u):誰(SELinux独自のユーザ)
  2. ロール(_r):役割、グループ
  3. タイプ(_t):アクセス先
    (対象はプロセスかファイルで、プロセスの場合はドメインということもある。)
  4. セキュリティレベル(sX,cX):機密のレベル

これらを組み合わせて

 

誰(SElinuxUser/role)何(type)に対してどんな制限をする”

 

という文脈をコンテキストlとして記述しておいて、SELinuxのサービスがセキュリティのポリシーとして適用します。

 

SElinuxの状態は、sestatus (-vは詳細表示)コマンドで確認できます。

[root@host1 ~]# sestatus -v
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: 28

Process contexts: ...プロセスのコンテキスト
Current context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Init context: system_u:system_r:init_t:s0
/usr/sbin/sshd system_u:system_r:sshd_t:s0-s0:c0.c1023

File contexts: ...ファイルのコンテキスト
Controlling terminal: unconfined_u:object_r:user_devpts_t:s0
/etc/passwd system_u:object_r:passwd_file_t:s0
/etc/shadow system_u:object_r:shadow_t:s0
/bin/bash system_u:object_r:shell_exec_t:s0
/bin/login system_u:object_r:login_exec_t:s0
/bin/sh system_u:object_r:bin_t:s0 -> system_u:object_r:shell_exec_t:s0
/sbin/agetty system_u:object_r:getty_exec_t:s0
/sbin/init system_u:object_r:bin_t:s0 -> system_u:object_r:init_exec_t:s0
/usr/sbin/sshd system_u:object_r:sshd_exec_t:s0
[root@host1 ~]#

 

また通常のユーザとは別にSELinuxのユーザが存在しまして、次のコマンドでそれらのマッピング状態を書くにできます。

[root@host1bynmtui ~]# 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 *
system_u     system_u        s0-s0:c0.c1023 *

 

 

 

ここで、SELnuxの動き方を、rootユーザでpasswdコマンドを実行している状況を例に説明してみたいと思います。


idコマンドから現在のユーザ(root)のSELinuxのUserは、unconfined_uとになっていることが確認できます。
※ちなみに、隣のunconfined_rはロールで、通常のユーザで言うとGroupみたいな感じです。

[root@host1 ~]# id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@host1 ~]#

 

 

 

passwdコマンドを実行するプロセスのラベル(ドメイン)は、psコマンドで確認できます。ここではpasswd_tドメインとなります。

[root@host1 ~]# ps -eZ | grep passwd
unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 14894 pts/1 00:00:00 passwd
[root@host1 ~]#

 

passwdコマンドが実行されたときにアクセスするファイルのラベル(タイプ)は、lsコマンドから、それぞれ以下の通りになっています。
[root@host1 ~]# ls -Z /usr/bin/passwd
-rwsr-xr-x. root root system_u:object_r:passwd_exec_t:s0 /usr/bin/passwd
[root@host1 ~]#
[root@host1 ~]# ls -Z /etc/shadow
----------. root root system_u:object_r:shadow_t:s0 /etc/shadow
[root@host1 ~]#

 

上記の例はこちらを参考にいたしました。

第2章 SELinux コンテキスト - Red Hat Customer Portal

 

図にするとこんな感じになりますが、SELinuxが有効なときはこのようなラベル付がバックグラウンドで行われています。

f:id:linlinrh:20171101120837p:plain

  1. ユーザ(unconfined_u)はpasswdを実行するときに、プロセスのコンテキストの影響を受けて、
  2. passwardコマンドも(system_uのユーザで)ファイルにアクセスしに行く際はファイルのコンテキストの制限を受けます。

 

 

そんなSELinuxですが、基本パッケージでインストールしたRHEL7.xではOSの起動とともに有効になり、2つのモードで切り替えることができます。

  • Enforcing モード:
    デフォルトのモードで、SElinuxのポリシーが強制されてアクセス制御が行われます。ポリシー違反の場合はアクセスの拒否が行われます。
  • Permissive モード:
    ポリシーは読み込まれてラベルの作成も行われますが、ポリシー違反によるアクセス拒否は行わません。ただログには記録されるのでトラシューやデバッグで使用できます。

SELinuxのモードを確認するにはgetenforceコマンドを使用します。デフォルトではEnforcingになります。


[root@host1 ~]# getenforce
Enforcing
[root@host1 ~]#

 

続いて、permissiveモードに切り替えてみます。

 
[root@host1 ~]# setenforce 0

もう一度getenforceを実行するとpermissiveと表示されます。
[root@host1 ~]# getenforce
Permissive
[root@host1 ~]#

 

enforcingモードに戻すには、パラメータに1を指定します。

[root@host1 ~]# setenforce 1

 

上記の手順は一時的にモードを切り替えるだけなので、SELinuxがrestartするとデフォルトのenforcingに戻ってしまいます。なので起動時のモードを永続的に変更したい場合は、SELinuxのConfigファイルを編集する必要があります。

 

[root@host1 ~]# vim /etc/selinux/config

f:id:linlinrh:20171101135752p:plain

ファイルの更新を適用させるためには、OSを再起動します。

[root@host1 ~]# reboot

 

上記のSELINUX=の項目に設定できる値としては、

enforcing - SELinux security policy is enforced.

permissive - SELinux prints warnings instead of enforcing.

の他に

disabled - No SELinux policy is loaded.

もありまして、こちらを選ぶとSELinux自体を無効にできますが、無効になっている間に作成したファイルにはラベルが付きませんので注意が必要です。RHELではpermissiveやenforcingに変更した際に、自動で再ラベルが行われるみたいですが、/etc/selinux/configを編集してSELinuxを有効にしたあとは、

# touch /.autorelabel

を実行して、明示的に再ラベルしておくようにしたほうが安心かと思います。

 

<参考資料> 

1.4. SELinux の状態とモード - Red Hat Customer Portal

4.4. SELinux の状態とモードの永続的変更 - Red Hat Customer Portal