У меня есть следующая конфигурация для VirtualHost:
<VirtualHost *:80>
DocumentRoot /srv/emptywebroot
<Directory /srv/emptywebroot>
Require all denied
</Directory>
# Dashboard proxy
RewriteEngine on
LogLevel alert rewrite:trace6
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /dashboard/(.*) ws://dashboard:3838/dashboard/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /dashboard/(.*) http://dashboard:3838/dashboard/$1 [P,L]
ProxyPreserveHost on
ProxyPassReverse /dashboard http://dashboard:3838/dashboard
</VirtualHost>
Когда я захожу на сайт, http://myurl/dashboard
я получаю ошибку 404 из панели управления.
При проверке журналов перезаписи я получаю:
[Wed Mar 21 14:04:08.051070 2018] [rewrite:trace2] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] init rewrite engine with requested uri /dashboard/
[Wed Mar 21 14:04:08.051114 2018] [rewrite:trace1] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] pass through /dashboard/
[Wed Mar 21 14:04:08.051176 2018] [rewrite:trace3] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] add path info postfix: /srv/emptywebroot/dashboard -> /srv/emptywebroot/dashboard/
[Wed Mar 21 14:04:08.051186 2018] [rewrite:trace3] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] applying pattern '(.*)' to uri '/srv/emptywebroot/dashboard/'
[Wed Mar 21 14:04:08.051199 2018] [rewrite:trace4] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] RewriteCond: input='' pattern='=websocket' => not-matched
[Wed Mar 21 14:04:08.051208 2018] [rewrite:trace3] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] add path info postfix: /srv/emptywebroot/dashboard -> /srv/emptywebroot/dashboard/
[Wed Mar 21 14:04:08.051216 2018] [rewrite:trace3] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] applying pattern '(.*)' to uri '/srv/emptywebroot/dashboard/'
[Wed Mar 21 14:04:08.051225 2018] [rewrite:trace4] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] RewriteCond: input='' pattern='!=websocket' => matched
[Wed Mar 21 14:04:08.051234 2018] [rewrite:trace2] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] rewrite '/srv/emptywebroot/dashboard/' -> 'http://dashboard:3838//srv/emptywebroot/dashboard/'
[Wed Mar 21 14:04:08.051243 2018] [rewrite:trace2] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] escaped URI in per-dir context for proxy, http://dashboard:3838//srv/emptywebroot/dashboard/ -> http://dashboard:3838//srv/emptywebroot/dashboard/
[Wed Mar 21 14:04:08.051264 2018] [rewrite:trace2] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] forcing proxy-throughput with http://dashboard:3838//srv/emptywebroot/dashboard/
[Wed Mar 21 14:04:08.051272 2018] [rewrite:trace1] [pid 1548:tid 140453800191744] mod_rewrite.c(476): [client 10.174.120.65:59506] 10.174.120.65 - - [idisrv.sivsa.com/sid#7fbdfdd1ed20][rid#7fbdf018f0a0/initial] [perdir /dashboard/] go-ahead with proxy request proxy:http://dashboard:3838//srv/emptywebroot/dashboard/ [OK]
Так что /srv/emptywebroot
получает префикс перед передачей URI прокси. Я бы хотел, чтобы это не было префиксом. Я пробовал RewriteBase /
и некоторые другие вещи, но я не понимаю смысла.
Как избежать добавления DocumentRoot в качестве префикса к URI в этом контексте?
ПРАВКА 1: Бэкэнд панели мониторинга на dashboard:3838 не обслуживается Apache, это блестящий сервер (https://shiny.rstudio.com/). Я запустил tcpdump на хосте панели управления, и произошло то, что показано выше: DocumentRoot получает префикс в виде прокси-виртуального хоста Apache, поэтому бэкэнд запрашиваетhttp://dashboard:3838//srv/emptywebroot/dashboard, вместоhttp://панель инструментов:3838/панель инструментовкак мне нужно. Надеюсь, это проясняет мою ситуацию, поэтому переформулирую вопрос: как мне указать mod_rewrite не разрешать локальные пути (добавляя префикс DocumentRoot)? В моем случае это прокси mod_rewrite (проверьте [P] в правиле перезаписи, поэтому добавление префикса к локальным путям не является моим желаемым поведением.
решение1
Согласно журналу перезаписи, эти строки вашего набора правил были нарушены
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /dashboard/(.*) http://dashboard:3838/dashboard/$1 [P,L]
Так как RewriteRule
у есть [L]
флаг, то следующие строки больше проверяться не будут.
Теперь этот запрос войдет в следующий раунд перезаписи. <VirtualHost dashboard:3838>
Вы можете заглянуть туда, чтобы узнать, почему ваш URI /dashboard/
приводит к ошибке HTTP 404.
- Существует ли этот каталог?
- Есть ли какое-нибудь RewriteRule, которое может решить эту проблему?
решение2
Я обнаружил, что принудительное сопоставление правила перезаписи с REQUEST_URI путем добавления условия перезаписи к REQUEST_URI решает проблему, поэтому следующее работает для меня:
<VirtualHost *:80>
DocumentRoot /srv/emptywebroot
<Directory /srv/emptywebroot>
Require all denied
</Directory>
# Dashboard proxy
RewriteEngine on
LogLevel alert rewrite:trace6
RewriteCond %{HTTP:Upgrade} =websocket
RewriteCond %{REQUEST_URI} ^/dashboard
RewriteRule /dashboard/(.*) ws://dashboard:3838/dashboard/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteCond %{REQUEST_URI} ^/dashboard
RewriteRule /dashboard/(.*) http://dashboard:3838/dashboard/$1 [P,L]
ProxyPreserveHost on
ProxyPassReverse /dashboard http://dashboard:3838/dashboard
</VirtualHost>
Я нашел документацию по адресуhttp://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteruleНесколько сбивает с толку, так как в нем говорится: «В контексте VirtualHost шаблон будет изначально сопоставляться с частью URL после имени хоста и порта и перед строкой запроса (например, «/app1/index.html»). Это (%-декодированный) URL-путь.», но в моем случае он, похоже, сопоставляется с локальным разрешенным путем. Поэтому добавление RewriteCond для изменения того, что перезаписывает RewriteRule (в моем случае REQUEST_URI), похоже, работает.