Kubernetes 上のコンテナを既知の脆弱性から防護

VMware はコンテナネットワーキング向けのソリューションとして、IaaS、CaaS からアプリケーション層に至る様々なレイヤの製品をご提供しています。

  • Kubernetes を下支えする IaaS/vSphere 環境のネットワーク&セキュリティ製品である VMware NSX
  • 仮想ロードバランサー製品である NSX-ALB (Advanced LoadBalancer) と、NSX-ALB を外部 LB として利用し Kuberbetes Service LoadBalancer、Ingress、Gateway 機能を実現する AKO (Avi Kubernetes Operator)
  • Tanzu 製品群にも組み込まれているオープンソースの CNI である Antrea
  • Kubernetes のクラスターネットワーキング機能として NSX を活用する NCP (NSX Container Plugin)
NSX, Antrea, NSX-ALB/AKO によるマルチ Kubernetes クラスタ管理

Antrea CNI はそれ単体で Kubernets のセキュリティを強化する高度なネットワークポリシーを利用可能ですが、NSX Manager 連携機能を利用すれば、マルチクラスタ環境での一貫した Kubernetes ネットワークポリシーを管理することが可能です。また VM のような既存のワークロードとの間でファイアウォール機能を利用することも可能になっています。詳しくは、以下のブログをご参照ください。

VMware では、さらに高度なセキュリティ機能を Kubernetes に提供するため、Antrea の IDPS 機能を開発中です。IDPS という名前が示すとおり、この機能により Kubernetes 上のコンテナの送受信トラフィックを監査し、既知の攻撃に該当するものがあれば検出して通報することが可能になりました。本ブログでは、この Antrea IDPS 機能の概要と利用方法をご紹介したいと思います。

なお、2023年11月時点では Antrea IDPS は Tech Preview となり、まだ正式にサポートされないことにご注意ください。正式版では仕様追加や変更が入る可能性もありますので、リリースされた際には本ブログでもアップデートしていきたいと思います。

 

Antrea IDPS のコンセプト

Antrea IDPS は、IDPS Controller と IDPS Agent により実行されます。IDPS Agent は各ワーカーノード上で DaemonSet として実行され、IDPS 機能を実行する Suricata エンジンおよびシグネチャの制御を行うコントローラの2つのコンテナから成ります。IDPS Controller は Deployment として実行され、NSX および VMware NTICS (NSX Threat Intelligence Cloud Service) への登録、NTICS からのシグネチャのダウンロードと配信、ポリシー制御などの処理を実行します。シグネチャの更新確認と同期は定期的に実行します。

Antrea IDPS Controller と Agent

 

このように Antrea IDPS はクラスタ内のすべての Kubernetes ノードに展開されるため、ゲートウェイ型 IDPS では難しかった East-West を含むすべてのコンテナトラフィックを検査することができます。Antrea IDPS は、Kubernetes 環境に NSX のゼロトラストなネットワークセキュリティ機構を展開するものだと言えます。

なお、2023年11月時点では IDS 機能を Tech Preview でサポートしています。IPS は将来サポート予定です。

 

Antrea Traffic Control (TC) カスタムリソース

IDPS Agent でシグネチャを使った既知の脅威の検査を行うには、コンテナ通信をIDPS Agent に転送する必要がありますが、この機能は Antrea Traffic Control (TC) 機能が実行します。これは Antrea CNI で利用可能なカスタムリソースで、特定の Pod のトラフィックを OVS 内部ポート、デバイス、トンネルなどに転送 (Redirect) またはコピー (Mirror) します。

下の例では、”app=web” のラベルが付いた Pod のトラフィックを Antrea OVS 内部ポートである “tap0″ にコピーしています。”tap0” に接続されている IDS Agent (suricata) がトラフィックを受信して解析し、潜在的な既知の脅威の有無をチェックします。

Antrea TC の詳細についてはこちらもご参照下さい。

 

Antrea IDPS の利用条件

Antrea IDPS 機能を利用するには、VMware が提供する製品版の Antrea である VMware Container Networking with Antrea (VCNA) が必要になります。この機能の使用権は NSX の Advanced または Enterprise エディション、もしくは VCNA の Enterprise エディションのご利用で入手いただけます。また NSX Thread Prevention (TP) または NSX Advanced Thread Prevention (ATP) が同時に必要となります。

