Red Hat Interactive Labを使ってみた

# 目次
1. [記事の目的・ゴール](#記事の目的ゴール)
2. [Red Hat Interactive Labの概要](#red-hat-interactive-labの概要)
3. [ラボの説明](#ラボの説明)
4. [ラボの詳細](#ラボの詳細)
4. [まとめ](#まとめ)
# 記事の目的・ゴール 
この記事では、Red Hat interactive labsの操作方法と使用方法について説明します。また、例として4つのラボの内容について案内し、これらのラボで取り上げられている技術についても説明します。

# Red Hat Interactive Labの概要 

Red Hat インタラクティブラボは、Red Hat Enterprise Linux、Red Hat OpenShift、Red Hat Ansible Automation Platform などの Red Hat 製品のユースケースを題材にしたインタラクティブな実践学習シナリオで、無料で利用できます。これらのシナリオには設定済みの Red Hat® OpenShift® が付属されており、ユーザーは Kubernetes を使用してアプリケーションの構築、デプロイ、実行、管理を実験、実践、確認することができます。

:::note info
Red Hat Interactive Labではユーザー登録が不要です。
:::

これらのハンズオン学習シナリオラボは、以下のリンクからアクセスできます。
https://www.redhat.com/en/interactive-labs

![Home page of Red Hat interactive lab](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/a06987b2-faea-3f6e-c4e5-afe4c454c70e.png)

## Red Hat Enterprise Linuxとは 
Red Hat Enterprise Linux（RHEL）は、Red Hatがビジネス市場向けに開発したエンタープライズLinuxオペレーティングシステム（OS）です。以前は Red Hat Linux Advanced Server として知られていた RHEL は、100以上のベンダーとクラウドで認定されています。

また、RHELは、環境間で信頼性が高く、一貫性のある基盤をユーザーに提供します。アプリケーションサービスとワークロードを迅速に提供するために必要なすべてのツールが装備されています。

**試してみるRHELのシナリオはこちら:**
- [Configure terminal session recording](https://www.redhat.com/en/interactive-labs/configure-terminal-session-recording)
- [Secure containers with SELinux (Udica)](https://www.redhat.com/en/interactive-labs/secure-containers-with-selinux)
- [Configure the system-wide cryptographic policy](https://www.redhat.com/en/interactive-labs/configure-system-wide-cryptographic-policy)
- [Customize the system-wide cryptographic policy](https://www.redhat.com/en/interactive-labs/customize-system-wide-cryptographic-policy)

これらのシナリオは Red Hat Enterprise Linux labs の 「protect」 セクションにあります。Red Hat インタラクティブラボの[ホームページ](https://www.redhat.com/en/interactive-labs)に移動した後、Red Hat Enterprise Linux labs セクションを見つけ、See all を押します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/65203a56-3e90-c56f-8903-e1b23f4d02f6.png)

### RHELの 「Protect」 セクションとは
RHEL の「Protect」セクションには、アプリケーションやプロセスのセキュリティのユースケースに焦点を当てたシナリオが含まれています。現在、CLI 端末、コンテナ、SQL、ファイアウォールなどに関連するシナリオがあります。これらのシナリオでは、脆弱性を監視し、データとファイルのプライバシーを保護し、コンプライアンス標準を満たすなどのユーザーケースを実施します。
# ラボの説明
### 必要条件:
上記で説明したように、すべてのハンズオンラボには設定済みのRHELが付属しています。そのため、ラボの内容を実行するためには特に準備する必要ものはありません。

## ラボ1: Configure terminal session recording 
本シナリオでは、ユーザーと管理者の端末セッションを記録して、レビューすることで、システムを監視します。また、端末セッションを記録することはユーザーと管理者が端末で行ったタスク、コマンド、とその出力全部を記録するということです。

### シナリオのゴール: 
ターミナルセッションを記録し、記録されたセッションを確認できるようになります。
### シナリオに含まれる概念：
- ターミナルセッション録画用ソフトウェアのインストール
- ターミナルセッションの有効化と記録
- 記録されたセッションの一覧表示
- RHEL Webコンソールを使って記録したセッションを再生
- tlogコマンドを使って記録したセッションを再生

### ターミナル・セッションを記録する理由
端末のセッションを記録して共有することは有用です。セッションの記録は、新しい開発者のための教材として使ったり、管理者がそのマシンで特定のタスクを実行するのが困難なときに、実行された内容やマシンの状態を確認したりすることができます。

セキュリティに関してはユーザーがターミナルで実行したコマンドと、それらが生成した出力をレビューすることで、セキュリティ違反、改ざん、脆弱性に関する洞察を得ることができます。

## ラボ2: Secure containers with SELinux (Udica) 
本シナリオでは、コンテナ化されたアプリケーション（Apache）がホーム・ディレクトリにアクセスしたいが、デフォルトのコンテナのタイプ（container_t）により制限されています。一方、コンテナ化されたApacheは、任意のネットワーク・ポートにバインドすることができます。

RHEL のコンテナ・ツールですUdicaを使って、コンテナ化された Apache のためにカスタムの SELinux セキュリティ・プロファイルを生成します。これによって、アプリケーションにホーム・ディレクトリへの特定のアクセス権を許可する一方で、Apache がバインドできるネットワーク・ポートを制限することができます。

### シナリオのゴール: 
コンテナ・イメージを実行し、コンテナの用途に合わせてカスタマイズした SELinux プロファイルをUdicaを使って生成できるようになります。

### シナリオに含まれる概念：
- 実行中のコンテナの SELinux ポリシーの許可ルールを確認
- Udica を使用してコンテナの SELinux セキュリティプロファイルを生成
- Udica が生成した CIL（Common Intermediate Language）ファイルに基づいて、コンテナにポリシーモジュールを適用
- 実行中のコンテナの SELinux ポリシーの許可ルールを再クエリし、アクションが許可されていることを確認

### SELinuxとは

Security-Enhanced Linux (SELinux) はLinuxカーネルのセキュリティモジュールで、アクセス制御のセキュリティポリシーをサポートするメカニズムを提供します。SELinuxはもとよりアメリカ国家安全保障局（NSA）がLinux Security Modules (LSM)を使用してLinuxカーネルv2.4用のローダブルカーネルモジュールとして開発したものです。
 
SELinuxは2000年にオープンソースとしてリリースされ、2003年にアップストリームのLinuxカーネルに統合されました。実際、SELinux（Android 5.0+とRed Hat/Fedoraではデフォルトで有効）は、カーネルソースツリーの`/security`ディレクトリにリストされていることも確認できます。

### セキュリティ・プロファイルとは
セキュリティプロファイルは、**サブジェクト**または**サブジェクトのグループ**に関連付けることができるアクセス権の設定のコレクションです。本シナリオでは、**サブジェクト**は**コンテナ化されたアプリケーション**です。セキュリティ・プロファイルは、アプリケーションがさまざまなリソースに対して実行できるアクション（表示、作成、編集など）を決定します。
### Udicaとは
Udica は、コンテナ用の SELinux セキュリティ・プロファイルを生成するために RHEL 8 から利用可能になったユーティリティです。Udicaを使用すると、Linux-capabilities、マウントポイント、ポート定義を含むコンテナ JavaScript Object Notation (JSON) ファイルの検査に基づいてポリシーを作成できます。

Udicaのポリシーは、検査の結果を使用して生成されたルールと、指定された SELinux 共通中間言語（CIL）ブロックから継承されたルールを組み合わせです。

Udica については [RHEL 9 のドキュメント](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_selinux/creating-selinux-policies-for-containers_using-selinux#introduction-to-udica_creating-selinux-policies-for-containers)を参照してください。

UdicaのGithubリポジトリ：
https://github.com/containers/udica


## ラボ3: Configure the system-wide cryptographic policy

本シナリオでは、セキュリティのチームがより強力な暗号アルゴリズムをアプリケーションで使用することを要求しており、SHA-1のような弱いアルゴリズムの使用はサンセットすることにします。そのため、複雑な暗号、プロトコルのバージョン、そして使用可能な暗号を、マシン上で実行されているすべてのサービスに対して強制する作業を実施します。

### シナリオのゴール: 
RHEL のシステム全体の暗号化ポリシーの適用、変更、トラブルシューティングできるようになります。本シナリオでは、アプリケーションの例として Apache Web サーバーを使用します。

### シナリオに含まれる概念：
- 現在のシステム全体の暗号化ポリシー設定の確認
- 現在の暗号化ポリシーの設定を変更
- 暗号化ポリシーの更新後のアプリケーションのトラブルシューティング
- より強力な暗号化ポリシーに準拠するようにアプリケーションの設定を変更


### 暗号とは

暗号は、意図された受信者だけが読めるように、送信された情報を不明瞭にする技術です。

ほとんどの暗号システムは、平文と呼ばれる暗号化されていないメッセージから始まり、1つ以上の暗号化キーを使って暗号文と呼ばれる解読不可能なコードに暗号化されます。

暗号文が傍受され、暗号化アルゴリズムが強力なものであれば、不正な盗聴を防止できます。一方、意図された受信者は、正しい復号化キーを持っているため、簡単にテキストを解読することができます。

```mermaid
---
title: 暗号とは
---
flowchart TD;    
    id1(平文);
    id2(暗号文);
    id3(平文);
    id4(暗号文);
    id5[/復号\];
    id6[\暗号/];
    id7{{キー}};
    受信者~~~id2 ---- id5---> id1;    
    id7-->id5;
    id7 --> id6;
    送信者~~~id3 ----id6---> id4;

```

## ラボ4: Customize the system-wide cryptographic policy
本シナリオでは、システム全体の暗号化ポリシーを作成し、RHEL暗号ライブラリを使用するすべてのアプリケーションに適用する作業を実施します。

### シナリオのゴール: 
RHEL のシステム全体の暗号化ポリシーをカスタマイズできるようになります。本シナリオでは、アプリケーションの例として Apache Web サーバーを使用します。

### シナリオに含まれる概念：
- 現在のシステム全体の暗号化ポリシー設定を確認
- ポリシーに含まれる暗号化メソッドをカスタマイズ
- 指定されたポリシーにポリシー修飾子を適用した後、アプリケーションを再起動
- アプリケーションの設定が変更された暗号化ポリシーに準拠していることを確認

### 本シナリオで使用するFUTUREの暗号化ポリシーとは

[RHEL 9のドキュメント](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening)によると、FUTUREの暗号化ポリシーは以下の通りです：

将来のポリシーを試すための、より厳しいセキュリティ・レベルです。このポリシーでは、署名アルゴリズムにSHA-1を使用することを許可せず、TLS 1.2と1.3プロトコル、IKEv2とSSH2プロトコルを許可します。RSA鍵とDiffie-Hellmanパラメータは、3072ビット以上であれば使用可能です。

# ラボの詳細
各ラボのステップとプロセスについて詳しく説明します。ラボには、終了までの予想時間と環境の制限時間が設定されています。すなわち、予想時間を超えても、制限時間内でしたらラボの環境は利用可能です。

予想時間はこちらで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/5b0098ad-cbf6-f7a1-94f4-ecf63ffabbe7.png)

制限時間はラボに入ったら確認できます (次のページで*Start*をクリックするまでカウンターはスタートしません。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/0a017660-ddd2-bbd6-cd65-2b7d4cd78e47.png)

ラボに入ると、このUIが表示されます。右側はラボの説明パネルで、左側はあなたの作業端末です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/ec437683-41e6-1f29-8e35-8ea96d6f7f48.png)

では、最初のラボを始めましょう。
## ラボ1: Configure terminal session recording 

### ステップ1: ソフトウェアをインストール

まず、2つのrpmパッケージ `cockpit-session-recording` と `tlog` をインストールします。
```bash
yum install -y cockpit-session-recording tlog
```
インストール後、ターミナルには次のように表示されます。

出力結果：

```terminal
Installed:
  cockpit-session-recording-4-2.el8.noarch
  tlog-8-2.el8.x86_64

Complete!
```
:::note info
`cockpit-session-recording`はWeb Consoleの機能を追加するパッケージで、セッション録画の有効化と設定に使用します。
`cockpit-session-recording`のリポジトリ：
https://github.com/Scribery/cockpit-session-recording

`tlog`パッケージは、記録された端末セッションを記録・閲覧するためのツールです。
`tlog`のリポジトリ
https://github.com/Scribery/tlog
:::

右下の`Next`ボタンをクリックして次のステップに進みます。

### ステップ2: ログインとWeb Consoleの操作

必要なソフトウェアがインストールされたので、次はターミナルセッションの記録を設定し、有効にします。ターミナルセッションの記録を設定するには、Webコンソールを使用します。
次に、ターミナルタブの隣にある *RHEL Web Console* タブをクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/a484c4cc-3a55-bcdd-276e-afbcd06b8a8b.png)

新しいブラウザのタブが開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/3436f702-4aad-87bf-af26-0715e633f528.png)
以下の認証情報を使用します。

```
ユーザネーム: rhel 
パスワード: redhat
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/df4190a9-8b0f-a3b6-5b93-b96c472342f1.png)


次に`管理者アクセスをオンにする`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/a82fc778-082e-d14a-a467-493901646eef.png)

パスワード `redhat`を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/f9c43829-aafa-a6c1-ad28-adc55c3c74e2.png)

cockpit-session-recordingのrpmパッケージをインストールしたので、左側のナビゲーションメニューで*Session Recording*オプションを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/3d7abd37-3d50-2e69-024c-2c531aff2402.png)

### ステップ3: セッション録画の設定と有効化

現在セッション記録アプリケーションは空白です。右上の歯車アイコンをクリックすると、セッション録画の構成設定に移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/03be4c2d-49ad-453d-d98f-c95ee3f7b66d.png)

表示されたページで、セッション録画の設定情報にアクセスできます。
`SSSD Config` セクションで、Scopeが`All`を選択し、Saveをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/a44f22b1-11d1-9ec5-7802-9eb60b1de426.png)

Save ボタンをクリックすると、Web Console が sssd のスコープを詳細に記述した設定ファイルを書き出します。

設定を保存したら、WebコンソールをSession Recordingに戻します。

### ステップ4: 設定をレビュー

ラボ環境のターミナルに戻ります。

Web Console は sssd 用の小さな設定ファイル（`/etc/ssd/conf.d/ssd-session-recording.conf`）を書き込みました。ファイルを開き、スコープが all に設定されていることと、すべてのユーザーとグループのすべてのセッションが記録されるようにしていることを確認します。
```bash
cat /etc/sssd/conf.d/sssd-session-recording.conf
```

```terminal
[session_recording]
scope=all
exclude_users=
exclude_groups=
```
Web Consoleによって変更された設定は/etc/tlog/tlog-rec-session.confに保存されています。例えば、セッションが記録されているユーザーに表示される通知メッセージなども同様です。必要であれば、このファイルを確認してみてください。

```bash
cat /etc/tlog/tlog-rec-session.conf
```
出力結果：
```terminal
"notice" : "ATTENTION! Your session is being recorded!",
```
### ステップ5: セッションの記録
ユーザーをrhelユーザーに変更し、セッションの記録を始めます。
```bash
su - rhel
```
bashセッションが開始されると、rhelユーザーはtlogコンフィギュレーションで設定された通知メッセージを受け取ることを確認できます。

出力結果：

```terminal
root@rhel:~# su - rhel
Last login: Thu Feb  3 19:21:21 UTC 2022 from ::ffff:136.32.60.35 on web console
Locale charset is ANSI_X3.4-1968 (ASCII)
Assuming locale environment is lost and charset is UTF-8

ATTENTION! Your session is being recorded!

[rhel@rhel ~]$
```
ここで、rhelユーザーのセッションでいくつかのコマンドを実行します。
```bash
ls /tmp
```
[comment]: <> (This command lists all files in the `/tmp` directory except for hidden files.)
```bash
who
```
[comment]: <> (`who` command displays information about all users currently on the local system. )
```bash
df -hP
```
[comment]: <> (The `df` command displays information about total space and available space on a file system.)
```bash
dnf list installed
```
[comment]: <> (DNF is a a package manager for .rpm-based Linux distributions.
In this command, you're listing installed packages with `dnf`.)

セッションの記録データが入りましたので、ユーザーの端末セッションからログアウトします。

```terminal
exit
```

### ステップ6: 記録したセッションをWeb Consoleで確認
Web Consoleに戻ります。

まだ Session Recording ページにいない場合は、そこに移動してください。

すると、録画されたセッションが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/010cbe0e-045a-1952-0599-e44a049faff8.png)

セッションを選択すると、セッションを再生できるプレーヤーが統合されたページに移動されます。再生ボタンを押すと、セッションを確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/37f8a101-7c98-129b-dd2c-da568dc6fa19.png)

セッションはリアルタイムで記録されているので、`bash`セッションを開始してもすぐにコマンドを実行し始めなかった場合は、その待ち時間も記録され、セッションの記録に反映されます。

ビデオプレーヤーの機能に加え、プレーヤーの右側にあるボタンでズームイン、ズームアウトができ、コンテンツをより近くで見たり、遠くから見たりすることができます。また、プレーヤーウィンドウの下部にある検索機能は、録画されたセッションのテキストを検索し、その文字列が見つかったタイムコードを報告します。これらのタイムコードはリンクであり、プレーヤー内の再生位置を変更します。

また、プレーヤーの下には、このセッションに関する追加のメタデータと、セッションのログエントリがあります。

### ステップ7: コマンドラインから録画セッションを確認

`tlog-play` のコマンドで、コマンドラインから記録したセッションを確認することができます。また、`tlog-play` はセッションIDを受け取ってそのセッションを再生します。

デフォルトの設定では、記録されたセッションデータは journald 管理ログに送られます。利用可能なセッションデータを調べるには、`journalctl` コマンドを使用します。以下のコマンドはjournald 管理ログを検索し、`rec` 文字列とそのメッセージに含まれる識別子を含む文字列を探します。

```bash
journalctl -o verbose | grep -P "\"rec\".*?\,"
```
以下はそのメッセージの一例ですが、各セッションに関連するメッセージは１つかそれ以上あります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/caa03e8a-2aca-92da-6941-9eb610ba2553.png)
セッションを再生するには、セッションIDで`tlog-play`を実行する：
```bash
tlog-play -r journal -M TLOG_REC=2431dc8406af4ef190abe5017d45a153-124a-13069
```
セッションIDは異なると思いますので、以下のコマンドは、いくつかのシェルツールを使って、journaldから最初の記録を分離します。セッションを再生すると、既存の端末セッションが再生に使用されます。再生が完了すると、セッションはコントロールに戻されます。

:::note info
`<CTRL>-C`で再生を中断することができます。
:::

```bash
tlog-play -r journal -M TLOG_REC=$(journalctl -o verbose | grep -P "\"rec\".*?\." | cut -d, -f3 | cut -d: -f2 | head -n 1 | sed -e s/\"//g)
```

上記のコマンドは、リアルタイムでセッションを完了まで再生します。

**以上ラボ１でした。**

## ラボ2: Secure containers with SELinux (Udica) 

### ステップ1: ソフトウェアのインストールと設定

SELinux は、特権の昇格を利用した攻撃を軽減するために、システム上で実行されているプロセス／コンテナを分離する技術です。Udica は、Red Hat がサポートするコンテナのツール（Podman、Skopeo、Buildah など）ファミリーを補完する新しいツールです。

:::note info
注：本ラボでは、SELinux の基礎とコンテナの基礎を十分に理解していることを前提としています。
:::


始める前に、Udica（コンテナ用のSELinuxポリシーを生成するツール）やsetools-console（SELinuxポリシーの分析を容易にするツール群）といったパッケージが必要です。本デモでは、コンテナーのランタイム関連のパッケージはすでにインストールされています。
`Terminal 1` タブをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/8c8573d7-f5fc-246a-8d81-93c7899287f6.png)

コンテナホストに `udica` と `setools-console` パッケージをインストールします。
```bash
dnf install -y udica setools-console
```
最新のRHEL9 UBIイメージをコピーします。

```bash
podman pull registry.access.redhat.com/ubi9/ubi:latest
```
利用可能なコンテナイメージを一覧表示するには、`podman` を使用します。

```bash
podman images
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/59c1c4b7-2209-0db1-3de9-67e94b3ab44e.png)

 `Terminal 2` タブをクリックします。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/3a6a7792-0672-cd1b-0613-daaf68ae7a40.png)

コンテナ内の `/home` へのアクセスをホストの `/home` に*read-only*で渡し、コンテナ内の `/var/spool` へのアクセスをホストの `/var/spool` に*read-write*で渡し、ホストのポート `80` をコンテナのポート `80` にトラフィックを渡すようにバインドします。


```bash
CONTAINER=$(podman run -v /home:/home:ro -v /var/spool:/var/spool:rw -d -p 80:80 -it registry.access.redhat.com/ubi9/ubi)
```

:::note info

注：ホームディレクトリは読み取り専用でマウントされ、`/var/spool/ ディレクトリ`は読み書き可能でマウントされる。

:::

`Terminal 1`へ戻ります。

Podmanを使ってアプリケーションコンテナのステータスをチェックし、実行中のコンテナIDを確認します。


```bash
podman ps; CONTAINERID=$(podman ps | grep registry.access.redhat.com | cut -b 1-12)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/b3820f84-a090-1803-c477-061ebf39eb85.png)


SELinux を使用すると、コンテナ・プロセスには 'container_t' というコンテナ・タイプが割り当てられます。

`Terminal 1`で、実行中のコンテナに割り当てられた SELinux タイプを確認します。

```bash
ps -eZ | grep container_t
```
出力結果：
```terminal
system_u:system_r:container_t:s0:c182,c1016 25755 pts/0 00:00:00 bash
```
RHEL では、SELinux はデフォルトで有効になっており、強制モードになっています。システムの `sestatus` の出力を調べることで確認できます。

```terminal
sestatus
```
出力結果：
```terminal
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
<- 出力簡略 ->
```
### ステップ2：コンテナ・アクセスとSELinuxポリシーの検査
`Terminal 2`で、`podman exec` コマンドを使用して、実行中のコンテナ内に対話型のシェルを作成します。
```bash
podman exec -t -i $CONTAINER /bin/bash
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/65726b46-5725-dcd1-e6aa-2c96dc02522f.png)

コンテナの`/home`ディレクトリへのアクセスを確認します。

```bash
cd /home; ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/866a177e-2e69-3fa6-e068-3846f2013872.png)

`Terminal 1` で、SELinux ポリシーを照会して、`/home` ディレクトリへのアクセスに適用される許可実行ルールを検索します。

```bash
sesearch -A -s container_t -t home_root_t -c dir -p read
```

検索結果は空です。container_tタイプには`/home`ディレクトリへの読み取りアクセスを許可するルールがないため、SELinuxによってアクセスがブロックされます。

`Terminal 2`で、コンテナの `/var/spool/` ディレクトリへのアクセスを確認します。

```bash
cd /var/spool/; ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/c61d2cec-b5c6-37cf-6a20-6f944654030d.png)

SELinux が `/var/spool` ディレクトリへのアクセスを制限しています。

`Terminal 2`で、コンテナの `/var/spool/` ディレクトリへの読み書きアクセスを確認します。

```bash
touch test
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/605ab2dc-1a6a-0637-46c0-d7dc0bb5c070.png)

`Terminal 1`で、SELinux ポリシーを照会して、`/var/spool` ディレクトリへのアクセスに適用される許可実施ルールを検索します。


```bash
sesearch -A -s container_t -t var_spool_t -c dir -p read
```
検索結果は空です。container_tタイプが/var/spool/ディレクトリへの読み取りアクセスを許可するルールがないため、SELinuxによってアクセスがブロックされます。


`container_t`のネットワーク アクセスに関する SELinuxのポリシーを確認します。

```bash
sesearch -A -s container_t -t port_type -c tcp_socket
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/d4a48ac0-2120-7271-764a-b58489cbbeb7.png)

`Sandbox`はSELinuxにおけるデフォルトのプロセスタイプです。また、`Container`はコンテナに使用されるドメインです。`corenet`タイプはLinuxカーネルに使用されます。出力は、これらの各ドメインについて、TCPポートの制限なしに、バインド、接続、メッセージの送受信が許可されていることを意味します。


### ステップ 3: Udica による SELinux コンテナポリシーの生成

カスタム SELinux セキュリティ・ポリシーを作成するために、Udica はコンテナの JSON ファイルをスキャンして、コンテナが必要とする Linux の機能を探します。ネットワークポートも同様の状況で、Udica は SELinux ユーザースペースライブラリを使用して、検査されたコンテナで使用されるポートの正しい SELinux ラベルを取得します。

`Terminal 1`で、Podman を使用して実行中のコンテナを検査し、JSON 形式のコンテナ検査ファイルを生成します。


```bash
podman inspect $CONTAINERID > container.json
```
Udicaでコンテナ JSON ファイルを使用して、カスタム SELinux セキュリティポリシーを生成します。この場合、カスタム SELinux セキュリティポリシーの名前は 'my_container' となります。


```bash
udica -j container.json my_container
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/af3d5790-9f01-ab7f-6dee-8779e9ac13c5.png)

コンテナ用のカスタム SELinux セキュリティ・ポリシーを作成しました。このポリシーをカーネルにロードしてアクティブにします。

```bash
semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}
```
`Terminal 1`で、コンテナを一旦停止して再度起動します。すると、ポリシーが有効になります。


```bash
podman stop $CONTAINERID
```

`Terminal 2` で、新しいカスタムコンテナポリシーを使用するイメージから新しいコンテナランタイムを作成します。

```bash
CONTAINER=$(podman run --security-opt label=type:my_container.process -v /home:/home:ro -v/var/spool:/var/spool:rw -d -p 80:80 -it registry.access.redhat.com/ubi9/ubi)
```
### ステップ 4: Udica による SELinux コンテナ・ポリシーの検証

コンテナ用に Udica を使用して生成され、SELinux によって強制されたポリシーを確認できます。

コンテナホストの SELinux ポリシーを照会して、`/home` ディレクトリへのアクセスに適用される許可実施ルールを検索します。

`Terminal 1` に以下を入力します。

```bash
sesearch -A -s my_container.process -t home_root_t -c dir -p read
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/4837c2e1-a62f-e2e0-cb03-369822627031.png)

ホームディレクトリへの読み取りアクセスを許可する許可ルールが存在します。

同じく、コンテナ・ホストのSELinuxポリシーを照会して、/var/spool/ディレクトリへのアクセスに適用されている許可実施ルールを検索します。

```bash
sesearch -A -s my_container.process -t var_spool_t -c dir -p read
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/0b602646-ccb7-f070-576a-f449f13f789d.png)

`var/spool`ディレクトリへの読み取りアクセスを許可するルールが存在します。


コンテナホストのSELinuxポリシーを照会して、ネットワークアクセスを確認します。

```bash
sesearch -A -s my_container.process -t port_type -c tcp_socket
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/03062980-1b0d-e771-356a-0d880be944ec.png)

