Classic Load Balancer (CLB) のレイヤー 7 リスナーを使用する際に、X-Forwarded-For HTTP ヘッダーからクライアント IP アドレスを取得します。
仕組み
CLB のレイヤー 7 リスナー (HTTP/HTTPS) は、クライアント IP アドレスを X-Forwarded-For HTTP ヘッダーに保持します。バックエンドサーバーは、設定後にこの IP を取得できます。
X-Forwarded-For フィールドの形式は次のとおりです:
X-Forwarded-For: <クライアント IP アドレス、プロキシサーバー 1 の IP、プロキシサーバー 2 の IP、...>この方法を使用する場合、リストの左端の IP アドレスがクライアント IP アドレスです。
CLB は HTTPS を終端し、HTTP 経由でバックエンドサーバーと通信します。HTTPS リスナーを使用している場合でも、バックエンドサーバーは HTTP 専用に設定してください。
手順
前提条件
レイヤー 7 リスナーを持つ CLB インスタンスが作成されていること。このトピックでは、ポート 80 の HTTP リスナーを使用します。詳細については、「CLB インスタンスの作成と管理」および「HTTP リスナーの追加」をご参照ください。
バックエンドサーバーを持つサーバーグループが CLB インスタンスに追加されていること。このトピックでは、HTTP プロトコル、ECS インスタンス、およびポート 80 を持つ vServer グループを使用します。詳細については、「vServer グループの作成と管理」をご参照ください。
ステップ 1:リスナーが X-Forwarded-For を使用していることの確認
Classic Load Balancer (CLB) コンソールにログインします。
上部メニューで、インスタンスがデプロイされているリージョンを選択します。
インスタンス ページで、対象のインスタンスを見つけてその ID をクリックします。
インスタンス詳細 ページで、リスナー タブをクリックし、対象のレイヤー 7 リスナーを見つけてその ID をクリックします。
リスナーの詳細ページで、追加のHTTPヘッダー セクションに X-Forwarded-For:クライアントの IP を取得 が含まれていることを確認します。
デフォルトでは、CLB のレイヤー 7 リスナーは X-Forwarded-For ヘッダーを使用してクライアント IP アドレスを取得します。この機能は無効にできません。
ステップ 2:バックエンドサーバーの設定
このセクションでは、バックエンドサーバーのアクセスログにクライアント IP アドレスを記録する方法 (
X-Forwarded-Forフィールド経由) について説明します。コネクションレイヤーの変数 (Nginx の$remote_addrなど) は、引き続き CLB の転送 IP を示し、影響を受けません。既存のログ形式、アクセス制御、レート制限ルールを変更せずに機能させるために、コネクションレイヤーの変数 (
$remote_addrなど) を実際のクライアント IP に置き換えたい場合は、「コネクションレイヤーアドレスのクライアント IP への置換 (Nginx および Apache)」をご参照ください。
Nginx サーバー
環境例:CentOS 7.9 と Nginx 1.20.1。ご使用の構成とは異なる場合があります。
nginx -V | grep http_realip_moduleを実行して、http_realip_module がインストールされているかどうかを確認します。Nginx はこのモジュールを使用して X-Forwarded-For レコードを解析します。出力に
--with-http_realip_moduleが含まれている場合、モジュールはインストールされています。次のステップに進みます。http_realip_module は Nginx 1.0.4 (2011) 以降で利用可能です。古いバージョンを使用している場合は、設定をバックアップして Nginx をアップグレードしてください。
http_realip_module がインストールされていない場合は、モジュールを付けて Nginx を再コンパイルするか、yum などのパッケージマネージャーを使用して Nginx を再インストールしてください。
Nginx の設定ファイルを編集します。
nginx -tを実行してファイルパスを確認します。デフォルトは/etc/nginx/nginx.confです。http { # log_format に $http_x_forwarded_for が含まれていることを確認します。この変数は、X-Forwarded-For の値を記録します。 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # ... }sudo nginx -s reloadコマンドを実行して、Nginx の設定をリロードします。
Apache サーバー
環境例:CentOS 7.9 と Apache 2.4.6。ご使用の構成とは異なる場合があります。
httpd -M | grep remoteip_moduleを実行して、remoteip_module がインストールされているかどうかを確認します。Apache はこのモジュールを使用して X-Forwarded-For レコードを解析します。出力に
remoteip_module (shared)が含まれている場合、モジュールはインストールされています。次のステップに進みます。remoteip_module は Apache 2.4.0 (2012) 以降で利用可能です。古いバージョンを使用している場合は、設定をバックアップして Apache をアップグレードしてください。
remoteip_module がインストールされていない場合は、モジュールを付けて Apache を再コンパイルするか、yum などのパッケージマネージャーを使用して Apache を再インストールしてください。
Apache の設定ファイルを編集します。デフォルトパスは
/etc/httpd/conf/httpd.confです。# ... <IfModule log_config_module> # X-Forwarded-For 情報を記録するために %{X-Forwarded-For}i を追加します。 LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b" common #... </IfModule> # ...sudo systemctl restart httpdコマンドを実行して、Apache サービスを再起動します。
IIS サーバー
環境例:Windows Server 2016。ご使用の構成とは異なる場合があります。
「F5XForwardedFor ファイル」をダウンロードして解凍します。
OS のアーキテクチャに基づいて、
F5XFFHttpModule.dllとF5XFFHttpModule.iniをx86\またはx64\ディレクトリから IIS の読み取り権限がある場所にコピーします。[サーバー マネージャー] で、[IIS マネージャー] を開きます。
サーバーを選択し、[モジュール] をダブルクリックします。

[ネイティブ モジュールの構成] をクリックし、次に [登録] をクリックします。

ダウンロードした .dll ファイルを追加します。
ファイル名を入力し、パスを選択して [OK] をクリックします。

新しく登録されたモジュールが自動的に選択されます。[OK] をクリックします。

サーバーのホームページに戻り、[ログ記録] モジュールをダブルクリックします。
X-Forwarded-Forフィールドを記録するようにログ形式を設定します。[フィールドの選択] をクリックします。

左下隅にある [フィールドの追加] をクリックし、ログフィールドを追加して、[OK] をクリックします。

右上隅にある [適用] をクリックして変更を保存します。
IIS サーバーを再起動して設定を有効にします。
ステップ 3:クライアント IP 取得の確認
サーバーの種類に応じて手順に従います。
Nginx サーバー
Nginx のアクセスログを調べて、クライアント IP の取得を確認します。
Nginx アクセスログのデフォルトパスは /var/log/nginx/access.log です。
$http_x_forwarded_for フィールドの左端の IP がクライアント IP アドレスです。

Apache サーバー
Apache のアクセスログを調べて、クライアント IP の取得を確認します。
Apache アクセスログのデフォルトパスは /var/log/httpd/access_log です。
%{X-Forwarded-For}i フィールドの左端の IP がクライアント IP アドレスです。

IIS サーバー
IIS ログを調べて、クライアント IP の取得を確認します。
ログファイルのパスはログ記録モジュールで確認します。

X-Forwarded-For フィールドの左端の IP がクライアント IP アドレスです。

よくある質問
100 で始まる IP からの頻繁なアクセス
ロードバランシングシステムは、外部リクエストをバックエンドの ECS インスタンスに転送し、ヘルスチェックを実行します。これらのリクエストはどちらもシステムから発信されます。
ロードバランシングシステムは、予約済みの CIDR ブロック 100.64.0.0/10 を使用します。このブロックは Alibaba Cloud 専用であり、セキュリティリスクはありませんが、100 で始まる IP からの頻繁なアクセスの原因となります。
サーバー上の iptables やその他のセキュリティソフトウェアがこの CIDR ブロックをブロックしないようにしてください。
WAF、CDN、GA を使用したクライアント IP の取得
トラフィックが WAF、CDN、または Global Accelerator (GA) を経由して CLB に到達する場合でも、X-Forwarded-For を使用してクライアント IP を取得できます。これらのサービスは、追加設定なしでデフォルトで X-Forwarded-For を通過します。
X-Forwarded-For のなりすましを防ぐには、カスタムヘッダーを使用してクライアント IP を記録します。たとえば、クライアント > CDN > WAF > CLB > ECS アーキテクチャでは、CDN は Ali-Cdn-Real-Ip ヘッダーを渡すことができます。WAF で、クライアント IP 判定方法として「ヘッダーフィールドの指定」を選択し、ヘッダーを Ali-Cdn-Real-Ip に設定します。Nginx のログ変数を $http_Ali_Cdn_Real_Ip に設定します。
追加のセキュリティ対策:
バックエンドサーバーで XFF ヘッダーを検証およびフィルタリングします。形式と IP アドレスを確認し、無効または不審な値を拒否します。
CLB とバックエンドサーバーの間にファイアウォールと ACL を使用して、XFF ヘッダーを標的とする悪意のあるリクエストをフィルタリングします。
SSL/TLS 暗号化を使用して、XFF ヘッダーの送信を含む通信を中間者攻撃から保護します。
ACK 環境でのクライアント IP の取得
Container Service for Kubernetes (ACK) クラスターでは、方法は同じですが、一部の操作の詳細が異なります。詳細については、「ネットワーク管理に関する FAQ」をご参照ください。
コネクションレイヤーアドレスのクライアント IP への置換 (Nginx および Apache)
Nginx
デフォルトでは、Nginx ログの $remote_addr は CLB の内部転送 IP (100.64.0.0/10 範囲) を記録します。これを実際のクライアント IP に置き換えて、既存のログ形式、アクセス制御、レート制限ルールを変更なしで機能させるには、ngx_http_realip_module モジュールを使用します。
nginx -V | grep http_realip_moduleを実行して、モジュールがインストールされていることを確認します。設定ファイル (デフォルト:
/etc/nginx/nginx.conf) のhttpブロックに以下を追加します:set_real_ip_from 100.64.0.0/10; real_ip_header X-Forwarded-For; real_ip_recursive on;sudo nginx -tを実行して設定を検証し、次にsudo nginx -s reloadを実行してリロードします。
設定が有効になった後、アクセスログ (デフォルト:/var/log/nginx/access.log) を確認して、$remote_addrが実際のクライアント IP を表示していることを確認します。
WAF や CDN などの複数のプロキシをトラフィックが通過する場合は、各プロキシレイヤーの送信元 IP 範囲を set_real_ip_from に追加します。ヘルスチェックリクエスト (HEAD、X-Forwarded-Forなし) は、引き続き$remote_addrを100.64.0.0/10として表示しますが、これは想定どおりの動作です。
Apache
デフォルトでは、Apache ログの %h は CLB の内部転送 IP を記録します。これを実際のクライアント IP に置き換えて、既存のログ形式と Require ip アクセス制御ルールを変更なしで機能させるには、Apache 2.4 の組み込み mod_remoteip モジュールを使用します。
httpd -M | grep remoteip_moduleを実行して、モジュールがインストールされていることを確認します。設定ファイル (デフォルト:
/etc/httpd/conf/httpd.conf) に以下を追加します:RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 100.64.0.0/10sudo systemctl restart httpdを実行して、Apache サービスを再起動します。
設定が有効になった後、アクセスログ (デフォルト:/var/log/httpd/access_log) を確認して、%hが実際のクライアント IP を表示していることを確認します。
WAF や CDN などの複数のプロキシをトラフィックが通過する場合は、各プロキシレイヤーの送信元 IP 範囲を RemoteIPTrustedProxy に追加します。ヘルスチェックリクエスト (HEAD、X-Forwarded-Forなし) は、引き続き%hを100.64.0.0/10として表示しますが、これは想定どおりの動作です。
関連ドキュメント
他のタイプのロードバランサーでは、異なる方法を使用します。
Application Load Balancer (ALB):X-Forwarded-For を使用します。詳細については、「ALB を使用したクライアント IP アドレスの取得」をご参照ください。
Network Load Balancer (NLB):サーバーグループまたは PROXY プロトコルを使用します。詳細については、「NLB を使用したクライアント IP アドレスの取得」をご参照ください。
CLB レイヤー 4 リスナー:直接取得するか、PROXY プロトコルを使用します。詳細については、「CLB レイヤー 4 リスナーを使用したクライアント IP アドレスの取得」をご参照ください。