X-Forwarded-For

X-Forwarded-For 經常被使用於經過 NAT 或 Proxy 時,由於其 Source IP 已被轉換,所以 Server 端通常都無法得知原始的 Client IP 為何,為了解決這樣的問題,於是有了 X-Forwarded-For,於 HTTP 的 Request Header 中插入此變數,而其值就是真正的 Client IP,像最常見的 Squid 或目前市面上常見的 Server Load Balance (wiki 中有列出許多具有此功能的 Vendor)皆具有這樣的功能。

PHP sample

這邊的邏輯就是…如果 HTTP_X_FORWARDED_FOR 有值,那就代表 REMOTE_ADDR 這變數中的 IP 是 Proxy IP,而 X_FORWARDED_FOR 為 Client IP;如果 X_FORWARDED_FOR 為空則 REMOTE_ADDR 即為 Client IP。

// This is another way to get X-Forwarded-For value.
// $real_client_ip = $headers["X-Forwarded-For"];
 
  if( getenv('HTTP_X_FORWARDED_FOR') != '' )
  {
    $proxy_ip = (!empty($HTTP_SERVER_VARS['REMOTE_ADDR'])) ?
    $HTTP_SERVER_VARS['REMOTE_ADDR'] :
    ((!empty($HTTP_ENV_VARS['REMOTE_ADDR'])) ?
    $HTTP_ENV_VARS['REMOTE_ADDR'] : $REMOTE_ADDR);
    $client_ip = getenv('HTTP_X_FORWARDED_FOR');
  }
  else
  {
    $client_ip = (!empty($HTTP_SERVER_VARS['REMOTE_ADDR']))?
    $HTTP_SERVER_VARS['REMOTE_ADDR'] :
    ((!empty($HTTP_ENV_VARS['REMOTE_ADDR'])) ?
    $HTTP_ENV_VARS['REMOTE_ADDR'] : $REMOTE_ADDR);
    $proxy_ip = "";
  }