Вопрос или проблема
Я использую Ubuntu-15.10 wily, Apache-2.4.12
Я пытался использовать ProxyPass в VirtualHost, поддерживающем SSL, следующим образом:
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass /myapp/ http://127.0.0.1:8090/
ProxyPassReverse /myapp/ http://127.0.0.1:8090/
С указанной конфигурацией я предполагал, что всё, что обслуживается сервером на этом порту, например, web
, будет добавлено к https://www.example.com/myapp/web
.
Однако это не то, что я получаю. В журналах Apache я получаю:
... Файл не существует: /var/www/html/web, реферер: https://www.example.com/myapp/
Это связано с тем, что я не понимаю, что должно делать ProxyPass
? Или что-то не так с моей конфигурацией, что мне нужно исправить?
ДОПОЛНЕНИЕ (18 февраля 2016 года)
Я включил журналирование для mod_proxy
и вижу следующее, что не имеет смысла:
... соединение http://127.0.0.1:8090/ с 127.0.0.1:8090
... подключено / к 127.0.0.1:8090
... создан сокет fam 2 для 127.0.0.1
... соединение установлено с 127.0.0.1:8090 (127.0.0.1)
... соединение завершено с 127.0.0.1:8090 (127.0.0.1)
... http: освободил соединение для (127.0.0.1)
... прокси: завершение соединения
Я предполагаю, что один из адресов в первой строке является внутренним заполнителем, а другой — URL, который извлекается. Но почему во второй строке извлечённый URL подключается к /
вместо /myapp/
согласно ProxyPass?
Я нашёл решение, но это не то, на что я надеялся и не то, что ожидал от своих чтений о ProxyPass
. Это может быть моя ошибка, или документация не так ясна, как должна быть. ProxyPass
не может добавить проксируемый URL к пути вымышленного имени. Поэтому мне пришлось настроить моё приложение так, чтобы загружать его из директории на назначенном порту, а не из корня URL, как показано ниже:
ProxyPass /myapp http://127.0.0.1:8090/myapp
ProxyPassReverse /myapp http://127.0.0.1/myapp
Кроме того, необходимо использовать RewriteRule
, если есть ресурсы, которые нужно загружать, например, запросы, изображения, скрипты и т.д.
Правила Rewrite будут следующими:
RewriteEngine On
RewriteRule ^(.*) http://0.0.0.0:8090/$1 [P,L]
Мне кажется, что есть множество других решений, которые могут включать другие модули прокси и, возможно, RewriteRule
, однако это решение столь же простое, насколько я знаю Apache.
Таким образом, итог в том, что по крайней мере первая компонента пути должна присутствовать с обеих сторон, чтобы ProxyPass
выполнял свою работу. Я не могу использовать ProxyPath
для загрузки на путь, который я выдумываю, без дополнительных осложнений в настройках прокси.
Я надеюсь, что кто-то найдёт этот ответ полезным.
Ответ или решение
Конфигурация прокси-сервера в Apache с использованием директив ProxyPass
и ProxyPassReverse
может вызывать сложности, особенно если вы хотите использовать определенный путь для проксирования, а не корень вашего веб-сервера. Ваша ситуация с использованием ProxyPass
на базе Apache 2.4.12
на Ubuntu 15.10
— типичный пример, когда возникают разные интерпретации работы этих директив. Давайте разберемся с вашей конфигурацией и предложим решение.
Проблема
Ваш первоначальный код, который использует:
ProxyPass /myapp/ http://127.0.0.1:8090/
ProxyPassReverse /myapp/ http://127.0.0.1:8090/
предполагал, что все запросы к https://www.example.com/myapp/...
будут корректно проксироваться к http://127.0.0.1:8090/...
. Однако, согласно логам:
... File does not exist: /var/www/html/web, referer: https://www.example.com/myapp/
кажется, что Apache пытается найти запрашиваемый ресурс /var/www/html/web
, что свидетельствует о том, что запрос не был корректно проксирован.
Причина проблемы
Причина, по которой Apache не правильно обрабатывает запросы, заключается в том, что добавленный „/myapp“ не сопоставляется с путём на проксируемом сервере. Директива ProxyPass
использует маппинг 1:1, что означает, что все URL-адреса будут восприниматься относительно корня сервера. Когда вы добавляете /myapp/
, Apache пытается проксировать этот путь, однако не знает, как правильно обратиться к действительному расположению ресурса на проксируемом сервере, так как ваш сервер по адресу http://127.0.0.1:8090/
не содержит каталога /myapp/
.
Решение
Для правильной настройки вам действительно нужно, чтобы сервер на localhost:8090
обрабатывал запросы в соответствии с /myapp
. Худшее решение — это изменение настройки вашего приложения (если это возможно), чтобы оно принимало запросы по пути /myapp
.
Вот решение, которое использует вашу первую идею, но немного модифицирует её:
ProxyPass /myapp http://127.0.0.1:8090/myapp
ProxyPassReverse /myapp http://127.0.0.1:8090/myapp
В этом случае все запросы к https://www.example.com/myapp/...
будут перенаправлены к http://127.0.0.1:8090/myapp/...
. Это гарантирует, что ваш сервер на localhost
найдет нужные маршруты.
Использование RewriteRule
Если вам необходимо обработать ресурсы, которые вызываются через запросы, то вам также может понадобиться использовать mod_rewrite
. Например:
RewriteEngine On
RewriteRule ^/myapp/(.*) http://127.0.0.1:8090/myapp/$1 [P,L]
Это правило будет захватывать любые ресурсы, запрашиваемые через путь /myapp/
, и проксировать их к соответствующему ресурсу на сервере localhost
.
Заключение
Конфигурация проксирования в Apache может быть чувствительной к путям, и для успешного использования ProxyPass
требуется, чтобы проксируемый сервер был настроен соответствующим образом. Убедитесь, что конфигурация ваших серверов совпадает, и используйте RewriteRule
для более гибкой обработки запросов. Таким образом, вы улучшите работу вашего приложения, и ваши пользователи получат доступ ко всем необходимым ресурсам без ошибок.
Эти изменения и рекомендации помогут вам правильно настроить Apache и обеспечить безотказную работу вашей прокси-инфраструктуры.