TCP ポート 80 に関連付けられた SELinux タイプを取得します。TCP ポート 80 は Apache がバインドするポートです。

```bash
semanage port -l | grep -w "80"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/15df05bd-01aa-3556-0042-c920375a6a5c.png)

### ステップ5：実行中のコンテナの再検査

`Terminal 2` で、実行中のコンテナに入り、bash シェルを起動します。

```bash
podman exec -t -i $CONTAINER /bin/bash
```
コンテナが`/home`ディレクトリにアクセスできるかどうかを確認します。

```bash
cd /home/; ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/f38ecd6a-9fce-7b75-14dd-fcfba70778d4.png)

SELinuxに`/home`ディレクトリへのアクセスを許可するルールがあるため、これで成功です。

コンテナが`/var/spool/`ディレクトリへの読み取りアクセス権を持っているかどうかを確認します。

```bash
cd /var/spool/; ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/fc3afd92-e7f2-d0b2-37d4-e647ba3b1c37.png)

同様に、SELinuxに`/var/spool/`ディレクトリへの読み取りアクセスを許可するルールがあるため、これも成功です。

コンテナが`/var/spool/`ディレクトリへの書き込みアクセス権を持っているかどうかを確認します。

```bash
touch test; ls
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/135955d9-b0b3-ddc7-2a79-4e3bd5499ba3.png)

