KubescapeでKubernetesクラスタの脆弱性スキャンをしてみよう

この記事は[ZOZO #1 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/zozo)の17日目の記事です。
昨日は [@satto_sann](https://qiita.com/satto_sann)さんの [Alexaスキル開発でGoogleカレンダーAPIと連携してみた](https://qiita.com/satto_sann/items/34cdfa8231eb455849b3) でした。

##はじめに

師走を迎え、セキュリティ脆弱性対応に駆け回った皆様も多いのではないかと思います。いかがお過ごしでしょうか？
さて、本記事ではKubernetesクラスタの脆弱性を検査するKubescapeを紹介します。


##Kubescapeとは？
[Kubescape](https://github.com/armosec/kubescape)は[Armosec社](https://www.armosec.io/)が公開しているOSSプロジェクトです。
コンセプトは、以下ブログに詳しい記載があります。
https://www.armosec.io/blog/kubescape-the-first-tool-for-running-nsa-and-cisa-kubernetes-hardening-tests/

以下のような特徴があります。

- Kubernetesのセキュリティリスクをスコア計算できる。
- 以下のような複数のセキュリティおよびコンプライアンスフレームワークを選択できる。
    - [NSA-CISA Kubernetes Hardening Guidance](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF)
    - [MITRE ATT&CK®](https://attack.mitre.org/)
    - [Armobest Kubernetes Framework](https://www.armosec.io/blog/armobest-kubernetes-framework/)
- 使いやすいCLIインターフェイスと柔軟な出力形式を持つ。
- Kubernetesクラスタへのインストール不要で、読み取り専用の権限があれば実行可能。
- [SaaSのダッシュボードサービス](https://portal.armo.cloud/)が提供されている。

##インストール方法
Kubescapeコマンドのインストール方法については、以下に記載があります。
https://github.com/armosec/kubescape#install

ご利用の環境に合わせて、適宜インストールを行ってください。

##使ってみる
物は試しということで、コマンドラインベースで早速使ってみます。
まずは、使用中のKubernetesクラスタについて、[MITRE ATT&CK®](https://attack.mitre.org/) に基づき検査してみます。
下記は、Docker DesktopからKubernetesを有効化して作成したデフォルトのdocker-desktop clusterに対して実行しています。

```
$ kubescape scan framework mitre

MITRE FRAMEWORK
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
|                             CONTROL NAME                              | FAILED RESOURCES | EXCLUDED RESOURCES | ALL RESOURCES | % SUCCESS |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| Access Kubernetes dashboard                                           |        0         |         0          |      147      |   100%    |
| Access container service account                                      |        12        |         0          |      187      |    93%    |
| Access tiller endpoint                                                |        0         |         0          |       1       |   100%    |
| Applications credentials in configuration files                       |        0         |         0          |      18       |   100%    |
| CVE-2021-25741 - Using symlink for arbitrary host file system access. |        0         |         0          |       9       |   100%    |
| CVE-2021-25742-nginx-ingress-snippet-annotation-vulnerability         |        0         |         0          |      11       |   100%    |
| Cluster internal networking                                           |        4         |         0          |       4       |    0%     |
| Cluster-admin binding                                                 |        3         |         0          |      139      |    97%    |
| CoreDNS poisoning                                                     |        7         |         0          |      149      |    95%    |
| Data Destruction                                                      |        35        |         0          |      139      |    74%    |
| Delete Kubernetes events                                              |        7         |         0          |      139      |    94%    |
| Exec into container                                                   |        3         |         0          |      139      |    97%    |
| Exposed dashboard                                                     |        0         |         0          |       3       |   100%    |
| Exposed sensitive interfaces                                          |        0         |         0          |      10       |   100%    |
| Kubernetes CronJob                                                    |        0         |         0          |       0       |    NaN    |
| List Kubernetes secrets                                               |        20        |         0          |      139      |    85%    |
| Malicious admission controller (mutating)                             |        0         |         0          |       0       |    NaN    |
| Malicious admission controller (validating)                           |        0         |         0          |       0       |    NaN    |
| Mount service principal                                               |        5         |         0          |       8       |    37%    |
| Privileged container                                                  |        1         |         0          |       8       |    87%    |
| SSH server running inside container                                   |        0         |         0          |      10       |   100%    |
| Writable hostPath mount                                               |        5         |         0          |       8       |    37%    |
| hostPath mount                                                        |        5         |         0          |       8       |    37%    |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
|                           RESOURCE SUMMARY                            |        64        |         0          |      204      |    68%    |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
```

何やら複数のリソースで脆弱性の指摘がされているように見えます。
これら指摘事項の種別は、KubescapeではControlと呼んでおり、以下のドキュメントから指摘内容とその対処について調べることができます。
https://hub.armo.cloud/docs/controls

FAILED RESOURCESが7件カウントされている`Delete Kubernetes events`について調べてみましょう。
すると、以下のドキュメントに辿り着きます。
https://hub.armo.cloud/docs/c-0031

要約すると、攻撃者はクラスター内でのアクティビティの検出を回避するために、Kubernetes Eventをすべて削除して、証跡を隠そうとする場合があるため、
[最小権限の原則](https://ja.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E6%A8%A9%E9%99%90%E3%81%AE%E5%8E%9F%E5%89%87)に基づいて、Eventを削除するサブジェクトの数を最小限に抑えましょうということのようです。

このようにControlの指摘内容を基に、1つずつ対処検討していくことで、Kubernetesクラスタをよりセキュアに保つことができそうです。


## Tips

kubescapeコマンドのオプションや使用例は概ね以下ドキュメントに記載されています。
https://hub.armo.cloud/docs/examples
https://github.com/armosec/kubescape#usage--examples

ここでは、よく使いそうな利用例をいくつか紹介します。


- [NSA-CISA Kubernetes Hardening Guidance](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF)に基づき、スキャンする

```
kubescape scan framework nsa
```

- 指定したnamespaceを対象にスキャンする

```
kubescape scan framework nsa --include-namespaces testns
```

- 指定したnamespaceを除いてスキャンする

```
kubescape scan framework nsa --exclude-namespaces kube-system
```

- 特定のマニフェストファイルをオフラインでスキャンする

```
kubescape scan framework nsa *.yaml
```

- kustomize buildで生成したマニフェストをスキャンする

```
kustomize build . | kubescape scan framework nsa -
```

- 指定した閾値よりスコアが下回るかどうかチェックする

```
kubescape scan framework nsa --fail-threshold 80
```

閾値を下回った場合、以下のようなエラーメッセージが出力されます。


```
Error: Scan score is below threshold
```
なお、`--fail-threshold`オプションは、閾値を下回った場合はexit code 1となる旨、[ドキュメント](https://hub.armo.cloud/docs/options)に書いてあるのですが、
今回検証に使用したkubescape v1.0.135では、exit code 0となっており、期待通りの動作がされませんでした。(検証不足だったらすいません)

こちらが正しくexit code 1で終了する場合、このコマンドオプションを活用し、
マニフェストファイルをapplyするCIの中で、exit code 1となったらデプロイさせないような制御、
つまり、一定の閾値を下回るマニフェストファイルの適用は許可しないような制御が可能となりそうです。


##おわりに
本記事では、Kubernetesクラスタのセキュリティ脆弱性を検査するKubescapeを紹介しました。
見逃しがちな脆弱性について、皆様も年末の大掃除に取り組んでみてはいかがでしょうか？