LoginSignup
0

More than 1 year has passed since last update.

posted at

updated at

Organization

NLB + Nginx +α でのアクセスログ

初めに

すでに色々と情報はあるNginx ですが、AWSのNetwork Load Balancer(以降NLB)をTargetにてIP指定+nginx を連携させた際のアクセスログが、かゆい所に手が届いてなかったのでその際の情報をまとめてみました。

困った事

  • NLBとNginxを連携したところ、Nginxのアクセスログに出力していた送信元のクライアントIPが変わってしまった。
  • Nginx のアクセルログにX-Forwarded-Forの値を出力させたいが、その値が入る $http_x_forwarded_for 変数にも-(ハイフン)となり取れていないので、後続(下図におけるApache)へ渡せるようにしたい。

image.png

原因

  • 困った事の原因としては、NLB(target group)の設定で、ターゲットをインスタンス指定でなくIP指定としていた為、 出力していたクライアントのIPがNLBのIPになっていた。これはAWS仕様。
  • NLBはX-Forwarded-Forを付与しない為、個別に設定する必要があった。
    (NLBでは送信元IPアドレスと送信元ポートの書き換えを行わないため、パケットからの情報でアクセス元が判断する)

対応前

nginx.conf
  • log_format
    余談ですが、log_formatにて変数を””(ダブルクォーテーション)で囲っているものは値に空白を含む可能性のある場合に設定しておくと位置特定に便利です。
    log_format  main  '$remote_addr $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent"';
Nginx
  • access.log

remote_addr にはNLBのIPアドレスが入るためクライアントIPは出力されてない。

172.26.22.241 - [09/Dec/2020:18:07:46 +0900] "GET / HTTP/2.0" 403 2135 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36"


対応

  • NLB target group
    Proxy Protocol ヘッダーから送信元のIP アドレスを取得するため、NLBのターゲットグループにてProxy Protocol V2 機能を利用する。

有効化にチェックをつけて保存する。(反映に数分かかります。)
image.png

  • Nginx
    Nginx でのproxy_protocolの設定。
ディレクティブ 説明
listen ディレクティブにproxy_protocolを追加することで有効になる。
real_ip_header 今回X-Forwarded-Forはとれていないので、remote_addrをクライアントIPで上書きしたいのであれば「real_ip_header proxy_protocol」とする必要がある。remote_addrをクライアントIPで上書きしたくないので今回は不要。
set_real_ip_form NLBのIPアドレスを指定。
real_ip_recursive real_ip_header X-Forwarded-Forの場合に意味のある設定のため今回は不要。
server {
    listen 443 ssl proxy_protocol;
    set_real_ip_from XXX.XXX.XXX.XXX;
}

nginx.conf のlog_formatに変数を追加。

  • $proxy_protocol_addr :クライアントのIPアドレスが格納される。
  • $proxy_protocol_port :クライアントのポートが格納される。
log_format  main  '$proxy_protocol_addr:$proxy_protocol_port  $remote_addr:$remote_port $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" "$http_user_agent" $server_port';                    

Nginx access_log
クライアントのIPアドレスとポートが出力されるようになりました。

192.178.185.120:51714 172.26.22.241:6919 - [09/Dec/2020:18:43:34 +0900] "GET / HTTP/2.0" 403 2135 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" 443


対応 + α

欲しい情報は無事取得できましたが、アクセスログの最後に出力しようとしている http_x_forwarded_forは変わらず-(ハイフン)のままなので、後続のサーバでも取得できません。

後続へ転送設定時に取得したproxy_protocol_addr変数の値を渡す必要があります。

Nginxの後ろにあるApacheのアクセスログに出力されているか確認します。

location / {
    proxy_pass  http://XXX.XXX.XXX.XX2/;
    proxy_set_header Host XXX.XXX.XXX.XX2;
    proxy_set_header X-Forwarded-for $proxy_protocol_addr; 
    proxy_pass_request_headers on;
}
  • Apache
    Nginxで設定した X-Forwarded-For の値を Apache のアクセスログで出力されているか確認する為にApache側のLogFormatを以下のように変更します。

httpd.conf

 LogFormat  "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

access.log(Apache)

192.178.185.120 172.26.22.183 - - [09/Dec/2020:18:43:31 +0900] "GET /noindex/css/fonts/Light/OpenSans-Light.ttf HTTP/1.0" 404 240 "https://XXX-nlb-dev-XXXXXXXXXXXXX.elb.ap-northeast-1.amazonaws.com/noindex/css/open-sans.css" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36"


NLBとNginxのアクセスログ出力項目

障害調査や監査等でNLBのアクセスログとNginxのアクセスログを突合せたいケースがあると思います。
その際に、どの項目で突合せできるかまとめてみました。
NLBのアクセスログをベースにNginxのアクセスログへ出力できる変数を表にしてみました。

  • NLBの項目と突合せできそうなものを表にします。(一部マスキングしています)
  • 意外と対応する項目がない。
    ★箇所がクライアントIP、portではなくNLBの値になってしまう。
フィールド(NLB) NLB出力結果 Nginx変数 Nginx出力結果
type tls
バージョン 2.0
time 2020-12-10T08:22:43 \$time_iso8601、$time_local 2020-12-10T17:22:44+09:00、10/Dec/2020:17:44:09 +0900
elb net/xxx-NLB-DEV/XXXXXXXXXXXXX
listener XXXXXXXXXXXXX
client:port 192.178.185.120:57569 \$remote_addr:$remote_port \$proxy_protocol_add:\$proxy_protocol_port 172.26.22.241:58000 192.178.185.120:57831
destination:port 172.26.22.241:443
connection_time 102628
tls_handshake_time 4
received_bytes 1008
sent_bytes 28259 \$bytes_sent 28259
incoming_tls_alert -
chosen_cert_arn arn:aws:iam::XXXXXXXXXXXXX:server-certificate/dx-xxx-test2
chosen_cert_serial -
tls_cipher ECDHE-RSA-AES128-GCM-SHA256
tls_protocol_version tlsv12
tls_named_group -
domain_name xxx-nlb-dev-XXXXXXXXXXXXX.elb.ap-northeast-1.amazonaws.com $host xxx-nlb-dev-XXXXXXXXXXXXX.elb.ap-northeast-1.amazonaws.com
alpn_fe_protocol h2
alpn_be_protocol h2
alpn_client_preference_list "h2","http/1.1"

NLBのアクセスログの詳細については以下の公式を参考にしてください。
Network Load Balancer のアクセスログ

Nginx 日本語ドキュメント
NLB

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0