コンテナ内にnetcat (nc)パッケージをインストールし、ポートバインディングを確認します。

```bash
dnf install -y nc
```
`nc`でコンテナ内でポート80をリッスンし、5秒後に`nc`をタイムアウトします。

```bash
timeout 5s nc -lvvp 80
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/8ae1d5e5-867d-4ef7-f03c-99eaac683eb9.png)

上の出力から、netcatがポート80に接続してリッスンできたことがわかかります。これは、ポート80でこのネットワークアクションを許可するSELinuxのルールがあるからです。

同様に、コンテナ内でポート8080をリッスンし、5秒後にタイムアウトします。

```bash
timeout 5s nc -lvvp 8080
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/f2788c54-8fb4-027d-42e8-3fc7fdb3de7e.png)

上の出力から、netcatがポート8080に接続できず、リッスンできなかったことがわかります。ポート8080に接続するSELinuxルールがないため、SELinuxによってブロックされました。

**以上ラボ2でした。**
## ラボ3: Configure the system-wide cryptographic policy
### ステップ1：環境の検証

提供されたシステムターミナルセッションを使用して、初期環境を検証します。

まず、現在のシステム全体の暗号化ポリシーを検証します。

```
update-crypto-policies --show
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/be2f0f20-65fd-d628-3667-fef76407c931.png)

システム全体の暗号化ポリシーはRHEL のデフォルト設定で、`DEFAULT` という名前のポリシーです。

Secure Socket Layer (SSL) は、システム全体の暗号化ポリシーで管理される暗号化方式の 1 つです。このラボでは、SSLを利用するサービスとしてApacheを扱うことになります。したがって、SSLの管理方法の変更は、これらの暗号フレームワークを利用するサービスに影響を与える可能性もあります。

マシン上でApacheが稼働していることを確認します。

```
systemctl status httpd.service --no-pager
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/91aded5f-9232-d8c3-6af0-4cebb79e83be.png)

