SELinuxの調査や確認時に使えそうなコマンドメモ

(関連リンク) [SELinuxの論理パラメータ一覧(CentOS7)](https://qiita.com/hamamoto_abc/items/4b12c0512c3b6f231210)

各コマンドが無い場合には以下のようにしてインストール。

```
yum install *bin/<コマンド名>
yum install *bin/sesearch
```

# SELinux 自体のモード切替

|コマンド|説明|
|:--|:--|
|setenforce permissive|ログだけ出して、実際の動きは制限しない。|
|semanage permissive -a httpd_t|特定のドメインだけ制限しないようにする。元に戻す場合は -d で実行。|
|setenforce enforcing|ログも出して制限もする。SELinuxの普通の動き。|

## semanage

|コマンド|説明|
|:--|:--|
|semanage fcontext -l|ファイル コンテキストの標準一覧|
|semanage port -l    |ポート番号 のコンテキスト一覧|
|semanage login -l   |Linuxユーザ と SELinuxユーザ の紐づけ一覧|
|semanage user -l    |SELinux ユーザ の一覧|
|semanage boolean -l |論理パラメータの一覧|

# ファイルコンテキスト
|コマンド|説明|
|:--|:--|
|ls -aZ|このディレクトリにあるファイルのコンテキストを表示|
|semanage fcontext -l|デフォルトのコンテキスト一覧を表示|
|matchpathcon /var/www/*|そのパスのデフォルトのコンテキストが何かを表示|

デフォルトのコンテキスト一覧を表示。
<code>less /etc/selinux/targeted/contexts/files/file_contexts</code>

**httpd_sys_content_t** の file/dir を探す。
<code>(find / -context '\*:**httpd_sys_content_t**:\*' | xargs -r ls -dpZ --) 2>/dev/null</code>


# 論理パラメータ

|コマンド|説明|
|:--|:--|
|semanage boolean -l|どんな論理パラメータがあるのかを表示|
|semanage boolean -l --locallist|変更した分の表示|
|getsebool -a|現在の on/off 状況を表示|
|sesearch --allow --bool **httpd_read_user_content**|定義されてるルールの確認|

### **httpd_read_user_content** について調査。###
意味を確認。
<code># semanage boolean -l | grep **httpd_read_user_content**</code>
現在の on/off を確認。
<code># getsebool **httpd_read_user_content**</code>
アクセス制御ルールが何なのかを確認。先頭 DT だと現在無効。ET だと有効。
<code># sesearch --allow --bool **httpd_read_user_content**</code>
ドメイン **httpd_t** の **httpd_sys_content_t** に対する論理パラメータを確認
<code># sesearch --allow --source httpd_t --target **httpd_sys_content_t** -C</code>

# sesearch

論理パラメータ名(httpd_read_user_content) から アクセス制御ルール を確認する。
<code># sesearch --allow --bool **httpd_read_user_content** -C</code>
タイプ(guest_t) が適応先(--target)となっている アクセス制御ルール を探す
<code># sesearch --allow --target **guest_t**</code>
タイプ(httpd_t) が適応元(--source)となっている アクセス制御ルール を探す
<code># sesearch --allow --source **httpd_t**</code>
タイプ に書き込み可能な アクセス制御ルール を探す
<code># sesearch --allow --target **httpd_sys_content_t** --class file -p write</code>
ドメイン **httpd_t** の **httpd_sys_content_t** に対する論理パラメータを探す
<code># sesearch --allow --source **httpd_t** --target **httpd_sys_content_t** -C</code>

※ _t で終わっていないものは、アトリビュートなので以下で確認。
<code># seinfo --attribute=**application\_exec\_type** -x</code>

-- ここから sesearch のオプション --
表示したいものをオプションで指定

|オプション|説明|
|:--|:--|
|-A(--allow)|allowルールを表示|
|-T(--type)|Search for type_transition, type_member, and type_change rules. <br>(タイプの遷移に関するものを表示？)|
|--all|全部|

絞り込み

|オプション|説明|
|:--|:--|
|-b(--bool) NAME|論理パラメータを指定したい場合に使う|
|-c(--class) NAME|オブジェクトのクラス名|
|-s(--source) NAME|ルールの適用元|
|-t(--target) NAME|ルールの適応先|
|-p(--perm) NAME|操作許可の指定。複数の場合は,区切り(permission)|
|--role_source=NAME|Find rules with role NAME as their source. (？)|
|--role_target=NAME|Find rules with role NAME as their target. (？)|

その他オプション

|オプション|説明|
|:--|:--|
|-C(--show_cnd)|論理パラメータの状態によって変更になるルールを表示する|
|-d(--direct)|があると、完全一致での検索になる。でもアトリビュートにあるのが hit しなくなる|
|-n(--linenum)|ルールファイル内での行数を表示|
|-r(--regex)|タイプ名や属性名に正規表現を使う|

# ドメイン遷移

\# ps -ZC systemd
LABEL　　　　　　　PID　TTY　TIME　CMD
system_u:system_r:**init_t**:s0          1 ?        00:05:08 systemd

\# ls -Z /usr/sbin/httpd
-rwxr-xr-x. root root system_u:object_r:**httpd_exec_t**:s0 /usr/sbin/httpd

■ systemd(**init_t**) が /usr/sbin/httpd(**httpd_exec_t**) を実行すると **httpd_t** に遷移、を確認。
　※ sepolicy transition はドメイン属性があるものしか指定できない。
　※ ドメイン属性を持つタイプの一覧。seinfo -adomain -x
　※ sesearch --type は --source ドメイン --target タイプ で検索。

\# sepolicy transition --source **init_t** --target **httpd_t**
　**init_t** @ **httpd_exec_t** --> **httpd_t**

\# sesearch --type --target **httpd_exec_t**
　type_transition **init_t** **httpd_exec_t** : **process httpd_t**;

\# sesearch --type --source **init_t** | grep **httpd**
　type_transition **init_t** **httpd_exec_t** : process **httpd_t**;

\# sesearch --type --source **init_t** --target **httpd_exec_t**
　type_transition **init_t** **httpd_exec_t** : process **httpd_t**;

\# sesearch --type --source **init_t** --target **httpd_t**
　　※ hit なし





# ユーザ、ロール

|コマンド|説明|
|:--|:--|
|seinfo -r|利用可能なロールを表示|
|seinfo -u|利用可能な SELinux ユーザを表示|
|semanage login -l|Linuxユーザ と SELinuxユーザ の紐づけ一覧|
|semanage user -l|SELinux ユーザ の一覧|

■ SELinuxユーザ **guest_u** がログインした場合に割り当てられるセキュリティコンテキスト。
cat /etc/selinux/targeted/contexts/users/**guest_u**
　guest_r:guest_t:s0              guest_r:guest_t:s0
　system_r:crond_t:s0             guest_r:guest_t:s0
　system_r:initrc_su_t:s0         guest_r:guest_t:s0
　system_r:local_login_t:s0       guest_r:guest_t:s0
　system_r:remote_login_t:s0      guest_r:guest_t:s0
　system_r:sshd_t:s0              guest_r:guest_t:s0

例：**system_r:sshd_t:s0** でログインした場合には **guest_r:guest_t:s0** になる。

/etc/selinux/targeted/contexts/users/* にファイルが無い SELinuxユーザは
/etc/selinux/targeted/contexts/default_contexts 
のログイン方法の違いによりセキュリティコンテキストが割り当てられる。

■ ロールのデフォルトタイプ。
/etc/selinux/targeted/contexts/default_type



# ログ

|コマンド|説明|
|:--|:--|
|less /var/log/audit/audit.log|ログ|
|ausearch -m avc|コマンドでログを見るほうが整形されて見やすい|
|ausearch -m avc -ts today|今日の分のログ|
|ausearch -m avc -ts recent|ここ10分間のログ|
|ausearch -m avc -c httpd|プロセスを指定|
|ausearch -m avc -c smbd|Sambaの場合|

// tail -f で見る場合。
tail -f /var/log/audit/audit.log | ausearch -i

type = [typeの種類](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/security_guide/sec-audit_record_types)
{ } の中が拒否されたパーミッション。
comm="" が実行したファイル。
path="" がアクセスを試みた先。
scontext="" が拒否られたプロセスのコンテキスト。
tcontext="" がアクセスしようとした先のコンテキスト。

# SELnux が原因でアプリが動かない場合の対応方法。

[今困っている事]
　samba でファイル共有しているファイルを apache/php で使用したいが、
　Permission denied となってページが開けない。

[対応]
SELinux のログを元に、アクセス制御ルール を追加する。

```
//いったんログをクリア。
# cat /dev/null > /var/log/audit/audit.log

// ここでブラウザからアクセスする(エラーで開けない)。

// SELinux のログからルールを作成して取り込み。
# audit2allow -M my_rule1 < /var/log/audit/audit.log
# semodule -i my_rule1.pp

// ルールの中身を確認。
# cat my_rule1.te

module my_rule1 1.0;

require {
        type httpd_t;
        type samba_share_t;
        class file getattr;
}

#============= httpd_t ==============
allow httpd_t samba_share_t:file getattr;
```

再度、ブラウザからアクセスする。
と、またエラーになるのでルール作成と取り込みを行う。

```
// さきほど my_rule1 だったので、my_rule2 で作成して取り込み。
# audit2allow -M my_rule2 < /var/log/audit/audit.log
# semodule -i my_rule2.pp
```

再度、ブラウザからアクセスする。
と、またエラーになるのでルール作成と取り込みを行う。

・・・これを繰り返す。

私の今回の場合はこれを 10回 繰り返して最終的に以下のようになりました。

```
# cat my_rule10.te

module my_rule10 1.0;

require {
        type httpd_t;
        type samba_share_t;
        class dir { add_name create read write };
        class file { append create getattr open read setattr write };
}

#============= httpd_t ==============
allow httpd_t samba_share_t:dir { add_name create read write };
allow httpd_t samba_share_t:file setattr;
allow httpd_t samba_share_t:file { append create getattr open read write };
```

なので、ここまでの過程をいったん削除して、最終的な my_rule10 だけを取り込む事に。

```
// 取り込まれたものを確認。my_rule_1 ～ 10 が確認できる。
# semodule -l | grep my_rule

// ルールを削除する。
# semodule -r my_rule1 my_rule2 my_rule3 my_rule4 my_rule5
# semodule -r my_rule6 my_rule7 my_rule8 my_rule9 my_rule10

// 最終的な my_rule10.pp だけ取り込む。
# semodule -i my_rule10.pp
```

とりあえず、これで対応終わり。

・・・が後日、SELinux が原因でアプリが動かない箇所が見つかったのでこの前作成した .te ファイルを編集して再度ルールを追加。

/var/log/audit/audit.log をみると以下が確認できたので、

avc: denied { remove_name } for pid=27733 comm=httpd ～ tclass=dir permissive=0
avc: denied { rename } for pid=27936 comm=httpd ～ tclass=file permissive=0
avc: denied { lock } for pid=27733 comm=httpd ～ tclass=file permissive=0

dir に remove_name を追加、
file に rename と lock を追加する。

```
# mkdir work
# cp my_rule10.te work/my_rule11.te
# cd work
# vi my_rule11.te

module my_rule11 1.0;

require {
        type httpd_t;
        type samba_share_t;
        class dir { add_name create read write remove_name };
        class file { append create getattr open read setattr write rename lock };
}

#============= httpd_t ==============
allow httpd_t samba_share_t:dir { add_name create read write remove_name };
allow httpd_t samba_share_t:file setattr;
allow httpd_t samba_share_t:file { append create getattr open read write rename lock };

// .te ファイルを元に .pp を作成する。
# make -f /usr/share/selinux/devel/Makefile

make: /usr/share/selinux/devel/Makefile: そのようなファイルやディレクトリはありません
make: *** ターゲット `/usr/share/selinux/devel/Makefile' を make するルールがありません.  中止.

// エラーになったので yum で入れてから再度実行して取り込み。
# yum install -y selinux-policy-devel
# make -f /usr/share/selinux/devel/Makefile
# semodule -i my_rule11.pp

// 前のが要らなくなったので削除。
# semodule -r my_rule10

// ファイルを移動してから作業用フォルダを削除。
# mv my_rule11.pp my_rule11.te ../
# rm -r work
```

以上。