Задать вопрос
@sevnet
Системный аналитик, бизнес-консультант

Как настроить HTTPS прокси сервер на одном IP, что backend сервера видели IP клиента?

Собственно задача такая.
Есть один IP адрес, на нем висит 7 доменных имен, за ним стоят 7 серверов, абсолютно разношерстных, на разных ОС, на разных web-серверах и NGINX и apache, у каждого масса своих настроек.
Надо чтобы один Reverse proxy разруливать весь трафик по типу как маршрутизатор, но не по IP адресами, по доменном именам.

Собственно я уже такой и настроил на NGINX. Прописал всем сайтам
server {
        listen 443  ssl;
        server_name sd-info.ru www.site1.ru;
        access_log /var/log/nginx/site1.ru.access.log;
        error_log /var/log/nginx/site1.ru.error.log notice;
        ssl_certificate /etc/letsencrypt/live/site1.ru/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/site1.ru/privkey.pem; # managed by Certbot
        ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;



        location ~* {
                proxy_ignore_client_abort on;
                proxy_pass https://192.168.88.111;
                proxy_redirect https://192.168.88.111 ~*;
                proxy_set_header Host $host;
                proxy_max_temp_file_size 0;
                proxy_ssl_server_name on;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-Port $server_port;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header HTTPS YES;

                # WebSocket support
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
         }
}

Но этот вариант оказался нерабочим, т.к. начались от разных владельцев всякого рода жалобы, кому-то надо параметр
client_max_body_size 20М;
другому
client_max_body_size 1024М;
третьему надо сжатие, четвертому нет, таймауты у всех разные, mime.types тоже разные, по пошло поехало, только что и приходится постоянно править всем настройки.

Пробовал настраивать через нотации upstream типо вот так:
map $ssl_preread_server_name $name {
        site1.ru  site1;
        site2.ru  site2;
    }
    upstream site1p80 {
            server 192.168.88.231:80;
            }

Но тут есть главный недостаток, конечные сервера не получают IP адрес клиентов, что требуется обязательно!

Попробовал настроить HAProxy, так же без наличия SSL сертификатов не работает маршрутизация по именам серверов:
global
        maxconn 4096
        chroot /var/lib/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
        bind *:80
        mode http
        redirect scheme https code 301 if !{ ssl_fc }
frontend https_frontend_ssl_pass
        mode tcp
        bind *:443
       use_backend site1 if { ssl_fc_sni site1.ru }
       use_backend site2 if { ssl_fc_sni site2.ru }
backend site1
        mode tcp
        server site1 192.168.88.102:443 send-proxy
backend site2
        mode tcp
        server site12 192.168.88.111:443 send-proxy

В общем я замучился конкретно.
Поделитесь, пожалуйста, опытом кто как решал эту проблему проксирования https с одного IP на несколько backend серверов, без установки TSL соединения, а прямиком на уровне Laeyr 4, а не Laeyr 7?
  • Вопрос задан
  • 154 просмотра
Подписаться 2 Сложный Комментировать
Решения вопроса 2
IvanU7n
@IvanU7n
nothing interesting here
если от https://nginx.org/en/docs/stream/ngx_stream_ssl_pr... и https://nginx.org/en/docs/stream/ngx_stream_proxy_... (через proxy_protocol on) не получится добиться желаемого, то на одном ip-адресе ваше "нужно" идёт в пешее эротическое

да и то оно хоть как-то имеет смысл если не используется EncryptedHello и "серверы" согласятся использовать PROXY-протокол

и с https по-другому никак, в этом его суть, что на уровне ниже 7 до расшифровки (терминирования tls-сессии) это просто набор зашифрованных данных, на который можно медитировать до посинения, но так не узнать что там есть
Ответ написан
@sevnet Автор вопроса
Системный аналитик, бизнес-консультант
Взлетело, и полёт нормальный.
Ivan Ustûžanin - подсказал ссылки, там почти всё что нужно, но кое-то было не очевидно, сейчас про это напишу.

В общем вся конструкция строится на технологии Proxy Protocol специально для этого кейса разработанной.

Для настройки потребуется настроить 3 вещи:
1. NGINX сервер frontend (первично принимающий весь трафик от роутера, либо напрямую из интернет).
2. NGINX или Apache (или другие) сервер backend.
3. ОБЯЗАТЕЛЬНО! Прописать в файле /etc/hosts на backend серверах сопоставление доменов с frontend сервером (именно frontend!). Если при этом требуется, чтобы сервер мог обращаться ещё и сам к себе по некоторому доменному имени (это надо например push-server в Битрикс), то надо прописать любое выдуманное имя хоста в /etc/hostname, и отдельной записью прописать его на локальный IP в /etc/hosts

1. Конфиг на стороне NGINX Reverse Proxy (он же frontent):
NGINX должен быть собран с модулями:
--with-stream_ssl_module
--with-stream_ssl_preread_module
--with-stream_realip_module


user www-data;
worker_processes auto;
worker_rlimit_nofile 10240;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    use epoll;
	worker_connections 30720;
	multi_accept on;
}
stream {
    proxy_protocol on; #обязательно включаем, без него IP адреса из приходящего SSL трафика не передать дальше
    map $ssl_preread_server_name $name {
        siteone.ru                  so;
        sitetwo.ru            		st;
        sitetree.ru           		str;
    }
	#bitrix1
    upstream so80 {
            server 192.168.0.100:80;
            }
    upstream so443 {
            server 192.168.0.100:443;
            }
    upstream so8893 {
            server 192.168.0.100:8893;
            }
    upstream so8894 {
            server 192.168.0.100:8894;
            }
	#bitrix2
    upstream st80 {
            server 192.168.88.114:80;
            }
    upstream st443 {
            server 192.168.88.114:443;
            }
    upstream st8893 {
            server 192.168.88.114:8893;
            }
    upstream st8894 {
            server 192.168.88.114:8894;
            }
	#web site
    upstream str80 {
            server 192.168.88.102:80;
            }
    upstream str443 {
            server 192.168.88.102:443;
            }
			
	#web traffic		
	server {
            listen 80;
            proxy_pass ${name}80;
          }
    server {
            listen 443;
            proxy_pass ${name}443;
            ssl_preread on;
         }
		 
	#push&pull bitrix
    server {
            listen 8893;
            proxy_pass ${name}8893;
           }
    server {
            listen 8894;
            proxy_pass ${name}8894;
            ssl_preread on;
            }
}


2. Конфиг на стороне принимающего сервера (backend).
1. Для каждого слушаемого порта в директиву listen дописываем proxy_protocol, иначе вообще не заработает.
Должно получиться что-то типо
server {
    listen 443 default_server ssl proxy_protocol;
    ...
    proxy_set_header X-Real-IP       $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
    ...
}

2. Для отлова IP адреса клиента прописываем в директиве http
http {
    set_real_ip_from #IP вашего frontend#;
    real_ip_header proxy_protocol;
}

3. Сделать записи в/etc/hosts как описано выше.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@Drno
Ну так Nginx настройте, под каждый домен свой конфиг отдельный и всё...
Ответ написан
karabanov
@karabanov
Системный администратор
Это делается с помощью set_real_ip_from
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы