2016-03-26 11 views
1

私のnodejsサーバーの要求オブジェクトからクライアントのIPアドレスを取得しようとしています。haproxy docker container内のリクエストからクライアントIPを取得する方法は?

私の技術構造は次のとおりです。 私は2つのドッカーコンテナを実行しています。 1つはhaproxyであり、他のものはnodejsであり、expressjsフレームワークを使用します。すべての着信トラフィックは、プロキシとロードバランシングに使用するhaproxyによって最初に受信されます。 Haproxyは、構成ファイル内のACLsに基づいて、要求を適切なバックエンドに転送します。

私のnodejs内のx-forwarded-forリクエストヘッダーにアクセスしようとしましたが、ドッカーネットワークゲートウェイインターフェイス172.17.0.1のIPだけが返されました。

haproxy構成に向かい、defaultsブロック内のoption forwardfor header X-Client-IPを使用すると、x-client-ipヘッダーをドッキングネットワークゲートウェイインターフェイスipに設定します。また、デバッグログも同じIPを記録しています。

これは問題です。 haproxyはコンテナ内で実行されているため、ドッカーネットワークゲートウェイインターフェイスがクライアントであると考えています。

実際のクライアントのIPをコンテナ内のhaproxyに取得すると、nodejsに転送できるようになりますか?

これは私のhaproxy設定ファイルです:

global 
    debug 
    maxconn 4096 

defaults 
    mode http 
    timeout connect 5000ms 
    timeout client 50000ms 
    timeout server 50000ms 
    timeout http-keep-alive 50000ms 
    option http-keep-alive 
    option http-server-close 
    option forwardfor header X-Client-IP 

frontend http-in 
    bind *:80 
    acl is_api hdr_end(host) -i api.3dphy-dev.com 

    use_backend api if is_api 

    default_backend default 

backend default 
    server s0 "${DOCKER_INTERFACE_IP}:3000" 

backend api 
    balance leastconn 
    option httpclose 
    option forwardfor 
    server s1 "${DOCKER_INTERFACE_IP}:17884" 

私が使用して私のhaproxyコンテナを実行します。

docker run -d --name haproxy_1 -p 80:80 -e DOCKER_INTERFACE_IP=`ifconfig docker0 | grep -oP 'inet addr:\K\S+'` -v $(pwd)/config/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy:1.6 

注:私は任意のファイアウォールを使用していません。また、私の設定の改善を提案することも自由です。キープ・アライブも問題であることが証明されています。

+0

私はこの作業に時間を費やします。私は恐怖を見てきました....下記の答えを見てください。私は動作していますhaproxy:1.6バージョンも、これはここで問題ではないでしょう。 – eljefedelrodeodeljefe

答えて

2

は、最後にドッキングウィンドウのフォーラムを通じて精練後の溶液を見つけることができました。

解決策は2段階プロセスです。

global 
    debug 
    maxconn 4096 

defaults 
    mode http 
    timeout connect 5000ms 
    timeout client 50000ms 
    timeout server 50000ms 
    timeout http-keep-alive 50000ms 
    option http-keep-alive 
    option http-server-close 

frontend http-in 
    bind *:80 
    option forwardfor 
    acl is_site hdr_end(host) -i surenderthakran-dev.com 

    use_backend site if is_site 

    default_backend default 

backend default 
    server s0 "${DOCKER_INTERFACE_IP}:3000" 

backend site 
    balance leastconn 
    option httpclose 
    option forwardfor 
    server s1 "${DOCKER_INTERFACE_IP}:17884" 

お知らせfrontend http-inブロック内option forwardforの追加を:

は、最初に私はこれに私の haproxy設定を更新する必要がありました。これは、haproxyのフロントエンド部分に、クライアントIPをリクエストヘッダーに追加するよう指示します。

docker run -d --name haproxy_1 -p 80:80 -e DOCKER_INTERFACE_IP=`ifconfig docker0 | grep -oP 'inet addr:\K\S+'` -v $(pwd)/config/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro --net=host haproxy:1.6 

お知らせドッカrunコマンドで--net=hostオプションの追加:

第二に、ドッキングウィンドウrunコマンドをに更新する必要があります。これは、新しいコンテナを起動し、ホストと同じネットワークカードを使用するようにドッカーに指示します。

元のクライアントIPが要求ヘッダーに追加され、要求が転送されるすべてのアプリケーションのx-forwarded-for要求ヘッダーでアクセスできます。

0

これは、アドレスを完全に解決する必要があるため、起動時にホストに接続していないときに投げつけるので、haproxyの動作は不可能です。私は多くの回避策を試みましたが(おそらくそれは可能かもしれません)、私はあきらめて実行しましたdocker-compose

私は以前の投稿に役立つ実行例を投稿しました。

実際に既に存在するホストにコンテナをリンクすることです。これはドッカーのリンクによって行われます。

ドッキングウィンドウ-compose.yml

api1: 
    build: . 
    dockerfile: ./Dockerfile 
    ports: 
    - 3955 
    links: 
    - mongo 
    - redis 
    environment: 
    - REDIS_HOST=redis 
    - MONGO_HOST=mongo 
    - IS_TEST=true 
    command: "node app.js" 

api2: 
    build: . 
    dockerfile: ./Dockerfile 
    ports: 
    - 3955 
    links: 
    - mongo 
    - redis 
    environment: 
    - REDIS_HOST=redis 
    - MONGO_HOST=mongo 
    - IS_TEST=true 
    command: "node app.js" 

mongo: 
    image: mongo 
    ports: 
    - "27017:27017" 
    command: "--smallfiles --logpath=/dev/null" 

redis: 
    image: redis 
    ports: 
    - "6379:6379" 

haproxy: 
    image: haproxy:1.5 
    volumes: 
    - ./cluster:/usr/local/etc/haproxy/ 
    links: 
    - "api1" 
    - "api2" 
    ports: 
    - 80:80 
    - 70:70 
    expose: 
    - "80" 
    - "70" 

haproxy.cfg

global 
    log 127.0.0.1 local0 
    log 127.0.0.1 local1 notice 

defaults 
    log global 
    mode http 
    option httplog 
    option dontlognull 
    timeout connect 5000 
    timeout client 10000 
    timeout server 10000 

listen stats :70 
    stats enable 
    stats uri/

frontend balancer 
    bind 0.0.0.0:80 
    mode http 
    default_backend aj_backends 

backend aj_backends 
    mode http 
    balance roundrobin 
    option forwardfor 
    http-request set-header X-Forwarded-Port %[dst_port] 
    http-request add-header X-Forwarded-Proto https if { ssl_fc } 
    option httpchk HEAD/HTTP/1.1\r\nHost:localhost 
    default-server inter 3s fall 5 
    server api1 api1:3955 
    server api2 api2:3955 
関連する問題