はじめに

この記事は、下記について書いた記事となります。

  • 対象読者
    :mTLS(相互TLS認証)環境下のAPIGWのログ(アクセスログ)から、クライアント証明書の情報を確認したい方
  • 記事内容
    :APIGWアクセス時に何のクライアント証明書を使っているのかをログから確認したい場合の方法を記載
    :APIGWアクセス失敗時の原因調査を実施したい場合などのケースを想定してログ設定/確認を実施

案件対応の検証でAPIGWのログ設定をする機会がありました。
実際に設定を実施し、ログを確認してみた内容となります。
この記事がどなたかのご参考となれば幸いです。

 

検証時の環境など

  • APIGW (カスタムドメイン / mTLS:設定済み)
  • 各種証明書:独自CAにて ルートCA証明書/サーバ証明書/クライアント証明書 を発行
    (= 検証のため自己署名証明証 (おれおれ証明書)を使用 / 中間証明書は未発行 )
    (※これらの各証明書を使用してAPIGWのmTLSを設定)
  • API:サンプルAPI (PetStore) を使用
  • デフォルトのエンドポイント:無効
  • アクセス確認:ローカルPCからクライアント証明書を使用してAPIGWのカスタムドメインにアクセス
  • 実行結果/ログ確認:成功・失敗の2パターンを確認

(参考:APIGW:REST API の相互 TLS 認証の設定)

 

準備:APIGW – 実行ログ・アクセスログ有効化 / $context 変数設定

  • 下記記事を参考にログ設定を有効化 (実行ログ・アクセスログ)

APIGWのログ取得 (実行ログ•アクセスログ) を有効化 / 無効化する方法

 

  • アクセスログの $context 変数 に、下記を一行で入力して有効化する
{ "accountId":"$context.accountId", "apiId":"$context.apiId", "domainName":"$context.domainName", "domainPrefix":"$context.domainPrefix", "error.message":"$context.error.message", "error.responseType":"$context.error.responseType", "extendedRequestId":"$context.extendedRequestId", "httpMethod":"$context.httpMethod", "identity.sourceIp":"$context.identity.sourceIp", "identity.clientCert.clientCertPem":"$context.identity.clientCert.clientCertPem", "identity.clientCert.subjectDN":"$context.identity.clientCert.subjectDN", "identity.clientCert.issuerDN":"$context.identity.clientCert.issuerDN", "identity.clientCert.serialNumber":"$context.identity.clientCert.serialNumber", "identity.clientCert.validity.notBefore":"$context.identity.clientCert.validity.notBefore", "identity.clientCert.validity.notAfter":"$context.identity.clientCert.validity.notAfter", "identity.userAgent":"$context.identity.userAgent", "path":"$context.path", "protocol":"$context.protocol", "requestId":"$context.requestId", "requestTime":"$context.requestTime", "requestTimeEpoch":"$context.requestTimeEpoch", "resourceId":"$context.resourceId", "resourcePath":"$context.resourcePath", "stage":"$context.stage", "responseLatency":"$context.responseLatency", "responseLength":"$context.responseLength", "status":"$context.status" }

(※引用元:相互 TLS を必要とする API Gateway カスタムドメイン名からの HTTP 403 Forbidden エラーをトラブルシューティングする方法を教えてください。 - API Gateway が実行ログとアクセスログを生成できるようにする CloudWatch のアクセスロギングに推奨される $context 変数)

 

  • ログ設定を確認

 

ローカルPCからクライアント証明書を使ってAPIGWにアクセス、実行結果 確認

  • アクセス:OKパターン (※認証設定されたクライアント証明書を使用してアクセス)
$ ls my_client*
my_client.csr   my_client.key   my_client.pem   my_client02.csr my_client02.key my_client02.pem
$ curl --include --insecure --key my_client.key --cert my_client.pem https://<カスタムドメイン>/pets
HTTP/2 200
x-amzn-requestid: 663837a7-884d-40ac-b046-1a8ff65656dc
access-control-allow-origin: *
x-amz-apigw-id: ahrPkF7stjMF26A=
x-amzn-trace-id: Root=1-668a2596-2b32f5e914a6325727587489
content-type: application/json
content-length: 184
date: Sun, 07 Jul 2024 05:20:22 GMT

[
  {
    "id": 1,
    "type": "dog",
    "price": 249.99
  },
  {
    "id": 2,
    "type": "cat",
    "price": 124.99
  },
  {
    "id": 3,
    "type": "fish",
    "price": 0.99
  }
]

 

  • アクセス:NGパターン (※認証設定されていないクライアント証明書を使用してアクセス)
$ ls my_client*
my_client.csr   my_client.key   my_client.pem   my_client02.csr my_client02.key my_client02.pem
 $ curl --include --insecure --key my_client02.key --cert my_client02.pem https://<カスタムドメイン>/pets
HTTP/2 403
x-amzn-requestid: 5fc39214-e591-43e7-94c0-2575a6a19994
x-amzn-errortype: ForbiddenException
x-amz-apigw-id: ahs7jH4vtjMFmig=
content-type: application/json
content-length: 23
date: Sun, 07 Jul 2024 05:31:53 GMT

{"message":"Forbidden"}

 

実行ログ・アクセスログを確認

  • アクセス:OKパターン (※認証設定されたクライアント証明書を使用してアクセス)

< 実行ログ >

< アクセスログ (※こちらでクライアント証明書の情報を確認可能) >

 

  • アクセス:NGパターン (※認証設定されていないクライアント証明書を使用してアクセス)

< 実行ログ >

< アクセスログ (※こちらでクライアント証明書の情報を確認可能) >

 

  • 【補足】$context変数の記述からクライアント証明書の情報に関するものを抜粋
    (※ $context.identity.clientCert.* の記述が、クライアント証明書の情報に関する $context変数 となる)
{
"identity.clientCert.clientCertPem":"$context.identity.clientCert.clientCertPem", 
"identity.clientCert.subjectDN":"$context.identity.clientCert.subjectDN",
"identity.clientCert.issuerDN":"$context.identity.clientCert.issuerDN", 
"identity.clientCert.serialNumber":"$context.identity.clientCert.serialNumber", 
"identity.clientCert.validity.notBefore":"$context.identity.clientCert.validity.notBefore", 
"identity.clientCert.validity.notAfter":"$context.identity.clientCert.validity.notAfter",
}

(参考:API Gateway マッピングテンプレートとアクセスのログ記録の変数リファレンス)

・$context.identity.clientCert.clientCertPem
:クライアントが相互 TLS 認証中に提示した PEM エンコードされたクライアント証明書

・$context.identity.clientCert.subjectDN
:クライアントが提示する証明書のサブジェクトの識別名

・$context.identity.clientCert.issuerDN
:クライアントが提示する証明書の発行者の識別名

・$context.identity.clientCert.serialNumber
:証明書のシリアル番号

・$context.identity.clientCert.validity.notBefore
:証明書が無効になる前の日付

・$context.identity.clientCert.validity.notAfter
:証明書が無効になった日付

 

その他 補足

  • アクセスログ共有時の注意点
    (※クライアント証明書の秘匿情報が表示されるため、外部共有時などの際には取扱注意)