加えて、互換性のある NSX と Antrea のバージョンの利用が必要です。以下でご紹介する設定例では、NSX 4.1 および OSS 版の Antrea 1.12.0 を使用しています。また対象の Kubernetes クラスタは v1.25.5、ベース OS は Ubuntu 20.04.6 LTS で構成しています。

Antrea 連携の手順についてはこちらのブログに手順の例を記載しております。

 

実際にやってみた

ここからは、Antrea~NSX 連携の設定が完了している前提で、展開方法および動作例を順にご紹介してきます。もし現状の Antrea IDS の動作についてすぐにお知りになりたい場合は「2. Antrea IDS の動作確認」のセクションに進んでいただければと思います。

  1. Antrea Kubernetes クラスタへの IDPS の展開
  2. Antrea IDS の動作確認

 

1. Antrea Kubernetes クラスタへの IDPS の展開

ここでは Antrea IDPS の展開手順を順に追っていきます。

 

1-1. Antrea Traffic Control の有効化

Antrea IDPS を有効化するには、Antrea CNI において Antrea TC を有効にしておく必要があります。Antrea v1.12.0 においては TC は Alpha version であり、デフォルトでは無効化されています。これを有効化するために以下のコマンドで Antrea の configmap を編集します。


$ kubectl edit configmap antrea-config -n kube-system

そして “TrafficControl” の設定を以下のように修正します。


...
# Enable mirroring or redirecting the traffic Pods send or receive.
  TrafficControl: true
...

エディタを終了後、この設定を有効化するために Antrea Controller と Agent を再起動します。


$ kubectl rollout restart deployments/antrea-controller -n kube-system 
$ kubectl rollout restart daemonsets/antrea-agent -n kube-system

 

1-2. Antrea IDPS イメージのバージョンを特定

Antrea IDPS のパッケージをダウンロードする必要がありますが、その前に、使用中の Antrea のバージョンからダウンロードする IDPS イメージを決定します。本ブログの執筆時点では製品版 VCNA は 1.7.0 が最新で、それに含まれる OSS Antrea バージョンは 1.11.1 となります。今回は Antrea 1.12.0 を使っているので、VCNA 1.7.0 に対応する最新のイメージを使います。各 VCNA バージョンに対応する OSS Antrea のベースバージョン、および Antrea NSX Adaptor イメージは、各 VCNA バージョンのリリースノートで確認できます。

※ 2023年11月時点では VCNA 1.8 が最新です。VCNA 1.8 を使う場合は以下をご参照下さい。

VCNA 1.7 Release Notes 内の Antrea IDPS images の記載から、Ubuntu 環境で利用する IDPS Controller および Agent と Surictata のイメージが以下であることが分かります。これはこの後のステップで使用します。

  • Antrea controller and agent
    • projects.registry.vmware.com/antreainterworking/idpsdebian:v1.11.1_vmware.3
  • Suricata
    • projects.registry.vmware.com/antreainterworking/suricata:v1.11.1_vmware.3

 

1-3. Antrea IDPS パッケージの入手

Antrea IDPS Controller および Agent を展開するためのマニフェストを含むパッケージを入手します。 VMware Customer Connect に NSX TP または ATP 製品をダウンロードできるユーザ ID でログインします。ログイン後、右上の地球儀のアイコンをクリックして言語を English に切り替えます。

次に、[Products and Accounts] メニューから [All Products] を選んで移動します。右側のプルダウンメニューから [Networking & Security] を選択します。エンタイトルされているすべてのネットワーキング製品がリストされるので、[VMware Antrea] を見つけて [View Download Components] をクリックします。

ダウンロード可能なすべての VCNA バージョンが表示されるので、ここでは 1.7.0 (Limited Export) を選んで [GO TO DOWNLOADS] をクリックします。

VCNA 1.7.0 Limited Export のダウンロード可能なパッケージがリストされます。Antrea IDPS のパッケージ ( “IDS/IPS” の文字列が含まれている) の中から、[VMware Container Networking with Antrea (Advanced) – IDS/IPS Debian Images and Manifests] を選択し、[DOWNLOAD NOW] をクリックしてダウンロードします。

 

1-4. Antrea IDPS マニフェストの編集