アクティブステータスがアクティブ（実行中）であることを確認します。

デフォルトの設定では、Apache は自動的に作成された SSL 自己署名証明書を `/etc/pki/tls/certs/localhost.crt` に保存します。ここで、自動的に作成された自己署名入り SSL 証明書ファイルで使用されている RSA 公開鍵の長さを確認します。

```
openssl x509 -in /etc/pki/tls/certs/localhost.crt -text | grep bit
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/4b73d58b-7721-456d-a3cb-e387001c353c.png)

デフォルトの設定では、Apache は 2048 ビットの公開鍵を持つ証明書を使用します。

httpsポート(443)でApacheに接続するにはopensslを使用します。この接続の一部として、openssl はサービスとの接続を暗号化するために証明書のコピーを受け取ります。クライアントのウェブ・ブラウザが、2048 ビットの公開鍵証明書を利用していることを確認します。


```
openssl s_client -connect localhost:443 </dev/null 2>/dev/null | grep '^Server public key'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/a5ee45d2-8bfb-d722-9bbd-bbadf993b0ae.png)

クライアントのブラウザは接続を暗号化するために Apache サービスから 2048 ビットの鍵と SSL 証明書を提供されます。

### ステップ2：システム全体の暗号化ポリシーをFUTUREに設定

CSOから次のようなEメールが届きました。
```
Application and Infrastructure Administrators,

I recently returned from an industry security conference, and at that
conference, I learned of some recommended security industry practices
that our Applications and services should be using.  Specifically, we
should disable some less-secure encryption algorithms and enforce some
minimum strength used by others.

Those of you that have applications and services that utilize asymmetric
encryption through RSA based certificates, your certificates should use
at least a 3072 bit public key for their cipher.

TLS connections should only be offered to clients using TLS version 1.2
or higher.  TLS 1.0 and 1.1 should no longer be used for encrypted
connection to services or applications.

Application and services should now be configured to not use SHA1 for
digital signatures.

These changes will allow client data to transit the internet in a more
secure fashion.

-CSO
```
長い英文ですが、メールの内容はシステムが以下の要件を満たさないといけないということです。
- 少なくとも3072ビットの公開鍵を使用しなければなりません。
- TLS接続は、TLSバージョン1.2以上を使用するクライアントのみにする

