nginxでX-Forwarded-Forの値に$proxy_add_x_forwarded_forを安易に使わない方が良い2019/08/17nginxnginxでX-Forwarded-Forヘッダを付与するのに$proxy_add_x_forwarded_forという便利な変数がありますが、迂闊に設定するとちょっと危ないのでメモします。variable.https://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for受け取ったリクエストヘッダにXFFヘッダがなければ、XFFヘッダを作成してクライアントIPアドレスを値に設定してバックエンドにリクエストを送ります。受け取ったリクエストヘッダにXFFがあれば、それにカンマ区切りでクライアントのIPアドレスを追加してバックエンドにリクエストを送ります、とあります。以下の一行を追加するだけで、上記の挙動を自動でやってくれるため大変便利です。$proxy_add_x_forwarded_for;しかし、この変数を利用している場合、以下のような問題が起こります。問題1:nginxがXFFを生成するフロントエンドの場合、XFFの改ざんが可能になるnginxがXFFを生成するフロントエンドとなっている場合です。$proxy_add_x_forwarded_forは、単純に「XFFがあれば追加し、なければ作る」という挙動しか行わないため、悪意のあるクライアントがXFFヘッダをつけてリクエストを飛ばしてきた場合、そのXFFヘッダにそのままクライアントIPアドレスを追加してバックエンドに流してしまいます。バックエンドに対するクライアントIPアドレスの偽装が可能になる可能性があります。LBやFW等で一旦リクエストを受け取って、そのバックエンドとしてnginxを利用している場合、そのLBやFWが悪意あるXFFの破棄、およびXFFの新規生成を行ってくれていれば、nginx側はこの問題を気にする必要はありません。LBやFWの挙動は確認しておく必要があります。問題1:どうすればいいかnginxがXFFを生成するフロントエンドでなければ、$proxy_add_x_forwarded_forを使ってもいいです。なければ、nginxでXFFを生成する際に$proxy_add_x_forwarded_forを使ってはいけません。以下のように、クライアントIPアドレスをそのままXFFの値とすれば、悪意あるXFFの消去ができるためOKです。問題2::real_ip_headerなどで$remote_addrが変更されている場合、正しく上流プロキシのIPアドレスをXFFに追加できない公式ドキュメントの記述にもあるように、$proxy_add_x_forwarded_forは$remote_addrの値をXFFに埋め込みます。$proxy_add_x_forwarded_forは、$remote_addrが直近のリクエストを送信したサーバのIPアドレスであることを期待するため、多段プロキシ環境などで$remote_addrを上流プロキシではなくクライアントのIPアドレスに変更している場合に、上流プロキシのIPアドレスをXFFに埋め込めないという問題が発生します。下記の記事で言うと、内部プロキシproxy2で、XFFに$proxy_add_x_forwarded_forを利用している場合に問題が起こります。問題2:期待されるXFFの値とこの設定で実際に設定されるXFFの値バックエンドが受け取るXFFリクエストヘッダ、つまりproxy2が付与するXFFヘッダの値です。すればいいか記事に記載の通り、上流プロキシproxy1から受け取ったXFFヘッダに、上流プロキシのIPアドレスを追記してやればいいです。$proxy_add_x_forwarded_forは使えません。https://stackoverflow.com/questions/29279084/nginx-proxy-add-x-forwarded-for-and-real-ip-header以上、はまったポイントでした。問題1はあまりネットで問題とされていないっぽいけど、私の何か思い違いだろうか。