Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Transparent reverse HAProxy в 3-Legs схеме

    Scheduled Pinned Locked Moved Russian
    25 Posts 5 Posters 4.8k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • I
      IB
      last edited by

      Коллеги,
      никто не разбирался с тем, как сделать прозрачный reverse proxy в классической трехногой схеме на HAProxy? Суть проблемы:
      1. Есть pfsense на сервере с тремя сетевыми картами - LAN, WAN, DMZ
      2. Между LAN и DMZ - роутинг, выход в WAN из DMZ и LAN - с NAT-ом (естественно)
      3. В DMZ находится сервер (пусть будет веб-сервер), к которому обращаются как из LAN, так и из Интернета по HTTP, и по SSH из внутренней сети. Требуется, чтобы этот сервер видел реальные адреса тех, кто к нему обращается по HTTP.
      4. На pfsense установлен HAProxy, настроен листенер HTTP на внешний адрес, настроен в качестве бэк-сервера веб-сервер в DMZ.
      5. На LAN-интерфейсе разрешены обращения к веб-серверу по HTTP и SSH.

      Все работает. Однако веб-сервер видит пользователей LAN по адресам, а пользователей из Интернета - по адресу HAProxy.

      Если теперь в настройках бэк-сервера включить прозрачное проксирование, то веб-сервер начинает видеть пользователей из Интернета правильно, по их адресам, а пользователи из LAN теряют доступ к веб-серверу. Судя по всему, при включении прозрачности генерируется правило ipfw, которое перехватывает весь обратный трафик от веб-сервера, и передает на обработку в HAProxy. А т.к. HAProxy пропускает через себя только трафик из Интернета, то он не знает, что делать с локальным трафиком, и дропит его.

      Я так подозреваю, что можно решить проблему настройкой листенера на интерфейсе LAN, но тогда надо будет как-то разносить имена DNS - для HTTP и SSH. Это неудобно. Или настраивать листенеры на LAN и для SSH, и для HTTP (не хотелось бы, т.к. ситуация несколько более сложная, чем описана мною).

      Кто-то решал подобную задачу?

      P.S. Советы по использованию другого прокси также принимаются

      1 Reply Last reply Reply Quote 0
      • werterW
        werter
        last edited by

        http://www.itblah.com/pfsense-backend-web-servers-log-firewalls-ip-access-logs/

        http://habrahabr.ru/post/247297/
        http://serverfault.com/questions/302282/how-can-i-use-haproxy-with-ssl-and-get-x-forwarded-for-headers-and-tell-php-that
        http://www.helptouser.com/server/302282-how-can-i-use-haproxy-with-ssl-and-get-x-forwarded-for-headers-and-tell-php-that.html

        http://www.itblah.com/pfsense-enable-stats-latest-devel-package/

        P.s. Как вариант :
        https://forum.pfsense.org/index.php?topic=79798.0

        1. делаем 1 апач-прокси во внутренней сетке, пробрасываем 80/443 на него. Можно заюзать ngnix в качестве фронтеда.
        2. настраиваем на нём домены в апаче с редиректами на нужные серые серваки
        3. раскидываем домены по сервакам.
        1 Reply Last reply Reply Quote 0
        • I
          IB
          last edited by

          Спасибо за ответ. К сожалению, все эти описания просто о реверсном прокси, и не затрагивают тему собственно его прозрачности. В лучшем случае они подразумевают, что бэк-сервер нормально понимает X-Forwarded-For. В моем случае это не так.

          У Апача тоже с прозрачностью проблемы, как и у сквида. Я имею в виду - как минимум в рамках конфигуратора pfSense.

          Вот если попробовать продолжить в сторону HAProxy (ну нравится мне он!  :) )

          Для каждого "прозрачного" бэкенда конфигуратор HAProxy генерирует правило ipfw вида

          fwd ::1 tcp from <адрес_бэкенда> <порт_бэкенда> to any in recv <интерфейс_бэкенда>
          

          Вот можно как-то подправить "to any" так, чтобы было "ко всем, кроме серых"? Или "ко всем кто не на LAN-интерфейсе"? Подправить так, чтобы при реконфиге не ломалось?

          1 Reply Last reply Reply Quote 0
          • G
            gmn
            last edited by

            А если убрать из вашей схемы haproxy?
            И сделать редирект (port forward) порта на внешнем интерфейсе в DMZ.
            А такой же редирект на внутреннем интерфейсе в DMZ.
            И для сайтов сделать split dns - во внешний мир отдавать внешний IP. В LAN - внутренний IP.
            В итоге с LAN-а на web-сервер пользователи не будут ходить через внешний интерфейс шлюза.
            И в логе web-сервера у вас будут настоящие адреса источников запросов (без обработки заголовков x-forward …).

            1 Reply Last reply Reply Quote 0
            • I
              IB
              last edited by

              А если убрать из вашей схемы haproxy?
              И сделать редирект (port forward) порта на внешнем интерфейсе в DMZ.

              Это издержки моего упрощенного описания ситуации :) На самом деле все сложнее - в DMZ куча всяких серверов, висящих на одних и тех же внешних адресах-портах, отличающихся доменными именами. Так что без реверсного прокси не обойтись. Вот какой выбрать и как настроить - вопрос.

              squid3 в составе pfSense весь какой-то нехороший, на 80 и 443 порты ругается, требует либо лезть в настройки ядра, либо заворачивать трафик через loopback, никак не делает прозрачность. Вот апач еще не пробовал. У него с прозрачностью как?

              1 Reply Last reply Reply Quote 0
              • G
                gmn
                last edited by

                Так что без реверсного прокси не обойтись.

                Ну почему же.
                Web-сервер нормально понимает ServerName и по нему направит запрос необходимому сайту.

                У Apache это параметр "ServerName".
                http://httpd.apache.org/docs/2.4/vhosts/name-based.html

                У nginx - "server_name".

                1 Reply Last reply Reply Quote 0
                • G
                  gmn
                  last edited by

                  Но если все же решите haproxy использовать, то включайте опцию "forwardfor" на фронтэнде.
                  А на сервере-получателе запроса в DMZ вычитывайте этот заголовок.
                  У nginx задайте свой формат лога "log_format" и добавьте там, где хотите, параметр "$http_x_forwarded_for".
                  И будете видеть реальный src IP.

                  1 Reply Last reply Reply Quote 0
                  • I
                    IB
                    last edited by

                    Ну почему же.
                    Web-сервер нормально понимает ServerName и по нему направит запрос необходимому сайту.

                    У Apache это параметр "ServerName".
                    http://httpd.apache.org/docs/2.4/vhosts/name-based.html

                    У nginx - "server_name".

                    Вообще-то это и есть реверсный прокси. Особенно если "необходимые сайты" живут не на том же самом сервере, который принимает соединение :)

                    Но если все же решите haproxy использовать, то включайте опцию "forwardfor" на фронтэнде.
                    А на сервере-получателе запроса в DMZ вычитывайте этот заголовок.
                    У nginx задайте свой формат лога "log_format" и добавьте там, где хотите, параметр "$http_x_forwarded_for".
                    И будете видеть реальный src IP.

                    Вопрос не в логах, а в настоящей прозрачности.

                    1 Reply Last reply Reply Quote 0
                    • G
                      gmn
                      last edited by

                      @IB:

                      У Apache это параметр "ServerName".
                      http://httpd.apache.org/docs/2.4/vhosts/name-based.html
                      У nginx - "server_name".

                      Вообще-то это и есть реверсный прокси. Особенно если "необходимые сайты" живут не на том же самом сервере, который принимает соединение :)

                      Нет, это обычный "Name-based Virtual Host".

                      Вопрос не в логах, а в настоящей прозрачности.

                      Тогда что вы понимаете под "настоящей прозрачности"?

                      1 Reply Last reply Reply Quote 0
                      • I
                        IB
                        last edited by

                        Нет, это обычный "Name-based Virtual Host".

                        Если сайты на том же сервере. Если на других - …

                        Тогда что вы понимаете под "настоящей прозрачности"?

                        На целевой сервер TCP-соединение приходит от адреса клиента, а не реверсного прокси.

                        1 Reply Last reply Reply Quote 0
                        • werterW
                          werter
                          last edited by

                          squid3 в составе pfSense весь какой-то нехороший, на 80 и 443 порты ругается, требует либо лезть в настройки ядра, либо заворачивать трафик через loopback, никак не делает прозрачность

                          Пропишите адреса необходимых Вам ресурсов в исключения (в Destination). Тогда на эти ресурсы будете ходить мимо сквида - напрямую.

                          1 Reply Last reply Reply Quote 0
                          • I
                            IB
                            last edited by

                            @werter:

                            squid3 в составе pfSense весь какой-то нехороший, на 80 и 443 порты ругается, требует либо лезть в настройки ядра, либо заворачивать трафик через loopback, никак не делает прозрачность

                            Пропишите адреса необходимых Вам ресурсов в исключения (в Destination). Тогда на эти ресурсы будете ходить мимо сквида - напрямую.

                            Так у него я все равно прозрачность не нашел, у сквида. Плохо искал?

                            1 Reply Last reply Reply Quote 0
                            • G
                              gmn
                              last edited by

                              @IB:

                              На целевой сервер TCP-соединение приходит от адреса клиента, а не реверсного прокси.

                              Как мне кажется, вы многого хотите :)
                              И чтобы соединение было прямое, не проксированное, и чтобы хосты назначения были разные …
                              Тогда только прокси, который по имени будет различать к какому бакэенду направить запрос.
                              Средствами pf вы не сделаете проброс порта по условию ... Т.е. если имя сайта такое-то - туда иди. Такое - сюда ходи ... :)
                              Это только (чем я делал) - haproxy или nginx.
                              И логи смотреть на фронтэнде - здесь будут честные IP источников запроса.
                              На бакэендах будет IP прокси. Будь то или squid, или haproxy, или nginx, или ...
                              Выход из ситуации - это обработка заголовка "x-forwarded-for" или "x-real-ip" (какой добавите на фронтэенде) на бакэнде.

                              1 Reply Last reply Reply Quote 0
                              • R
                                rubic
                                last edited by

                                @IB:

                                HAProxy пропускает через себя только трафик из Интернета, то он не знает, что делать с локальным трафиком, и дропит его.

                                К какому адресу обращаются клиенты из LAN идущие на веб-сервер? В смысле к локальному или публичному?

                                1 Reply Last reply Reply Quote 0
                                • I
                                  IB
                                  last edited by

                                  @rubic:

                                  @IB:

                                  HAProxy пропускает через себя только трафик из Интернета, то он не знает, что делать с локальным трафиком, и дропит его.

                                  К какому адресу обращаются клиенты из LAN идущие на веб-сервер? В смысле к локальному или публичному?

                                  К локальному, DMZ-шному.

                                  1 Reply Last reply Reply Quote 0
                                  • P
                                    PiBa
                                    last edited by

                                    Sorry i dont speak Russian, but do maintain haproxy package on pfSense..

                                    Trying to read / translate this thread im thinking some people are having a slight misunderstanding of the underlying problem presented. If you want to be able to proxy a ssh connection (which i think is one of the desired outcome's?) its not possible to insert a x-forwarded-for header. But haproxy can proxy those connections while keeping the client-ip available to the backend, i think you found that option "Transparent ClientIP" in the backend configuration right?

                                    The desired scenario would be like described here: http://blog.haproxy.com/2011/08/03/layer-7-load-balancing-transparent-proxy-mode/ where the clientip is also used for the connection to the webserver however because pf on freebsd currently does not yet support 'diver-reply' even though it is documented, some trickery is done with ipfw is done to divert reply packets from the webserver back to the haproxy client socket with a non-local ip address.

                                    However this ipfw rule causes trouble for direct clien to webserver traffic .. Im not aware of any other possibility to implement this currently besides waiting for the divert-reply to get implemented into FreeBSD.. ( https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=188511 ) If someone knows a better way im open to suggestions ;) .

                                    For http based traffic inserting the x-forwarded-for header is a good option though..

                                    If i'm totally missing the point, sorry for this non-russian post.

                                    1 Reply Last reply Reply Quote 0
                                    • R
                                      rubic
                                      last edited by

                                      Я, честно говоря, не знаю как там haproxy встраивается в поток, но попробуйте обратиться из LAN к публичному адресу веб-сервера и посмотрите, что будет. По идее, запрос должен попасть в прозрачный haproxy и далее по назначению, т. к. слушаюший socket привязывается к IP,  а не к интерфейсу. pfSense пофиг к какому из его собственных IP вы обратились - все попадет в local process, т. е. в  haproxy.

                                      Если не поможет, можно (если можно) попробовать повесить листенер на loopback и делать port forward на 127.0.0.1 как с WAN, так и с LAN

                                      1 Reply Last reply Reply Quote 0
                                      • I
                                        IB
                                        last edited by

                                        @rubic:

                                        …но попробуйте обратиться из LAN к публичному адресу веб-сервера и посмотрите, что будет. По идее, запрос должен попасть в прозрачный haproxy и далее по назначению, т. к. слушаюший socket привязывается к IP,  а не к интерфейсу. pfSense пофиг к какому из его собственных IP вы обратились - все попадет в local process, т. е. в  haproxy.

                                        Если не поможет, можно (если можно) попробовать повесить листенер на loopback и делать port forward на 127.0.0.1 как с WAN, так и с LAN

                                        Навскидку обращение из LAN на WAN-адрес не проходит - браузер шлет запрос на внешний адрес, а ответ получает с внутреннего.

                                        Насчет заворота на loopback с листенером на нем - попробую позже, отпишусь. По идее должно сработать. Но гемора с настройками будет…

                                        1 Reply Last reply Reply Quote 0
                                        • I
                                          IB
                                          last edited by

                                          @PiBa:

                                          Sorry i dont speak Russian, but do maintain haproxy package on pfSense..

                                          I repeat my question here: https://forum.pfsense.org/index.php?topic=98017.0 Sorry my English  ;)

                                          1 Reply Last reply Reply Quote 0
                                          • G
                                            gmn
                                            last edited by

                                            Да, с транспарент могут быть проблемы, о чем и предупреждает pfsense:
                                            "WARNING Activating this option will load rules in IPFW and might interfere with CaptivePortal and possibly other services due to the way server return traffic must be 'captured' with a automatically created fwd rule. This also breaks directly accessing the (web)server on the ports configured above. Also a automatic sloppy pf rule is made to allow HAProxy to server traffic."

                                            Прочитал ваш вопрос на английском.
                                            "Servers S1 and S2 must see real client IP" - какие там web-сервера используются?
                                            Это я к тому, что haproxy умеет добавлять заголовок "X-Forwarded-For", а Apache и nginx (да и IIS тоже, и другие наверняка) умеют его обрабатывать.
                                            Вот ссылка на документацию nginx - http://nginx.org/ru/docs/http/ngx_http_realip_module.html
                                            "Модуль ngx_http_realip_module позволяет менять адрес клиента на переданный в указанном поле заголовка."
                                            Т.е. и в логе, и в переменной _SERVER["REMOTE_ADDR"] будет адрес источника, а не прокси.

                                            https://rtcamp.com/tutorials/nginx/forwarding-visitors-real-ip/

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.