【SELinux】初心者によるSELinuxの概要覚書&再帰的なコンテキストの設定

## はじめに
よろしくお願いします。IT未経験の新卒１年目です。
2ヶ月ほど前に現場でSELinuxに触れる機会があったのですが、その時に知ったことや苦戦した設定などをここに共有します。
私のように初めてSELinuxを触る方の一助になれば幸いです。

::: note warn
自分用の覚書のため、大事な情報を端折っていたり情報が誤っていたりするおそれがあります。
間違った情報・古い情報がありましたらコメントをお願いします。
:::

## SELinux概要
### SELinuxとは
ざっくり言えばLinuxにおけるアクセス制御の仕組みで、その名(**S**ecurity-**E**nhanced Linux)の通り、Linuxのセキュリティを強化することができます。
以下はRed Hatから引用した概要です[[1]](#引用元)。
>SELinux (Security-Enhanced Linux) は、システムにアクセスできるユーザーを管理者がよりきめ細かく制御するための、Linux® システム向けセキュリティ・アーキテクチャです。もともとは、Linux Security Modules (LSM) を使用した Linux カーネルへの一連のパッチとして、アメリカ国家安全保障局 (NSA) によって開発されました。 SELinux は 2000 年にオープンソース・コミュニティにリリースされ、2003 年にアップストリームの Linux カーネルに統合されました。

ここで述べられている「きめ細かく」制御できるというのがSELinuxの特徴になります。
一般的な権限+パーミッションで設定できる「誰のアクセスを許可するか」「どのような操作を許可するか」以上の詳細な設定が可能になります。

### コンテキスト
上述のきめ細かな設定のためにSELinuxではコンテキストという情報を使用します。
SELinuxをinstallしたサーバーでlsコマンドに-Zオプションを付けるとSELinuxのコンテキストを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/3ae2a8a6-0ea0-7d92-3036-93775038aa7e.png)


写真上で線を引いた、:３つでつながったよくわからないやつがコンテキストで、ユーザー・ロール・タイプ・レベルから構成されています。
自分が特に大事だと感じたのはタイプです。タイプを設定することで、プロセスごとのアクセス制限が可能になり、root権限が乗っ取られた場合でも被害を抑えることができます。詳細は[別のサイト](https://www.tohoho-web.com/ex/selinux.html#selinux_policies)が参考になりました。

## SELinuxの設定
細かな概要や導入方法は他のサイトにお任せするとして、ここでは自分が手こずった具体的な設定をご紹介します。
### chcon：コンテキストの一時的な変更
chconコマンドを使うとコンテキストを**一時的に**変更することができます。
```shell
chcon [-u ユーザー] [-r ロール] [-t タイプ] [-l レベル] (対象パス)
```
rootのホームディレクトリ内に存在するディレクトリaのコンテキストについて、タイプがhttpd_sys_content_tとなるようにchconコマンドで変更してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/1bdb411c-65c2-c937-17a1-4f641895814e.png)
（ディレクトリa内のファイルは変わらず）ディレクトリaのコンテキストだけが変更されていることが分かります。
ディレクトリa内のファイル含めてすべてのコンテキストを変更したい場合は-**R**オプションを付けましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/7d12d61d-a1da-a693-bd70-ebd3704b1aaf.png)
ファイルを作成すると作成元のディレクトリと同じコンテキストがファイルに割り当てられます。これはディレクトリに-Rオプションを**付けていても付けていなくても**同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/8c807ce2-9c51-3140-28e0-2e53bc02f10c.png)

### restorecon：コンテキストの再設定
対象パスのコンテキストに、後述のsemanage fcontextで設定した内容を反映させます。このとき、chconで設定した内容がリセットされます。

```shell
restorecon (対象パス)
```
こちらも-**R**オプションでディレクトリ配下のファイルに再帰的に設定を適応できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/24f7ae70-aeac-7895-7b48-9f6ed390bf6f.png)