これらの要件はすべて、RHEL に付属するシステム全体の暗号化ポリシーを使用して設定および実施できます。新しい組織ポリシーに準拠するため、FUTURE 暗号化ポリシーを使用するようシステムを更新します。FUTURE ポリシーに変更することで、マシン上で使用される暗号化ライブラリとサービス、またはマシン上で実行されるアプリケーションが、上記のCSOが定めた要件に準拠するように設定されます。

```
update-crypto-policies --set FUTURE
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/cdc99bcc-0671-8664-8d06-1a7a29804f4d.png)

この変更により、マシン上で一部の暗号化アルゴリズム、デジタル署名のSHA1を使用することができなくなります。さらに、RSAの証明書には少なくとも3072ビットの公開鍵が必要です。また、このマシンはTLS 1.2以上のTLS接続のみを提供するようになりました。

新しいポリシー「FUTURE」がシステムに適用されたことを確認します。

```
update-crypto-policies --show
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/b0a462ed-b1bb-a288-cd6c-a629fe6e2cbd.png)

RHEL 9 に同梱されている暗号化ポリシーの詳細に興味がありましたら、こちらで確認できます。

```
man crypto-policies
```
### ステップ3：サービスの問題を解決
システム全体の暗号化ポリシーを変更した後、Apacheサービスを再起動して、新しいポリシーで実行できるようにする必要があります。

