プロジェクト

全般

プロフィール

SELinux

概要

プロセスとファイルのアクセス制御におけるSELinux

Linuxの伝統的なアクセス制御では、ユーザー・グループをプロセスに割当て、プロセスがファイルにアクセスする際に、ファイルに設定されたユーザー・グループに対するパーミッションによってアクセス可否を決めています。また、rootユーザー(特権ユーザー)が割り当てられたプロセスは、すべてのファイルにアクセスが可能です。
そのため、いったんrootユーザーが奪取されると、そのホスト上のファイルはアクセスされ放題となります。

SELinuxでは、伝統的なアクセス制御に加えて、さらにプロセスに割当てられてドメインとファイルに割当てられたタイプとが予め定義されたポリシーで許可されているときに限ってアクセスが可能となります。そこで、rootユーザー権限でプロセスを動かすことができても、そのプロセスのドメインがポリシーで許可されたタイプを持つファイル以外にはアクセスできません。

コマンド

調査系のコマンド

ps -Z

プロセスのドメインを調べます。

$ ps ax -Z
system_u:system_r:httpd_t:s0    16549 ?        S      0:00 /usr/sbin/httpd

ls -Z

ファイルのタイプを調べます。

$ ls -Z
-rw-rw-r--. redmine redmine system_u:object_r:var_lib_t:s0   README.rdoc

ausearch

SELinuxのログ(audit.log)から抜粋します。

  • 特定のメッセージ種類(例:AVC)を抜粋
    # ausearch -m avc
    time->Wed Feb 28 04:52:01 2018
    type=SYSCALL msg=audit(1519761121.411:493759): arch=c000003e syscall=2 success=no exit=-13 a0=7ffd9d0e2790 a1=90800 a2=d42b95 a3=fffffffffffffff0 items=0 ppid=24250 pid=24252 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=40015 comm="logrotate" exe="/usr/sbin/logrotate" subj=system_u:system_r:logrotate_t:s0-s0:c0.c1023 key=(null)
    type=AVC msg=audit(1519761121.411:493759): avc:  denied  { read } for  pid=24252 comm="logrotate" name="redmine" dev=vda3 ino=6815801 scontext=system_u:system_r:logrotate_t:s0-s0:c0.c1023 tcontext=system_u:object_r:var_lib_t:s0 tclass=lnk_file
    
  • 日時を指定して抜粋
    # ausearch -m avc -ts today

    -tsは抜粋する日時範囲の開始を指定。
    -teは抜粋する日時範囲の終了を指定。
    単語で指定の場合の例)today, yesterday, this-week, week-ago, boot, recent, 等

semanage fcontext

ディレクトリ・ファイルに割当てられているタイプを調べます。

# semanage fcontext -l
SELinux fcontext                                   タイプ                コンテキスト

/                                                  directory          system_u:object_r:root_t:s0
/.*                                                all files          system_u:object_r:default_t:s0
/[^/]+                                             regular file       system_u:object_r:etc_runtime_t:s0
  :

sesearch

プロセスのドメインがリソースのタイプに対し可能な操作を調べます。

  • ドメインhttpd_tがタイプvar_lib_tに対し可能な操作を調べる
    $ sesearch -A -s httpd_t -t var_lib_t
      :
    allow httpd_t file_type:dir { getattr open search };
    allow httpd_t file_type:filesystem getattr;
    allow httpd_t var_lib_t:dir { add_name getattr ioctl lock open read remove_name search write };
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_run_preupgrade ]:False
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_run_preupgrade ]:True
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_run_stickshift ]:False
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_run_stickshift ]:True
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_serve_cobbler_files ]:False
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_serve_cobbler_files ]:False
    allow httpd_t var_lib_t:dir { getattr open search }; [ httpd_serve_cobbler_files ]:True
    allow httpd_t var_lib_t:file { getattr ioctl lock open read };
    allow httpd_t var_lib_t:lnk_file { getattr read };
      :
    

httpd_t以外にもdaemon、nsswitch_domain等が表示されましたが、上述はhttpd_tだけを抜粋しています。

semanage port(ポートタイプの調べ方)

# semanage port -l
SELinux ポートタイプ                 プロト      ポート番号
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
ssh_port_t                     tcp      22
 :

設定系のコマンド

chcon

ファイルのSELinuxコンテキストを一時的に変更します。再ラベル付けされるかrestoreconコマンドが実行されるとchconで指定した内容が失われます。

  • ファイルまたはディレクトリに対して設定
    ~$ chcon -t httpd_sys_content_t /var/lib/svn
  • ディレクトリ以下に再帰的に設定
    ~$ chcon -R -t httpd_sys_content_t /var/lib/svn

semanage fcontext

ファイルのSELinuxコンテキストを永続的に変更します。
変更内容は、/etc/selinux/targeted/contexts/files/file_contexts に反映されます。新規ファイル・ディレクトリに対してコマンドを実行したときは、file_contexts.local に反映されます。

~$ sudo semanage fcontext -a -t httpd_sys_context_t /var/lib/svn
~$ sudo restorecon -v /var/lib/svn

新規作成のファイル及びディレクトリは親ディレクトリのSELinuxタイプを引き継ぎます。
しかし、既に作成されたディレクトリについては後から引継ぎはできないので、次のように正規表現でパターンを指定します。

~$ sudo semanage fcontext -a -t httpd_sys_context_t "/var/lib/svn(/.*)?" 
~$ sudo restorecon -R -v /var/lib/svn

既に割り当てられたリソースタイプを変更する場合、semanage fcontext の -aオプションではエラー(already defined)となるので、-mオプションを指定します。

~$ sudo semanage fcontext -m -t httpd_sys_context_t "/var/lib/git(/.*)?" 

メモ集

httpd関係

httpdからの読み書き

~$ getsebool httpd_unified
httpd_unified --> on

のとき、httpd_sys_content_t は、httpdからの読み書きが可能です。

指定したディレクトリ以下をhttpdで読み書き可能としたい

例えば、/var/lib/svn以下にあるリポジトリをhttpdで読み書きする場合、/var/libにはhttpdのアクセスが設定されていないのでそのままでは書き込み時にエラーとなります。

~$ sudo semanage fcontext -a -t httpd_sys_content_t '/var/lib/svn(/.*)?'
~$ sudo restorecon -R /var/lib/svn
  • 注)/var/lib/svn(/.*)? をシングルクォートではなくダブルクォートで囲むとエラーとなります(コマンドシェルが先に展開してしまうため)

ポート番号を80から変更したらhttpdが起動しない

# service httpd start
Starting httpd: (13)Permission denied: make_sock: could not bind to address [::]:8086
(13)Permission denied: make_sock: could not bind to address 0.0.0.0:8086
no listening sockets available, shutting down
Unable to open logs

SELinuxが、httpdの利用可能なポートを管理しています。デフォルトでは次の中の"http_port_t"に記載されている、80, 81, 443, 488, 8008, 8009, 8443, 9000ポートが利用可能です。

# semanage port -l | grep http
http_cache_port_t              tcp      3128, 8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

ポートの追加は、semanageで可能です。

# semanage port -a -t http_port_t -p tcp 8086


ほぼ4年前に更新