### semanage fcontext：設定されているコンテキストの表示・コンテキストの永続的な設定など
semanageコマンドでコンテキストを永続的に設定することができます。まずは下記のコマンドで現在設定されているコンテキストを確認してみましょう。
```
semanage fcontext -l
```
このコマンドで一覧表示されるコンテキストがデフォルトの設定のようになり、restoreconコマンドを実行すればここで一覧表示されているコンテキストに従って設定を切り替えてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/17099070-9e83-05f8-b1a6-3b6e900fbc55.png)
先ほど、操作する前やrestoreconコマンドをしたあとのファイルでコンテキストのタイプが```admin_home_t```となっていたのは、ここで/root直下のファイルすべてに対して```admin_home_t```がコンテキストのタイプになるよう設定されていたからだったわけですね。
それではsemanageコマンドで実際にコンテキストを変更してみましょう。
```
semanage fcontext -a [-u ユーザー] [-r ロール] [-t タイプ] [-l レベル] "(対象の絶対パス)"
```
上のコマンドでコンテキストを永続的に設定することができます。ただし、このコマンドだけでは実際のコンテキストは**変更されません**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/a900175e-1195-dbad-55f5-d7a90064e780.png)
そのため、先ほどのrestoreconを使って設定を反映させてあげる必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/4f768cfa-3ae6-ee58-b7cb-0372186080bc.png)
また、chcon/restoreconコマンドと異なり、semanageには再帰的な設定が可能な-**Rオプションがありません**。
そのため、ディレクトリ内の全フォルダにコンテキストを設定したいときは、パスをワイルドカードと正規表現で指定する必要があります（最初に確認したroot直下の設定もそういう書き方がされていました）。
```shell
semanage fcontext -a [-t タイプ] "(対象ディレクトリ)(/.*)?"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/c7bf94b1-b139-3447-9c0b-b82b8bdbe3d8.png)

### 実際にやったミス

上記のようになかなかややこしい仕組みになっているため、SELinuxを実際に触った際も色々とミスをしてしまいました。上記の中で自分が混乱・苦戦した設定やその結果起こったミスなどを以下にメモしておきます。

 - semanageコマンドによる設定は再帰的に適応されない
→ディレクトリ内で新規作成したファイルは設定通りのコンテキストになっており、再帰的に設定できていないことに気付けずそのままにしてしまった
 - semanageコマンドによる設定後は、restoreconコマンドで設定を反映させないといけない
 - restoreconコマンドは-Rオプションを付けないとコンテキストを再帰的に設定できない
→semanageコマンドでコンテキストを再帰的に設定した後にrestoreconコマンドで反映させたつもりが、-Rオプションを付け忘れたので大元のファイルしか設定が反映されていなかった

:::note warn
SELinuxのコンテキストで設定をミスると、本来できるファイルのダウンロードができない・そもそもファイルが作れない……など、ちゃんとした障害が発生するので、ls -lZコマンドやsemanage fcontext -lコマンドなどで入念に確認しましょう！
:::

## おわりに
ただでさえ仕組みが難解・設定が複雑・ミスした時のリスクがデカい……等々の理由からSELinuxの設定は~~自分含め~~一般的に敬遠されがちな風潮があります。実際にgoogleでSELinuxと検索すると、1個目のサジェストに無効と出てきます。

![スクリーンショット 2024-12-22 115738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812707/7f23e592-5f9d-3029-56c7-e8b4c2100f87.png)

このように不人気なSELinuxですが、使いこなせれば柔軟かつ強力なアクセス制御が可能になると思われます。
この記事では具体的な説明を最低限に端折ってしまったのでこれだけ読んでもよく意味がわからないと思いますが、これからSELinuxを触る人にとって少しでも役に立ってほしいと思います。
ありがとうございました。


## 引用元
[1]：https://www.redhat.com/ja/topics/linux/what-is-selinux