:::note info
 注: Red Hat では、すべてのサービスを新しい暗号化ポリシーで初期化するためにシステムを再起動することを推奨していますが、本ラボでは Apache ウェブサービスだけ再起動します。

:::
```
systemctl restart httpd.service
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/12ee0473-332b-836a-de67-03c9c4481289.png)

Apache サービスの再起動が失敗しました。ApacheのSSLエラーログでより具体的なエラーメッセージを確認することができます。以下のコマンドのエラーメッセージを診断し、調整します。

```
tail -2 /var/log/httpd/ssl_error_log
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/02a9202d-7f72-465e-9a4d-c88d37b47167.png)

:::note info
注：ログの日付、時間、プロセスID、その他のメタデータは異なる場合があります。重要なのは、エントリーの最後にあるメッセージです。
:::

ログ・データから、Apacheが起動しないエラーの原因は、`/etc/pki/tls/certs/localhost.crt`ファイルにあります。ステップ1で、このファイルには2048ビットの公開鍵を使用したRSA証明書が含まれていたことを確認しました。しかし、新しいFUTUREポリシーにより、RSA証明書には少なくとも3072ビットの公開鍵が必要になります。

FUTUREシステム全体の暗号化ポリシーは、既存の証明書と公開鍵で実行するとポリシー設定に違反するため、Apacheの起動を停止しています。次の手順では、この問題を解決します。



