CDN経由のnginxでLBサーバーを構築し、ユーザーIPを参照して振り分けを行った話
はじめに
こんにちは、マイグレーションチームのwakaです。
nginxを使ってLBサーバーを構築する機会があったのですが、前段にLBやCDNを挟んだ状態でユーザーのIPを参照する要件がやや曲者だったので、備忘録的な感じで残したいと思います。
今回動作確認を行う構成
X-Forwarded-Forの値にいくつかのIPが入った状態をAWSで再現したいため、前段にCloudFrontなどのCDN系のサービスとALBを置いて、一台のEC2をLBサーバーとして設定します。
また、今回の検証ではCloudFrontのキャッシュの設定は無効にしております。
LBサーバーのnginx.confについて
ユーザーIPを変数に格納する処理の追加
http {…} 内にmap {…}を追加します。
以下のように記載すれば$http_x_forwarded_forに入っているIPの中で、1つ目の要素を$clientRealIpに格納させることができます。
map $http_x_forwarded_for $clientRealIp { ~^(?P[0-9\.]+),?.*$ $firstAddr; }
LBサーバーとしての分散処理の追加
http {…} 内にupstream {…} を追加します
hashの値として$clientRealIpを指定します。
これにより、同じIPからのアクセスの場合は同じサーバーに振り分けられます。
upstream backend_server { hash $clientRealIp; server xx.xxx.xxx.xx; server xx.xxx.xx.xxx; }
後段のサーバーにリクエストを渡す設定の追加
location {…} 内にproxy_pass {…} を追加します
location / { proxy_pass http://backend_server; proxy_set_header Host $http_host; add_header X-Forwarded-For $http_x_forwarded_for; add_header clientRealIp $clientRealIp; }
add_header系を入れておくことで、レスポンスヘッダーに各情報が表示されるようになるため、テストの際に確認しやすくなるかと思います。
動作検証
それぞれのindex.htmlにそれぞれServer1, Server2という文字を入れておき、どちらが表示されたかがわかる形にして検証を行います。
サンプルではpyhtonでGETする際のヘッダーにX-Forwarded-Forの値を指定する/しない場合の分散状況を集計しておりますが、curlなどでも確認可能です。
X-Forwarded-Forに毎回別の値を指定した場合
[waka]% python curl.py 接続先は http://xxxxxxxxxxxxxx.cloudfront.net/ です。 Server1が呼び出された回数は15回です。 Server2が呼び出された回数は15回です。
headerにX-Forwarded-Forの値を設定した場合、$clientRealIpに入るのはX-Forwarded-Forで指定した値となります。
毎回別の新規IPからアクセスが来るという状態になりますので、両方のサーバーへのアクセスが分散されるという形になります。
X-Forwarded-Forの値を設定しない場合
[waka]% python curl.py 接続先は http://xxxxxxxxxxxxxx.cloudfront.net/ です。 Server1が呼び出された回数は0回です。 Server2が呼び出された回数は30回です。
通常のブラウザからのアクセスなど、X-Forwarded-Forの値を設定しなかった場合$clientRealIpに入るのはユーザーIPとなります。
毎回同じIPからアクセスが来るという状態になりますので、今回の設定では片方のサーバーにのみ流れるという形となります。
最後に
間にサーバーが挟まっている状態でもユーザーIPが取得できますので、upstreamに利用するだけでなく、特定のIPのみ表示を変更するといった使い方にも利用できそうです。
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitter2022年に中途入社した人です。好きなAWSサービスはLambdaです。
Recommends
こちらもおすすめ
-
テレワーク導入で日本の企業を盛り上げよう
2017.7.26
-
pyenvによるPythonの開発環境構築【Mac】
2023.6.12
-
gulp+babelでのフロントエンド開発について – 2. gulpによるビルド
2015.11.17
-
RPGツクールMVを触ってみる
2015.12.25
-
クラウドセキュリティ態勢管理#AWS#Horangi Warden
2022.9.8
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28
AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16