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 ]などのサードパーティのロードバランサーを使用する場合も、同様のアプローチを使用できます。
文学
- OSIネットワークモデルアプリケーション層プロトコル -ja.wikipedia.org
- ngx_http_realip_module モジュール -nginx.org
- OSIネットワークトランスポート層 -wikipedia.org
- PROXYプロトコル -haproxy.org
- HAProxy設定マニュアル: send-proxy-cbonte.github.io
- ngx_http_core_module モジュール:listenディレクティブ -nginx.org
- CloudFlare、Nginx、およびVarnishを使用して実際のIPアドレスを取得する -danielmiessler.com
- NginxとCloudFlareを使用して実際のIPアドレスを取得する -babaei.net
- Nginxでプロキシプロトコルを使用する -chrislea.com
- AWS Elastic Load Balancing-aws.amazon.com