Envoy プロキシのデプロイ設定
- English
- 日本語
サポートは、Envoy プロキシ に対して、sigsci-agent で実装された組み込みの Envoy gRPC API を介して利用可能です。これは gRPC サーバーとして実行されます。Envoy v1.11.0 以降が推奨されますが、Envoy v1.8.0 以降は、以下のドキュメントに記載されているように機能が制限されています。
Envoy (v1.11 以降) は、トラフィックを検査するための双方向 gRPC API をサポートしていません。代わりに、トラフィックを検査するために利用可能な 2つの独立した gRPC API があります。外部認証 HTTP フィルター (envoy.filters.http.ext_authz) gRPC API は、インバウンドリクエストの検査を待っている間、リクエストを保留状態にできるため、必要に応じてリクエストをブロックすることができます。その後、追加の gRPC AccessLog サービス gRPC API を使用して、送信リクエストデータを検査することができます。これら2つの API を、gRPC サーバーとして動作する sigsci-agent と組み合わせて使用することで、Envoy の組み込み API のみを用いて双方向の検査が可能になります。これにより、それぞれのアップストリームアプリケーションにモジュールをインストールすることなく、Web アプリケーションの検査が可能になります。この場合、sigsci-agent がモジュールとして機能します。
リクエスト許可 (通常) 処理
これは、sigsci-agent が Envoy を通じて許可している通常のリクエストの流れです。
クライアントからのリクエストは Envoy によって受信され、Envoy の
External Authorization (ext_authz)HTTP フィルターにルーティングされます。そこでリクエストのメタデータが抽出され、sigsci-agentを介して処理されます。リクエストメタデータは gRPC
ext_authzAPI を介してsigsci-agentに送信されます。sigsci-agentは、「許可リクエスト」レスポンスを返し、リクエストがext_authzHTTP フィルターを通過して通常の Envoy リクエスト処理を続行することを許可します。リクエストは追加の HTTP フィルターを通過し、ハンドラーに到達します。ハンドラーはリクエストを処理し、レスポンスを生成します。
リクエスト/レスポンスのメタデータは、Envoy
gRPC AccessLog Service (als)経由で非同期に抽出され、sigsci-agentで処理が行われます。並行して、レスポンスヘッダーや HTTP ステータスコードなどの追加のメタデータは gRPC
alsAPI 経由でsigsci-agentに送信され、さらに処理されます。一方、レスポンスデータは元のクライアントに送り返されます。
リクエストのブロック処理
これは、sigsci-agent が Envoy を通じたリクエストの処理をブロックした場合の流れです。
クライアントからのリクエストは Envoy によって受信され、Envoy の
External Authorization (ext_authz)HTTP フィルターにルーティングされます。そこでリクエストのメタデータが抽出され、sigsci-agentを介して処理されます。リクエストメタデータは gRPC
ext_authzAPI を介してsigsci-agentに送信されます。sigsci-agentは「ブロックリクエスト」レスポンスを返し、HTTP フィルターチェーンによるリクエストの処理を継続することを許可しません。これにより
ext_authzフィルターがトリガーされて HTTP 406 レスポンスが生成され、リクエストのそれ以降の処理がブロックされます。
Next-Gen WAF エージェントの設定
sigsci-agent は通常、Kubernetes を介してサイドカーとしてインストールされますが、通常のインストールとは設定が若干異なります。
sigsci-agent は、通常の RPC リスナーではなく、Envoy gRPC リスナーで実行されるように設定する必要があります。これを行うには、envoy-grpc-address エージェント設定オプションで Envoy gRPC リスナーを設定します。これにより、デフォルトの RPC リスナーの代わりにこのリスナーが起動します。
sigsci-agent 設定ファイルの設定値を次のように設定します。
envoy-grpc-address = "0.0.0.0:8000"もしくは sigsci-agent 環境内で設定値を次のように設定します。
SIGSCI_ENVOY_GRPC_ADDRESS=0.0.0.0:8000オプションとして、sigsci-agent は TLS を有効にして設定することも可能です。これを行うには、sigsci-agent 設定で証明書とキーファイルを設定します。
envoy-grpc-cert = "/path/to/cert.pem"envoy-grpc-key = "/path/to/key.pem"または
SIGSCI_ENVOY_GRPC_CERT=/path/to/cert.pemSIGSCI_ENVOY_GRPC_KEY=/path/to/key.pemさらに、レスポンスデータ処理を有効にすることを推奨します。これを行うには、sigsci-agent を設定し、envoy-expect-response-data エージェント設定オプションを設定することで、Envoy からのレスポンスデータを取得できるようにする必要があります。デフォルトでは、sigsci-agent 内のレスポンスデータは無視されます。これは、古いバージョンの Envoy をより適切にサポートするための Envoy 設定オプションであるためです。Envoy v1.10 以降をお使いの場合は、このオプションを有効にする必要があります。
sigsci-agent 設定ファイルの設定値を次のように設定します。
envoy-expect-response-data = 1もしくは sigsci-agent 環境内で設定値を次のように設定します。
SIGSCI_ENVOY_EXPECT_RESPONSE_DATA=1sigsci-agent における検査の一部は設定可能ですが、一般的にはデフォルトとして残しておくべきです。詳細は inspection-* エージェント設定を確認してください。
Envoy 設定
Envoy はリクエストデータを処理するためにメインハンドラーフィルターの前に外部認証 HTTP フィルター (envoy.filters.http.ext_authz) で設定する必要があります。また、gRPC AccessLog サービス をセットアップしてレスポンスデータを処理する必要があります (オプションですが推奨)。これを行うには、Envoy の設定に以下の複数の設定項目を追加する必要があります。sigsci-agent を介した gRPC 呼び出しを処理するクラスター、メインハンドラーの前の envoy.filters.http.ext_authz HTTP フィルター、およびレスポンスデータを有効にする場合は、HTTP リスナーフィルターの access_log セクションに追加された envoy.http_grpc_access_log サービス。
Next-Gen WAF エージェントクラスターの追加
sigsci-agent 設定で使用される Envoy gRPC アドレスで構成されたクラスターを追加する必要があります。現在、レスポンスデータが有効になっている場合、Envoy で gRPC サービスの一貫性のあるハッシュを有効化する方法が (まだ) ないため、ロードバランシングは正しく動作しません。したがって、レスポンスデータ検査なしで envoy.filters.http.ext_authz API のみをで使用する場合を除き、現時点ではロードバランシングを設定しないことを推奨します。
clusters: - name: sigsci-agent-grpc connect_timeout: 0.2s type: strict_dns #lb_policy: LEAST_REQUEST http2_protocol_options: {} #tls_context: {} ### You can also use 'hosts' below, but this is deprecated load_assignment: cluster_name: sigsci-agent-grpc endpoints: - lb_endpoints: - endpoint: address: socket_address: address: sigsci-agent port_value: 8000address は sigsci-agent に対して解決可能なホスト名もしくは IP であり、port_value は envoy-grpc-address オプションの sigsci-agent 設定で設定されたものと一致する必要があります。
ヒント :
connect_timeoutはsigsci-agentへの接続のタイムアウト (データ処理のタイムアウトではありません) であり、必要に応じて調整できます。TLS を使用する場合はtls_contextオプションを定義する必要があります。TLS はsigsci-agent設定でenvoy-grpc-certやenvoy-grpc-keyを使って設定できます。sigsci-agentで TLS が設定されている場合、空のtls_contextのみ (例 :tls_context: {}) を設定して、Envoy が TLS 経由で接続を認識できるようにする必要があります。証明書の検証が必要な場合は、validation_contextをtls_contextで設定し、検証に使用するtrusted_caファイル名を指定する必要があります。gRPC サービスは HTTP/2 ベースであるため、http2_protocol_options: {}オプションが必要です。これにより、トラフィックが HTTP/2 としてsigsci-agentクラスターに送られます。
Envoy 外部認可 HTTP フィルターを追加する
リスナーには、sigsci-agent クラスターを指すメインハンドラーの前に外部認証 HTTP フィルター (envoy.filters.http.ext_authz) を追加する必要があります。
http_filters:- name: envoy.filters.http.ext_authz typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz transport_api_version: V3 grpc_service: envoy_grpc: cluster_name: sigsci-agent-grpc timeout: 0.2s failure_mode_allow: true with_request_body: # Maximum request body bytes buffered and sent to the sigsci-agent max_request_bytes: 8192 # NOTE: If allow_partial_message is set false, then any request over # the above max bytes will fail with an HTTP "413 Payload Too Large" # so it is recommended to set this to true. allow_partial_message: true # NOTE: By default, envoy carries the HTTP request body as a UTF-8 string # and it fills the body @ # field. To pack the request body as raw bytes, # set pack_as_bytes to true. pack_as_bytes: true- name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Routerヒント :
failure_mode_allow: trueはフェイルオープンになるようにするためであり、推奨される設定です。そしてtimeoutは、指定された時間経過後に定義されたフェイルモード (フェイルオープンの場合は true、フェイルクローズの場合は false) で失敗することを許可します。これが完了すると、すべての HTTP リクエストは最初にenvoy.filters.http.ext_authzフィルターに送信され、sigsci-agentクラスターによって処理されます。次に、sigsci-agentはリクエストを処理し、リクエストがブロック対象の場合は 406 HTTP ステータスコードで認証を拒否し、許可される場合はリクエストを次の HTTP フィルターへ通過させます。他のモジュールと同様に、追加の HTTP リクエストヘッダーもリクエストに追加されます。
Envoy gRPC AccessLog サービスを追加する
これは推奨されるステップですが、任意です。Envoy で設定されている場合、 必要 があります。 Next-Genenvoy-expect-response-data WAF エージェント設定 セクションで記載されているように、 エージェント設定 オプションを設定し、エージェントも応答データを期待するように設定する。Envoy 外部認証 (envoy.filters.http.ext_authz) HTTP フィルターはリクエストデータのみを処理できます。sigsci-agent が完全な機能を発揮するためには gRPC AccessLog サービス を設定し、レスポンスデータを sigsci-agent に送信する必要があります。これを行うには、Envoy 設定のリスナーフィルター (通常は envoy.filters.network.http_connection_manager フィルターの下) にaccess_log セクションを追加する必要があります (セクションが存在しない場合)。存在する場合は、それに追加する必要があります。
詳細については、HTTP 設定マネージャーの access_log 設定オプションを参照してください。こちらに (既存のアクセスログエントリーに加えて) envoy.http_grpc_access_log エントリーを追加する必要があります。
推奨設定は以下の通りです (制限事項を最小限に抑えるためのさらなるカスタマイズについては制約と考慮事項を参照)。
access_log:- name: envoy.http_grpc_access_log typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig common_config: log_name: "sigsci-agent-grpc" transport_api_version: V3 grpc_service: envoy_grpc: cluster_name: sigsci-agent-grpc timeout: 0.2s additional_request_headers_to_log: # These sigsci-agent headers are required for correct processing: - "x-sigsci-request-id" - "x-sigsci-waf-response" # Optionally, additional headers can be added that should be recorded: - "accept" - "content-type" - "content-length" additional_response_headers_to_log: - "date" - "server" - "content-type" - "content-length"制約と考慮事項
Envoy プロキシで sigsci-agent を使用する際の現在の制限事項は以下の通りです。Envoy プロキシのサポートが将来改善されるにつれて、これらの制限事項は解消され、軽減される見込みです。
デフォルトではリクエストボディは処理されません
Envoy v1.10.0 以前では、Envoy の外部認証はリクエストボディを送信しませんでした。Envoy のすべてのバージョンにおいて、リクエストボディはデフォルトでは ext_authz 呼び出しに含まれず、設定されない限り sigsci-agent によって検査されません。
Envoy v1.10.0 以降では、リクエストボディを含めるサポートが envoy.filters.http.ext_authz 設定に組み込まれており、前述の通り Envoy 設定のこのセクションで with_request_body を設定することが可能にになりました。
Envoy v1.11.0 以降では、部分的なボディをより正確に検出できるようサポートが拡張されました。
HTTP/2 (およびgRPC) をサポートするには、Envoy は v1.12.1 以降のバージョンを実行している必要があります。 Envoy v1.10.0 から v1.12.1 では、 with_request_body を使用してリクエストボディを正しく送信できません。
しかし、Envoy のアップグレードが可能になるまでは、Lua を使ってこの Envoy の制限を回避することができます。以下は、gRPC ベースのボディを検査のために sigsci-agent に渡すために使用できる Lua フィルターの例です。
これを実現するには、Lua HTTPフィルター (envoy.lua) を envoy.ext_authz フィルターの前に設定し、このデータを含む内部 x-sigsci-encoded-body ヘッダーを追加します。ボディを抽出してリクエストに追加するには、以下のような短い Lua コードのスニペットを追加する必要があります。
http_filters: - name: envoy.lua config: inline_code: | -- Add a special header to pass the encoded body function envoy_on_request(req) local len = 0 local reqbody -- Determine the body length local cl = req:headers():get("content-length") if cl ~= nil then len = tonumber(cl) end -- gRPC does not have a content-length header to limit the body before buffering if len == 0 and req:headers():get("content-type") == "application/grpc" then -- Triggers buffering len = req:body():length() end -- Limit body length sent to the agent (adjust as needed) if len > 0 and len <= 8192 then -- Triggers buffering reqbody = req:body():getBytes(0, len) -- Encode the body for use in a header value local enc, t = string.gsub(reqbody, "[^%w]", function(chr) return string.format("%%%02X",string.byte(chr)) end) req:headers():add("x-sigsci-encoded-body", enc) end end - name: envoy.ext_authz config: grpc_service: envoy_grpc: cluster_name: sigsci-agent-grpc timeout: 0.2s failure_mode_allow: true# with_request_body:# max_request_bytes: 8192# allow_partial_message: true - name: envoy.router config: {}TLS ハンドシェイクのメタデータは抽出されません
現在、Envoy では送信元のリクエストで使用された TLS ハンドシェイクメタデータ (暗号やプロトコルバージョンなど) を sigsci-agent が参照する手段は (まだ) 提供されていません。このサイト (ワークスペース) では、TLS ハンドシェイクのメタデータに基づくシグナルはプロダクトでは表示されません。
この制限により、次のシステム信号は現在サポートされていません。
WEAKTLS
レスポンスベースのシグナルのみの場合、デフォルトで最小限のリクエストヘッダーのみが記録されます
リクエストが envoy.filters.http.ext_authz フィルターによって検査され、シグナルが発行されなかった場合、レスポンスは envoy.http_grpc_access_log サービスによって処理されます。レスポンスデータにシグナルが検出された場合、API がデフォルトですべてのリクエストヘッダーを送信しないため、シグナルと共に最小限のリクエストヘッダーのみが記録されます。ただし、追加のリクエストヘッダーを記録したい場合は、Envoy の additional_request_headers_to_log 設定の access_log オプションを介して追加する必要があります。
現在、以下のヘッダーが自動的に追加されます。
HostUser-AgentRefererX-Forwarded-For
2つの sigsci-agent 特有のヘッダーを追加する必要があります。さらに、追加のリクエストヘッダーは additional_request_headers_to_log を通じて明示的に追加できます。
additional_request_headers_to_log:# These sigsci-agent headers are required for correct processing:- "x-sigsci-request-id"- "x-sigsci-waf-response"# Optionally, additional headers can be added that should be recorded:- "accept"- "content-type"- "content-length"- "x-real-ip"デフォルトではレスポンスヘッダーは処理されません
上記と同様に、最小限のリクエストヘッダーが envoy.http_grpc_access_log サービスによって処理されないため、デフォルトではこの API にはレスポンスヘッダーが送信されません。記録したいヘッダーは、現在ワイルドカードを指定する手段がないため、Envoy の access_log 設定の additional_response_headers_to_log オプションに明示的にリストする必要があります。以下の項目が推奨されます。
additional_response_headers_to_log:- "date"- "server"- "content-type"- "content-length"サンプルデプロイ
サンプルデプロイ設定セクションには、完全な Envoy プロキシデプロイ設定が含まれています。これはご自身のデプロイの出発点として利用できます。サンプル設定を動作させるためには、次の手順を完了します。
サイト (ワークスペース) のエージェントキーを更新するには、次のコマンドを実行してください。
$ kubectl create secret generic sigsci.<site-name> \--from-literal=accesskeyid=<access-key-id> \--from-literal=secretaccesskey=<secret-access-key>必ず
<site-name>をサイト (ワークスペース) の名前に、<access-key-id>と<secret-access-key>をエージェントキーに置き換えてください。サンプルデプロイ設定を
envoy-deployment.yamlとして保存してください。次のコマンドを実行して
envoy-deployment.yamlをデプロイします。$ kubectl apply -f envoy-deployment.yaml(任意) ポートフォワーディングを設定し、次のコマンドを実行してローカルでデプロイをテストします。
$ kubectl port-forward svc/envoy 10000:10000
サンプルデプロイ設定
# ConfigMap: Contains the Envoy configuration with ext_authz integration.apiVersion: v1kind: ConfigMapmetadata: name: envoy-configdata: envoy.yaml: | node: id: proxy-node cluster: proxy-cluster static_resources: listeners: - name: listener_0 address: socket_address: address: 0.0.0.0 port_value: 10000 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: backend domains: ["*"] routes: - match: prefix: "/" route: cluster: edge_cluster host_rewrite_literal: "http.edgecompute.app" cors: allow_origin_string_match: - prefix: "*" allow_methods: GET, PUT, DELETE, POST, OPTIONS allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout max_age: "1728000" expose_headers: custom-header-1,grpc-status,grpc-message
access_log: - name: envoy.access_loggers.stdout typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog - name: envoy.http_grpc_access_log typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig common_config: log_name: "sigsci-agent-grpc" transport_api_version: V3 grpc_service: envoy_grpc: cluster_name: sigsci-agent-grpc timeout: 0.2s additional_request_headers_to_log: # These sigsci-agent headers are required for correct processing: - "x-sigsci-request-id" - "x-sigsci-waf-response" # Optionally, additional headers can be added that should be recorded: - "accept" - "content-type" - "content-length" additional_response_headers_to_log: - "date" - "server" - "content-type" - "content-length"
http_filters: # ext_authz filter calls the NGWAF agent via gRPC. - name: envoy.filters.http.ext_authz typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz transport_api_version: V3 grpc_service: envoy_grpc: cluster_name: sigsci-agent-grpc failure_mode_allow: false - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: # Cluster for forwarding requests to https://http.edgecompute.app. - name: edge_cluster connect_timeout: 0.25s type: LOGICAL_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: edge_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: http.edgecompute.app port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: "http.edgecompute.app" # Cluster used by the ext_authz filter to contact the NGWAF agent. - name: sigsci-agent-grpc connect_timeout: 0.25s type: STATIC lb_policy: ROUND_ROBIN http2_protocol_options: {} # <--- This tells Envoy to use HTTP/2 for gRPC load_assignment: cluster_name: sigsci-agent-grpc endpoints: - lb_endpoints: - endpoint: address: socket_address: # Both containers share the same network namespace. address: 127.0.0.1 port_value: 9999
---
# Deployment: Combines the Envoy proxy and the Next‑Gen WAF Agent sidecar.apiVersion: apps/v1kind: Deploymentmetadata: name: envoy-waf-deploymentspec: replicas: 1 selector: matchLabels: app: envoy-waf template: metadata: labels: app: envoy-waf spec: containers: # Envoy container – set to use debug logging for detailed output. - name: envoy image: envoyproxy/envoy:v1.22-latest args: - "-c" - "/etc/envoy/envoy.yaml" - "-l" - "debug" # Change to "trace" for even more verbosity. ports: - containerPort: 10000 volumeMounts: - name: envoy-config mountPath: /etc/envoy # Next‑Gen WAF Agent container (sigsci-agent) configured for ext_authz (gRPC mode). - name: sigsci-agent image: signalsciences/sigsci-agent:latest imagePullPolicy: IfNotPresent env: - name: SIGSCI_ACCESSKEYID valueFrom: secretKeyRef: name: sigsci.my-site-name-here key: accesskeyid - name: SIGSCI_SECRETACCESSKEY valueFrom: secretKeyRef: name: sigsci.my-site-name-here key: secretaccesskey # Instruct the agent to expect response data and configure its gRPC address. - name: SIGSCI_ENVOY_EXPECT_RESPONSE_DATA value: "1" - name: SIGSCI_ENVOY_GRPC_ADDRESS value: "localhost:9999" - name: SIGSCI_DEBUG_ALL_THE_THINGS value: "true" - name: SIGSCI_WAF_DATA_LOG value: "/dev/stdout" ports: - containerPort: 9999 securityContext: readOnlyRootFilesystem: true volumes: - name: envoy-config configMap: name: envoy-config
---
# Service: Exposes the Envoy listener on port 10000.apiVersion: v1kind: Servicemetadata: name: envoyspec: selector: app: envoy-waf ports: - protocol: TCP port: 10000 targetPort: 10000次の手順
エージェントとモジュールのインストールを確認し、モジュールオプションを調査する。