前のステップでダウンロードした ZIP パッケージファイルを unzip コマンドなどで解凍します。”images” と “manifests” の2つのディレクトリが生成されます。”images” には Antrea IDPS のコンテナイメージが含まれていますが、今回は VMware レポジトリからプルするので使用しません。”manifests” ディレクトリには、Antrea IDPS Controller と Agent を展開するためのマニフェストファイルがいくつか含まれています。


$ unzip antrea-idps-debian-1.11.1+vmware.3.zip
...
$ ls -F antrea-idps-debian-1.11.1+vmware.3
images/    manifests/
$ ls antrea-idps-debian-1.11.1+vmware.3/manifests
idps-openshift.yml idps-tkg.yml       idps-tkgi.yml       idps.yml

今回はアップストリームの Kubernetes を利用しているので、”idps.yml” を使用して展開します。”idps.yml” ファイルをエディタで開きます。

まず、antrea-idps-controller Deployment および antrea-idps-agent DaemonSet で参照されているイメージの設定を、リリースノートの記載に合わせて変更します。

  • Antrea Controller および Agent
    • image: “projects.registry.vmware.com/antreainterworking/idps-debian:v1.11.1_vmware.3
  • Suricata
    • image: “projects.registry.vmware.com/antreainterworking/suricata:v1.11.1_vmware.3

次に antrea-idps-licenses Secret で参照される NSX TP/ATP ライセンスの設定を変更します。まず NSX TP/ATP ライセンスコードを以下のコマンドでエンコードします。


$ echo <NSX TP/ATP License string> | base64

出力された文字列を、”idps.yml” 内の antrea-idps-licenses Secret の “nsx-license” に設定します。以下は設定例です。


.....
---
# Source: antrea-idps/templates/controller/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: antrea-idps-licenses
  namespace: kube-system
  labels:
    app: antrea-idps
type: Opaque
data:
  nsx-license: "<paste base64 encoded NSX TP/ATP license here>"
.....

 

1-5. Antrea IDPS マニフェストの適用

マニフェストの編集が終わったら実際にクラスタに適用していきます。以下のコマンドでマニフェストを適用します。IDPS Controller と Agent の起動し、カスタムリソースの設定が追加されます。


$ kubectl apply -f idps.yml

Antrea IDPS の起動時に NSX および VMware NTICS に対する登録が行われます。登録状況は以下のコマンドで確認できます。


$ kubectl get nsxregistrations interworking-info -n kube-system -o yaml
apiVersion: crd.antrea.tanzu.vmware.com/v1alpha1
kind: NSXRegistration
metadata:
  creationTimestamp: "2023-08-16T12:49:01Z"
  generation: 50460
  name: interworking-info
  resourceVersion: "11751994"
  uid: a945a9a8-4bd0-4f41-bfb6-4979024947b4
timestamp: cWRqIdWn0Hakj6E2c9aETQWnSVNr7CeKUGrveKTIVGWaGdb3YdfPiHoedpyt3OzKfaQ=

このように NSXRegistration カスタムリソースの interworking-info が正常に作成されたら登録成功です。生成されない場合は、Antrea NSX Adaptor を再起動することで登録できる場合があります。


$ kubectl rollout restart deployments/interworking -n vmware-system-antrea

合わせて、Antrea IDPS Controller と Agent が正常に起動していることを確認します。


$ kubectl get pod -n kube-system | grep idps
antrea-idps-agent-d4d7d                   2/2   Running   0         35m
antrea-idps-agent-sqw6c                   2/2   Running   0         35m
antrea-idps-agent-z2rgk                   2/2   Running   0         35m
antrea-idps-controller-5458b98f9f-zgsfj   1/1   Running   0         35m

 

2. Antrea IDS の動作確認

それでは、実際にテスト用のコンテナワークロードを展開して IDPS の動作を見てみます。以下の図はこれから確認する動作を簡単に図示したものです。IDPSPolicy カスタムリソースを使って、Antrea TC が特定の Pod のトラフィックを IDS にコピーするように設定します。対象の Pod はラベルを使って判別します。設定後、既知の脆弱性にヒットするトラフィックを該当 Pod からテストサイトに向けて生成すると、IDS が検出してロギングします。

Antrea IDS を使った既知の脅威の検出イメージ

 

2-1. IDPSPolicy の設定