### ステップ 4: SSL 証明書の再生成

FUTUREのシステム全体の暗号化ポリシーに準拠するために、3072ビット長以上のRSAキーを使用して、代替のSSL証明書を生成する必要があります。

更新されたSSL証明書を作成する前に、既存の証明書ファイルをバックアップしてください。

```
cp /etc/pki/tls/private/localhost.key /etc/pki/tls/private/localhost.key.orig
```
```
cp /etc/pki/tls/certs/localhost.crt /etc/pki/tls/certs/localhost.crt.orig
```
バックアップが終わりましたら、新しい代替のSSL証明書と公開鍵を生成します。新しいRSA証明書は、3072ビットの公開鍵を使用します。


```
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:3072 -subj='/C=XX/O=Default' -keyout /etc/pki/tls/private/localhost.key -out /etc/pki/tls/certs/localhost.crt
```
鍵のビット長を確認し、3072ビットであることを確認します。

```
openssl x509 -in /etc/pki/tls/certs/localhost.crt -text | grep bit
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/d21f75c1-b573-04ce-1432-6eab519d01eb.png)

これで、より大きな公開鍵を使用して新しいSSL証明書が作成され、FUTURE暗号化ポリシーの要件に準拠します。

:::note info
注：認証局発行の証明書を使用することを推奨します。認証局からの証明書を使用する場合、新しい証明書署名要求を生成し、認証局に提出する必要があります。認証局から署名された証明書を受け取ったら、それを配置し、それを参照するために必要な設定ファイルを更新します。

:::

### ステップ5：更新された証明書でApacheを起動

使用する証明書がシステム全体の暗号化ポリシーに準拠するようになったので、Apacheサービスを起動します。ポリシーに準拠しているので、問題なく起動できるはずです。


```
systemctl restart httpd.service
```
Apacheが稼働していることを確認します。
```
systemctl status httpd.service --no-pager
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/d27f75b4-fd64-76a9-8b2a-9cc7a0c204d2.png)

