Amazon Web Services ブログ
Bottlerocket を利用した Amazon EKS 上の Deployment を KubeArmor でよりセキュアにしよう
この記事は Secure Bottlerocket deployments on Amazon EKS with KubeArmor (記事公開日: 2022 年 10 月 20 日) の翻訳記事です。
Introduction
Bottlerocket はセキュリティに焦点を当てたオペレーティングシステム (OS) イメージです。ホストまたはワーカーノードを保護するために、すぐに利用可能なセキュリティオプションを提供します。セキュリティを考慮する上で Bottlerocket は便利ですが、Pod やコンテナのセキュリティは依然としてアプリケーション開発者やプロバイダーの責任です。CNCF (Cloud Native Computing Foundation) のサンドボックスプロジェクトである KubeArmor は、extended Berkeley Packet Filter (eBPF) とBerkeley Packet Filter-Linux Security Module (BPF-LSM) を活用して Pod やコンテナを保護するランタイムセキュリティエンジンです。
KubeArmor はポリシーの適用に Linux セキュリティモジュール (LSM) を使用します。LSM は数十年前からホストの強化に伝統的に使用されてきたカーネルテクノロジーです。どの Linux プラットフォーム (例: Alpine Linux や、Ubuntu、Bottlerocket のようなコンテナに最適化された OS) でも動作します。LSM は設定が非常に難しく、その複雑さからセキュリティ管理者は無効化してしまうことがよくあります。KubeArmor の主な目的の 1 つは、ユーザーが LSM 自体について心配することなく、LSM の使用を簡素化して必要なポリシーを適用することです。つまり KubeArmor は LSM 自体の利点を活用しながら LSM の複雑さを抽象化します。
ソリューション概要
図1. KubeArmor のアーキテクチャ
ポリシー適用のための BPF-LSM のカーネルサポート
バージョン 0.5 では、KubeArmor は BPF-LSM と統合してPod やコンテナベースのポリシーを適用できるようになりました。BPF-LSM は、新しいカーネル (バージョン > 5.7) で導入された新しい LSM (Linux セキュリティモジュール) です。BPF-LSM を使用すると、KubeArmor はユーザー指定のポリシーコントロールを含む LSM フックに bpf-bytecode
をアタッチできます。これによってすべてが変わります。bpf-bytecode
はより豊富な情報とカーネルコンテキストにアクセスできるようになり、SELinux や AppArmor ポリシー言語の制約内で動作する必要がなくなりました。例えば、SELinux はポリシー定義言語を定義する Common Intermediate Language (CIL) を使用しています。そして、このポリシー言語のセマンティクスに厳密に従わなければならないセキュリティルールがあります。同様に、AppArmor は明示的なポリシー言語構文を指定しており、ユーザー指定のルールもこれらの構造に従う必要があります。
図2. BPF-LSM と KubeArmor
どのプラットフォームが BPF-LSM をサポートしていますか?
- Bottlerocket
- Amazon Linux 2 の最新イメージ。注: デフォルトの Amazon Linux 2 はカーネルバージョン 5.4 のままなので、bpf-lsm を併用することはできません。カーネルバージョン 5.10 にアップグレードすれば bpf-lsm で使用できます。デフォルトのカーネルを 5.10 にアップグレードするには、このガイドに従ってください
- 詳細なリストについては、こちらをご確認ください。
KubeArmor が Bottlerocket のセキュリティを改善する方法
Bottlerocket は SELinux を使用してホストをロックダウンし、コンテナ間の限定的な分離を提供します。
KubeArmor は BPF-LSM を使用して プロセス、ファイル、プリミティブなネットワークの使用などに関するシステム動作を制限し、Bottlerocket でホストされている k8s
Pod を保護することでセキュリティを強化します。たとえば、Pod 内にマウントされた k8s
セキュリティアクセストークンは、デフォルトでその Pod 内のすべてのコンテナからアクセス可能です。
KubeArmor は、このようなトークンへのアクセスを特定のプロセスにのみ制限できます。同様に、KubeArmor はコンテナ内の機密情報(k8s
Secret、x509
証明書など)を保護するために使用されます。KubeArmor は、任意の証明書のフォルダ (/etc/ssl/
、/etc/pki/
、/usr/local/share/ca-certificates/
) 内のルート証明書を更新しようとする動作をブロックするようにポリシールールを指定できます。さらに、KubeArmor はコンテナ内の特定のバイナリの実行を制限することができます。
図3. Kubearmor が Bottlerocket のセキュリティを向上
なぜ Pod を保護することが重要なのでしょうか?
k8s
Pod は Ingress コントローラーを介して外部からアクセスされることがあるエンティティです。そのため Pod 内のワークロードまたはアプリケーションが脆弱であれば、危険にさらされる可能性が高くなります。攻撃者がコンテナエスケープを利用してホストを危険にさらす可能性があります。Pod には別システムへの攻撃を行ったり、データを盗み出したりする可能性がある攻撃ベクトルがあります。
NSA-CISA K8s Hardening Guide の引用:
「クラスター内で実行されるアプリケーションは一般的なターゲットです。これらのアプリケーションはクラスターの外部から頻繁にアクセスされるため、リモートのサイバー攻撃者も到達可能な状態です。攻撃者は既に侵害された Pod を軸に、公開されたアプリケーションの内部アクセス可能なリソースを使用してクラスター内の権限を昇格させたりすることができます。」
AWS の責任分担モデルでは、Pod とアプリケーションのセキュリティは、ワークロードを実行するお客様の範囲内にあります。何十年にもわたってホストとノードが強化されてきたのと同じように、KubeArmor は Pod を強化する方法を提供します。
KubeArmor のポリシーは、ワークロードがデプロイされて実行された後のランタイムに適用されます。KubeArmor のポリシー管理は同様の方法で処理されるべきであり、ネットワークポリシーもランタイムに適用されます。
現実世界のユースケース
コンテナ化されたワークロードの多くでベースイメージとして使用される alpine イメージには、基本的にパッケージ管理ツールである /sbin/apk
バイナリ が付属しています。これには、Pod 内の攻撃対象領域 (Attack Surface)を増やすツールを使用する、新しいバイナリがインストールされる可能性があります。本番環境では、これらのツールの実行を無効にするのが最善です。KubeArmor は、このようなバイナリの実行をブロックすることで攻撃対象領域を縮小します。
次のポリシー例は、その方法を示しています。
もう 1 つの方法として、k8s
クラスターに Pod をデプロイする場合が挙げられます。これは、どのアプリケーションも Pod 内でアクセスする必要がない場合でも、その Pod はデフォルトで /var/run/secrets/kubernetes.io/serviceaccount
のパスに Service Account トークンとともにマウントされるためです。攻撃者はトークンを利用して k8s
のAPI サーバーにアクセスし、クラスター内の別のアプリケーションに移動可能になります。
NSA-CISA K8s Hardening Guide in the context の引用:
「デフォルトでは、Kubernetes は Pod の作成時に自動的に Service Account をプロビジョニングし、実行時にアカウントのシークレットトークンを Pod 内にマウントします。Kubernetes のオーケストレーションはバックグラウンドで透過的に行われるため、コンテナ化されたアプリケーションの多くは Service Account に直接アクセスする必要はありません。アプリケーションが侵害された場合、サイバー攻撃者は Pod 内のアカウントトークンを収集し、クラスターをさらに侵害するために使用される可能性があります。」
KubeArmor には、Pod 内の Service Account トークンパスへのアクセスを無効にすることで、Pod 内の Service Account トークンパスへのアクセスを制限する方法があります。