CloudWatch Logsに統合されたログ記録、NLBでも試してみた
はじめに
前回、ALBのアクセスログをCloudWatch Logsへ直接配信する機能を検証しました。
その際に describe-configuration-templates のレスポンスで NLB_ACCESS_LOGS というログタイプを見つけ、公式ドキュメントでNLBのCloudWatch Logs統合を確認できたので、紹介します。
検証内容
検証環境
TLSリスナーを有効にしたNLBを用意し、アクセスログのCloudWatch Logs配信を検証しました。
| リソース | 値 |
|---|---|
| リスナー | TLS:443 (ELBSecurityPolicy-TLS13-1-2-2021-06) |
| ACM証明書 | nlb-test-tokyo.example.com (自己署名インポート) |
| ターゲットグループ | nlb-cwlogs-tg (TCP 443, IP, ターゲット未登録) |
| ロググループ | /aws/nlb/nlb-cwlogs-test/access |
| リージョン | ap-northeast-1 |
Vended Logs API による配信設定
ALBと同じ3ステップ(Delivery Source → Delivery Destination → Create Delivery)で設定します。NLB固有のポイントは --log-type に NLB_ACCESS_LOGS を指定する点です。
# 1. Delivery Source
aws logs put-delivery-source \
--name nlb-cwlogs-test-access \
--resource-arn arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:loadbalancer/net/nlb-cwlogs-test/2941e1f9f2463992 \
--log-type NLB_ACCESS_LOGS \
--region ap-northeast-1
# 2. Delivery Destination
aws logs put-delivery-destination \
--name nlb-cwlogs-test-cwl \
--output-format json \
--delivery-destination-configuration "destinationResourceArn=arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/nlb/nlb-cwlogs-test/access" \
--region ap-northeast-1
# 3. Create Delivery
aws logs create-delivery \
--delivery-source-name nlb-cwlogs-test-access \
--delivery-destination-arn arn:aws:logs:ap-northeast-1:123456789012:delivery-destination:nlb-cwlogs-test-cwl \
--region ap-northeast-1
APIで作成した配信設定は、NLB詳細画面のIntegrationsタブでも確認できます。

