VirtualService ルーティングルールと AuthorizationPolicy アクセス制御は、SQL インジェクション、クロスサイトスクリプティング (XSS)、その他の OWASP Top 10 攻撃などのアプリケーション層の脅威をカバーしません。Coraza WebAssembly (Wasm) プラグインは、Web Application Firewall (WAF) をゲートウェイの Envoy プロセス内に直接追加することで、この問題を解決します。すべてのインバウンドリクエストは検査され、悪意のあるトラフィックはサービスに到達する前にブロックされます。外部サイドカーや追加のネットワークホップは必要ありません。
Coraza は、ModSecurity SecRule 構文を使用するオープンソースの OWASP がメンテナンスする WAF エンジンです。これをデプロイするには、Coraza Wasm バイナリを OCI イメージとしてパッケージ化し、コンテナレジストリにプッシュします。次に、WasmPlugin リソースを適用して、Envoy フィルターチェーンにロードします。
仕組み
Coraza Wasm バイナリを OCI イメージとしてパッケージ化し、コンテナレジストリにプッシュします。
ASM ゲートウェイがイメージをプルできるように、Kubernetes Secret を作成します。
プラグインをゲートウェイの Envoy フィルターチェーンにロードし、SecRule ディレクティブを構成する
WasmPluginリソースを適用します。ゲートウェイは、構成されたルールに対してすべてのインバウンドリクエストを評価し、拒否ルールに一致するリクエストに対して
403 Forbiddenを返します。
前提条件
開始する前に、次のことを確認してください。
Container Service for Kubernetes (ACK) クラスターが追加された ASM インスタンス v1.18 以降。詳細については、「ASM インスタンスへのクラスター追加」をご参照ください。
自動サイドカープロキシ注入が有効になっていること。詳細については、「グローバル名前空間の管理」をご参照ください。
HTTPBin アプリケーションがデプロイされ、アクセス可能であること。詳細については、「HTTPBin アプリケーションのデプロイ」をご参照ください。
Container Registry Enterprise Edition インスタンス (OCI イメージをサポート)。詳細については、「Container Registry Enterprise Edition インスタンスの作成」をご参照ください。
Docker がインストール済みであること。詳細については、「Docker の入手」をご参照ください。
Wasm プラグインのロード方法
ASM は、Wasm プラグインをロードする 3 つの方法をサポートしています。このチュートリアルでは、OCI イメージ方式を使用します。
方式 | 仕組み | 使用する状況 |
OCI イメージ (このチュートリアルで使用) |
| ほとんどの本番環境へのデプロイメントに推奨されます。バージョン管理され、監査可能で、既存のレジストリインフラストラクチャで動作します。 |
ConfigMap |
| 迅速なプロトタイピングや、レジストリが利用できないエアギャップ環境に適しています。ConfigMap の 1 MiB サイズ制限があります。 |
HTTP ダウンロード |
| 一元化されたアーティファクトサーバーがすでに HTTP 経由でバイナリを提供している環境に適しています。 |
ステップ 1: Coraza Wasm OCI イメージのビルドとプッシュ
プラグインバイナリのダウンロードと準備
Coraza Wasm プラグインをダウンロードして解凍します。
wget https://github.com/corazawaf/coraza-proxy-wasm/releases/download/0.3.0/coraza-proxy-wasm-0.3.0.zip unzip coraza-proxy-wasm-0.3.0.zipバイナリの名前を
plugin.wasmに変更します。ASM はこの正確なファイル名を要求します。mv coraza-proxy-wasm.wasm plugin.wasm同じディレクトリに
Dockerfileを作成します。FROM scratch ADD ./plugin.wasm ./plugin.wasmOCI イメージをビルドします。
docker build -t coraza-proxy-wasm:latest .
イメージを Container Registry にプッシュ
Container Registry に名前空間を作成します。
Container Registry コンソールにログインします。左側のナビゲーションウィンドウで、[インスタンス] をクリックします。
[インスタンス] ページで、お使いの Container Registry Enterprise Edition インスタンスのカードをクリックします。
左側のナビゲーションウィンドウで、 を選択します。 [ネームスペースの作成] をクリックし、[ネームスペース] に
wasmを設定して、[OK] をクリックします。
レジストリのインターネットアクセスを有効化するには:左側のナビゲーションウィンドウで、 を選択します。[インターネット] タブをクリックし、「[インターネット経由のアクセスを有効化]」をオンにして、要件に応じてインターネットホワイトリストを追加します。ホワイトリストによる制御を必要としない場合は、デフォルトのホワイトリストを削除します。
説明この例ではパブリックエンドポイントを使用します。本番環境での使用には、セキュリティとネットワークパフォーマンスを向上させるために Virtual Private Cloud (VPC) アクセスを構成してください。詳細については、「VPC ACL の構成」をご参照ください。
レジストリにログインします。プロンプトが表示されたらパスワードを入力します。次のプレースホルダーをご利用の値に置き換えます。
プレースホルダー
説明
例
<your-username>Container Registry インスタンスのログインユーザー名
admin@china<your-registry-endpoint>ご利用の Container Registry インスタンスのエンドポイント
enterprise-registry.cn-hangzhoudocker login --username=<your-username> <your-registry-endpoint>.cr.aliyuncs.comイメージのタグ付けとプッシュ。前のセクションの
docker buildによって返されたイメージ ID を<image-id>に置き換えます。docker tag <image-id> <your-registry-endpoint>.cr.aliyuncs.com/wasm/coraza-proxy-wasm:latest docker push <your-registry-endpoint>.cr.aliyuncs.com/wasm/coraza-proxy-wasm:latestイメージがプッシュされたことを確認します。
latestタグの付いたイメージが表示された場合、プッシュは成功しています。「Container Registry コンソール」で、Enterprise Edition インスタンスを開きます。
左側のナビゲーションウィンドウで、 を選択します。[coraza-proxy-wasm] をクリックします。
左側のナビゲーションウィンドウで、[タグ] をクリックします。
ステップ 2: イメージプル用の Secret の作成
リポジトリは非公開であるため、ASM ゲートウェイが Wasm イメージをプルするには認証情報が必要です。レジストリ認証情報を含む Kubernetes Secret を作成します。
kubectl create secret docker-registry coraza-wasm-proxy \
-n istio-system \
--docker-server=<your-registry-endpoint>.cr.aliyuncs.com \
--docker-username=<your-username> \
--docker-password=<your-password>Secret は WasmPlugin リソースと同じ名前空間にある必要があります。このチュートリアルでは istio-system を使用します。プラグインが異なる名前空間をターゲットにする場合は、-n の値を調整してください。
Secret を検証します。
kubectl -n istio-system get secret coraza-wasm-proxyステップ 3: WasmPlugin リソースの適用
WasmPlugin リソースは、ロードするプラグイン、Envoy フィルターチェーンに挿入する場所、および構成方法を宣言します。
次の内容で
wasm-plugin.yamlという名前のファイルを作成します。次の表は主要フィールドを説明しています。この例では、defaultディレクティブセットは Coraza ルールエンジンを有効にし、単一のルールを定義します。x-user-typeヘッダーがbanedと等しいすべてのリクエストを拒否します。フィールド
説明
spec.urlタグを含む OCI イメージアドレス。
oci://、file://、およびhttp[s]://スキームをサポートします。spec.imagePullSecretレジストリ認証情報を含む Kubernetes Secret の名前。
spec.imagePullPolicyイメージプルポリシー。
spec.selectorこのプラグインをロードするワークロードを決定するラベルセレクター。ここではイングレスゲートウェイをターゲットにします。
spec.phaseフィルターチェーンにプラグインを挿入する場所。
AUTHNは認証フィルターの前に配置するため、リクエストは可能な限り早く検査されます。spec.pluginConfigCoraza 固有の構成。
directives_mapは SecRule 構文を使用して名前付きルールセットを定義します。default_directivesは、デフォルトで適用するルールセットを指定します。apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: coraza-proxy-wasm namespace: istio-system spec: imagePullPolicy: IfNotPresent imagePullSecret: coraza-wasm-proxy selector: matchLabels: istio: ingressgateway url: oci://<your-registry-endpoint>.cr.aliyuncs.com/wasm/coraza-proxy-wasm:latest phase: AUTHN pluginConfig: directives_map: default: - "SecDebugLogLevel 9" - "SecRuleEngine On" - "SecRule REQUEST_HEADERS:x-user-type \"@streq baned\" \"id:101,phase:1,t:lowercase,deny,msg:'denied by header'\"" default_directives: defaultkubectl で ASM インスタンスに接続し、リソースを適用します。
kubectl apply -f wasm-plugin.yaml
ステップ 4: WAF プラグインの検証
プラグインが機能していることを確認するために、許可されたリクエストとブロックされたリクエストの両方をテストします。
イングレスゲートウェイ経由で HTTPBin アプリケーションに通常のリクエストを送信します。
<gateway-ip>をご利用のイングレスゲートウェイの IP アドレスに置き換えます。詳細については、「イングレスゲートウェイの IP アドレスの取得」をご参照ください。期待される結果: ゲートウェイは200 OKを返します。curl -v http://<gateway-ip>/> GET / HTTP/1.1 > Host: <gateway-ip> ... < HTTP/1.1 200 OK < server: istio-envoy ...ブロックされたヘッダーを含むリクエストを送信します。期待される結果: ゲートウェイは
403 Forbiddenを返します。403応答は、Coraza WAF プラグインがアクティブであり、構成されたルールを適用していることを確認します。curl -v -H 'x-user-type: baned' http://<gateway-ip>/> GET / HTTP/1.1 > Host: <gateway-ip> > x-user-type: baned ... < HTTP/1.1 403 Forbidden < server: istio-envoy ...