- PVSM.RU - https://www.pvsm.ru -
Довольно часто требуется балансировать нагрузку между несколькими веб-серверами. При этом, как правило, необходимо, чтобы веб-приложения получали реальные IP-адреса клиентов, а не IP балансировщика.
В случае балансировки и терминации HTTP(S)-трафика на HAProxy (Layer 7 [1 [1]]) данная задача легко решается добавлением заголовка “X-Real-IP” и его обработкой на Nginx при помощи модуля ngx_http_realip_module [2 [2]]. При балансировке TCP-трафика от HTTPS-клиентов и передаче его на веб-сервера напрямую без модификации или терминации (Layer 4 [3 [3]]) добавить данный заголовок невозможно, поэтому требуется воспользоваться возможностями, предоставляемыми Proxy Protocol [4 [4], 5 [5], 6 [6]].
Рассмотрим оба варианта (балансировка L7 и L4) на примере выдержек из конфигурационных файлов haproxy 1.5.9 и nginx 1.6.2
В данном примере HTTPS-трафик от клиента терминируется на HAProxy, модифицируется и передается на Nginx так же по HTTPS.
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
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;
}
}
В данном примере HTTPS-трафик клиентов не модифицируется (HAProxy вмешивается в транспортный уровень) и его терминация происходит непосредственно на Nginx.
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
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;
}
}
Используя описанные выше настройки мы смогли передать веб-серверу Nginx, расположенному за HAProxy, реальные IP-адреса клиентов при работе по HTTPS. Подобным подходом так же можно воспользоваться при работе со сторонними балансировщиками нагрузки, например CloudFlare [7 [7], 8 [8]] и AWS ELB [9 [9], 10 [10]].
Автор: foboss
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/nginx/78645
Ссылки в тексте:
[1] 1: https://ru.wikipedia.org/wiki/Протоколы_прикладного_уровня
[2] 2: http://nginx.org/ru/docs/http/ngx_http_realip_module.html
[3] 3: https://ru.wikipedia.org/wiki/Транспортный_уровень
[4] 4: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
[5] 5: http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#send-proxy
[6] 6: http://nginx.org/ru/docs/http/ngx_http_core_module.html#listen
[7] 7: https://danielmiessler.com/getting-real-ip-addresses-using-cloudflare-nginx-and-varnish/
[8] 8: http://www.babaei.net/blog/2013/03/09/getting-real-ip-addresses-using-nginx-and-cloudflare/
[9] 9: https://chrislea.com/2014/03/20/using-proxy-protocol-nginx/
[10] 10: http://aws.amazon.com/elasticloadbalancing/
[11] Источник: http://habrahabr.ru/post/247297/
Нажмите здесь для печати.