ログの確認
配信設定後、openssl s_client でTLSリスナーへ接続したところ、ロググループに合計17イベントが記録されました。TLSハンドシェイク成功8件、失敗9件です。
NLBアクセスログは22フィールドで構成されており、すべてmandatoryです。
| # | フィールド | 説明 |
|---|---|---|
| 1 | type | リスナータイプ(tls) |
| 2 | version | ログバージョン(2.0) |
| 3 | time | TLS接続終了時刻 |
| 4 | elb | ロードバランサーリソースID |
| 5 | listener | TLSリスナーリソースID |
| 6 | client_port | クライアントIP:ポート |
| 7 | destination_port | 宛先IP:ポート |
| 8 | connection_time | 接続完了までの時間(ms) |
| 9 | tls_handshake_time | TLSハンドシェイク時間(ms) |
| 10 | received_bytes | 受信バイト数 |
| 11 | sent_bytes | 送信バイト数 |
| 12 | incoming_tls_alert | TLSアラート値 |
| 13 | chosen_cert_arn | 提示した証明書ARN |
| 14 | chosen_cert_serial | 証明書シリアル(予約、常に-) |
| 15 | tls_cipher | ネゴシエートされた暗号スイート |
| 16 | tls_protocol_version | TLSプロトコルバージョン |
| 17 | tls_keyexchange | 鍵交換方式 |
| 18 | domain_name | SNI値 |
| 19 | alpn_fe_protocol | クライアント側ALPNプロトコル |
| 20 | alpn_be_protocol | ターゲット側ALPNプロトコル |
| 21 | alpn_client_preference_list | ALPNクライアント希望リスト |
| 22 | tls_connection_creation_time | TLS接続開始時刻 |
レガシーS3アクセスログと同一の22フィールド構成のため、既存のパーサーをそのまま流用できます。
TLSハンドシェイク成功時のログ
{
"type": "tls",
"version": "2.0",
"time": "2026-07-24T04:36:07",
"elb": "net/nlb-cwlogs-test/2941e1f9f2463992",
"listener": "0a3675bbc9f8dc77",
"client_port": "203.0.113.1:4979",
"destination_port": "10.0.1.1:443",
"connection_time": "5014",
"tls_handshake_time": "14",
"received_bytes": "0",
"sent_bytes": "0",
"incoming_tls_alert": "-",
"chosen_cert_arn": "arn:aws:acm:ap-northeast-1:123456789012:certificate/9ec763a1-8142-429f-9965-df04bf745ca9",
"chosen_cert_serial": "-",
"tls_cipher": "TLS_AES_128_GCM_SHA256",
"tls_protocol_version": "tlsv13",
"tls_keyexchange": "x25519",
"domain_name": "nlb-test-tokyo.example.com",
"alpn_fe_protocol": "-",
"alpn_be_protocol": "-",
"alpn_client_preference_list": "-",
"tls_connection_creation_time": "2026-07-24T04:36:02"
}
connection_time が約5014msと長いのは、ターゲット未登録のためタイムアウトまでの待ち時間を含むためで、TLSハンドシェイク自体は14msで完了しています。
TLSハンドシェイク失敗時のログ
{
"type": "tls",
"version": "2.0",
"time": "2026-07-24T04:32:08",
"elb": "net/nlb-cwlogs-test/2941e1f9f2463992",
"listener": "0a3675bbc9f8dc77",
"client_port": "203.0.113.2:47148",
"destination_port": "10.0.2.1:443",
"connection_time": "364",
"tls_handshake_time": "-",
"received_bytes": "0",
"sent_bytes": "0",
"incoming_tls_alert": "48",
"chosen_cert_arn": "-",
"chosen_cert_serial": "-",
"tls_cipher": "-",
"tls_protocol_version": "-",
"tls_keyexchange": "-",
"domain_name": "-",
"alpn_fe_protocol": "-",
"alpn_be_protocol": "-",
"alpn_client_preference_list": "-",
"tls_connection_creation_time": "2026-07-24T04:32:08"
}
失敗時は incoming_tls_alert に 48(unknown_ca)が記録されています。自己署名証明書を検証しようとしたクライアントで発生したものです。ハンドシェイク失敗時はTLSネゴシエーション段階で切断されるため、connection_time は14〜374msと短い値でした。
配信タイムラグの実測
ログのイベント時刻(time)とCloudWatch Logsの取り込み時刻(@ingestionTime)を比較し、配信タイムラグを計測しました。
| イベント時刻 (time) | 取り込み時刻 (@ingestionTime) | ラグ |
|---|---|---|
| 04:31:57 | 04:32:43 | 46秒 |
| 04:32:08 | 04:33:07 | 59秒 |
| 04:33:44 | 04:34:06 | 22秒 |
| 04:36:07 | 04:37:07 | 60秒 |
| 04:36:51 | 04:37:05 | 14秒 |
| 04:36:54 | 04:37:04 | 10秒 |
レンジは10〜60秒、中央値は34秒でした。同環境でのALBの配信タイムラグが約2〜3分だったのに対し、NLBは大幅に速い結果です。
Logs Insights クエリ例
fields @timestamp, tls_protocol_version, tls_cipher, domain_name, connection_time, tls_handshake_time, incoming_tls_alert
| sort @timestamp desc
| limit 10
| filter incoming_tls_alert != "-" を追加すれば、TLSハンドシェイク失敗のみ抽出できます。古いTLSバージョンでの接続を監視したい場合は | filter tls_protocol_version = "tlsv12" のようにフィルタできます。
ALBとの比較ポイント
| 観点 | ALB | NLB |
|---|---|---|
| ログタイプ | 3種(Access/Connection/HealthCheck) | 1種(Access のみ) |
| リスナー要件 | 任意(HTTP/HTTPS) | TLSリスナー必須 |
| フィールド数 | Access: 34項目 | 22項目 |
| 記録対象 | 全リクエスト | TLS接続のみ |
| タイムラグ | 2〜3分 | 10〜60秒(実測値) |
| 出力フォーマット | json, plain | json, plain |
まとめ
NLBのアクセスログも、ALBと同じVended Logsの仕組みでCloudWatch Logsへ直接配信できるようになっていました。mTLS導入時のハンドシェイク失敗の即時検知や、TLS 1.2→1.3移行状況のモニタリングといったユースケースで、従来のS3ログ記録より手軽に利用できそうです。
参考リンク