まず、以下のような IDPSPolicy リソースのマニフェストを作成します。IDPSPolicy は Antrea IDPS を展開した際に同時に作成されたカスタムリソースです。ラベルが “app=web” の Pod に対し IDPS が適用されるように設定しています。


apiVersion: crd.antrea.tanzu.vmware.com/v1alpha1
kind: IDPSPolicy
metadata:
  name: test-ids-policy
spec:
  appliedTo:
    podSelector:
      matchLabels:
        app: web

このマニフェストを kubectl apply で適用します。IDPSPolicy が設定されると、IDPS Controller はそれを実現するために必要な Antrea TC の設定を行います。Antrea TC の設定状況を確認してみます。


$ kubectl get trafficcontrol
NAME              DIRECTION   ACTION   AGE
test-ids-policy   Both        Mirror   5m
$
$ kubectl get trafficcontrol test-ids-policy -o yaml
apiVersion: crd.antrea.io/v1alpha2
kind: TrafficControl
metadata:
  annotations:
    crd.antrea.tanzu.vmware.com/managed-by: IDPSPolicyController
  creationTimestamp: "2023-08-16T13:10:38Z"
  generation: 1
  name: test-ids-policy
  ownerReferences:
  - apiVersion: crd.antrea.tanzu.vmware.com/v1alpha1
    blockOwnerDeletion: true
    controller: true
    kind: IDPSPolicy
    name: test-ids-policy
    uid: b5b657b8-4ed3-41d9-b069-812ceb5fcb02
  resourceVersion: "6847554"
  uid: 793e23ad-ef76-45e0-9995-25bf3c34632e
spec:
  action: Mirror
  appliedTo:
    podSelector:
      matchLabels:
        app: web
  direction: Both
  targetPort:
    device:
      name: antrea-tap0

IDPSPolicy と同じ名前で TrafficControl リソースが作成されていることが分かります。Direction が “Both”(両方向)、Action が “Mirror”(コピー)になっていますが、IDS のみが実装されている現在の TechPreview 版ではデフォルトの設定動作となります。また podSelector のラベルとして “app=web” が設定されていますが、これは IDPSPolicy から受け継いだ設定です。

また targetPort として “antrea-tap0” デバイスが指定されていますが、これは IDPS Agent 展開時に自動的に作成される各ノードのデバイスで、このデバイスに IDPS Agent 側の “suricata-tap0” デバイスが接続されています。TrafficControl により “antrea-tap0” にコピーされたトラフィックは “suricata-tap0” を通じて IDS (Suricata) に送信されます。

 

2-2. テストサイトを利用した動作確認

それでは、作成した IDPSPolicy を使って実際にコンテナトラフィックを検査させてみます。今回は Kubernetes クラスタ内のコンテナから以下のテストサイトに擬似的な攻撃 (UID/GID スキャン) を行い、Antrea IDS が検出できるかどうかを確認します。

まず、以下のようなテスト用 Pod を作成し適用します。curl 等を使って HTTP 接続ができる Pod であれば何でも構いませんが、ラベルとして “app=web” が設定されており、クラスタ DNS ではなく外部 DNS を参照している必要があります。


apiVersion: v1
kind: Pod
metadata:
  name: testpod
  labels:
    app: web
spec:
  containers:
  - name: source
    image: quay.io/cilium/alpine-curl
    command: ["sh", "-c", "while true; do sleep 3600; done"]
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
    - xxx.xxx.xxx.xxx

このマニフェストを適用して Pod を起動した後、以下のコマンドで Pod からテストサイトに対して UID/GID スキャンを実施します。


$ kubectl exec testpod -- curl -s http://testmynids.org/uid/index.html
uid=0(root) gid=0(root) groups=0(root)

このトラフィックを受けた Suricata はテストサイトに対するスキャン攻撃と認識し、ログを生成します。ログはテスト用 Pod が動作しているノード内に生成されているので、ログインして確認します。


