Haproxy の背後にある PHP で外部 IP を取得する

Haproxy の背後にある PHP で外部 IP を取得する

Haproxy を使用して、同じマシン上で Websocket サーバーと Lighttpd Web サーバーを実行できるようにしています。Lighttpd サーバーで実行されている Web アプリケーションからマシンの外部 IP アドレスを取得したいと考えています。

haproxy なしでは、これは機能します:

PHP の

<?php
    $myip = $_SERVER['SERVER_ADDR'];
    $myurl = 'http://'.$myip.'/pathToProject/';
    define('URL', $myurl);
?>

しかし、プロキシの背後には$_SERVER['サーバーアドレス'];127.0.0.1 を返しますが、これは私が使用している PHP フレームワークでは動作しません。

プロキシ設定

global
    maxconn     4096
    nbproc      1

defaults
    mode        http

frontend all 0.0.0.0:80
    timeout client 86400000
    default_backend www_backend
    acl is_websocket hdr(Upgrade) -i WebSocket
    acl is_websocket hdr_beg(Host) -i ws
    use_backend socket_backend if is_websocket

backend www_backend
    balance roundrobin
    option forwardfor
    timeout server 30000
    timeout connect 4000
    server apiserver 127.0.0.1:8080 weight 1 maxconn 1024 check

backend socket_backend
    balance roundrobin
    option forwardfor
    timeout queue 5000
    timeout server 86400000
    timeout connect 86400000
    server apiserver 127.0.0.1:8082 weight 1 maxconn 1024 check

答え1

"option forwardfor"HAproxy が訪問者の実際の IP アドレスを含む新しいヘッダーを追加するように、HAproxy 構成ファイルにオプションを追加する必要があります。

その後、PHPコードで、REMOTE_ADDRの代わりにHTTP_X_FORWARDED_FORヘッダーをチェックします。

foreach (getallheaders() as $name => $value) {
    echo "$name: $value<br>\n";
}

完全な詳細な回答は、こちらでご覧いただけます:haproxy とクライアント IP アドレスをサーバーに転送する

答え2

理論的には、これはまさに次のようにして解決できる。

    option originalto

フロントエンドでは、ドキュメント

アプリケーションは X-Original-To ヘッダーに依存する必要があります。

答え3

ありがとう、うまくいきました....

1) ファイルを編集する ナノ /etc/haproxy/haproxy.cfgそこに追加します

    defaults
      mode http
      option forwardfor 

2) PHPでは

      <?php 
      echo '<pre>'; print_r(getallheaders()); echo '</pre>';


      // PROBLEM IS each browser has different "x-forwarder-for" some "X-Forwarder-for" and some browser gave you 2x ip "x.x.x.x, x.x.x.x"
      foreach ( getallheaders() as $k => $v) {
        if ( strtolower($k) == 'x-forwarded-for' ) {
          $tmp = explode(', ', $v);
          if ( $tmp[count($tmp)-1] != '' )
             $_SERVER['REMOTE_ADDR'] = $tmp[count($tmp)-1];     
        }
      }


      echo $_SERVER['REMOTE_ADDR'];
      ?>

3) IPアドレスを確認できます

答え4

これが私が解決した方法です (Linux でのみ動作します):

$myip = shell_exec("ifconfig eth0 | awk '/inet / {print$2}' | cut -d: -f2");
$myurl = 'http://'.$myip.'/page/';
define('URL', $myurl);

関連情報