LINUX.ORG.RU
ФорумAdmin

Проброс IP-адреса клиента на nginx через haproxy

 , ,


0

1

Добрый вечер, есть HAProxy в качестве балансера, который слушает порты 80 и 443 и направляет на разные бекенды на nginx'е.

При этом сайты на nginx, видят, что запрос пришел с IP-адреса балансера. И в логах только IP балансера.

Конфиг HAProxy:

 [root@140 ~]# cat /etc/haproxy/haproxy.cfg
global
  log         127.0.0.1 local2    
  chroot      /var/lib/haproxy    
  pidfile     /var/run/haproxy.pid
  maxconn     10000
  user        haproxy             
  group       haproxy
  daemon                          
  stats socket /var/lib/haproxy/stats
#---------------------------------------------------------
defaults
  mode     http   
  log      global  
  option   httplog   
  option   dontlognull
  option   http-server-close
  option   redispatch 
  retries  3 
  timeout http-request    10s
  timeout queue           1m
  timeout connect         10s        
  timeout client          1m
  timeout server          1m
  timeout http-keep-alive 10s
  timeout check           10s
  maxconn                 3000
#----------------------------------
# Конфигурация фронтенда http
#----------------------------------
frontend http_proxy
bind 192.168.1.140:80
option forwardfor header X-Real-IP
default_backend localhost

# 143.domen.ru
redirect scheme https code 301 if { hdr_end(host) -i 143.domen.ru } !{ ssl_fc }

# 180.domen.ru
acl 180.domen.ru hdr_dom(host) -i 180.domen.ru
use_backend 180.domen.ru if 180.domen.ru

#----------------------------------
# Конфигурация фронтенда https
#----------------------------------
frontend https-in
mode tcp
option tcplog
bind 192.168.1.140:443
option socket-stats
# option forwardfor header X-Real-IP
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
http-request add-header X-Forwarded-Proto https if { ssl_fc }

# 143.domen.ru
use_backend 143.domen.ru if { req_ssl_sni -i 143.domen.ru }

#----------------------------------
# Бекенды
#----------------------------------
backend localhost
server server1 127.0.0.1:8070

# 180.domen.ru
backend 180.domen.ru
server 180.domen.ru 192.168.1.180:80

# 143.domen.ru
backend 143.domen.ru
mode tcp
stick-table type binary len 32 size 30k expire 30m
acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
tcp-response content accept if serverhello
stick on payload_lv(43,1) if clienthello
stick store-response payload_lv(43,1) if serverhello
option ssl-hello-chk
server stn_container 192.168.1.143:443

Нашла, что проброс нужно делать опцией

 option forwardfor header X-Real-IP

Но она работает только в режиме mode http, а у меня ssl ходит по tcp, сертификаты хранятся на nginx, т.е. HAProxy получает шифрованный запрос, перенаправляет его на бекендный nginx, а nginx уже морочается с сертификатами.

Как тут приделать опцию, чтобы nginx знал ip клиента, а не HAProxy?

Ответ на: комментарий от Novell-ch

Спасибо за ответ!

В конфиге HAProxy прописала в бекенде:

# 143.domen.ru#
backend 143.domen.ru
mode tcp
stick-table type binary len 32 size 30k expire 30m
acl clienthello req_ssl_hello_type 1
acl serverhello rep_ssl_hello_type 2
tcp-request inspect-delay 5s
tcp-request content accept if clienthello
tcp-response content accept if serverhello
stick on payload_lv(43,1) if clienthello
stick store-response payload_lv(43,1) if serverhello
option ssl-hello-chk
server s1_tcp 192.168.1.143:443 send-proxy

В nginx на бекенде конфиг сайта привела к виду:

upstream 143.domen.ru.443 {
   server 192.168.1.143:8080;
   }

 server {
   listen 192.168.1.143:443;
   server_name 143.domen.ru;
   error_log /var/log/143.domen.ru443-error.log;
   access_log /var/log/143.domen.ru443-access.log;
  listen 443 ssl;
     ssl on;
     ssl_certificate /etc/letsencrypt/live/143.domen.ru/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/143.domen.ru/privkey.pem;
     ssl_session_cache shared:SSL:10m;
     ssl_session_timeout 10m;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_ciphers "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES$
     ssl_prefer_server_ciphers on;
     ssl_dhparam /etc/nginx/ssl/143.domen.ru/dhp-2048.pem;
#set_real_ip_from 192.168.1.140;
#    real_ip_header proxy_protocol;

location / {
      proxy_pass http://143.domen.ru.443;
      proxy_redirect off;
      proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    set_real_ip_from 192.168.1.140;
    real_ip_header proxy_protocol;
  }
}

При запросе сайта в браузере, ERR_SSL_PROTOCOL_ERROR... сайт не грузится.

В логе HAProxy:

Jan 31 18:57:23 localhost haproxy[5234]: 76.45.58.45:56215 [31/Jan/2018:18:57:23.228] https-in 143.domens.ru/s1_tcp 1/1/2 311 -- 1/1/0/0/0 0/0
manik207
() автор топика
Ответ на: Спасибо за ответ! от manik207

# ВНИМАНИЕ! Работа с директивой proxy_protocol возможна только в связке с haproxy.

# Для прямого доступа данную директиву необходимо отключить.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от vvn_black

Недавно раскуривал этот вопрос. Один из аргументов: гораздо более развитый функционал статистики искаропки

zolden ★★★★★
()
Ответ на: комментарий от zolden

thx, а то часто встречаю сабж в качестве revers proxy, хотя nginx привычнее.

vvn_black ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.