xxxxxx@k8s-worker-202:~$ tail -1 /var/log/antrea/suricata/eve.alert.2023-08-17.json 
{"timestamp":"2023-08-17T04:03:17.976560+0000","flow_id":1832424644662327,"in_iface":"suricata-tap0","event_type":"alert","src_ip":"18.65.206.64","src_port":80,"dest_ip":"192.168.1.5","dest_port":60928,"proto":"TCP","direction":"to_client","metadata":{"flowbits":["LL.priority_fb","LL.105241_0"],"flowints":{"client.idx":1,"server.idx":2}},"tx_id":0,"alert":{"action":"allowed","gid":1,"signature_id":4101454,"rev":3,"signature":"SLR Alert - TESTING IDPS ALERT SYSTEM - TESTMYIDS.COM","category":"Attempted User Privilege Gain","severity":4,"source":{"ip":"18.65.206.64","port":80},"target":{"ip":"192.168.1.5","port":60928},"metadata":{"blacklist_mode":["DISABLED"],"confidence":["90"],"created_at":["2019_01_01","2019_01_01"],"detector_id":["101357"],"exploited":["None"],"flip_endpoints":["True"],"ids_mode":["REAL"],"lock":["false"],"policy":["suricata-ips","suricata-ids","security-ips drop","balanced-ips drop","connectivity-ips drop"],"server_side":["False"],"severity":["1"],"signature_severity":["Major"],"threat_class_name":["Functional Testing"],"threat_name":["IDS Test testmyids.com"],"type":["suricata"]}},"http":{"hostname":"testmynids.org","url":"/uid/index.html","http_user_agent":"curl/7.83.1","http_content_type":"text/html","http_method":"GET","protocol":"HTTP/1.1","status":200,"length":39,"direction":"download"},"files":[{"filename":"/uid/index.html","sid":[],"gaps":false,"state":"CLOSED","stored":false,"size":39,"tx_id":0}],"app_proto":"http","flow":{"pkts_toserver":4,"pkts_toclient":4,"bytes_toserver":364,"bytes_toclient":809,"start":"2023-08-17T04:03:17.971831+0000"}}

一行が長いので、jq コマンドを使って整形してみました。


xxxxxx@k8s-worker-202:~$ tail -1 /var/log/antrea/suricata/eve.alert.2023-08-17.json | jq
{
  "timestamp": "2023-08-17T04:03:17.976560+0000",
  "flow_id": 1832424644662327,
  "in_iface": "suricata-tap0",
  "event_type": "alert",
  "src_ip": "18.65.206.64",
  "src_port": 80,
  "dest_ip": "192.168.1.5",
  "dest_port": 60928,
  "proto": "TCP",
  "direction": "to_client",
  "metadata": {
    "flowbits": [
      "LL.priority_fb",
      "LL.105241_0"
    ],
    "flowints": {
      "client.idx": 1,
      "server.idx": 2
    }
  },
  "tx_id": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 4101454,
    "rev": 3,
    "signature": "SLR Alert - TESTING IDPS ALERT SYSTEM - TESTMYIDS.COM",
    "category": "Attempted User Privilege Gain",
    "severity": 4,
    "source": {
      "ip": "18.65.206.64",
      "port": 80
    },
    "target": {
      "ip": "192.168.1.5",
      "port": 60928
    },
    "metadata": {
      "blacklist_mode": [
        "DISABLED"
      ],
.....

このように、IDS (Suricata) で testmynids に対するテスト攻撃として認識され、記録できたことが分かります。

今回は直接ログファイルを確認しましたが、fluentd 等を使ってログを収集すれば、VMware Aria Operations for Logs やその他の SIEM を使って解析することも可能です。

 

最後に

いかがでしたでしょうか。現状の Antrea IDPS の IDS 機能実装について、ご理解いただけたかと思います。

多くの企業でコンテナ基盤へのアプリ移行が進んでいる中で、コンテナワークロードのセキュリティ問題は喫緊の課題になりつつあります。特にゼロトラストなセキュリティ対策を実現する上で IDPS は必要な機能ではないでしょうか。VMware では vSphere 基盤上で East-West のトラフィックを検査し、ラテラルムーヴメントを阻止する仕組みとして NSX の分散 IDPS をすでに提供しておりますが、同じ課題はコンテナにおいても顕在する可能性があります。本ブログでご紹介した Antrea IDPS は、Kubernetes 環境での East-West トラフィックを保護する仕組みとしてその将来に期待しています。


〜お知らせ〜

※VMwareでは、各種製品をクラウド上でご評価いただける Hands-on Labs (HOL) を無償でご提供しています。
今回ご紹介した各種ソリューションへの入り口としてぜひご活用下さい。(Antrea連携機能のHOLはまだご提供しておりません)