アプリケーション開発こんにちは@mosuke5です。Apach+PHPで動作していたシステムに、リバースプロキシ(Nginx)を前段に挟むことになりました。理由は、もともと社内ネットワークでのみ利用するシステムだったのですが、インターネットの外からも利用することになり、インターネットからの入り口にリバースプロキシを導入したからです。Nginx->Apache->PHPという構成になりました。リバースプロキシを導入した際によく問題となることだが、Apacheからみるとすべてリバースプロキシから通信がきているようにみえます。接続元のIPアドレスがすべてリバースプロキシのもの変わってしまいます。そこで、HTTPヘッダーに接続元のIPアドレス追加しアプリ側(PHP)で受け取る方法とその際の注意点を書きます。リバースプロキシ側でHTTPヘッダー追加まず、デフォルトのNginxの設定では接続元のIPアドレスをHTTPヘッダーに含みません。そのため、本当のクライアント側のIPアドレスをHTTPヘッダーに追加します。一般的にX-Forwarded-ForというHTTPヘッダーを利用します。X-Forwarded-Forというヘッダー名にNginxでもっている変数$proxy_add_x_forwarded_forを追加する。リバースプロキシしかり、AWSのELBなどしかり、L7でのプロキシやロードバランサを利用した際に、よくX-Forwarded-Forというヘッダー名がでてきます。このヘッダーはなんなのか?HTTPの標準のヘッダーとして存在するのかと疑問に思い調べてみると、RFCには定義されていないが一般的に利用されているヘッダーであることがわかりました。HTTPヘッダフィールドの一つ。HTTPプロキシサーバまたは負荷分散装置(ロードバランサ)を経由してウェブサーバに接続するクライアントの送信元IPアドレスを特定する際のデファクトスタンダードである。2011年10月より同種のHTTPヘッダForwardedの標準化作業を開始した[1]。PHPでX-Forwarded-Forを受け取るリバースプロキシで’X-forwarded-For’という名前のHTTPヘッダーを追加したので、そのまま取得しようとするが、実はこのままだとうまくいきません。これはPHPのサーバ変数の仕様の問題です。PHPのサーバ変数に入れる際に、名前を規則に従って変更するからです。存在しないサーバ変数をvar_dumpを使って中身を確認してみると、HTTPが先頭についてて、すべて大文字になってて、ハイフンがアンスコに変わっていることが確認できます。}ためしにgetallheadersという関数で生のヘッダーの状態を確認してみると、想定通りでした。サーバ変数に格納するタイミングで、名前が変わるということです。}tcpdumpで生のパケットを確認してみる結果は見えているのですが、気になったのでtcpdumpで生パケットの状態を確認してみます。“になっていること確認できました。任意のHTTPヘッダーつけた場合それでは、X-Forwarded-For以外の任意のHTTPヘッダーをつけた場合も同様になるのか確認してみます。Nginxにて、’my-header’という名前でヘッダーを追加してPHP側で受け取ります。my-headerがHTTP_MY_HEADERに変わっていることが確認できた。}さいごにPHPでHTTPヘッダーを受け取る際の注意点について見てきました。ELBなどのL7のロードバランサを用いた場合も基本的に同様ですので、原理原則をおさえておくといいでしょう。Shopを使ったマイクロサービス体験のハンズオン「捉」2019年振り返り「LeanとDevOpsの科学」を読んで。