Apache reverse proxy на сайт с использованием NTLM-аутентификации не работает с mod_rewrite, но работает с mod_proxy.

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

У нас есть сервер обратного проксирования перед сервером Exchange, и мы хотели бы заблокировать больше путей. Минимизированные примеры:

Не работает (но работает для всех страниц, которые не требуют аутентификации):

<VirtualHost 192.168.1.81:443>
    ServerName autodiscover.example.com
    SSLEngine On
    SSLProxyEngine On
    Include conf/sslcert.conf
    RewriteEngine On

    RewriteRule (.*) https://exchangecluster.example.com$1 [P,L]
    ProxyPassReverse / https://exchangecluster.example.com/
</VirtualHost>

Работает:

<VirtualHost 192.168.1.81:443>
    ServerName autodiscover.example.com
    SSLEngine On
    SSLProxyEngine On
    Include conf/sslcert.conf
    RewriteEngine On

    ProxyPass / https://exchangecluster.example.com/
    ProxyPassReverse / https://exchangecluster.example.com/
</VirtualHost>

Запрос проходит при использовании правила переписывания и отвечает с 401 и предоставляет опции для WWW-Authenticate, как и ожидалось. С ProxyPass аутентификация пользователя работает, в то время как с RewriteRule пользователь постоянно запрашивает аутентификацию, что, как я предполагаю, связано с NTLM.

Есть несколько вопросов на StackExchange, которые говорят, что mod_proxy не может обрабатывать аутентификацию NTLM, но в этом случае это работает.

Проблему с mod-rewrite можно обойти, обрабатывая пути, которые не требуют аутентификации, затем запрещая пути, которые должны быть заблокированы, и затем выполняя глобальный ProxyPass.

Обходной путь:

<VirtualHost 192.168.1.81:443>
    ServerName autodiscover.example.com
    SSLEngine On
    SSLProxyEngine On
    Include conf/sslcert.conf
    RewriteEngine On

    # Заблокировать все запросы, кроме URL-адресов autodiscover
    RewriteCond "%{REQUEST_URI}" "!^/autodiscover/autodiscover\.(?:xml|json|svc)$" [NC]
    RewriteRule ^ - [F]

    ProxyPass / https://exchangecluster.example.com/
    ProxyPassReverse / https://exchangecluster.example.com/
</VirtualHost>

В комментарии к другому вопросу предлагалось использовать mpm_prefork_module вместо mpm_worker_module. Я проверил наш 00_mpm.conf, и мы используем worker, и это работает с proxypass, так что кажется, что мы упускаем что-то для опции прокси mod_rewrite.

Большинство вопросов, которые я нашел, касаются того, чтобы обратный прокси аутентифицировался через NTLM. Этот вопрос касается передачи аутентификации на сервер и сохранения сеанса, а не аутентификации с Apache (предполагается, что это не требуется для работы).

Необходимо ли включить какие-либо настройки для разрешения проксирования при использовании mod_rewrite?

Сделал это на Windows с NTLM для аналогичной проблемы на Jenkins, чтобы разрешить неограниченный доступ к wsagents.

# ограниченный доступ, кроме ProxyMatch
<ProxyMatch "^((?!tcpSlaveAgentListener|wsagents).)*$">
    NTLMAuth On
    NTLMAuthoritative On
    NTLMOfferBasic Off
  # Здесь добавьте ваши Requires... 
</ProxyMatch>

<Proxy "wsagents">
    Require all granted
</Proxy>

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

Ваш вопрос касается проблем, связанных с использованием Apache в качестве обратного прокси-сервера для передачи NTLM-аутентификации от клиента к серверу. В частности, наблюдается ситуация, когда использование модуля mod_rewrite для проксирования запросов недостаточно эффективно в контексте NTLM-аутентификации по сравнению с применением mod_proxy.

Теория

