Service Mesh (ASM) では、HTTP プロトコルまたは gRPC プロトコルを介して、カスタム認可サービスをメッシュの認可ワークフローに統合できます。本トピックでは、メッシュプロキシがリクエストを許可するかどうかを判断するために呼び出される、HTTP ベースのカスタム認可サービスを開発する方法について説明します。
背景情報
Service Mesh (ASM) は、認可ルールをリクエストに適用する前に、リクエストのアイデンティティを認証します。
ゲートウェイに到達するリクエスト — ゲートウェイで JWT 認証 (RequestAuthentication) を設定し、リクエストのアイデンティティを認証します。
メッシュ内のリクエスト — デフォルトでは、メッシュによって発行された mTLS 証明書がリクエストのアイデンティティを認証します。
リクエストのアイデンティティが確認された後、認可ポリシー (AuthorizationPolicy) を使用してリクエストの動作を制限できます。これらの標準機能に加えて、ASM は、リクエストを許可するかどうかを決定するカスタム認可サービスとの統合にも対応しています。
仕組み
HTTP ベースのカスタム認可サービスを統合すると、メッシュプロキシ (ゲートウェイまたはサイドカー) は、受信したリクエストの情報を含む HTTP 認可リクエストを生成します。その後、メッシュプロキシは認可リクエストをカスタム認可サービスに送信し、カスタム認可サービスがリクエストを許可するかどうかを決定します。
カスタム認可サービスが返すステータスコードによって結果が決まります。
ステータスコードが 200 の場合は、リクエストがチェックに合格したことを示し、リクエストは許可されます。
ステータスコードが 5xx の場合は、カスタム認可サービスが異常であることを示します。この場合、リクエストは設定に基づいて許可または拒否されます。
その他のステータスコードは、リクエストがチェックに失敗したことを示し、リクエストは拒否されます。
HTTP ベースのカスタム認可サービスの開発
ASM は、オープンソースの Istio サービスメッシュと互換性があり、Istio コミュニティはカスタム認可サービスのサンプル実装を提供しています。このサンプルでは、HTTP プロトコルと gRPC プロトコルの両方に対応するカスタム認可サービスを実装しています。次の抜粋は、ServeHTTP 関数内の HTTP ロジックを示しています。
// ServeHTTP は、HTTP チェックリクエストを実装します。
func (s *ExtAuthzServer) ServeHTTP(response http.ResponseWriter, request *http.Request) {
body, err := io.ReadAll(request.Body)
if err != nil {
log.Printf("[HTTP] read body failed: %v", err)
}
l := fmt.Sprintf("%s %s%s, headers: %v, body: [%s]\n", request.Method, request.Host, request.URL, request.Header, returnIfNotTooLong(string(body)))
if allowedValue == request.Header.Get(checkHeader) {
log.Printf("[HTTP][allowed]: %s", l)
response.Header().Set(resultHeader, resultAllowed)
response.Header().Set(overrideHeader, request.Header.Get(overrideHeader))
response.Header().Set(receivedHeader, l)
response.WriteHeader(http.StatusOK)
} else {
log.Printf("[HTTP][denied]: %s", l)
response.Header().Set(resultHeader, resultDenied)
response.Header().Set(overrideHeader, request.Header.Get(overrideHeader))
response.Header().Set(receivedHeader, l)
response.WriteHeader(http.StatusForbidden)
_, _ = response.Write([]byte(denyBody))
}
}ServeHTTP 関数は、checkHeader 変数が指定するリクエストヘッダーを読み取ります。ヘッダーの値がallowedValue の値と等しい場合、関数は 200 を返し、リクエストは許可されます。それ以外の場合、関数は 403 を返し、リクエストは拒否されます。
上記のコードはサンプル実装からの抜粋です。ExtAuthzServer 型、returnIfNotTooLong 関数、およびcheckHeader、allowedValue、resultHeader、overrideHeader、receivedHeaderなどの識別子は、サンプルの他の部分で定義されています。
この認可サービスは、checkHeader 変数に対応するヘッダーを使用します。したがって、カスタム認可サービスをメッシュにインポートする際には、認可リクエストに元のヘッダーを含める設定項目を設定する必要があります。そうしないと、期待どおりの結果が得られません。
カスタム認可サービスとメッシュの統合
開発したカスタム認可サービスを Container Service for Kubernetes (ACK) クラスターにデプロイし、ASM コンソールでそのサービスを ASM インスタンスに関連付けます。本トピックでは開発のみを扱います。カスタム認可サービスをメッシュにインポートする完全な手順については、「HTTP プロトコルを使用したカスタム認可の実装」をご参照ください。
サービスを関連付けた後、認可ポリシーで、この認可サービスを使用するメッシュプロキシを指定します。認可ポリシーの設定については、「HTTP プロトコルを使用したカスタム認可の実装」をご参照ください。