Closed5

Apache+PHPにおけるアクセス元IPの制御

dehio3dehio3
  • $_SERVER['REMOTE_ADDR'] は常に直接接続してきたクライアントのIPアドレス(CloudFrontやプロキシサーバーなどを含む)を返し、X-Forwarded-For の値はデフォルトでは使用されません
  • X-Forwarded-For は、プロキシやロードバランサーを経由した際に、元のクライアントのIPアドレスを伝えるために使用されるHTTPヘッダー
  • remoteip_module は、リクエストのIPアドレスをリバースプロキシやロードバランサーの後ろにあるクライアントの実際のIPアドレスに書き換えるためのApacheモジュール
  • RemoteIPHeader X-Forwarded-Forディレクティブは、X-Forwarded-For ヘッダーの値を使用して、リクエスト元のIPアドレスを上書きすることを指定
dehio3dehio3

AWS PrivateLink → NLB → ALB → Nginx

https://dev.classmethod.jp/articles/pondering-source-ip-address-of-network-load-balancer/#%25E3%2582%25BF%25E3%2583%25BC%25E3%2582%25B2%25E3%2583%2583%25E3%2583%2588%25E3%2582%2592ALB%2520%25E3%2581%258B%25E3%2581%25A4%2520%25E3%2582%25AF%25E3%2583%25A9%25E3%2582%25A4%25E3%2582%25A2%25E3%2583%25B3%25E3%2583%2588IP%25E3%2582%25A2%25E3%2583%2589%25E3%2583%25AC%25E3%2582%25B9%25E3%2581%25AE%25E4%25BF%259D%25E6%258C%2581%25E3%2582%2592%25E6%259C%2589%25E5%258A%25B9

log_format main 'remote_addr - $remote_user [time_local] "request" $status $body_bytes_sent "http_referer" "http_user_agent" "http_x_forwarded_for"';

