CLB のレイヤー 7 リスナーを使用する場合、X-Forwarded-For HTTP ヘッダーからクライアント IP アドレスを取得します。
仕組み
Classic Load Balancer (CLB) のレイヤー 7 リスナー (HTTP/HTTPS) は、X-Forwarded-For HTTP ヘッダーにクライアント IP アドレスを保持します。バックエンドサーバーは設定後にこの IP を取得できます。
X-Forwarded-For フィールドの形式は次のとおりです。
X-Forwarded-For: <client IP address, proxy-server-1-IP, proxy-server-2-IP, ...>
この方法を使用する場合、リストの左端の IP アドレスがクライアント IP アドレスです。
CLB は HTTPS 通信を終端し、HTTP 経由でバックエンドサーバーと通信します。HTTPS リスナーを使用する場合でも、バックエンドサーバーは HTTP のみで設定してください。
操作手順
前提条件
-
レイヤー 7 リスナーを持つ CLB インスタンスが作成されている必要があります。詳細については、「CLB インスタンスの作成と管理」および「HTTP リスナーの追加」をご参照ください。このトピックでは、例としてポート 80 の HTTP リスナーを使用します。
-
バックエンドサーバーを持つサーバーグループが CLB インスタンスに追加されている必要があります。詳細については、「vServer グループの作成と管理」をご参照ください。このトピックでは、例として HTTP プロトコルを使用し、ECS インスタンスとポート 80 を持つ 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が含まれている場合、モジュールはインストール済みです。次のステップに進んでください。ngx_http_realip_moduleは Nginx 1.0.4 (2011年) 以降で利用可能です。古いバージョンを使用している場合は、設定をバックアップしてから Nginx をアップグレードしてください。ngx_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}i を追加して X-Forwarded-For 情報を記録します。 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 アーキテクチャに基づいて、
x86\またはx64\ディレクトリからF5XFFHttpModule.dllとF5XFFHttpModule.iniを 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 からの頻繁なアクセス
CLB システムは、外部リクエストをバックエンドの ECS インスタンスに転送し、ヘルスチェックを実行します。これらのリクエストはどちらもシステムから発信されます。
CLB システムは予約済みの CIDR ブロック 100.64.0.0/10 を使用します。このブロックは Alibaba Cloud 専用であり、セキュリティリスクをもたらすものではありませんが、100 で始まる IP からの頻繁なアクセスはこのためです。
サーバー上の iptables やその他のセキュリティソフトウェアがこの CIDR ブロックをブロックしないようにしてください。
WAF、CDN、GA を使用したクライアント IP の取得
トラフィックが CLB に到達する前に WAF、CDN、または Global Accelerator (GA) を通過する場合でも、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」をご参照ください。
レイヤー 4 とレイヤー 7 リスナー:ソース IP の動作
クライアントリクエストが CLB を通過する際、バックエンドサーバーから見えるソース IP はリスナーのタイプによって異なります。
|
リスナータイプ |
ソース IP の処理 |
|
|
レイヤー 4 (TCP/UDP) |
CLB はクライアントのソース IP を直接転送します |
クライアントの送信元 IP アドレス |
|
レイヤー 7 (HTTP/HTTPS) |
CLB はリバースプロキシとして機能し、バックエンドサーバーとの間に新しい TCP 接続を確立します |
CLB 内部の転送 IP (100.64.0.0/10 の範囲) |
レイヤー 7 リスナーでは、CLB はクライアントの送信元 IP アドレスを伝達するために、X-Forwarded-For HTTP リクエストヘッダーを自動的に追加します。 Nginx アクセスログの $remote_addr にクライアント IP の代わりに 100.64.0.0/10 範囲の CLB 内部転送 IP が表示される場合、これは仕様通りの動作です。
コネクションレイヤーのアドレスをクライアント 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 に追加します。
X-Forwarded-Forを含まない HEAD ヘルスチェックリクエストの場合、$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/10 -
sudo 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 Protocol を使用します。詳細については、「NLB を使用したクライアント IP アドレスの取得」をご参照ください。
-
CLB レイヤー 4 リスナー:直接取得するか、Proxy Protocol を使用します。詳細については、「CLB レイヤー 4 リスナーを使用したクライアント IP アドレスの取得」をご参照ください。