[nginx] http_realip_module を使ってアクセス元のIPを取得する

背景

nginxのエラーログにこんなのがでていた。

2016/11/24 04:36:22 [error] 25825#0: *2877433 open() "/usr/share/nginx/html/tunnel" failed (2: No such file or directory), client: 10.xxx.xxx.215, server: , request: "GET /tunnel"

トラバーサル攻撃に見えるけど 10.xxx.xxx.xxx って Private IP だよなと思い、EC2 の IP やらなんやらを調べたが該当するものを発見できず。小一時間調べてもよくわからなかったので @toricls さんに相談してみた。

学び

ELB じゃないかということで調べたら、その通りだった。ELB の内側では nginx のアクセスログに ELB の IP アドレスが記録されてしまうので、 http_realip_module を使ってアクセス元の IP を表示するよう設定しておくべきらしい。

設定を書く

ser_real_ip_from にはリバースプロキシの IP range を設定する。今回の例でいうと ELB -> EC2 という構成なので、ELB の IP range のみ指定すれば良さそう。将来的に CloudFront を挟むようにした際には set_real_ip_from に追加することを忘れないようにしたい。

real_ip_header は、クライアントIPアドレスを判別するリクエストヘッダを指定できる。ELB が X-Forwarded-For ヘッダーを自動的にリクエストに追加するため、デフォルトの X-Real-IP から X-Forwarded-For に変更した。

最終的に default.conf に以下の内容を反映した。

set_real_ip_from   10.xxx.xxx.0/24;
real_ip_header     X-Forwarded-For;