CloudWatch Logsに統合されたログ記録、NLBでも試してみた

CloudWatch Logsに統合されたログ記録、NLBでも試してみた

ALBのCloudWatch Logs配信を検証した際、NLBアクセスログも同じVended Logsの仕組みでCloudWatch Logsへ直接配信できることを発見しました。実際にNLBで設定し、JSON形式のログ取得とフィールド構成の確認、配信タイムラグの実測まで試してみました。
2026.07.24

はじめに

前回、ALBのアクセスログをCloudWatch Logsへ直接配信する機能を検証しました。

https://dev.classmethod.jp/articles/alb-access-logs-cloudwatch-logs-vended/

その際に describe-configuration-templates のレスポンスで NLB_ACCESS_LOGS というログタイプを見つけ、公式ドキュメントでNLBのCloudWatch Logs統合を確認できたので、紹介します。

https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-cloudwatch-logs.html

検証内容

検証環境

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-typeNLB_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タブでも確認できます。

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_alert48(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ログ記録より手軽に利用できそうです。

参考リンク

https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-access-logs.html

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事