Application Load Balancer (ALB) がリクエストを転送する際、バックエンドサーバーに表示される送信元 IP アドレスは ALB インスタンスの IP アドレスです。ALB は、実際のクライアント IP を HTTP ヘッダーの X-Forwarded-For フィールドに追加できます。この IP は、バックエンドサーバーで簡単な設定を行うことで取得できます。
X-Forwarded-For フィールドの形式は次のとおりです:
X-Forwarded-For: <実際のクライアント IP, プロキシサーバー 1 の IP, プロキシサーバー 2 の IP, ...>手順
手順 1: リスナー設定の確認: X-Forwarded-For
ALB コンソールにログインし、対象インスタンスの ID をクリックして インスタンスの詳細 ページに移動します。
リスナー タブで、対象リスナーの ID をクリックします。リスナーの詳細 ページの 基本情報 セクションで、HTTP ヘッダーの追加 が
X-Forwarded-Forを含むように設定されていることを確認します。このオプションはデフォルトで有効になっています。有効になっていない場合は、基本情報 セクションの リスナーの変更 をクリックし、詳細設定 セクションで有効にしてください。
手順 2:バックエンドサーバーの設定
このトピックでは、バックエンドサーバーのアクセスログに (
X-Forwarded-Forフィールドを介して) 実際のクライアント IP を記録する方法について説明します。サーバーの接続層の変数 (Nginx の$remote_addrや Apache の%hなど) は、ALB の転送 IP (ローカル IP) に設定されたままで、影響を受けません。接続層の変数を実際のクライアント IP に直接置き換えたい場合 (これにより、これらの変数に基づく既存のロギング、アクセス制御、その他のルールが変更なしで機能するようになります) は、「Nginx または Apache による実際のクライアント IP の直接取得 (接続層アドレスの置換)」をご参照ください。
Nginx サーバー
このトピックでは、Alibaba Cloud Linux 3.2104 および nginx/1.20.1 を実行している Nginx サーバーを例に説明します。実際の設定は、お使いの環境によって異なる場合があります。
Nginx は http_realip_module モジュールを使用して X-Forwarded-For ヘッダーを解析し、実際のクライアント IP を取得します。
モジュールのインストールの確認:サーバーで
nginx -V 2>&1 | grep --color=auto http_realip_moduleコマンドを実行します。出力に--with-http_realip_moduleが含まれている場合、モジュールはインストールされています。
主要な Linux ディストリビューションでは、
yumやaptなどのパッケージマネージャーを介してインストールされた Nginx には、通常、このモジュールがデフォルトで含まれています。モジュールがインストールされていない場合は、パッケージマネージャーを使用して Nginx をインストールまたはアップグレードすることを推奨します。Nginx 設定ファイルの変更:
sudo nginx -tを実行して設定ファイルのパスを確認します。デフォルトのパスは通常/etc/nginx/nginx.confです。http { # X-Forwarded-For ヘッダーの値を記録するため、ログ形式に $http_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"'; # アクセスログで上記のログ形式を使用します。 access_log /var/log/nginx/access.log main; # ... }設定のリロード:
sudo nginx -tを実行して設定構文を確認します。構文が正しい場合は、sudo nginx -s reloadを実行して変更を適用します。
Apache サーバー
このトピックでは、Alibaba Cloud Linux 3.2104 および Apache/2.4.37 を実行している Apache サーバーを例に説明します。実際の設定は、お使いの環境によって異なる場合があります。
Apache は mod_remoteip モジュールを使用して X-Forwarded-For ヘッダーを解析し、実際のクライアント IP を取得します。
モジュールのインストールの確認:サーバーで
httpd -M | grep remoteip_moduleコマンドを実行します。出力にremoteip_module (shared)が含まれている場合、モジュールはインストールされています。
主要な Linux ディストリビューションでは、
yumやaptなどのパッケージマネージャーを介してインストールされた Apache には、通常、このモジュールがデフォルトで含まれています。モジュールがインストールされていない場合は、パッケージマネージャーを使用して Apache をインストールまたはアップグレードすることを推奨します。Apache 設定ファイルの変更:
httpd -Vを実行して設定ファイルのパスを確認します。デフォルトのパスは通常/etc/httpd/conf/httpd.confです。# ... <IfModule log_config_module> # ... # X-Forwarded-For ヘッダーの値を記録するため、ログ形式に %{X-Forwarded-For}i を含めます。 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{X-Forwarded-For}i" combined # ... # アクセスログで上記のログ形式を使用します。 CustomLog "logs/access_log" combined </IfModule> # ...設定のリロード:
sudo systemctl restart httpdを実行して変更を適用します。
IIS サーバー
このトピックでは、Windows Server 2022 21H2 および IIS 10.0 を実行している IIS サーバーを例に説明します。実際の設定は、お使いの環境によって異なる場合があります。
IIS マネージャーの [接続] ペインで、対象のサーバーを選択します。メインペインで、[ログ] をダブルクリックします。

[ログ ファイル] セクションで、[フィールドの選択] をクリックします。

[W3C ログ フィールド] ダイアログボックスで、[フィールドの追加] をクリックします。[カスタム フィールドの追加] ダイアログボックスで、フィールド情報を設定し、[OK] をクリックします。
[フィールド名]:
X-Forwarded-Forと入力します。[ソースの種類]:デフォルト値の
要求ヘッダーのままにします。[ソース]:
X-Forwarded-Forと入力します。

カスタムフィールドが追加されたことを確認し、[OK] をクリックします。

右側の [操作] ペインで、[適用] をクリックして変更を保存します。

手順 3:クライアント IP 取得の確認
バックエンドの Web サーバーのアクセスログをチェックして、実際のクライアント IP を取得できていることを確認します。
Nginx サーバー
Nginx アクセスログのデフォルトパスは /var/log/nginx/access.log です。
各ログエントリにおいて、$http_x_forwarded_for 変数の値が実際のクライアント IP です。

Apache サーバー
Apache アクセスログのデフォルトパスは /var/log/httpd/access_log です。
各ログエントリにおいて、%{X-Forwarded-For}i 変数の値が実際のクライアント IP です。

IIS サーバー
IIS アクセスログのデフォルトパスは %SystemDrive%\inetpub\logs\LogFiles です。
各ログエントリにおいて、最後の X-Forwarded-For フィールドの値が実際のクライアント IP です。

本番環境のベストプラクティス
X-Forwarded-For ヘッダーの検証とフィルタリング:バックエンドサーバーで、X-Forwarded-For ヘッダーを検証し、フィルタリングします。不正な形式のエントリや信頼できない IP アドレスを含むエントリは拒否します。
セキュリティポリシーの使用:ALB とバックエンドサーバー間でセキュリティグループやその他のサードパーティ製セキュリティポリシーを使用して、スプーフィングされた X-Forwarded-For ヘッダーを持つ悪意のあるリクエストを制限し、フィルタリングします。
TLS 暗号化:X-Forwarded-For ヘッダーの送信を含む、コンポーネント間の通信を保護するために TLS 暗号化を使用します。これにより、中間者攻撃やデータ改ざんのリスクが軽減されます。
よくある質問
100 から始まる IP からの頻繁なアクセス
アップグレード済みの ALB インスタンスは、関連付けられた vSwitch CIDR ブロックのプライベート IP アドレス (ローカル IP) を使用してバックエンドサーバーと通信します。
アップグレードされていない ALB インスタンスは、Alibaba Cloud によって予約されている
100.64.0.0/10アドレス範囲を使用してバックエンドサーバーと通信します。これにはセキュリティリスクはありません。
ALB は、バックエンドサーバーへのリクエスト転送に加えて、継続的なヘルスチェックも行います。アップグレードされていない ALB インスタンスを使用している場合、バックエンドサーバーのアクセスログには、100.64.0.0/10 範囲の IP アドレスからの多数のリクエストが記録されます。
ALB インスタンスとバックエンドサービス間の適切な接続を確保するために、バックエンドの Elastic Compute Service (ECS) インスタンス上の iptables またはその他のサードパーティ製セキュリティソフトウェアが、ALB インスタンスの vSwitch CIDR ブロックまたは 100.64.0.0/10 アドレス範囲をブロックしていないことを確認してください。
WAF、CDN、または GA を使用する場合のクライアント IP の取得
トラフィックが ALB に到達する前に Web Application Firewall (WAF)、Content Delivery Network (CDN)、または Global Accelerator (GA) などのサービスによって転送される場合でも、X-Forwarded-For フィールドから実際のクライアント IP を取得できます。これらの製品は、デフォルトでこのヘッダーを転送するため、追加の設定は不要です。
X-Forwarded-For のスプーフィングを防ぐために、他の HTTP ヘッダーを使用して実際のクライアント IP を記録できます:
Alibaba Cloud CDN の
Ali-Cdn-Real-Ipヘッダーを使用します。アーキテクチャは、クライアント > CDN > WAF > ALB > ECS です。デフォルトでは、CDN はオリジンサーバーに転送するリクエストに
Ali-Cdn-Real-Ip要求ヘッダーを追加します。このヘッダーは、CDN のポイントオブプレゼンス (POP) に接続したクライアントの実際の IP アドレスを渡します。WAF と統合する際は、クライアント IP 検出用のカスタムヘッダーとして
Ali-Cdn-Real-Ipを選択します。バックエンドの Nginx サーバーで
$http_ali_cdn_real_ipログ変数を設定して、このフィールドから実際のクライアント IP を取得します。
ALB リスナーの転送ルールの ヘッダーの挿入 アクションを使用して、リクエストに HTTP ヘッダー (キーと値のペア) を追加します。アーキテクチャは、クライアント > GA > ALB > ECS です。
ALB リスナーの転送ルールで、転送操作 を ヘッダーの挿入 に設定します。この例では、キーは
client-real-ipで、値は[システム定義]-[クライアント IP アドレス]に設定されています。リスナーで 実際のクライアントソース IP を見つける を有効にし、信頼できる IP アドレスリストにGA エンドポイントのパブリック出力 IP アドレスを追加します。
バックエンドの Nginx サーバーで
$http_client_real_ipログ変数を設定して、このフィールドから実際のクライアント IP を取得します。
ACK 環境でのクライアント IP の取得
詳細については、「AlbConfig を使用した ALB インスタンスの設定」をご参照ください。
Nginx または Apache による実際のクライアント IP の直接取得 (接続層アドレスの置換)
Nginx
デフォルトでは、Nginx ログの $remote_addr は ALB の転送 IP (ローカル IP) を記録します。これを実際のクライアント IP に置き換えるには (これにより、既存のロギングおよびアクセス制御ルールが変更なしで機能するようになります)、ngx_http_realip_module モジュールを使用します:
nginx -V 2>&1 | grep --color=auto http_realip_moduleを実行して、モジュールがインストールされていることを確認します。設定ファイル (デフォルト:
/etc/nginx/nginx.conf) のhttpブロックに以下を追加します:set_real_ip_from <インスタンスの vSwitch CIDR ブロック>; real_ip_header X-Forwarded-For; real_ip_recursive on;アップグレードされていない ALB インスタンスを使用する場合、
set_real_ip_fromを100.64.0.0/10に設定します。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ヘッダーが含まれないため、これらのリクエストに対する$remote_addrは、引き続き ALB インスタンスの vSwitch CIDR ブロック (またはアップグレードされていないインスタンスの場合は100.64.0.0/10) を表示します。これは想定される動作です。
Apache
デフォルトでは、Apache ログの %h は ALB の転送 IP (ローカル IP) を記録します。これを実際のクライアント IP に置き換えるには (これにより、既存のロギングおよび Require ip アクセス制御ルールが変更なしで機能するようになります)、Apache 2.4 に組み込まれている mod_remoteip モジュールを使用します:
httpd -M | grep remoteip_moduleを実行して、モジュールがインストールされていることを確認します。設定ファイル (デフォルト:
/etc/httpd/conf/httpd.conf) に以下を追加します:RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy <インスタンスの vSwitch CIDR ブロック>アップグレードされていない ALB インスタンスを使用する場合、
RemoteIPTrustedProxyを100.64.0.0/10に設定します。sudo systemctl restart httpdを実行して Apache を再起動します。
設定が有効になった後、アクセスログ (デフォルト:/var/log/httpd/access_log) を確認し、%hが実際のクライアント IP を表示するようになったことを確認します。
トラフィックが WAF や CDN などの複数のプロキシを通過する場合は、各プロキシレイヤーのオリジン IP 範囲を RemoteIPTrustedProxy に追加します。ヘルスチェックリクエストにはX-Forwarded-Forヘッダーが含まれないため、これらのリクエストに対する%hは、引き続き ALB インスタンスの vSwitch CIDR ブロック (またはアップグレードされていないインスタンスの場合は100.64.0.0/10) を表示します。これは想定される動作です。