サービスが実行され、使用されている証明書がシステム全体の暗号化ポリシー、`FUTURE`に準拠していることを確認したら、Apacheサービスに接続し、新しい証明書がクライアントブラウザに提供されていることを検証します。


```
openssl s_client -connect localhost:443 </dev/null 2>/dev/null | grep '^Server public key'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/206b6771-dc8d-d019-b00d-94c6905c1bdf.png)

**以上ラボ3でした。**

## ラボ4: Customize the system-wide cryptographic policy

### ステップ1: 現在のシステム全体の暗号化ポリシー設定を確認

CSOからのメールです。

```
Application and Infrastructure Administrators,

After my last e-mail recommending 3072 bit public keys, I have received few concerns that some applications would need additional time for migration.

To continue supporting these applications running on our platform, and to provide more time for these applications to upgrade, my recommendation is to disallow TLS (1.0, and 1.1), and not allow SHA-1 hash usage.

l allow 2048 bit ciphers usage for a certain period of time until all applications can be upgraded to use 3072 bit keys.

-CSO
```
一部のアプリケーションの移行は時間がかかるため、TLS（1.0および1.1）とSHA-1ハッシュの使用を許可せず、一時的に2048ビット暗号の使用を許可することになりました。

上記の CSO が定める要件に準拠するため、システムを更新して `FUTURE` ポリシーを変更し、2048 ビ ット長の鍵をサポートするようにします。

次に、システムで現在有効な暗号化ポリシーを確認します。

```
update-crypto-policies --show
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/c0a376c7-495c-8f5b-4659-22b47da67fe7.png)

Apacheを再起動します。
```
systemctl restart httpd.service
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/d27f2b93-ac76-ccf4-f670-9c16c2aaca1b.png)

Apacheの再起動が失敗しましたので、Apacheの状態を確認します。

```
systemctl status httpd.service --no-pager
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/da6373bc-a390-e7af-18f9-cc453a9fe396.png)

ApacheのSSLエラーログで、より具体的なエラーメッセージを見ることもできます。
```
tail -2 /var/log/httpd/ssl_error_log
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/7416ad9d-a408-2903-3143-17bf25f8b64c.png)

エラーメッセージは、FUTUREポリシーには最低3072ビットの鍵が必要ことを示しています。FUTUREポリシーには鍵の長さが3072ビット以上という要件があるため、2048ビットの鍵を使用しようとするとエラーが出ます。従って、今回はFUTURE暗号化ポリシーに2048ビットも使用できるようにしないといけません。

ここで、FUTUREポリシーが使用できる2048KEYS.pmodというポリシーモジュールを作成します。ポリシー修飾子は、update-crypto-policiesツールへのポリシー指示を含むテキストファイルです。


次に、最小鍵サイズを2048ビットに設定する2048KEYS.pmodというポリシー修飾子を作成します。
```
touch /etc/crypto-policies/policies/modules/2048KEYS.pmod
```
ポリシー修飾子ファイルでRSA鍵とDH鍵の最小鍵の長さを指定します。
```
echo "min_dh_size = 2048" > /etc/crypto-policies/policies/modules/2048KEYS.pmod
```
```
echo "min_rsa_size = 2048" >> /etc/crypto-policies/policies/modules/2048KEYS.pmod
```
新しく作成したポリシー修飾子を使って、変更したFUTUREポリシーを使用するようにシステムを構成します。
```
update-crypto-policies --set FUTURE:2048KEYS
```
複数のポリシー修飾子を適用したい場合は、複数のポリシー修飾子を「:」で区切って連結することができます。ポリシー修飾子は左から右に評価され、指定された名前のポリシーを変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/6aaa8166-a220-578e-a20d-5a885b4989dd.png)

新しいポリシーがシステムに適用されたことを確認します。

```
update-crypto-policies --show
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/cf5a9c97-3ad4-1f3a-9425-d3514b28747f.png)

### ステップ2: サービスの問題を解決

システム全体の暗号化ポリシーを変更した後、Apacheサービスを再起動する必要があります。


```
systemctl restart httpd.service
```
Apache が実行されていることを確認します。
```
systemctl status httpd.service --no-pager
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/dfa0243d-ffe9-c03b-898f-e5cf06c32f52.png)

Apacheが起動され、使用されている証明書が2048ビットであることを確認します。


```
openssl s_client -connect localhost:443 </dev/null 2>/dev/null | grep '^Server public key'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887927/f6af4e28-8e80-4b7f-be04-cfd91931ea44.png)

これで、2048ビット以上の暗号をサポートする、変更されたFUTURE暗号ポリシーを強制するようにRHELが設定されました。この設定により、Apacheは 2048 ビットの鍵を使用して実行し続けることができます。

**以上ラボ4でした。**

# まとめ
本記事では、Red Hat interactive labsについて説明し、セッション記録の重要性、SELinux とセキュリティ プロファイルとは何か、暗号化の概念について説明しました。さらに、RHEL セキュリティ ユースケースに関する4つのラボについても説明しました。本記事を通じて、Red Hat interactive labsの利用方法を理解し、他のRed hatのラボも引き続き試していただければ幸いです。