1 環境
[root@master ~]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
[root@master ~]# uname -r
3.10.0-514.el7.x86_64
2 SELinuxで使うコマンドとパッケージ
コマンド | パッケージ名 | 備考 |
---|---|---|
semanage | policycoreutils-python | ファイルやポートに対するタイプを変更する |
audit2allow | 同上 | ログからルールを作成する |
audit2why | 同上 | ログからアクセス拒否の理由を出力する |
restorecon | policycoreutils | デフォルトの SELinux コンテキストを復元する |
semodule | 同上 | モジュールのインストール、削除等をおこなう |
sestatus | 同上 | SElinuxの状態やBoolean値の状態を表示する |
sesearch | setools-console | |
seinfo | 同上 | |
findcon | 同上 | ファイルコンテキストを探す |
sepolicy | policycoreutils-devel | |
chcon | coreutils | |
matchpathcon | libselinux-utils | |
setroubleshootd | setroubleshoot-server |
3 セキュリティコンテキストの変更方法
ここでは、セキュリティコンテキストのタイプの変更方法について説明する。
3.1 一時的に変更する方法(chcon)
restoreconを実行すると、タイプがデフォルトのタイプに戻る。
テスト用のファイル(index.html)を作成する。
[root@master ~]# touch /var/www/html/index.html
テスト用ファイルのセキュリティコンテキストを確認する。タイプはhttpd_sys_content_tであることがわかる。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★httpd_sys_content_t:s0 /var/www/html/index.html
タイプをsamba_share_tに変更する。
[root@master ~]# chcon -t samba_share_t /var/www/html/index.html
タイプを確認する。samba_share_tに変更されたことがわかる。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★samba_share_t:s0 /var/www/html/index.html
リブートする。
[root@master ~]# shutdown -r now
タイプを確認する。リブート前のタイプ(samba_share_t)と同じであることがわかる。
つまり、リブートしてもタイプは変更されない、ということ。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/index.html
restoreconを実行する。
[root@master ~]# restorecon /var/www/html/index.html
タイプがhttpd_sys_content_tに戻ったことがわかる(★印)
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★httpd_sys_content_t:s0 /var/www/html/index.html
3.2 永続的に変更する方法(semanage)
セキュリティコンテキストのタイプを確認する。httpd_sys_content_tであることがわかる(★印)。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★httpd_sys_content_t:s0 /var/www/html/index.html
タイプをsamba_share_t に変更する(★印)
[root@master ~]# semanage fcontext -a -t ★samba_share_t /var/www/html/index.html
semanageを実行すると、セキュリティコンテキストがファイル(file_contexts.local)に保存されることがわかる。
[root@master ~]# grep index.html /etc/selinux/targeted/contexts/files/file_contexts.local
/var/www/html/index.html system_u:object_r:samba_share_t:s0
タイプを確認する。タイプは変更されていないことがわかる。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★httpd_sys_content_t:s0 /var/www/html/index.html
restoreconを実行する。
[root@master ~]# restorecon /var/www/html/index.html
タイプを確認する。samba_share_tに変更されたことがわかる(★印)。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★samba_share_t:s0 /var/www/html/index.html
[root@master ~]#
セキュリティコンテキストのタイプを確認する。タイプはsamba_share_tであることがわかる。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★samba_share_t:s0 /var/www/html/index.html
タイプからsamba_share_t を削除する。
[root@master ~]# semanage fcontext -d -t samba_share_t /var/www/html/index.html
セキュリティコンテキストのタイプを確認する。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★samba_share_t:s0 /var/www/html/index.html
[root@master ~]# grep index.html /etc/selinux/targeted/contexts/files/file_contexts.local
restoreconを実行する。
[root@master ~]# restorecon /var/www/html/index.html
タイプを確認する。タイプがhttpd_sys_content_tに戻ったことがわかる。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★httpd_sys_content_t:s0 /var/www/html/index.html
4 アクセスエラーが発生した場合の対処方法
アクセスエラーが発生した場合、下記いずれかの方法でアクセスを許可することができる。
1は推奨しない。
- OS全体のSELinux無効化(setenfore 0または/etc/sysconfig/selinux)
- 特定ドメインのみアクセスを許可する。
- ルールを作成して、アクセスを許可する。
4.1 OS全体でSELinuxを無効化する方法
[root@master ~]# cat /var/www/html/index.html
test
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/index.html
[root@master ~]#
httpdプロセスのドメインを確認する。ドメインはhttpd_tであることがわかる。
[root@master ~]# ps -Z -C httpd
LABEL PID TTY TIME CMD
system_u:system_r:httpd_t:s0 6683 ? 00:00:01 httpd
system_u:system_r:httpd_t:s0 6684 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 6685 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 6686 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 6687 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 6688 ? 00:00:00 httpd
[root@master ~]#
httpd_tドメインが httpd_sys_content_tタイプにアクセス可能かどうか確認する。
[root@master ~]# sesearch -A -s httpd_t -t httpd_sys_content_t
Found 25 semantic av rules:
allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ;
allow daemon httpd_sys_content_t : dir { getattr search open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t file_type : filesystem getattr ;
allow httpd_t file_type : dir { getattr search open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
allow httpd_t httpd_sys_content_t : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpd_content_type : lnk_file { read getattr } ;
allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow httpd_t httpdcontent : file { read getattr execute open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t httpdcontent : lnk_file { ioctl read write create getattr setattr lock append unlink link rename } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t httpd_content_type : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
httpアクセスをする。アクセスが拒否されたことがわかる。
[root@master ~]# curl http://localhost/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
-以下、略-
OS全体のSELinuxを無効化する。
[root@master ~]# setenforce 0
SELinxuの状態を確認する。SELinux無効であることがわかる。
[root@master ~]# getenforce
Permissive
httpアクセスする。今度はアクセスできた。
[root@master ~]# curl http://localhost/index.html
test
4.2 特定ドメインだけSELinuxを無効化する方法
SELinuxの状態を確認する。OS全体でSELinuxが有効になっていることがわかる。
[root@master ~]# getenforce
Enforcing
http_dドメインのSELinuxを無効化する。
[root@master ~]# semanage permissive -a httpd_t
http_dドメインのSELinuxが無効化されたことがわかる。
[root@master ~]# semanage permissive -l|grep httpd_t
httpd_t
httpアクセスする。アクセスできることがわかる。
[root@master ~]# curl http://localhost/index.html
test
http_dドメインのSELinuxを有効化する。
[root@master ~]# semanage permissive -d httpd_t
libsemanage.semanage_direct_remove_key: Removing last permissive_httpd_t module (no other permissive_httpd_t module exists at another priority).
http_dドメインのSELinuxが有効化されたことがわかる(リスト表示されないので)
[root@master ~]# semanage permissive -l|grep httpd_t
httpアクセスする。アクセスが拒否されたことがわかる。
[root@master ~]# curl http://localhost/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.html
on this server.</p>
</body></html>
4.3 ルールを作成する方法
[root@master selinux]# getenforce
Enforcing
[root@master selinux]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/index.html
[root@master selinux]# curl http://localhost/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.html
on this server.</p>
</body></html>
audit.logからアクセス許可のルールを作成する。
[root@master selinux]# audit2allow -M test < /var/log/audit/audit.log
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i test.pp
ファイルを確認する。
[root@master selinux]# ls
test.pp test.te
ルールの中身を確認する。
[root@master selinux]# cat test.te
module test 1.0;
require {
type httpd_t;
type samba_share_t;
class file { getattr open read };
}
# ============= httpd_t ==============
# !!!! The file '/var/www/html/index.html' is mislabeled on your system.
# !!!! Fix with $ restorecon -R -v /var/www/html/index.html
allow httpd_t samba_share_t:file { getattr open read };
[root@master selinux]#
モジュール(test.pp)をインストールする。
[root@master selinux]# semodule -i test.pp
インストールされているモジュールを確認する。
[root@master selinux]# semodule -l|grep -w test
test 1.0
httpアクセスする。今度はアクセスできた。
[root@master selinux]# curl http://localhost/index.html
test
モジュールを削除する。
[root@master selinux]# semodule -r test
libsemanage.semanage_direct_remove_key: Removing last test module (no other test module exists at another priority).
インストールされているモジュールを確認する。モジュールが削除できたことがわかる。
[root@master selinux]# semodule -l|grep -w test
[root@master selinux]#
httpアクセスをする。モジュールを削除してルールがなくなったので、アクセス拒否されたことがわかる。
[root@master selinux]# curl http://localhost/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
5 semanageコマンド
ディレクトリやポートに対するセキュリティコンテキストの設定、変更、削除を行う。
5.1 ディレクトリに対する操作
5.1.1 設定方法(-a)
テスト用ディレクトリを作成する。
[root@master ~]# mkdir -p /var/example
作成したディレクトリのセキュリティコンテキストのタイプを確認する。タイプがvar_tであることがわかる(★印)。
[root@master ~]# ls -lZd /var/example
drwxr-xr-x. root root unconfined_u:object_r:★var_t:s0 /var/example
/var/example配下のタイプをhttpd_sys_rw_content_tに設定する。"-a"が設定、"-t"がタイプを意味する。
[root@master ~]# semanage fcontext -a -t httpd_sys_rw_content_t "/var/example(/.*)?"
/var/example配下にhttpd_sys_rw_content_tのタイプが設定できたことがわかる。
[root@master ~]# semanage fcontext -l|grep /var/example
/var/example(/.*)? all files system_u:object_r:★httpd_sys_rw_content_t:s0
セキュリティコンテキストを確認する。テスト用ディレクトリのタイプは、var_tのままであることがわかる。
[root@master ~]# ls -lZd /var/example
drwxr-xr-x. root root unconfined_u:object_r:★var_t:s0 /var/example
restoreconを実行する。
[root@master ~]# restorecon -R /var/example
5.1.2 変更方法(-m)
セキュリティコンテキストを変更する。"-m"が変更、"-t"がタイプを意味する。
[root@master ~]# semanage fcontext -m -t public_content_t "/var/example(/.*)?"
セキュリティコンテキストのタイプを確認する。タイプは元のままであることがわかる(★印)。
[root@master ~]# ls -ldZ /var/example/
drwxr-xr-x. root root unconfined_u:object_r:★httpd_sys_rw_content_t:s0 /var/example/
restoreconを実行する。
[root@master ~]# restorecon -R /var/example/
ファイルコンテキストを確認する。指定したタイプが設定されていることがわかる(★印)。
[root@master ~]# ls -ldZ /var/example/
drwxr-xr-x. root root unconfined_u:object_r:★public_content_t:s0 /var/example/
5.1.3 削除方法(-d)
セキュリティコンテキストを削除する。"-a"が削除を意味する。
[root@master ~]# semanage fcontext -d "/var/example(/.*)?"
セキュリティコンテキストを確認する。タイプは元のままであることがわかる(★印)。
[root@master ~]# ls -ldZ /var/example/
drwxr-xr-x. root root unconfined_u:object_r:★public_content_t:s0 /var/example/
restoreconを実行する。
[root@master ~]# restorecon -R /var/example/
セキュリティコンテキストを確認する。デフォルトのタイプに戻ったことがわかる(★印)。
[root@master ~]# ls -ldZ /var/example/
drwxr-xr-x. root root unconfined_u:object_r:★var_t:s0 /var/example/
5.2 ポートに対する操作
ポートコンテキストにポート番号(22222)を追加する。"-a"が設定、"-t"がタイプを意味する。
[root@master ~]# semanage port -a -t kubernetes_port_t -p tcp 22222
ポートコンテキストを確認する。22222番ポートが登録されたことがわかる(★印)。
[root@master ~]# semanage port -l |grep kubernetes_port_t
kubernetes_port_t tcp ★22222, 4001, 4194, 10250
ポートコンテキストからポート番号(22222)を削除する。
[root@master ~]# semanage port -d -t kubernetes_port_t -p tcp 22222
ポートコンテキストを確認する。22222番ポートが削除されたことがわかる。
[root@master ~]# semanage port -l |grep kubernetes_port_t
kubernetes_port_t tcp 4001, 4194, 10250
[root@master ~]#
docker,kuberneteのポートコンテキストを表示する。
8080はkube-apiserver、10250はkubelet,4001はetcdのポート番号。他は良くわからない。
[root@master ~]# semanage port -l |grep -e 8080 -e 10250
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
kubernetes_port_t tcp 4001, 4194, 10250
[root@master ~]#
6 アクセス制御ルールの調査方法(sesearch)
6.1 allowルールの調べ方
httpd_tドメインが、httpd_sys_content_tタイプにアクセス可能かどうかを調べる。
一番最初に表示された結果(●印)をみると、httpd_tドメインは、httpd_sys_content_tタイプの
ディレクトリ(dir)に対して、ioctl,..,openできることがわかる。
[root@master ~]# sesearch -A -n -s httpd_t -t httpd_sys_content_t
Found 25 semantic av rules:
●allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ;
allow daemon httpd_sys_content_t : dir { getattr search open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t ★file_type : filesystem getattr ;
allow httpd_t ★file_type : dir { getattr search open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
allow httpd_t httpd_sys_content_t : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpd_content_type : lnk_file { read getattr } ;
allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow httpd_t httpdcontent : file { read getattr execute open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpdcontent : dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t httpdcontent : lnk_file { ioctl read write create getattr setattr lock append unlink link rename } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t httpd_content_type : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
[root@master ~]#
タイプの中でfile_typeというタイプには、"_t"がついていない(上記★印)。
"_t"がついていないタイプは、複数のタイプの集合である。
seinfo コマンドを実行すると、file_typeが、以下のようなタイプの集合であることがわかる。
このタイプの中にhttpd_sys_content_tが含まれている(■印)。
[root@master ~]# seinfo -afile_type -x
file_type
abrt_exec_t
abrt_initrc_exec_t
abrt_unit_file_t
abrt_etc_t
abrt_var_log_t
abrt_var_lib_t
abrt_tmp_t
abrt_var_cache_t
abrt_var_run_t
abrt_dump_oops_exec_t
abrt_handle_event_exec_t
-中略-
httpd_suexec_tmp_t
■httpd_sys_content_t
httpd_sys_htaccess_t
-以下、略-
さらに、オブジェクトクラスで絞り込みを行う。
-------------------------------
1. fileで絞り込む方法(-c file)
-------------------------------
[root@master html]# sesearch -A -s httpd_t -t httpd_sys_content_t -c file
Found 5 semantic av rules:
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow httpd_t httpdcontent : file { read getattr execute open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
-------------------------------
2. dirで絞り込む方法(-c dir)
-------------------------------
[root@master html]# sesearch -A -s httpd_t -t httpd_sys_content_t -c dir
Found 16 semantic av rules:
allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ;
allow daemon httpd_sys_content_t : dir { getattr search open } ;
allow httpd_t file_type : dir { getattr search open } ;
-以下、略-
--------------------------------------
3. lnk_fileで絞り込む方法(-c lnk_file)
--------------------------------------
[root@master html]# sesearch -A -s httpd_t -t httpd_sys_content_t -c lnk_file
Found 3 semantic av rules:
allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ;
allow httpd_t httpd_content_type : lnk_file { read getattr } ;
allow httpd_t httpdcontent : lnk_file { ioctl read write create getattr setattr lock append unlink link rename } ;
6.2 ファイル名遷移の調べ方(File Name Transition)
タイプ遷移に比べると、ファイル名遷移(File Name Transition)の方が、
より厳密にタイプ遷移を指定することが可能になる。
(1)の意味:unconfined_t ドメインのプロセスがvar_log_tタイプのディレクトリ配下にファイル(lastlog)を
作成すると、そのファイルのタイプはlastlog_t になる。
(2)の意味:unconfined_t ドメインのプロセスがvar_log_tタイプのディレクトリ配下にディレクトリ(lxc)を
作成すると、そのディレクトリのタイプがcontainer_log_t になる。
タイプ遷移を調べる。
[root@master ~]# sesearch -T -s unconfined_t -t var_log_t
Found 14 named file transition filename_trans:
type_transition unconfined_t var_log_t : file lastlog_t "lastlog"; ★...(1) ファイルの場合
type_transition unconfined_t var_log_t : file rpm_log_t "yum.log";
type_transition unconfined_t var_log_t : dir container_log_t "lxc"; ★...(2) ディレクトリの場合
type_transition unconfined_t var_log_t : file NetworkManager_var_lib_t "wpa_supplicant.log";
type_transition unconfined_t var_log_t : file devicekit_var_log_t "pm-powersave.log";
type_transition unconfined_t var_log_t : file faillog_t "btmp";
type_transition unconfined_t var_log_t : file faillog_t "tallylog";
type_transition unconfined_t var_log_t : file devicekit_var_log_t "pm-suspend.log";
type_transition unconfined_t var_log_t : dir var_log_t "anaconda";
type_transition unconfined_t var_log_t : dir snapperd_data_t ".snapshots";
type_transition unconfined_t var_log_t : file plymouthd_var_log_t "boot.log";
type_transition unconfined_t var_log_t : file faillog_t "faillog";
type_transition unconfined_t var_log_t : file wtmp_t "wtmp";
type_transition unconfined_t var_log_t : file rpm_log_t "up2date";
自分自身(bash)のセキュリティコンテキストを調べる。ドメインがunconfined_tであることがわかる(★印)。
[root@master ~]# ps -Z -p `echo $$`
LABEL PID TTY TIME CMD
unconfined_u:unconfined_r:★unconfined_t:s0-s0:c0.c1023 15501 pts/1 00:00:00 bash
/var/logディレクトリのタイプを調べる。タイプはvar_log_tであることがわかる。
[root@master ~]# ls -lZd /var/log
drwxr-xr-x. root root system_u:object_r:★var_log_t:s0 /var/log
上記(1)について確認する。/var/log配下にlastlogというファイルを作成する。
[root@master ~]# touch /var/log/lastlog
作成したファイルのタイプを確認する。タイプがlastlog_tであることがわかる。
[root@master ~]# ls -lZ /var/log/lastlog
-rw-r--r--. root root system_u:object_r:★lastlog_t:s0 /var/log/lastlog
別の名前のファイルを作成する。
[root@master ~]# touch /var/log/hoge
タイプがlastlog_t ではなく、var_log_tであることがわかる。
[root@master ~]# ls -lZ /var/log/hoge
-rw-r--r--. root root unconfined_u:object_r:★var_log_t:s0 /var/log/hoge
上記(2)について確認する。/var/log配下にlxcというディレクトリを作成する。
[root@master ~]# mkdir /var/log/lxc
作成したディレクトリのタイプを確認する。タイプがcontainer_log_t であることがわかる。
[root@master ~]# ls -lZd /var/log/lxc/
drwxr-xr-x. root root unconfined_u:object_r:★container_log_t:s0 /var/log/lxc/
別の名前のディレクトリを作成する。
[root@master ~]# mkdir /var/log/lll
タイプがcontainer_log_tではなく、var_log_tであることがわかる。
[root@master ~]# ls -lZd /var/log/lll
drwxr-xr-x. root root unconfined_u:object_r:★var_log_t:s0 /var/log/lll
7 ポリシ情報の表示(seinfo)
7.2 ドメインの確認方法
[root@master ~]# seinfo -adomain -x
domain
abrt_t
abrt_dump_oops_t
abrt_handle_event_t
abrt_helper_t
-中略-
httpd_t
httpd_helper_t
httpd_php_t
httpd_rotatelogs_t
httpd_suexec_t
httpd_sys_script_t
httpd_user_script_t
httpd_passwd_t
httpd_unconfined_script_t
-以下、略-
7.2 タイプの確認方法
[root@master ~]# seinfo -thttpd_t -x
httpd_t
nsswitch_domain
can_change_object_identity
corenet_unlabeled_type
domain
kernel_system_state_reader
netlabel_peer_type
daemon
syslog_client_type
pcmcia_typeattr_7
pcmcia_typeattr_6
pcmcia_typeattr_5
pcmcia_typeattr_4
pcmcia_typeattr_3
pcmcia_typeattr_2
pcmcia_typeattr_1
sepgsql_client_type
Aliases
phpfpm_t
7.3 Permissiveドメインの確認方法
[root@master ~]# seinfo --permissive -x
Permissive Types: 6
blkmapd_t
hsqldb_t
ipmievd_t
sanlk_resetd_t
systemd_hwdb_t
targetd_t
[root@master ~]#
8 httpdをデフォルトポート番号(80)以外のポート番号で動かす方法
8.1 SELinux設定変更前の状態
SElinuxがEnforcingの状態で次のことを確認する。
- httpdがListenポート番号として8888番を使えるかどうか?
結論として、デフォルトのままでは使えない。8.2または8.3で使えるようにする。
SElinuxの状態を確認する。
[root@master ~]# getenforce
Enforcing
httpdサーバのListenポート番号を変更(80->8888)する。
[root@master ~]# cat /etc/httpd/conf/httpd.conf|grep Listen
# Listen: Allows you to bind Apache to specific IP addresses and/or
# Change this to Listen on specific IP addresses as shown below to
# Listen 80
Listen 8888
httpdを起動する。httpdの起動が失敗したことがわかる。
[root@master ~]# systemctl start httpd
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
[root@master ~]#
httpd失敗の原因をjournalctlコマンドで確認する。bindシステムコールで"Permission denied"が発生していることがわかる(★印)。
[root@master ~]# journalctl -u httpd
-中略-
3月 26 10:08:40 master httpd[33016]: [Sun Mar 26 10:08:40.308429 2017] [alias:warn] [pid 33016] AH00671: The ScriptAlias directive in /etc/httpd/conf/httpd.
3月 26 10:08:40 master httpd[33016]: [Sun Mar 26 10:08:40.310101 2017] [alias:warn] [pid 33016] AH00671: The ScriptAlias directive in /etc/httpd/conf/httpd.
3月 26 10:08:40 master httpd[33016]: [Sun Mar 26 10:08:40.310143 2017] [alias:warn] [pid 33016] AH00671: The ScriptAlias directive in /etc/httpd/conf/httpd.
3月 26 10:08:40 master httpd[33016]: [Sun Mar 26 10:08:40.310158 2017] [alias:warn] [pid 33016] AH00671: The ScriptAlias directive in /etc/httpd/conf/httpd.
3月 26 10:08:40 master httpd[33016]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.0.10. Set the 'Ser
3月 26 10:08:40 master httpd[33016]: (13)Permission denied: AH00072: make_sock: ★could not bind to address [::]:8888
3月 26 10:08:40 master httpd[33016]: (13)Permission denied: AH00072: make_sock: ★could not bind to address 0.0.0.0:8888
3月 26 10:08:40 master httpd[33016]: no listening sockets available, shutting down
3月 26 10:08:40 master httpd[33016]: AH00015: Unable to open logs
3月 26 10:08:40 master systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
3月 26 10:08:40 master kill[33018]: kill: cannot find process ""
3月 26 10:08:40 master systemd[1]: httpd.service: control process exited, code=exited status=1
3月 26 10:08:40 master systemd[1]: Failed to start The Apache HTTP Server.
3月 26 10:08:40 master systemd[1]: Unit httpd.service entered failed state.
3月 26 10:08:40 master systemd[1]: httpd.service failed.
-以下、略-
httpd失敗の原因をaudit.logでも確認してみる。bindシステムコールでEACCESが発生していることがわかる(★印)。
[root@master ~]# ausearch -i -if /var/log/audit/audit.log |less
----
type=SERVICE_START msg=audit(2017年03月26日 10:03:24.529:6087) : pid=1 uid=root auid=unset ses=unset subj=system_u:system_r:init_t:s0 msg='unit=httpd comm=sy
stemd exe=/usr/lib/systemd/systemd hostname=? addr=? terminal=? res=failed'
----
type=SYSCALL msg=audit(2017年03月26日 10:03:24.391:6086) : arch=x86_64 syscall=bind★ success=no exit=EACCES(許可がありません) a0=0x3 a1=0x7f163cfb4cf8 a2=0x10
a3=0x7ffcbc0743cc items=0 ppid=1 pid=32961 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(2017年03月26日 10:03:24.391:6086) : avc: denied { name_bind } for pid=32961 comm=httpd src=8888 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket
----
type=SYSCALL msg=audit(2017年03月26日 10:03:24.390:6085) : arch=x86_64 syscall=bind★ success=no exit=EACCES(許可がありません) a0=0x4 a1=0x7f163cfb4db8 a2=0x1c a3=0x7ffcbc074180 items=0 ppid=1 pid=32961 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(2017年03月26日 10:03:24.390:6085) : avc: denied { name_bind } for pid=32961 comm=httpd src=8888 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket
8.2 SELinuxの設定変更による方法
SELinuxの設定変更をして、httpdがListenできるポート番号を追加する。
ここでは、8888番ポートを追加する例を示す。
httpがListenできるポート番号を確認する。
[root@master ~]# semanage port -l|grep -w http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@master ~]# seinfo --portcon=8888
portcon tcp 1024-32767 system_u:object_r:unreserved_port_t:s0
portcon udp 1024-32767 system_u:object_r:unreserved_port_t:s0
httpがListenできるポート番号(8888)を追加する。
[root@master ~]# semanage port -a -t http_port_t -p tcp 8888
ポート番号を確認する。8888番が追加されたことが確認できる(★印)。
[root@master ~]# semanage port -l|grep -w http_port_t
http_port_t tcp ★8888, 80, 81, 443, 488, 8008, 8009, 8443, 9000
SElinuxの状態を確認する。Enforcingになっていることがわかる。
[root@master ~]# getenforce
Enforcing
httpdを起動する。今度は起動できた。
[root@master ~]# systemctl start httpd
[root@master ~]#
ポート番号を確認する。httpdが8888番を使っていることがわかる。
[root@master ~]# lsof -i:8888
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 33085 root 4u IPv6 223046 0t0 TCP *:ddi-tcp-1 (LISTEN)
httpd 33086 apache 4u IPv6 223046 0t0 TCP *:ddi-tcp-1 (LISTEN)
httpd 33087 apache 4u IPv6 223046 0t0 TCP *:ddi-tcp-1 (LISTEN)
httpd 33088 apache 4u IPv6 223046 0t0 TCP *:ddi-tcp-1 (LISTEN)
httpd 33089 apache 4u IPv6 223046 0t0 TCP *:ddi-tcp-1 (LISTEN)
httpd 33090 apache 4u IPv6 223046 0t0 TCP *:ddi-tcp-1 (LISTEN)
[root@master ~]#
8888番ポートにアクセスする。
[root@master ~]# cat /var/www/html/index.html
test
[root@master ~]# curl http://localhost:8888
test
8.3 httpdの定義ファイルを変更する方法
ここでは、SELinuxの設定変更をしない例を示す。
httpがListenできるポート番号を確認する。ここでは9000番ポートを使う(★印)。
[root@master ~]# semanage port -l|grep -w http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, ★9000
httpdが9000番ポートでListenするように編集する。
[root@master ~]# cat /etc/httpd/conf/httpd.conf|grep Listen
-中略-
Listen 9000
SELinuxの状態を確認する。Enforcingであることがわかる。
[root@master ~]# getenforce
Enforcing
httpdを起動する。起動できたたことがわかる。
[root@master ~]# systemctl start httpd
[root@master ~]#
ポート番号を確認する。httpdが9000番ポートでListenしていることがわかる。
[root@master ~]# lsof -i:9000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 33186 root 4u IPv6 227510 0t0 TCP *:cslistener (LISTEN)
httpd 33187 apache 4u IPv6 227510 0t0 TCP *:cslistener (LISTEN)
httpd 33188 apache 4u IPv6 227510 0t0 TCP *:cslistener (LISTEN)
httpd 33189 apache 4u IPv6 227510 0t0 TCP *:cslistener (LISTEN)
httpd 33190 apache 4u IPv6 227510 0t0 TCP *:cslistener (LISTEN)
httpd 33191 apache 4u IPv6 227510 0t0 TCP *:cslistener (LISTEN)
9000番ポートにアクセスする。
[root@master ~]# cat /var/www/html/index.html
test
[root@master ~]# curl http://localhost:9000
test
9 正しいルール、タイプの確認方法
9.1 正しいルールの確認方法(audit2why)
アクセス拒否の理由を調べる。1行が長いので折り返しています。
テスト環境の設定が悪いので、コマンドが誤ったアクセス拒否理由を出力している(TEルール作成を指示している)。
本来は、TEルールを作成するのではなく、index.htmlのタイプをhttpd_sys_content_tに変更するのが正解だと思う。
[root@master ~]# ausearch -m avc -ts today |audit2why
type=AVC msg=audit(1490574054.437:1121): avc: denied { getattr } for
pid=6451
comm="httpd"
path="/var/www/html/kernel-3.10.0-514.el7/linux-3.10.0-514.el7.centos.x86_64/HTML/index.html"
dev="sda3"
ino=9952163
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:admin_home_t:s0
tclass=file
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
-以下、略-
9.2 正しいタイプの確認方法(matchpathcon)
ファイルやディレクトリーに正しいセキュリティコンテキストが設定されているかどうかをチェックする。
初期状態を確認する。
[root@master ~]# ls -Z /var/www/html
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 docker-1.12.5-14
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 etcd-3.1.0-2
-rw-r--r--. root root unconfined_u:object_r:samba_share_t:s0 index.html
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 kernel-3.10.0-514.el7
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 kubernetes1.4
正しいセキュリティコンテキストが設定されているかどうかをチェックする。
それぞれ★印以降のセキュリティコンテキストを設定すべき、との表示が出力されれていることがわかる。
[root@master ~]# matchpathcon -V /var/www/html/*
/var/www/html/docker-1.12.5-14 has context unconfined_u:object_r:admin_home_t:s0, should be ★system_u:object_r:httpd_sys_content_t:s0
/var/www/html/etcd-3.1.0-2 has context unconfined_u:object_r:admin_home_t:s0, should be ★system_u:object_r:httpd_sys_content_t:s0
/var/www/html/index.html has context unconfined_u:object_r:samba_share_t:s0, should be ★system_u:object_r:httpd_sys_content_t:s0
/var/www/html/kernel-3.10.0-514.el7 has context unconfined_u:object_r:admin_home_t:s0, should be ★system_u:object_r:httpd_sys_content_t:s0
/var/www/html/kubernetes1.4 verified.
[root@master ~]#
テストとして、index.htmlのタイプだけを正しいセキュリティコンテキスト変更する。
[root@master ~]# restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
index.htmlのセキュリティコンテキストを確認する。正しいタイプに設定されたことがわかる(★印)。
[root@master ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:★httpd_sys_content_t:s0 /var/www/html/index.html
[root@master ~]#
10 ドメイン遷移の調べ方
10.1 遷移可能なドメイン一覧を調べる方法
httpd_tドメインが遷移できるドメインを調べる。
(1)は、httpd_tドメインがantivirus_exec_tタイプのファイルを実行すると、
antivirus_tというタイプにドメイン遷移する、という意味。
[root@master selinux]# sepolicy transition -s httpd_t
httpd_t @ antivirus_exec_t --> antivirus_t ★...(1)
httpd_t @ sepgsql_trusted_proc_exec_t --> sepgsql_trusted_proc_t
httpd_t @ httpd_php_exec_t --> httpd_php_t
-以下、略-
10.2 遷移可能かどうかを調べる方法
httpd_tドメインがhttpd_php_tドメインに遷移可能かどうかを調べる。遷移可能であることがわかる。
[root@master selinux]# sepolicy transition -s httpd_t -t httpd_php_t
httpd_t @ httpd_php_exec_t --> httpd_php_t
12 ブール値
ブール値を使うと、SELinux ポリシー記述の知識がなくても、ランタイム時にSELinux ポリシーの一部を変更できます。これにより、SELinux ポリシーの再ロードや再コンパイルをせずに、NFS ファイルシステムへのサービスによるアクセスを許可するといった変更が可能になります。
12.1 ブール値の一覧表示方法
[root@master ~]# semanage boolean -l
SELinux boolean 状態 初期値 説明
privoxy_connect_any (オン , オン) privoxy がすべての TCP ポートに接続できるかどうかを指定します。
smartmon_3ware (オフ , オフ) smartmon が 3ware コントローラーにおいてデバイスをサポートできるかどうかを指定しま
す。
-以下、略-
13 Docker,KubernetesのSELinux利用状況
13.1 ドメイン
[root@master ~]# ps -Z -C kube-apiserver,kube-scheduler,kube-controller-manager,kube-proxy,kubelet
LABEL PID TTY TIME CMD
system_u:system_r:unconfined_service_t:s0 75435 ? 00:00:11 kube-apiserver
system_u:system_r:unconfined_service_t:s0 75448 ? 00:00:12 kube-scheduler
system_u:system_r:unconfined_service_t:s0 75455 ? 00:00:16 kube-controller
system_u:system_r:unconfined_service_t:s0 75468 ? 00:00:22 kube-proxy
system_u:system_r:unconfined_service_t:s0 75592 ? 00:00:08 kubelet
[root@master ~]# ps -Z -C etcd
LABEL PID TTY TIME CMD
system_u:system_r:initrc_t:s0 75419 ? 00:00:13 etcd
[root@master ~]# ps -Z -C dockerd-current,docker-containerd-current
LABEL PID TTY TIME CMD
system_u:system_r:container_runtime_t:s0 75504 ? 00:00:08 dockerd-current
system_u:system_r:container_runtime_t:s0 75515 ? 00:00:01 docker-containe
13.2 タイプ
[root@master ~]# ls -lZ /etc/kubernetes/
-rw-r--r--. root root system_u:object_r:etc_t:s0 apiserver
-rw-r--r--. root root system_u:object_r:etc_t:s0 config
-rw-r--r--. root root system_u:object_r:etc_t:s0 controller-manager
-rw-r--r--. root root system_u:object_r:etc_t:s0 kubelet
-rw-r--r--. root root system_u:object_r:etc_t:s0 proxy
-rw-r--r--. root root system_u:object_r:etc_t:s0 scheduler
[root@master ~]# ls -lZ /etc/etcd/
-rw-r--r--. root root unconfined_u:object_r:etc_t:s0 etcd.conf
[root@master ~]# ls -lZ /etc/sysconfig/docker*
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/sysconfig/docker
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/sysconfig/docker-network
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/sysconfig/docker-storage
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/sysconfig/docker-storage-setup
Z 参考情報
SELinux リファレンス・ポリシーで新しいドメインを作成する
SELinuxを独学したよ
Linux OS のセキュリティ-2
SELINUX ユーザーおよび管理者のガイド
CentOS SELINUX
SELinuxの構成および使用
SELinux/Tutorials/How does a process get into a certain context