本文の内容は、2024年11月5日にSysdig Team が投稿したブログ(https://sysdig.com/blog/adding-runtime-threat-detection-to-gke-with-falco/)を元に日本語に翻訳・再構成した内容となっております。
Google Kubernetes Engine(GKE)などのマネージド Kubernetes サービスでワークロードを実行する大きな利点の 1 つは、Google が業界のベスト プラクティスに従ってクラスターをデプロイおよび管理していることです。
GKE クラスターは非常に安全で信頼性が高いですが、改善の余地は常にあります。
このブログでは、Falco を使用してランタイム脅威検出を追加することで、GKE のすでに優れたセキュリティを強化する方法について説明します。
Falcoとは何ですか?
Falco は、ランタイム脅威検知を提供する Cloud Native Computing Foundation プロジェクトです。Falco はすぐに使用できる状態で、システムコールを調べて疑わしいアクティビティがあれば警告します。また、コンテナはホストと同じカーネルを共有するため、Falco はホスト上のアクティビティだけでなく、そのホストで実行されているすべてのコンテナ上のアクティビティも監視できます。さらに、Falco は Kubernetes とコンテナ ランタイムの両方からデータを取得して、アラートに追加のコンテキストを追加します。
GKE クラスターで Falco を実行すると、次のようなさまざまなイベントの通知を受け取ることができます。
- 誰かが高い権限でコンテナを起動しましたか?
- 誰かが稼働中のコンテナにシェルアクセスしましたか?
- デプロイ後にコンテナに実行ファイルが追加されましたか?
これらはほんの一例に過ぎません。Falcoには、外部からの脅威だけでなく、クラスターが業界のベストプラクティスに従って運用されていない場合にも気付けるよう、80以上のルールが用意されています。
GKEインストール時の考慮事項
FalcoをGKEにインストールするには、2つの方法があります。1つ目はGoogle Cloud Marketplaceにある「click-to-run」形式のパッケージを使用する方法で、2つ目はFalcoのHelmチャートを利用する方法です。「click-to-run」のパッケージはGKE上でFalcoをすぐに実行する最も簡単な方法ですが、提供されるバージョンが最新リリースより遅れることがあるのがデメリットです。
また、現時点ではFalcoをGKEのAutopilotモードで動作させることはできない点にも注意が必要です。これは、Falcoがドライバをインストールする際に特権アクセスで動作するinitコンテナを使用するためで、Autopilotでは特権コンテナの実行が許可されていないためです。
さらに、GKE上でFalcoを使用するには、FalcoのeBPFドライバの1つを利用する必要があります。Falcoはシステムコールイベントをキャプチャするためにドライバを使用し、このドライバはロード可能なカーネルモジュールまたはeBPFプローブとして提供されます。実際、Falcoには「eBPF」(クラシックeBPF)と「モダンeBPF」という2種類のeBPFプローブがあり、詳細はFalcoのドキュメントで確認できます。
Google Cloud側では、GKEはデフォルトで作業ノードプールにContainer-Optimized OS(COS)を使用します。COSはセキュリティ強化されたOSであり、基盤となるOSの一部へのアクセスが制限されています。このセキュリティ制約により、Falcoがカーネルモジュールを挿入してシステムコールを処理することはできません。しかし、COSはeBPFをサポートしているため、このオプションを使用します(具体的にはクラシックeBPFプローブを利用します)。
Google Cloud Marketplace経由でFalcoをインストールする
注: 手順に従う場合は、Google Cloud アカウントに適切な権限があることを確認する必要があります。
Google Cloud Marketplace 経由で Falco をインストールするのは、非常に簡単なプロセスです。
- Google Cloud アカウントにログインし、新しい GKE クラスターをデプロイしたり、既存のクラスターを操作するために必要な権限があることを確認します。
- Google Cloud Marketplaceの Falco オファリングに移動します 。
- configure ボタンをクリックします 。
- 次のダイアログでは、GKE クラスターが実行されるゾーンと、クラスターが実行されるネットワークおよびサブネットを選択できます。このチュートリアルでは、デフォルト値で問題ありません。
- 次に、Falco を新しい GKE クラスターにデプロイするか、既存のクラスターを使用するかを選択します。Create New Cluster をクリックすると、 Google Cloudはすぐに新しいクラスターのデプロイを開始するので注意が必要です。また、プロジェクトにある Autopilot クラスタはグレー表示され、選択できません。
- 次に、Falcoを実行するネームスペースを選択できます。このブログの他の部分と一貫性を保つために、ネームスペースを「default」から「falco」に変更してください。
- 同様に、このブログの他の部分と一貫性を保つため、アプリインスタンス名も「falco」に変更してください。
- Falcoのルールには異なる優先度レベルがあり、実行したい最低優先度レベルを選択できます。優先度レベルは深刻度に応じて並べられており、通常、最低レベルを高く設定するとアラートの数が減り(ノイズの削減に役立ちます)、必要な通知だけを受け取ることができます。この例では、最低優先度レベルを「debug」に設定したままにしておきましょう。
- Stackdriver は、Google Cloud のロギングおよびモニタリング スイートの旧称です。Falco のメトリクス (実際のアラートではなく、Falco のパフォーマンスに関するメトリクス) を調べたい場合は、そのオプションを選択できます。このブログではこれについては取り上げませんので、チェックを外したままにしておいてください。
- 「DEPLOY」をクリックして、ターゲットクラスターにFalcoをデプロイします。(新しいクラスターをデプロイする場合は、デプロイが完了するまで待ってから「DEPLOY」ボタンをクリックしてください。)
これで、Falco が GKE クラスター上で実行されるはずです。次のセクションをスキップして、「Falco のテスト」に進むことができます。
Helm で Falco をインストールする
HelmはKubernetes上にFalcoをインストールするための事実上の標準ツールです。Falcoは公式のHelmチャートを維持しており、そのチャートはFalcoプロジェクト全体の一部として管理されています。
以下の手順に従ってセットアップする場合、次のものが必要です:
- 適切な権限を持つGoogle Cloudアカウント
- 操作可能なGKEクラスター
- ローカルコンピュータにHelmとkubectlがインストールされていること、または、Google Cloud Shellを使用すること(こちらにはHelmとkubectlが既にインストールされています)注意: kubectlのコンテキストが、Falcoをインストールしたいクラスターに設定されていることを確認してください。
前提条件が整ったので、実際のインストールを始めましょう。
Falco チャートを Helm リポジトリに追加します。
helm repo add falcosecurity \ https://falcosecurity.github.io/charts && \ helm repo update
falco
Falco を実行するためのネームスペースを作成します 。
kubectl create namespace falco
Helm を使用して Falco をデプロイします。 driver.kind
パラメータを使用してカーネル ドライバーを eBPF プローブに設定することに注意してください。
helm install falco \ -n falco \ --set tty=true \ --set driver.kind=ebpf \ falcosecurity/falco
Falco ポッドがオンラインになるまで待ちます。
kubectl get pods -n falco -w
最終的には、以下のような表示が確認できるはずです:
falco-wfglg 2/2 Running 0 76s falco-mdrlb 2/2 Running 0 91s falco-7vxz6 2/2 Running 0 91s
注: クラスター内のノードごとに 1 つの Falco エントリが表示されます。この場合、Falco は 3 ノードのクラスターで実行されているため、エントリは 3 つあります。
ログを調べて、Falco が正しく実行されていることを確認します。
kubectl logs -n falco -c falco -l app.kubernetes.io/name=falco
次のようなエントリが表示されます。
Fri Nov 3 15:48:07 2023: Falco version: 0.36.2 (x86_64) Fri Nov 3 15:48:07 2023: Falco initialized with configuration file: /etc/falco/falco.yaml Fri Nov 3 15:48:07 2023: Loading rules from file /etc/falco/falco_rules.yaml Fri Nov 3 15:48:07 2023: The chosen syscall buffer dimension is: 8388608 bytes (8 MBs) Fri Nov 3 15:48:07 2023: Starting health webserver with threadiness 2, listening on port 8765 Fri Nov 3 15:48:07 2023: Loaded event sources: syscall Fri Nov 3 15:48:07 2023: Enabled event sources: syscall Fri Nov 3 15:48:07 2023: Opening 'syscall' source with BPF probe. BPF probe path: /root/.falco/falco-bpf.o
FalcoがGKEクラスター上で正常に稼働していることを確認できました。次のステップは、不審なアクティビティをシミュレーションし、Falcoがそれを検出するかどうかを確認することです。
Falcoのテスト
Falcoのデフォルトルールの1つは、稼働中のコンテナにシェルアクセスが行われた際にアラートを発するものです。以下の手順に従って、そのルールを発動させてみましょう。
Alpine コンテナを起動し、実行を継続するためにスリープ状態にします。
kubectl run alpine –image alpine – sh -c "sleep infinity"
Alpineが稼働しているコンテナ上で、以下のコマンドを実行してシェルを起動してください:
kubectl exec -it alpine -- sh -c "ls -al"
次に、Falco ログをチェックしてアラートを確認します。
kubectl logs -c falco -n falco -l app.kubernetes.io/name=falco |\ grep "Notice"
以下のような表示が確認できるはずです:
18:52:06.630209324: Notice A shell was spawned in a container with an attached terminal (evt_type=execve user=root user_uid=0 user_loginuid=-1 process=sh proc_exepath=/bin/busybox parent=runc command=sh -c ls -al terminal=34816 exe_flags=EXE_WRITABLE container_id=e71eac85a570 container_image=docker.io/library/alpine container_image_tag=latest container_name=alpine k8s_ns=default k8s_pod_name=alpine)
アラートには、コンテナID、イメージ、名前、そして実行されたコマンドなどの詳細情報が含まれていることに注目してください。
まとめ
冒頭で述べたように、マネージドKubernetesサービスを利用する大きな利点の1つは、クラスターの強化に関する多くの作業がすでに行われている点です。しかし、Falcoを使用してクラスター内のアクティビティに関するランタイムの洞察を提供することで、クラスターが適切に運用されているか、悪意のある攻撃者によって侵害されていないかを確認する助けとなります。
Falcoについてさらに学びたい場合は、ドキュメントやGitHubリポジトリをご覧ください。また、KubernetesのSlackサーバーにある「#Falco」チャンネルでも情報を提供しています。