gRPC プロキシのデプロイを設定する

Next-Gen WAF エージェントgRPC トラフィックのプロキシとして設定し、protobuf ベースの gRPC メッセージ (Content-Type: application/grpc) を検査することができます。gRPC トラフィックに対するルールを作成できます。

エージェントを設定する

sigsci-agent を gRPC トラフィックのプロキシとして設定するには、エージェント設定を編集する必要があります。

制約事項

gRPC トラフィックの検査は、エージェントがリバースプロキシリスナーとして設定されている場合にのみ利用可能です。その他のエージェントおよびモジュールの設定では、gRP 検査はサポートされていません。

最大 gRPC メッセージ長の設定

プロキシされるメッセージのサイズを制限するため、gRPC メッセージの最大サイズを調整する必要があります。

inspection-max-content-length = 307200

gRPC メッセージのサイズが設定値を超えると、リバースプロキシは、Received message larger than maxsize エラーを返します。

リバースプロキシ gRPC リスナーを作成する

注 : gRPC のリバースプロキシリスナーは、gRPC トラフィックのみをプロキシします。

以下は、TLS を使用してポート 9000 から 9001 へ gRPC をプロキシするリバースプロキシリスナーの例です。

[revproxy-listener.9000]
inspection-debug = true
listener = "https://127.0.0.1:9000"
upstreams = "https://127.0.0.1:9001"
tls-key = "/etc/sigsci/key.pem"
tls-cert = "/etc/sigsci/cert.pem"
tls-ca-roots = "/etc/sigsci/cert.pem"
grpc = true
tls-verify-servername = "test.signalsciences-dev.net"
#tls-insecure-skip-verify = true

grpctrueに設定すると、gRPCモードを有効にできます。

grpc = true

gRPC には 1つのアップストリームのみがサポートされています。アップストリームサーバーは HTTP/2 をサポートしている必要があります。

リスナーとアップストリームでは、HTTPS と HTTP の両方がサポートされていますが、HTTPS の使用を推奨します。リスナーに HTTPS を使う場合は、tls-keytls-cert を指定する必要があります。アップストリームの HTTPS 証明書を検証したい場合は、tls-ca-roots を指定する必要があります。

設定エラーのトラブルシューティング

エラーが発生した場合は、以下のトラブルシューティングのヒントを試してみてください。

  • certificate signed by unknown authority : リクエストのホスト名がアップストリーム証明書で指定されたホスト名と一致しない場合、接続は失敗します (例 : ホスト名ではなく IP アドレスで接続した場合)。tls-verify-servername を、証明書に有効なホスト名に設定します。他の方法がすべて失敗した場合は、tls-insecure-skip-verify = true を使用して TLS 検証を実行してください。

  • remote error: tls: bad certificate もしくは cannot validate certificate for [ip address] because it doesn't contain any IP SANs: 問題が発生している場合は、HTTP/2 デバッグ出力を有効にできます。エージェントを起動する際、GODEBUG 変数を次のいずれかに設定します。GODEBUG="http2debug=1" は基本的な接続およびフレームのデバッグ情報を提供し、GODEBUG="http2debug=2" は詳細なデータを提供します。

ルールの使用

gRPC トラフィック用のルールを作成できます。protobuf エンコーディングを使用する gRPC トラフィックの場合、PostArgs には引数を表す一連のキーと値のペアが設定されます。キーは、プロトファイルに割り当てられたファイルフィールドのインデックス (1-N) となります。PostArgs には文字列型のみが追加されます

たとえば、次の proto ファイルを考えてみましょう。

syntax = "proto3";
package grpctest;
service TestService {
rpc Send (Request) returns (Response) {}
}
message Request {
string message = 1;
bool test = 2;
int32 int1 = 3;
float float1 = 4;
uint64 uint1 = 5;
message EmbeddedMessage {
string message = 1;
}
EmbeddedMessage emsg = 6;
SubRequest submsg = 7;
}
message SubRequest {
repeated string message = 1;
uint64 uint1 = 3;
}
message Response {
string message = 1;
bool test = 2;
}

すべての Send コールには、解析されるリクエストメッセージが存在します。抽出されるのは文字列型のみです。重複するフィールドは、重複した名前付きエントリとして表示されます。埋め込みメッセージおよびサブメッセージは、パスベースのインデックスに追加されます。フィールド名はワイヤプロトコルに表示されないため、インデックスのみが使用されます。

パーサー抽出の例

以下は、名前ベースのパスフィールド (JSON/XMLに類似) が gRPC の解析されたインデックスに解析される例です。

  • /message = "test" : /1 = "test"

  • /emsg/message = "test 2": /6/1 = "test 2"

  • /submsg/message = "test 3": /7/1 = "test 3"

これらの抽出された PostArgs フィールドは SmartParse によって検査されますが、JSON/XML 値と同様にカスタムルールを使用して検査することもできます。さらに、Path フィールドには gRPC パス (通常 /package.ServiceName/Method) が含まれます。

ルールの例

Type: request
Conditions:
* all of
* Path equals `/grpctest.TestService/Send`
* Post Parameter exists where
* all of
* Name equals: `/1/6/1`
* Value equals: `block me`
Actions: Block request