# 5. Consumer EC2 on Consumer VPCからConsumer VPC上のVPCエンドポイントにアクセス
10.10.0.36 - - [10/Jun/2022:07:52:49 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.79.1" "10.10.0.39"
or
10.10.0.57 - - [10/Jun/2022:07:53:02 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.79.1" "10.10.0.60"
  • remote_addrはALB IP Address
  • http_x_forwarded_forはNLB IP Address
dehio3dehio3

ALBのX-Forwarded-Forの扱い

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/x-forwarded-headers.html#x-forwarded-for

  • Application Load Balancer がターゲットにHTTPリクエストを送信する前に、リクエストの X-Forwarded-Forヘッダーを変更、保持、または削除できます。
  • デフォルトでは、Application Load Balancer は、クライアントの IP アドレスを X-Forwarded-For リクエストヘッダーに格納し、このヘッダーをサーバーに渡します。
  • X-Forwarded-For リクエストヘッダーがオリジナルリクエストに含まれていない場合、ロードバランサーはリクエスト値としてクライアント IP アドレスを持つリクエストヘッダーを作成します。
  • それ以外の場合、ロードバランサーはクライアント IP アドレスを既存のヘッダーに追加し、 ヘッダーをサーバーに渡します。X-Forwarded-For リクエストヘッダーには、カンマで区切られた複数の IP アドレスを含めることができます。
dehio3dehio3

mod_remoteip

https://httpd.apache.org/docs/current/mod/mod_remoteip.html

  • Apache はデフォルトでは接続の client_ip 値でユーザエージェントを識別し、 接続の remote_host と remote_logname はこの値から派生します。
  • mod_remoteip はリクエストの間、プロキシやロードバランサから提供された アドバタイズされたユーザエージェント IP で接続のクライアント IP を上書きします。
  • カンマで区切られた複数のユーザーエージェントIPアドレスがヘッダー値に リストされているときは、それらはRight-to-Leftの順番で処理されます。 与えられたユーザーエージェントIPアドレスが、先行するIPアドレスの提示 を信頼できない場合、処理は停止する。
  • ヘッダーフィールドは、この未確認のIPアドレスの残りのリストに更新され るか、すべてのIPアドレスが信頼された場合、このヘッダーはリクエストから 完全に取り除かれる。
    RemoteIPHeader X-Forwarded-For
  • mod_remoteip が指定されたヘッダフィールドヘッダの値を ユーザエージェント IP アドレス、または中間ユーザエージェント IP アドレスのリストとして 扱うようにします
  • 他のディレクティブが使用されない限り、 mod_remoteip は RemoteIPHeader の IP 値を提示するすべてのホストを信頼します
RemoteIPHeader X-Client-IP
RemoteIPInternalProxy 10.0.2.0/24 or RemoteIPInternalProxyList conf/trusted-proxies.lst
  • 一つ以上のアドレス (またはアドレスブロック) を、 ユーザエージェント IP の有効な RemoteIPHeader の値として信頼するように 追加します。
  • RemoteIPInternalProxy が設定されていない場合、mod_remoteip はプライベートIPアドレスを持つプロキシのX-Forwarded-For ヘッダーを無視します。
dehio3dehio3

RemoteIPHeaderがX-Forwarded-Forで置き換える順序

X-Forwarded-For ヘッダーに複数のIPアドレスが含まれている場合、RemoteIPHeader の設定によって $_SERVER['REMOTE_ADDR'] に置き換わるIPアドレスが決まります。X-Forwarded-For ヘッダーには通常、最も左にクライアントの実際のIPアドレスがあり、その後にプロキシを通過した順番でIPアドレスが追加されます。

X-Forwarded-For の構造

X-Forwarded-For ヘッダーに複数のIPアドレスがある場合、次のようになります:

X-Forwarded-For: clientIP, proxy1IP, proxy2IP, ...

ここで、clientIP がクライアントの実際のIPアドレス、proxy1IP が最初のプロキシのIPアドレス、proxy2IP が次のプロキシのIPアドレスという順番で記録されています。

RemoteIPHeader による置き換えの順番

Apacheの mod_remoteip が有効になっていて、RemoteIPHeaderX-Forwarded-For に設定されている場合、以下の順番で処理が行われます。

  1. 最初のIP(左端)から順に処理:

    • RemoteIPHeader に設定された X-Forwarded-For ヘッダーのIPアドレスは、最初に出現するIP(最も左側のIP)から順に処理されます。
    • Apacheはこのヘッダーを左から右に読み込み、最初に有効で信頼できるIPアドレスを $_SERVER['REMOTE_ADDR'] に設定します。
  2. 信頼されたプロキシが設定されている場合:

    • RemoteIPInternalProxy または RemoteIPInternalProxyList が設定されている場合、これらの信頼できるプロキシのIPアドレスを認識し、信頼できるプロキシを通過した後の最初のIPアドレス(つまり、クライアントのIPアドレス)を $_SERVER['REMOTE_ADDR'] に設定します。
  3. 信頼されていないプロキシがある場合:

    • 信頼されていないプロキシを通過したIPアドレスが存在する場合、その後ろのIPアドレスは無視されます。信頼されていないプロキシのIPが先に見つかった場合、そのIPが $_SERVER['REMOTE_ADDR'] に設定される可能性があります。

例えば、次のような X-Forwarded-For ヘッダーがあるとします。

X-Forwarded-For: 203.0.113.1, 198.51.100.1, 192.0.2.1
  • 203.0.113.1: クライアントのIP
  • 198.51.100.1: 最初のプロキシのIP
  • 192.0.2.1: 2番目のプロキシ(信頼されたプロキシとして設定)

信頼されたプロキシがある場合

もし RemoteIPInternalProxy 192.0.2.1 が設定されている場合、Apacheは X-Forwarded-For の最初のIPである 203.0.113.1 をクライアントのIPアドレスと見なし、$_SERVER['REMOTE_ADDR'] に設定します。

信頼されたプロキシがない場合

RemoteIPInternalProxy の設定がない場合、$_SERVER['REMOTE_ADDR'] は通常、最も右端(最新のプロキシ)のIPアドレスである 192.0.2.1 が設定されるか、信頼できると判断された最初のIP(198.51.100.1)が設定されることになります。

まとめ

  • X-Forwarded-For のIPアドレスは、左から右へ順番に処理されます。
  • RemoteIPInternalProxy が設定されている場合、信頼できるプロキシを通過した後の最初のIPアドレスが $_SERVER['REMOTE_ADDR'] に設定されます。
  • 信頼されていないプロキシのIPアドレスが見つかると、その後のIPアドレスは無視されるか、信頼されていないプロキシのIPが使用されることがあります。

これにより、正確なクライアントIPアドレスを取得するためには、適切に RemoteIPInternalProxy を設定することが非常に重要です。

このスクラップは2ヶ月前にクローズされました