管理ツールのインストール

  • 管理ツールのパッケージ
    # yum install setroubleshoot
  • GUI用追加パッケージ
    # yum install policycoreutils-gui

動作モード切替

ログ分析

  • ログ分析
    # sealert -a /var/log/audit/audit.log
  • 一時許可ポリシーの適用
    # grep <分析して出てきたキーワード> /var/log/audit/audit.log | audit2allow -M mypol
    # semodule -i mypol.pp
  • 複数の項目を許可するポリシーが必要な場合
    1. SELinux を Permissive モードに切り替えて該当プログラムを実行し、動かない原因が SELinux であることを確認する。 # setenforce 0
    2. 一時許可ポリシーを削除。 # semodule -r mypol
    3. ログファイル更新。 # service auditd rotate
      • 更新に失敗する場合は、auditd の動作確認/再起動を行う。 # service auditd status # service auditd restart
    4. 該当プログラムを実行し、ログを記録する。
    5. Enforcing モードに戻す。 # setenforce 1
    6. ログからポリシーを作成する。
      • 許可すべき項目が不明な場合
        「XXX」は自分で決めた名前。
      # cat /var/log/audit/audit.log | audit2allow -M mypol_XXX
      
      • 許可すべき項目が既知の場合
        必要な項目を「|」で繋げて検索する。
      # grep "項目1\|項目2\|項目3" /var/log/audit/audit.log | audit2allow -M mypol_XXX
      
    7. ポリシーの確認
      関係ない項目まで許可されていないかどうか確認する。 # vi mypol_XXX.te
      • ポリシーの手動コンパイル # checkmodule -M -m -o mypol_XXX.mod mypol_XXX.te # semodule_package -o mypol_XXX.pp -m mypol_XXX.mod
    8. ポリシーをインストール。 # semodule -i mypol_XXX.pp

スクリプト

コンパイルとインストール

  • 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

sshd

# setsebool -P nis_enabled 1

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_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

ポート設定

  • 許可ポート確認 (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 <ディレクトリ>
  • 動的コンテンツ
    # chcon -R -t httpd_sys_script_exec_t <ディレクトリ>
  • シンボリックリンクに対してコンテキストの変更を行うと、デフォルトではリンク先のコンテキストが変更される。
    シンボリックリンク自体のコンテキストを変更するには「--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/ にアクセスしようとしてブロックされる

リンク