Table of Contents
管理ツールのインストール
- 管理ツールのパッケージ
# yum install setroubleshoot
- GUI用追加パッケージ
# yum install policycoreutils-gui
動作モード切替
- 現在のモードを調べる。
# getenforce
- 「Enforcing」モードに変更。
# setneforce 1
- 「Permissive」モードに変更。
# setenforce 0
- SELinuxの動作モードをコマンドラインで切り替えるには - @IT
動作モードの永続的変更
- Disabled → Enforcing の場合、設定不備等で最悪起動しなくなる可能性があるので、一旦 Permissive で動作確認する。
- Disabled → Permissive/Enforcing の場合、再起動時に再ラベル付けが行われるため、起動に時間が掛かることがある。
-
/etc/selinux/config
- Permissive
SELINUX=permissive SELINUXTYPE=targeted
- Enforcing
SELINUX=enforcing SELINUXTYPE=targeted
- Permissive
第2章 SELinux のステータスおよびモードの変更 Red Hat Enterprise Linux 8 | Red Hat Customer Portal
ログ分析
- ログ分析
# sealert -a /var/log/audit/audit.log
- 一時許可ポリシーの適用
# grep <分析して出てきたキーワード> /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp
- 複数の項目を許可するポリシーが必要な場合
- SELinux を Permissive モードに切り替えて該当プログラムを実行し、動かない原因が SELinux であることを確認する。
# setenforce 0
- 一時許可ポリシーを削除。
# semodule -r mypol
- ログファイル更新。
# service auditd rotate
- 更新に失敗する場合は、auditd の動作確認/再起動を行う。
# service auditd status # service auditd restart
- 該当プログラムを実行し、ログを記録する。
- Enforcing モードに戻す。
# setenforce 1
- ログからポリシーを作成する。
- 許可すべき項目が不明な場合
「XXX」は自分で決めた名前。
# cat /var/log/audit/audit.log | audit2allow -M mypol_XXX
- 許可すべき項目が既知の場合
必要な項目を「|」で繋げて検索する。
# grep "項目1\|項目2\|項目3" /var/log/audit/audit.log | audit2allow -M mypol_XXX
- 許可すべき項目が不明な場合
- ポリシーの確認
関係ない項目まで許可されていないかどうか確認する。# vi mypol_XXX.te
- ポリシーの手動コンパイル
# checkmodule -M -m -o mypol_XXX.mod mypol_XXX.te # semodule_package -o mypol_XXX.pp -m mypol_XXX.mod
- ポリシーをインストール。
# semodule -i mypol_XXX.pp
- SELinux を Permissive モードに切り替えて該当プログラムを実行し、動かない原因が SELinux であることを確認する。
スクリプト
コンパイルとインストール
-
installSELPolicy.zip
#!/bin/bash if [ $# -lt 1 ]; then echo "usage: $0 <policy.te>" echo "SELinux Policy ファイルをコンパイル&インストールします。" exit 1 fi POLICYNAME="$1" POLICYNAME=${POLICYNAME##*/} POLICYNAME=${POLICYNAME%.*} checkmodule -M -m -o ${POLICYNAME}.mod ${POLICYNAME}.te semodule_package -o ${POLICYNAME}.pp -m ${POLICYNAME}.mod rm -f ${POLICYNAME}.mod EXIST=`semodule -l | grep ${POLICYNAME}` if [ -n "$EXIST" ]; then semodule -v -r ${POLICYNAME} fi semodule -v -i ${POLICYNAME}.pp
ポリシーをソート
- ポリシーファイルの require 部および { } 内をソートするスクリプト。
sort_policy.zip#!/usr/bin/perl use strict; use warnings; use utf8; my $fileNameIn = shift or die("usage: sort_policy.pl <infile.te>\n"); my $fileNameOut = $fileNameIn . '.sorted'; open( my $fhIn, '<', $fileNameIn ) or die( "$fileNameIn: $!\n" ); open( my $fhOut, '>', $fileNameOut ) or die( "$fileNameOut: $!\n" ); while( my $line = <$fhIn> ){ if ( $line =~ /^require\s+\{/ ){ last; } print $fhOut $line; } print $fhOut "require {\n"; my @types = (); my @classes = (); while( my $line = <$fhIn> ){ if ( $line =~ /^\}/ ){ last; } $line = sortInBracket( $line ); if ( $line =~ /^\s+type/ ){ push( @types, $line ); } else { push( @classes, $line ); } } print $fhOut sort( @types ); print $fhOut sort( @classes ); print $fhOut "}\n"; while( my $line = <$fhIn> ){ if ( $line =~ /^allow\s/ ){ $line = sortInBracket( $line ); } print $fhOut $line; } close( $fhIn ); close( $fhOut ); exit(); sub sortInBracket { my $line = shift || ''; $line =~ s<\{\s*([^\}]+)\s*\}><'{ '.join(" ", sort(split(/\s+/, $1))).' }'>e; return $line; } # EOF
ブーリアン値設定
現在の設定値を確認 (httpの場合)
# getsebool -a | grep http
ftpd
- ユーザホームディレクトリの読み書き許可
許可が無いと「500 OOPS: cannot change directory」エラーでログインできない。# setsebool -P ftp_home_dir 1
- ユーザホームディレクトリ外の読み書き許可
# setsebool -P allow_ftpd_full_access 1
httpd
- メール送信を許可
# setsebool -P httpd_can_sendmail 1
- ネットワークアクセスを許可
# setsebool -P httpd_can_network_connect 1
- データベースアクセスを許可
# setsebool -P httpd_can_network_connect_db 1
- ユーザディレクトリへのアクセスを許可
# setsebool -P httpd_read_user_content 1
- ユーザのホームディレクトリへのアクセスを許可
# setsebool -P httpd_enable_homedirs 1
- スクリプトのファイル書き出しを許可
# setsebool -P httpd_sys_script_anon_write 1
named
- 外部ドメインの名前解決に失敗する(検索結果のキャッシュに失敗している)
# setsebool -P named_write_master_zones 1
smbd
- ユーザホームディレクトリのアクセスを許可
# setsebool -P samba_enable_home_dirs 1
- 共有フォルダの読み書きを許可
# setsebool -P samba_export_all_rw 1
ポート設定
- 許可ポート確認 (sshdの場合)
# semanage port -l | grep ssh
- 許可ポート追加 (POPの場合)
# semanage port -a -t ssh_port_t -p tcp <追加ポート>
- 許可ポート確認 (POPの場合)
# semanage port -l | grep pop_port_t
- 許可ポート追加 (POPの場合)
# semanage port -a -t pop_port_t -p tcp <追加ポート>
コンテキスト設定
- /var/www/html, /var/www/cgi-bin 以外にApacheのコンテンツを配置する場合、ディレクトリに適切なタイプを設定する必要がある。
- コンテキスト確認
# ls -lZ
- 静的コンテンツ
# chcon -R -t httpd_sys_content_t <ディレクトリ>
- 動的コンテンツ
# find . -name "*.cgi" -or -name "*.pl" | xargs chcon -v -t httpd_sys_script_exec_t
- サービス設定ファイル
# chcon -t systemd_unit_file_t /usr/lib/systemd/system/your-service.service # chcon -t systemd_unit_file_t /usr/lib/systemd/system/your-service.timer
- シンボリックリンクに対してコンテキストの変更を行うと、デフォルトではリンク先のコンテキストが変更される。
シンボリックリンク自体のコンテキストを変更するには「--no-dereference」を指定する。# chcon --no-dereference -t httpd_sys_script_exec_t <シンボリックリンク>
- Apacheで新規ディレクトリや新規ファイルを作成する必要がある場合は、書き込まれるディレクトリに対してパーミッション設定に加えてfcontext設定が必要。
その際、パスはフルパスで指定すること。
SELinux コンテキスト: ファイルのラベル付け# chmod 777 /var/www/vh1-html/Service1/store/ # semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/vh1-html/Service1/store/(.*)" # restorecon -vR /var/www/vh1-html/Service1/store/
バグ
ps コマンドが /proc/ にアクセスしようとしてブロックされる
- ログ例
type=AVC msg=audit(xxx.xxx:xxx): avc: denied { getattr } for pid=xxx comm="ps" path="/proc/<pid>" dev=proc ino=xxx scontext=unconfined_u:system_r:httpd_sys_script_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=dir
- sealert 分析結果
ps に、 <pid> directory の getattr アクセスがデフォルトで許可されるべきです。
- Bug 982205 – SELinux is preventing /usr/bin/ps from 'getattr' accesses on the directory /proc/.