Как удалить протокол прокси с помощью HAproxy?

Рассмотрим следующую ситуацию:

                                      Internet
                                         ||
                                         ||
                                  .------''------.
                                  | HTTPS (:443) |
                                  '------..------'
                                         ||
                 .-----------------------'|
                 |                       \/
                 |           3rd party HAproxy service
                 |                       ||
                 |                       ||
             optional        .-----------''-----------.
               route         | PROXY Protocol (:5443) |
                 |           '-----------..-----------'
                 |                       ||                                 ________
      ___________|_______________________||________________________________| SERVER |____
     |           |                       \/                                              |
     |           |                 local HAproxy                                         |
     |           |                       ||                                              |
     |           |                       ||                                              |
     |           |                .------''------.                                       |
     |           |                | HTTPS (:443) |                                       |
     |           |                '------..------'                                       |
     |           |                       ||                                              |
     |           |                       ||                                              |
     |           |                       \/                                              |
     |           '---------------> local webserver                                       |
     |___________________________________________________________________________________|

На внутреннем сервере есть HAproxy и Apache httpd, локально работающие на портах 5443 и 443 соответственно.

Мой локальный веб-сервер не поддерживает протокол PROXY. Поэтому я хочу, чтобы HAproxy перехватил протокол PROXY от сторонней службы и передавал данные на локальный веб-сервер либо по протоколу HTTPS, либо просто по протоколу TCP.

В случае HTTPS я полагаю, что он должен манипулировать HTTP-пакетами, используя правильный SSL-сертификат, чтобы добавить исходный IP-адрес отправителя в X-Forwarded-For заголовки HTTP (которые должны предоставляться протоколом PROXY).

Однако документация по HAproxy ужасна, если вы новичок в HAproxy. , и я не смог найти примеров, объясняющих, как это сделать. Я знаю, что это должно быть возможно, поскольку HAproxy указан как «Программное обеспечение, поддерживающее протокол прокси», но как?


person Yeti    schedule 18.05.2018    source источник


Ответы (1)


Да, вам необходимо использовать accept-proxy ключевое слово после bind в объявлении внешнего интерфейса. Также будет полезно прочитать о связанном ключевом слове send-proxy , который используется в данной «сторонней службе HAproxy».

Протокол PROXY можно вернуть в исходное состояние, используя следующую конфигурацию HAproxy:

frontend app-proxy
  bind *:5443 accept-proxy
  mode tcp
  option tcplog
  default_backend app-httpd
backend app-httpd
  mode tcp
  server app1 127.0.0.1:443 check

Это примет протокол PROXY на порт 5443, разделит его и отправит данные TCP на 443.

Если вы хотите манипулировать HTTP-пакетами в данных TCP, зашифрованных с помощью SSL, вам потребуется доступ к правильным сертификатам SSL (к которым ваш веб-сервер уже должен иметь доступ). Это то, что вы, вероятно, захотите сделать.

frontend app-proxy
  bind *:5443 accept-proxy ssl crt /path/to/certnkey-file.pem
  mode http
  option httplog
  default_backend app-httpd
backend app-httpd
  mode http
  server app1 127.0.0.1:443 check ssl verify none

Преимущество последнего подхода заключается в том, что исходные данные клиента сохраняются при прохождении через прокси, так что вы знаете, каков исходный IP-адрес вашего посетителя. В этом вся идея использования протокола PROXY в первую очередь! HAproxy автоматически обновит заголовок X-Forwarded-For, указав правильный IP-адрес, который был передан по протоколу PROXY.

person Yeti    schedule 19.05.2018
comment
Обратите внимание, что каждый раз, когда вы используете протокол прокси, важно убедиться, что ваша служба никогда не будет принимать запросы от чего-либо, кроме доверенного источника, независимо от того, делаете ли вы это с ограничениями на основе IP, взаимной аутентификацией TLS или каким-либо другим механизмом, потому что ненадежный источник может подделать преамбулу (заголовки) протокола прокси и, таким образом, подделать его идентичность. Это не уязвимость как таковая, это то же самое со стандартным X-Forwarded-For - при синтаксическом анализе справа налево первый ненадежный IP-адрес - единственное значение, которому вы действительно можете верить. Все, что находится слева от этого, может быть подделано. - person Michael - sqlbot; 20.05.2018
comment
@ Michael-sqlbot Хорошее замечание. Но если я правильно понимаю, то неважно, принимаете ли вы самозванца или нет - вы всегда можете проверить действительность впоследствии, основываясь на IP-адресах в X-Forwarded-For. Последний IP-адрес не может быть подделан, потому что он добавляется только в конечной точке на основе источника TCP-пакета. Так что даже когда вы принимаете запросы от ненадежного источника, вы можете проверить это позже, проверив X-Forwarded-For, верно? - person Yeti; 21.05.2018
comment
Нет, я так не думаю, потому что X-Forwarded-For будет содержать все, что было написано в сообщении протокола прокси, а не адрес из IP-стека, не так ли? Протокол прокси неявно доверяет отправителю отправку точного сообщения. - person Michael - sqlbot; 21.05.2018