Можно ли ограничить доступ к URL-адресам в Tomcat за обратным прокси с помощью RemoteAddrValve?

Вопрос или проблема

Я использую Tomcat 9 за Apache Httpd в классической конфигурации с использованием mod_proxy

Apache Httpd настроен как обратный прокси:

<IfModule mod_proxy.c>      

   # Явно не проксируем страницы ошибок

   ProxyPass        "/http_error/" !

   # Передаем каждый запрос Tomcat, который слушает на 127.0.0.1:8080

   ProxyPass        "/" "http://127.0.0.1:8080/"
   ProxyPassReverse "/" "http://127.0.0.1:8080/"

</IfModule>

Я могу легко добавить контроль доступа на уровне Apache Http с помощью mod_authz_core и mod_authz_host.

Но могу ли я сделать это на уровне Tomcat?

Например, приложение менеджера по умолчанию выполняет фильтрацию в своем META-INF/context.xml (в моем случае, /var/lib/tomcat/webapps/manager/META-INF/context.xml), настраивая RemoteAddressValve:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

Это гарантирует, что приложение менеджера может быть доступно только клиентами, обращающимися с локального адреса. В случае Tomcat, находящегося за прокси, это, конечно, всегда правда – все запросы приходят с 127.0.0.1.

Поэтому я подумал, что могу ограничить доступ к хосту 192.168.1.34 (например), сделав следующее:

Сделать IP-адрес клиента проверяемым

Настроить RemoteIpValve для передачи X-Forwarded-For заголовков в поле исходного IP-адреса запросов:

В server.xml, на уровне Engine:

<Valve className="org.apache.catalina.valves.RemoteIpValve"
       internalProxies="192\.168\.1\.30|127\.0\.0\.\1" />

где internalProxies указывает ожидаемый адрес обратного прокси.

Фильтрация по IP-адресу

Изменить запись RemoteAddressValve в context.xml веб-приложения на:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       allow="192\.168\.1\.34" />

Теперь мы должны иметь возможность получить доступ к веб-приложению с клиента с IP-адресом 192.168.1.34.

Этот трюк не срабатывает – доступ с 192.168.1.34 фактически отклоняется!

Поэтому, возможно, конфигурация правильная. Из справочного материала:

usePeerAddress: Используйте адрес соединения пира вместо IP-адреса клиента. Они будут различаться, если перед Tomcat используется обратный прокси в сочетании либо с протоколом AJP, либо с HTTP-протоколом плюс RemoteIp(Valve|Filter).

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       usePeerAddress="true"
       allow="192\.168\.1\.34" />

Но это тоже не срабатывает, доступ не разрешен.

Можно ли сделать так, чтобы это работало?

Ответ или решение

Вопрос: Можно ли ограничить доступ к URL-адресам в Tomcat за обратным прокси с использованием RemoteAddrValve?

Введение

В данной статье рассмотрим возможность ограничения доступа к ресурсам веб-приложений в Tomcat, работающем за обратным прокси-сервером Apache Httpd. Вы правильно отметили, что Apache Httpd может осуществлять контроль доступа на своем уровне с использованием модулей, таких как mod_authz_core и mod_authz_host. Однако, вопрос о том, можно ли реализовать подобный контроль доступа в самом Tomcat, также имеет важное значение.

Настройка обратного прокси

Обратный прокси-сервер Apache Httpd предоставляет гибкие возможности для настройки маршрутизации и фильтрации запросов. Как вы верно указали в вашей конфигурации, сервер перенаправляет все запросы к Tomcat, работающему на локальной машине. Важно понимать, что после этого все входящие запросы, по сути, будут восприниматься Tomcat как исходящие от 127.0.0.1, что затрудняет использование фильтров на основе IP-адресов на уровне приложения.

Передача информации о клиентском IP-адресе

Для решения этой проблемы вы можете использовать RemoteIpValve, который позволяет передавать исходные IP-адреса клиентов через заголовок X-Forwarded-For. В вашем случае правильная настройка в файле server.xml может выглядеть так:

<Valve className="org.apache.catalina.valves.RemoteIpValve"
       internalProxies="192\.168\.1\.30|127\.0\.0\.\1"
       remoteIpHeader="X-Forwarded-For"
       proxiesHeader="X-Forwarded-By" />

Здесь internalProxies указывает адреса доверенных прокси, и только запросы от них смогут передавать корректный IP-адрес клиента.

Настройка фильтрации IP-адресов в Tomcat

Теперь, когда клиентский IP-адрес будет правильно обрабатываться, вы можете настроить RemoteAddrValve в конфигурации вашего приложения (например, в META-INF/context.xml):

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       allow="192\.168\.1\.34" />

Это должно обеспечить доступ к вашему приложению только для клиентов с адресом 192.168.1.34.

Использование параметра usePeerAddress

Опция usePeerAddress предназначена для случаев, когда необходимо использовать адрес подключенного клиента вместо адреса, полученного через RemoteIpValve. Если вы уже настроили RemoteIpValve, то значение usePeerAddress должно оставаться по умолчанию (false), иначе Tomcat будет рассматривать соединение как исходящее от прокси, а не от клиента.

Если вы установите:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       usePeerAddress="true"
       allow="192\.168\.1\.34" />

То это может вызвать проблемы, так как Tomcat может уже не "видеть" IP-адреса пользователей, передаваемые через заголовки.

Заключение

Таким образом, для возможности ограничения доступа к URL-адресам в Tomcat, работающем за прокси, рекомендуем использовать RemoteIpValve, чтобы правильно передавать IP-адреса клиентов, и затем фильтровать доступ с помощью RemoteAddrValve. Не забывайте также проверять, что соответствующие заголовки корректно передаются от прокси-сервера к Tomcat и что конфигурация соответствует требованиям безопасности вашей окружения.

Помните, что правильная настройка обратного прокси требует детального подхода к безопасному хранению и обновлению конфигураций. При возникновении дополнительных вопросов или проблем всегда можно обратиться к документации Tomcat и Apache Httpd или найти помощь в сообществах пользователей.

Оцените материал
Добавить комментарий

Капча загружается...