HTTPおよびTCPバランシングモードでHAProxy(フロントエンド)からNginx(バックエンド)にHTTPSクライアントのIPアドレスを取得します

多くの場合、複数のWebサーバー間で負荷を分散する必要があります。 この場合、原則として、WebアプリケーションはIPバランサーではなくクライアントの実際のIPアドレスを受信する必要があります。



HAProxy(レイヤー7 [ 1 ])でHTTP(S)トラフィックのバランスを取り、終了する場合、このタスクは「X-Real-IP」ヘッダーを追加し、ngx_http_realip_module [ 2 ]モジュールを使用してNginxで処理することで簡単に解決できます。 HTTPSクライアントからのTCPトラフィックのバランスを取り、変更または終了せずに直接Webサーバーに転送する場合(レイヤー4 [ 3 ])、このヘッダーの追加は不可能であるため、プロキシプロトコル[4、5、6]によって提供される機会を使用する必要があります。



例として設定ファイルhaproxy 1.5.9およびnginx 1.6.2からの抜粋を使用して、両方のオプション(L7とL4のバランス)を考えてみましょう。



アプリケーションレベルでの分散(レイヤー7):HAProxyでHTTPSトラフィックを終了し、HTTPS経由でNginxに送信する



この例では、クライアントからのHTTPSトラフィックはHAProxyで終端され、変更され、HTTPSを介してNginxにも送信されます。



haproxy.cfg



global maxconn 4096 chroot /usr/share/haproxy uid 99 gid 99 daemon tune.ssl.default-dh-param 2048 defaults log global option redispatch option tcp-smart-accept option tcp-smart-connect retries 3 maxconn 2000 timeout connect 5000 timeout check 3000 timeout client 50000 timeout server 50000 frontend http_frontend *:80 mode http redirect scheme https code 301 if !{ ssl_fc } frontend https_frontend_ssl_terminate mode http bind *:443 ssl crt /etc/haproxy/ssl/public.example.com.pem option forwardfor header X-Real-IP default_backend web_server_http backend web_server_http mode http balance roundrobin #    backend  HTTPS server s1_https 192.168.1.10:443 ssl verify none server s2_https 192.168.1.20:443 ssl verify none
      
      







nginx.conf



 server { server_name localhost; listen 443 ssl default_server; ssl_certificate /etc/nginx/ssl/internal.example.com.pem; ssl_certificate_key /etc/nginx/ssl/internal.example.com.key; #  HAProxy set_real_ip_from 192.168.1.254; real_ip_header X-Real-IP; root /usr/share/nginx/html; index index.html index.htm; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ /\.ht { deny all; } }
      
      







トランスポートレベルバランシング(レイヤー4):HAProxyからNginxへのTCPトラフィックの転送



この例では、クライアントのHTTPSトラフィックは変更されず(HAProxyはトランスポートレイヤーに干渉します)、その終了はNginxで直接発生します。



haproxy.cfg



 global maxconn 4096 chroot /usr/share/haproxy uid 99 gid 99 daemon defaults log global option redispatch option tcp-smart-accept option tcp-smart-connect retries 3 maxconn 2000 timeout connect 5000 timeout check 3000 timeout client 50000 timeout server 50000 frontend http_frontend *:80 mode http redirect scheme https code 301 if !{ ssl_fc } frontend https_frontend_ssl_pass mode tcp bind *:443 default_backend web_server_tcp backend web_server_tcp mode tcp balance roundrobin # !   send-proxy  , #    ,   . #  Nginx     listen #  proxy_protocol. server s1_tcp 192.168.1.10:443 send-proxy server s2_tcp 192.168.1.20:443 send-proxy
      
      







nginx.conf



 server { server_name localhost; # !    proxy_protocol      haproxy. #       . listen 443 ssl default_server proxy_protocol; ssl_certificate /etc/nginx/ssl/public.example.com.pem; ssl_certificate_key /etc/nginx/ssl/public.example.com.key; #  HAProxy set_real_ip_from 192.168.1.254; real_ip_header proxy_protocol; root /usr/share/nginx/html; index index.html index.htm; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ /\.ht { deny all; } }
      
      







おわりに



上記の設定を使用して、HTTPS経由で作業するときにクライアントの実際のIPアドレスをHAProxyの背後にあるNginx Webサーバーに転送することができました。 CloudFlare [ 7、8 ]やAWS ELB [ 9、10 ]などのサードパーティのロードバランサーを使用する場合も、同様のアプローチを使用できます。



文学



  1. OSIネットワークモデルアプリケーション層プロトコル -ja.wikipedia.org
  2. ngx_http_realip_module モジュール -nginx.org
  3. OSIネットワークトランスポート層 -wikipedia.org
  4. PROXYプロトコル -haproxy.org
  5. HAProxy設定マニュアル: send-proxy-cbonte.github.io
  6. ngx_http_core_module モジュール:listenディレクティブ -nginx.org
  7. CloudFlare、Nginx、およびVarnishを使用して実際のIPアドレスを取得する -danielmiessler.com
  8. NginxとCloudFlareを使用して実際のIPアドレスを取得する -babaei.net
  9. Nginxでプロキシプロトコルを使用する -chrislea.com
  10. AWS Elastic Load Balancing-aws.amazon.com



All Articles