はじめに
CNCF Blogを徘徊していたらKubescape: The first open source tool for running NSA and CISA Kubernetes hardening testsという記事を見つけました。
The first open source toolと書かれていて気になったのでアドベントカレンダー21日目はKubescapeを取り上げます。
Kubernetesのみならずコンテナをプロダクション環境で利用しているとやはりセキュリティは気になります。
ところがコンテナとなると仮想環境ということでしっかりとセキュリティ対策ができているといえるプロジェクトは少ないのではないでしょうか。
CVE Detailsのページを確認するとKubernetes関連の脆弱性は予想以上に多くあります。
Kubernetesのセキュリティチェックを行うツールはすでにいくつか存在していますが、Kubescapeもセキュリティチェックツールを検討する際の選択肢の1つに加わりました。
1. Kubescapeとは
1.1 概要
冒頭で述べたように、KubescapeはArmo社が提供するKubernetesのセキュリティチェックツールです。
Goで実装されており、Apache-2.0 Licenseで配布されています。
2021年8月にv0.0.5がファーストリリースされており、2021年12月にはv1.0.135がリリースされています。githubのリリースノートを見ると、数日〜1週間のスパンでリリースされており開発スピードの速さが伺えます。
Armo社の公式ブログでは1つのツールで複数のフレームワークを用いてセキュリティスキャンできるという点で、first toolであると書かれています。
また、CICDパイプラインへの組み込みを考慮して開発されており、JenkinsやCircleCI、Github、Gitlabのワークフローへも容易に組み込めます。
1.2 Kubescapeでできること
KubescapeではKubernetesのセキュリティスキャンを実施できます。
スキャン対象となるものは以下の3つです。
- Kubernetesクラスタ
- Kubernetesマニフェスト(yamlファイル)
- Helm Chart
また、スキャンする際に指定できるフレームワークとして、現時点では以下の3つがあります。
-
nsa
:NSA-CISA Kubernetes Hardening Guidance -
mitre
:MITRE ATT&CK®※ -
armobest
:ARMOBest
※Armo社の公式ブログではMITRE ATT&CK®の表を拡張したMicrosoft社のthreat matrix for Kubernetesの方が紹介されています。
複数フレームワークを利用してセキュリティスキャンできることも含め、下記のような点がKubescapeの特徴として挙げられています。
- Kubernetesのリスクスコアを数値で出せるため、リスクトレンドを可視化できる
- 複数フレームワークを使用してセキュリティチェックできる
- 独自のフレームワークを作成して利用できる
- スキャン結果をExceptionとして受け取り、ハンドリングできる
- DevOpsツール(Jenkins等)への組み込みが容易
- Kuberntesクラスタへのインストールが不要
1.3 KubescapeとOpen Policy Agent
アドベントカレンダー5日目ではOpen Policy Agent (OPA) のユースケース4選を紹介していますが、
KubescapeでもOpen Policy Agentが用いられています。
Kubescapeは、Kubernetesクラスタ上にリソースを作成する必要はなく、kube-apiserverから取得したKubernetesのリソース情報に対してregoで記述したポリシーを適用しています。
Kubescape based on OPA engine: https://github.com/open-policy-agent/opa and ARMO's posture controls.
The tools retrieves Kubernetes objects from the API server and runs a set of regos snippets developed by ARMO.
出典:https://github.com/armosec/kubescape
Armo社のgithubレポジトリにarmosec/regolibraryというものがあり、regoで記述されたポリシーを見ることができます。
公式な記載は見当たりませんが、Kubescapeによるスキャンでもこちらのポリシー用いられていると思われます。
例えばhostpathが利用されているPodに対してはalert-any-hostpathという下記のようなPolicyによりチェックさされています。
deny[msga] {
pod := input[_]
pod.kind == "Pod"
volumes := pod.spec.volumes
volume := volumes[i]
begginingOfPath := "spec."
result := isDangerousHostPath(volume, begginingOfPath, i)
podname := pod.metadata.name
msga := {
"alertMessage": sprintf("pod: %v has: %v as hostPath volume", [podname, volume.name]),
"packagename": "armo_builtins",
"alertScore": 7,
"failedPaths": [result],
"alertObject": {
"k8sApiObjects": [pod]
}
}
}
2. Kubescapeを使ってみる
2.1 インストール
kubescapeは簡単にインストールすることができます。
githubレポジトリに書かれてある通り、インストール用のシェルを実行しても良いですが、ここでは直接実行ファイルをダウンロードします。
今回は、v1.0.135を使用します。
$ curl -L -o kubescape https://github.com/armosec/kubescape/releases/download/v1.0.135/kubescape-ubuntu-latest
$ chmod 755 kubescape
Kubeescapeのインストールは以上で完了です。
必要であればPATHを通しておきましょう。
kubescapeの基本的な使用方法やオプション引数についてはgithubレポジトリに記載されています。
2.2 Kubernetesクラスタのスキャン
実際にkubescapeを用いてKubernetesクラスタのスキャンを行ってみます。
スキャンする際は下記のようにフレームワークを指定できます。
kubescape scan framework nsa
kubescape scan framework mitre
kubescape scan framework armobest
以下は、kubeadmで作成した直後のクラスタに対してnsaのフレームワークを用いてスキャンした結果です。
$ ./kubescape scan framework nsa
~中略~
NSA FRAMEWORK
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| CONTROL NAME | FAILED RESOURCES | EXCLUDED RESOURCES | ALL RESOURCES | % SUCCESS |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| Allow privilege escalation | 0 | 0 | 8 | 100% |
| Allowed hostPath | 4 | 0 | 7 | 42% |
| Applications credentials in configuration files | 0 | 0 | 18 | 100% |
| Automatic mapping of service account | 39 | 0 | 39 | 0% |
| CVE-2021-25741 - Using symlink for arbitrary host file system access. | 0 | 0 | 8 | 100% |
| CVE-2021-25742-nginx-ingress-snippet-annotation-vulnerability | 0 | 0 | 0 | NaN |
| Cluster internal networking | 4 | 0 | 4 | 0% |
| Cluster-admin binding | 1 | 0 | 68 | 98% |
| Container hostPort | 0 | 0 | 7 | 100% |
| Control plane hardening | 0 | 0 | 1 | 100% |
| Dangerous capabilities | 0 | 0 | 7 | 100% |
| Exec into container | 1 | 0 | 68 | 98% |
| Exposed dashboard | 0 | 0 | 0 | NaN |
| Host PID/IPC privileges | 0 | 0 | 7 | 100% |
| Immutable container filesystem | 6 | 0 | 7 | 14% |
| Ingress and Egress blocked | 7 | 0 | 7 | 0% |
| Insecure capabilities | 0 | 0 | 7 | 100% |
| Linux hardening | 2 | 0 | 7 | 71% |
| Non-root containers | 0 | 0 | 7 | 100% |
| Privileged container | 1 | 0 | 7 | 85% |
| Resource policies | 5 | 0 | 7 | 28% |
| hostNetwork access | 6 | 0 | 7 | 14% |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| RESOURCE SUMMARY | 51 | 0 | 131 | 61% |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
スキャン結果には以下の項目が表示されます。
CONTROL NAME
:スキャン項目(Control)
FAILED RESOURCES
:スキャンでNGとなった項目数
EXCLUDED RESOURCES
:除外したリソース数(オプション引数で除外設定ができます)
ALL RESOURCES
:対象となるすべてのリソース数
% SUCCESS
:OKとなった割合
Kubeadmにより作成した直後のKuebrnetesクラスタですが、下記のような項目でNGとなっているようです。
- Allowed hostPath:ホストパスをマウントしているPodがある
- Automatic mapping of service account:サービスアカウントの自動マッピングを有効にしている
- Cluster internal networking:ネットワークポリシーが定義されていないため、コンテナへの侵入した攻撃者がクラスタ内のコンテナを移動可能になる可能性がある
- Cluster-admin binding:クラスタのadmin権限を有しているリソースが存在しており、悪意のある挙動操作を実行可能な状態である
- Exec into container:kubectl execコマンドで悪意のあるコマンドを実行可能なコンテナが存在する
- Immutable container filesystem:コンテナのファイスシステムとしてミュータブル(read-write)なものが使用されている
- Ingress and Egress blocked:Pod間で任意のIngress/Egress通信が可能となっている
- Linux hardening:コンテナそのものに必要以上の権限を与えている可能性がある
- Privileged container:特権モードのコンテナが存在する
- Resource policies:CPUやMemory制限がないため、リソースが過剰に消費される可能性がある
- hostNetwork access:Podへ侵入した攻撃者がホストネットワークを利用できる可能性がある
作成直後のクラスタなのでほとんど何も出ないだろうと思っていたら、予想外に多くで驚きでした。
ここでスキャンNGとなっている項目はetcdやkube-proxyなどコントロールプレーンの構成要素です。
マネージドなKubernetesサービスではコントロールプレーンがマネージドなため、ユーザがこれらを意識する必要はありませんが、独自でクラスタを構築する際は上記のような危険をはらむコンテナを所有しているという点を意識しておく必要がありそうです。
2.3 yamlファイルのスキャン
Kubernetesクラスタと同様にマニフェスト(yamlファイル)のセキュリティスキャンも行ってみます。
スキャン対象としてGuestbookを利用します。
Kubernetesクラスタのスキャンと同様のコマンドを利用し、スキャン対象を引数として与えることで実行できます。
kubescape scan framework nsa <スキャン対象>
kubescape scan framework mitre <スキャン対象>
kubescape scan framework armobest <スキャン対象>
$ ./kubescape scan framework nsa examples-master/guestbook/*.yaml
~中略~
NSA FRAMEWORK
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| CONTROL NAME | FAILED RESOURCES | EXCLUDED RESOURCES | ALL RESOURCES | % SUCCESS |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| Allow privilege escalation | 3 | 0 | 3 | 0% |
| Allowed hostPath | 0 | 0 | 3 | 100% |
| Applications credentials in configuration files | 0 | 0 | 3 | 100% |
| Automatic mapping of service account | 0 | 0 | 0 | NaN |
| CVE-2021-25741 - Using symlink for arbitrary host file system access. | 0 | 0 | 3 | 100% |
| CVE-2021-25742-nginx-ingress-snippet-annotation-vulnerability | 0 | 0 | 0 | NaN |
| Cluster internal networking | 0 | 0 | 0 | NaN |
| Cluster-admin binding | 0 | 0 | 0 | NaN |
| Container hostPort | 0 | 0 | 3 | 100% |
| Control plane hardening | 0 | 0 | 0 | NaN |
| Dangerous capabilities | 0 | 0 | 3 | 100% |
| Exec into container | 0 | 0 | 0 | NaN |
| Exposed dashboard | 0 | 0 | 0 | NaN |
| Host PID/IPC privileges | 0 | 0 | 3 | 100% |
| Immutable container filesystem | 3 | 0 | 3 | 0% |
| Ingress and Egress blocked | 3 | 0 | 3 | 0% |
| Insecure capabilities | 0 | 0 | 3 | 100% |
| Linux hardening | 3 | 0 | 3 | 0% |
| Non-root containers | 0 | 0 | 3 | 100% |
| Privileged container | 0 | 0 | 3 | 100% |
| Resource policies | 0 | 0 | 3 | 100% |
| hostNetwork access | 0 | 0 | 3 | 100% |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
| RESOURCE SUMMARY | 3 | 0 | 3 | 0% |
+-----------------------------------------------------------------------+------------------+--------------------+---------------+-----------+
上記の出力結果では省略していますが、スキャンでNGとなった項目については下記のようにNG項目と対象を教えてくれます。
ただし、何をどう修正してよいかは教えてくれないため、是正するにはKubernetesやコンテナの知識が必要となります。
[control: Allow privilege escalation] failed 😥
Description: Attackers may gain access to a container and uplift its privilege to enable excessive capabilities.
Failed:
Deployment - frontend
Deployment - redis-master
Deployment - redis-slave
Guestbookでは以下のような項目がNGとなっていることが分かります。
- Allow privilege escalation:攻撃者が特権モードへ昇格可能
- Immutable container filesystem:コンテナのファイスシステムとしてミュータブル(read-write)なものが使用されている
- Ingress and Egress blocked:Pod間で任意のIngress/Egress通信が可能となっている
- Linux hardening:コンテナそのものに必要以上の権限を与えている可能性がある
おわりに
Kubernetes関連のOSSは無数にあり、有名どころだけに絞ったとしても有限時間でキャッチアップすることは難しいです。
幸い、今回取り上げたKubescapeはインストールや使用方法が非常に簡単(実質何もしてない)でした。
しかし、セキュリティスキャンということでスキャン結果を理解して是正していくにはそれなりの知識が必要になります。
また、KubescapeではOpen Policy Agentが利用されていたということもあり、応用的なツールをさわるのも良いですが、それ以前にやはりKubernetesそのものや、Open Policy Agentなどベースとなる技術を習得していくことが重要だと改めて気づかされました。
本記事では、Kubescapeの概要と実行結果だけを示しましたが、それぞれのチェック項目が具体的に何をチェックしていて、NGとなった際にどう対処すればよいのかなども記事にできると良いなと思います(未来の自分に期待)。