На первый взгляд, mod_rewrite и mod_proxy могут казаться взаимозаменяемыми, поскольку оба они могут быть использованы для перенаправления и проксирования HTTP-запросов. mod_proxy является специализированным модулем для проксирования запросов, предоставляя более глубокую интеграцию и оптимизацию, в то время как mod_rewrite изначально разработан для манипуляции URI и перенаправления. Один из ключевых моментов здесь заключается в том, как эти модули обрабатывают заголовки HTTP, особенно в контексте сложной схемы аутентификации, такой как NTLM.

NTLM-аутентификация требует поддержки сессий, поскольку она включает в себя многоступенчатый обмен данными между клиентом и сервером. Процесс NTLM-аутентификации предполагает три этапа, включая отправку и обработку токенов аутентификации между браузером и сервером. Важно, чтобы все эти обмены происходили в рамках одной и той же сессии.

Пример

В предоставленном вами рабочем решении с использованием ProxyPass:

<VirtualHost 192.168.1.81:443>
    ServerName autodiscover.example.com
    SSLEngine On
    SSLProxyEngine On
    Include conf/sslcert.conf
    RewriteEngine On

    ProxyPass / https://exchangecluster.example.com/
    ProxyPassReverse / https://exchangecluster.example.com/
</VirtualHost>

mod_proxy позволяет Apache обрабатывать сессии NTLM, сохраняя все требуемые атрибуты подключения, такие как заголовки, необходимые для успешной аутентификации. Это происходит за счет специфической обработки заголовков, таких как WWW-Authenticate, что обеспечивает корректный поток обмена NTLM-пакетами.

Применение

Когда используется mod_rewrite:

<VirtualHost 192.168.1.81:443>
    ServerName autodiscover.example.com
    SSLEngine On
    SSLProxyEngine On
    Include conf/sslcert.conf
    RewriteEngine On

    RewriteRule (.*) https://exchangecluster.example.com$1 [P,L]
    ProxyPassReverse / https://exchangecluster.example.com/
</VirtualHost>

Существует вероятность, что mod_rewrite может не корректно передавать все необходимые заголовки или нюансы, связанные с управлением сессиями NTLM. Причиной этому может быть ограниченная функциональность или настройки, которые не позволяют полностью сохранить контекст NTLM-аутентификации. Именно поэтому, даже если запрос и проходит, происходит повторная проверка подлинности: сессия не сохраняется корректно, и сервер продолжает запрашивать повторную аутентификацию у клиента.

Для решения этой проблемы вы можете использовать комбинирование конфигураций или уклоняться от использования mod_rewrite для сложной обработки случаев, связанных с NTLM. С точки зрения конфигурации, где вы заблокируете пути, не требующие аутентификации, а затем используете стандартный ProxyPass, это позволит избежать вышеупомянутого ограничения:

<VirtualHost 192.168.1.81:443>
    ServerName autodiscover.example.com
    SSLEngine On
    SSLProxyEngine On
    Include conf/sslcert.conf
    RewriteEngine On

    # Block all requests except the autodiscover URLs
    RewriteCond "%{REQUEST_URI}" "!^/autodiscover/autodiscover\.(?:xml|json|svc)$" [NC]
    RewriteRule ^ - [F]

    ProxyPass / https://exchangecluster.example.com/
    ProxyPassReverse / https://exchangecluster.example.com/
</VirtualHost>

Если вам все же необходимо использовать mod_rewrite, возможно, вы сможете улучшить его поведение, строго контролируя заголовки, которые должны быть переданы клиенту или серверу для поддержания сессии NTLM. Убедитесь в том, что ProxyPreserveHost On и любые другие параметры, обеспечивающие корректное управление HTTP-заголовками, корректно настроены.

Таким образом, решение вашего вопроса может заключаться в полном отказе от использования mod_rewrite для NTLM или более тщательной проверке и настройке правил проксирования и аутентификации, чтобы обеспечить полную и непрерывную поддержку сессий.

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

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