【AWS ALB】ALBのmTLS認証を実装した際のログに関する整理

## はじめに
re:invent2023でALBがmTLS認証をサポートすることが発表されました。
[Application Load Balancer での TLS を使用した相互認証](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/mutual-authentication.html)

これに伴い、ALBが出力するLogにConnection Logsが追加されました。
このConnection Logsにはどんな情報が記載されるのか？
Access Logsに含まれる情報とどんな差異があるのか？
気になったので、試してみながら整理したので紹介させて頂きます。

※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。

## 試した概要
以下2つのシナリオを実施

- クライアント認証が成功したケース
- クライアント認証が失敗したケース

シナリオ毎に取得した情報
- Verboseでのcurl出力結果
- Connection logs
- Access log

## クライアント認証が成功したケース
### Verboseでのcurl出力
※出力結果から固有情報はマスキングしています。
~~~console
*   Trying x.x.x.x:443...
* Connected to 【access logs③】hogehoge.com (x.x.x.x) 【connection logs③】port 443
* ALPN: curl offers 【access logs①】h2,http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using 【Connection logs④】【Access logs⑧】TLSv1.2 / 【Connection logs⑤】　【Access logs⑦】ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: C=JP; ST=Tokyo; L=Default City; O=Default Company Ltd; CN=hogehoge.com
*  start date: Mar  1 06:18:32 2024 GMT
*  expire date: Mar 31 06:18:32 2024 GMT
*  issuer: C=JP; ST=Tokyo; L=Default City; O=Default Company Ltd; CN=root-ca
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://hogehoge.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: hogehoge.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.3.0]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: hogehoge.com
> User-Agent: curl/8.3.0
> Accept: */*
> 
< HTTP/2 【Connection logs⑧】200 
< server: awselb/2.0
< date: Fri, 01 Mar 2024 08:48:35 GMT
< content-type: text/plain; charset=utf-8
< content-length: 4
< 
* Connection #0 to host hogehoge.com left intact
~~~

ここで得られた情報とそれぞれのログにどの情報が記載されるのか整理します。

### Connection logs
※ログから固有情報はマスキングしています。
~~~
【Connection logs①】2024-03-01T08:48:35.930691Z 【Connection logs②】x.x.x.x 45224 【Connection logs③】443 【Connection logs④】TLSv1.2 【Connection logs⑤】ECDHE-RSA-AES128-GCM-SHA256 【Connection logs⑥】0.014 【Connection logs⑦】"CN=client,O=Default Company Ltd,L=Default City,ST=Tokyo,C=JP" NotBefore=2024-03-01T08:34:02Z;NotAfter=2024-03-08T08:34:02Z 8657EFA581D298ED 【Connection logs⑧】Success
~~~
記載されている内容の整理
|項番|記載内容|
|---|---|
|① |タイムスタンプ|
|② |接続元情報|
|③ |接続先ポート|
|④ |TLSプロトコル|
|⑤ |使用される暗号スイート|
|⑥ |ハンドシェイクが成功するまでの時間|
|⑦ |クライアント証明書情報　シリアル等|
|⑧ |接続ステータス|

このようにConnection logはクライアント認証に特化したログが出力されることが分かります。

### Access logs
※ログから固有情報はマスキングしています。
~~~console
【Access logs①】h2 【Access logs②】2024-03-01T08:48:35.944933Z 【Access logs③】app/test-pub-alb/hogehoge 【Access logs④】x.x.x.x:45224 【Access logs⑤】- -1　-1 -1 200 - 59 79 【Access logs⑥】"GET https://hogehoge.com:443/ HTTP/2.0" "curl/8.3.0" 【Access logs⑦】ECDHE-RSA-AES128-GCM-SHA256 【Access logs⑧】TLSv1.2 - 【Access logs⑨】"Root=1-65e19663-1d0f89e7196ef2aa6000b1ea" "hogehoge.com" "arn:aws:acm:ap-northeast-1:xxxx:certificate/xxxx" 【Access logs⑩】0 【Access logs⑪】2024-03-01T08:48:35.944000Z 【Access logs⑫】"fixed-response" "-" "-" "-" "-" "-" "-"
~~~
記載されている内容の整理
|項番|記載内容|
|---|---|
|① |接続方式|
|② |タイムスタンプ|
|③ |ELB情報|
|④ |接続元情報|
|⑤ |接続元まで応答を返す処理のポイント毎の時間及び、レスポンスステータス　このデータを取る際は、ALBが直接レスポンスを返しているので基本データなし|
|⑥ |リクエスト情報|
|⑦ |使用される暗号スイート|
|⑧ |TLSプロトコル|
|⑨ |SSL証明書関連情報|
|⑩ |アクション情報　このデータを取る際は、ALBが直接レスポンスを返しているので基本データなし|
|⑪ |リクエストを受領した時間|
|⑫ |応答関連情報|

このようにAccess logsは接続元に応答を返すまでの処理に特化したログが出力されることが分かります。
また、「使用される暗号スイート」「TLSプロトコル」等は、Connection logs、Access logs両方に出力されることが分かります。

## クライアント認証が失敗したケース
### Verboseでのcurl出力
※出力結果から固有情報はマスキングしています。
~~~console
*   Trying x.x.x.x:443...
* Connected to hogehoge.com (54.199.86.166) port 443
* ALPN: curl offers h2,http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* Recv failure: Connection reset by peer
* OpenSSL SSL_connect: Connection reset by peer in connection to hogehoge.com:443 
* Closing connection
curl: (35) Recv failure: Connection reset by peer
~~~
クライアント認証に失敗しているので、接続先から拒否されていることが分かります。

### Connection logs
※ログから固有情報はマスキングしています。
~~~console
【Connection logs①】2024-03-01T08:49:19.299515Z 【Connection logs②】x.x.x.x 54522 【Connection logs③】443 【Connection logs④】TLSv1.2 【Connection logs⑤】ECDHE-RSA-AES128-GCM-SHA256 【Connection logs⑥，⑦】- "-" - - 【Connection logs⑧】Failed:UnmappedConnectionError
~~~
記載されている内容の整理
記載されている内容の整理
|項番|記載内容|
|---|---|
|① |タイムスタンプ|
|② |接続元情報|
|③ |接続先ポート|
|④ |TLSプロトコル|
|⑤ |使用される暗号スイート|
|⑥ |ハンドシェイクが成功するまでの時間|
|⑦ |クライアント証明書情報　シリアル等|
|⑧ |接続ステータス|

ハンドシェイクやクライアント証明書情報が欠落しています。
※今回は何も指定せずにcurlしています。
「マッピングされていないランタイム接続エラー」と出力され、接続が拒否されていことが分かります。

### Access logs
これは出力がありませんでした。クライアント認証に失敗しているので、ELB側でのリクエスト受領まで行かなかったため、出力されなかったと考えられます。

## まとめ
mTLS認証を設定してみて、出力されるログを整理してみました。
クライアント認証に失敗しているとAccess logsには何も出力されないので、mTLS認証を実装するなら、Connections logsを有効化しておかないとトラブル発生時とかは厳しそうです。
あと、mTLS認証を実装する場合、監査ログ目的では、Connections logsの有効化は必須になりそうです。

Connection logsの有効化方法に関しては、以下のリンクの記事にまとめておりますので、CDKの実装をご検討される際は、参考にしてください。
[【AWS CDK】CDKを用いたALB mTLS認証の実装](https://qiita.com/akwayne/items/7049cae0f82345665939)



※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。