The Apple Geek

Чему ты научился сегодня?

Модификация URL при проксировании в Apache

Я периодически использую в Apache модуль mod_proxy_http для проксирования трафика с одного frontend’а на различные backend’ы. Конфигурация, которая перебрасывает запросы с http://company.com/news/ на внутренний сервер http://internal.company.com/ такая:

ProxyPass        /news/  http://internal.company.com/
ProxyPassReverse /news/  http://internal.company.com/

Всё работает хорошо, до тех пор, пока на внутреннем сервере вместо относительных URL вида “/css/style.css” не появляются абсолютные URL “http://internal.company.com/css/style.css”. В этом случае html возвращается внешнему клиенту, он пытается взять css/js или перейти по внутреннему адресу http://internal.company.com, который недоступен из Интернет, и на этом всё заканчивается. Страницы не отображаются, ссылки не работают.

Приходилось выкручиваться с прописыванием внешних URL на внутренних серверах, это рождало проблемы доступа из внутренней сети. Они лечились Split DNS (внутренним и внешним клиентам отдавались на один запрос разные имена). Всё это рождало дополнительные сложности, в итоге с трудом поддерживалось и диагностировалось.

Сегодня мне снова понадобилось решить эту задачу. Провёл изучение текущего состояния вопроса и нашёл отличное решение - mod_substitute, который к тому же входит в стандартную поставку Apache 2.2 и не требует компиляции из сторонних исходников.

Теперь конфигурация выглядит примерно так:

ProxyPass        /news/  http://internal.company.com/
ProxyPassReverse /news/  http://internal.company.com/

AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|http://internal.company.com/|http://company.com/news/|in"

Замечу - нагрузка на сервер минимальна, нужно переписывать только text/html. Для других случаев понадобится более расширенная конфигурация. Но направление решения вопроса я показал, от чего-то уже можно оттолкнуться.