本文の内容は、2021年12月13日にAlberto Pellitteriが投稿したブログ(https://sysdig.com/blog/mitigating-log4j-kubernetes-network-policies/)を元に日本語に翻訳・再構成した内容となっております。
2021年12月10日、Apacheのlog4jに存在する重要な脆弱性、CVE-2021-44228(通称”log4shell”)が明らかになり、すでにインターネット上で広く悪用されています。前回は、この脆弱性と、Sysdig スキャニングレポートを使用してイメージ内の脆弱性を見つける方法について説明しました。理想的な世界では、パッチの適用は迅速かつ簡単で、何の問題もなく完了します。
しかし実際には、技術的にも官僚的な対応にもハードルが高く、パッチの適用に時間がかかることがよくあります。また、サードパーティのデバイスやソフトウェアについては、脆弱性を適切に修正するための知見が得られない場合があります。このような場合には、脆弱性の緩和策が必要となります。この記事では、特にSysdigのランタイム生成されたKubernetesネットワークポリシーを活用することで、log4jの問題をどのように緩和することができるかを説明します。
従来の緩和策
Web Application Firewall (WAF)は、HTTPトランスポートを必要とする脆弱性を緩和するための最初の選択肢であることが多いです。Google Cloudでは、Cloud Armor WAFを使用して、log4jの悪用に使用されることが知られているJNDI文字列の一部を含むリクエストをブロックすることについて説明しています。他のWAFベンダーも同様の記事を公開しています。最初は効果的で簡単に適用できますが、これらのソリューションはパターンマッチに基づいており、多くの場合、迂回することができます。このGithubのレポでは、シグネチャー検出をバイパスするために文字列を変更する様々な方法の一部を紹介しています。

Kubernetesの緩和策
お使いの環境がKubernetesを実行している場合、log4jを軽減するための別のオプションがあります。ネットワークポリシーは、ポッドがクラスター内外のネットワークエンティティとどのように通信できるかを決定します。log4jの脆弱性の重要な側面の1つは、ペイロードを取得するためにサーバーが別のサーバーに到達することを強制することです。このegressは、Kubernetesのネットワークポリシーで防ぐことができます。
Kubernetesのネットワークポリシーを作成する際に厄介なのは、ワークロードの正常な運用を妨げず、かつ脅威をブロックするポリシーを作ることです。ここで、Sysdig Secureのワークロードのランタイム分析が非常に価値を発揮します。
Sysdigはワークロードの実行を監視し、アプリケーションがどのように動作しているのか、何が正常なのかを理解し始めます。例えば、以下はシンプルなJavaベースのアプリケーションについてSysdigが理解する内容です。

より複雑な例では、アプリケーションが通信する必要のある一般的なネットワークや、その他の関連リソースが表示されますが、この例では、シンプルなアプリケーションで問題ありません。
大きな特徴は、Generated Policy タブをクリックするだけで、この情報から直接Kubernetesのネットワークポリシーを生成できることです。今回の場合、アプリケーション例向けに生成されたポリシーは次のようになります。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: generated-network-policy namespace: example-java-app spec: ingress: [] egress: - to: - namespaceSelector: matchLabels: app: raw chart: raw-0.2.5 heritage: Helm release: namespaces podSelector: matchLabels: app.kubernetes.io/instance: example-java-app app.kubernetes.io/name: example-java-app-javaapp ports: - port: 8080 protocol: TCP - to: - namespaceSelector: {} ports: - port: 53 protocol: UDP podSelector: matchLabels: app.kubernetes.io/instance: example-java-app app.kubernetes.io/name: example-java-app-jclient policyTypes: - Ingress - Egress
上記のランタイム生成ポリシーに見られるように、egressアクティビティはHelmを使用してインストールされたリソースと、UDPポート53を介したDNSアクティビティの開始に限定されています。他のすべてのトラフィックは、TCPを使用するため、悪意のあるペイロードをダウンロードするlog4jエクスプロイトのステージを含めて、許可されません。
egressが予想されるがリストにない場合は、見られた個々のIPアドレスやCIDRブロックを Egressタブの下に追加することができます。Ingressトラフィックについても同様です。追加の変更は、Ingress タブで行います。生成されたポリシーは、実装する前に正確さを確認する必要があります。
注:上記のポリシー例では、すべてのIngressトラフィックも拒否されます。

Ingressの設定を変更するには、Ingressタブに便利なドロップダウンボックスがあり、ポリシーをすべてのIngressを許可するなど、いくつかのデフォルト設定に変更することができます。

ネットワークポリシーを作成すると、kubectlなどのDevOpsチームが採用しているツールを使って適用することができます。
注:新しいネットワークポリシーを適用する前に、以前に適用したネットワークポリシーを考慮する必要があります。
まとめ
理想的には、log4jの脆弱性を迅速かつ完全に修復することです。これはすぐには実行できないことが多いので、その間に緩和策を実施する必要があります。WAFは1つの選択肢ですが、常に変化する攻撃文字列に追いつくのは難しいかもしれません。Sysdigのランタイム解析とKubernetesネットワークポリシーは、もう一つの緩和策を提供し、エクスプロイトが悪意のあるペイロードを取得するのを防ぎながら、お客様の環境を正常に動作させることができます。
Sysdig Secureでは、他のオープンソース・プロジェクトとともに、アウトオブボックスルールでFalcoを拡張し、Kubernetesのセキュリティとの連携と管理をさらに容易にしています。30日間の無料トライアルに登録して、ご自身の目で確かめてください!