Regra de reescrita do Apache prefixando DocumentRoot

Regra de reescrita do Apache prefixando DocumentRoot

Eu tenho a seguinte configuração para um 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>

Quando visito, http://myurl/dashboardrecebo um 404 no back-end do painel.

Quando inspeciono os logs de reescrita, recebo:

[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]

Portanto, /srv/emptywebrooté prefixado antes de passar o URI para o proxy. Eu gostaria que isso não fosse prefixado. Eu tentei RewriteBase /e algumas outras coisas, mas não entendi.

Como posso evitar que DocumentRoot seja prefixado ao URI neste contexto?

EDITAR 1: O back-end do painel em dashboard:3838 não é servido pelo Apache, é um servidor brilhante (https://shiny.rstudio.com/). Eu executei um tcpdump no host do painel, e o que acontece é o que foi visto acima: DocumentRoot é prefixado pelo proxy virtualhost do apache, então o backend é solicitadohttp://painel:3838//srv/emptywebroot/dashboard, em vez dehttp://painel:3838/painelcomo eu preciso. Espero que isso esclareça minha situação, reformulando assim a pergunta: Como instruir o mod_rewrite a não resolver caminhos locais (prefixando DocumentRoot)? No meu caso, este é um proxy mod_rewrite (marque [P] na regra de reescrita, portanto, prefixar caminhos locais não é meu comportamento desejado.

Responder1

De acordo com o Rewrite Log, essas linhas do seu conjunto de regras foram atingidas

RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /dashboard/(.*) http://dashboard:3838/dashboard/$1 [P,L]

Como RewriteRuletem um [L]Flag, as próximas linhas não serão mais verificadas

Agora, esta solicitação entrará na próxima rodada de reescrita. <VirtualHost dashboard:3838> Você pode procurar lá para descobrir por que seu URI /dashboard/resulta em um erro HTTP 404.

  • Este diretório existe?
  • Existe algum RewriteRule que possa resolver isso?

Responder2

Descobri que forçar a regra de reescrita a corresponder a REQUEST_URI, adicionando uma condição de reescrita em REQUEST_URI antes, resolve o problema, então o seguinte funciona para mim:

<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>

Encontrei a documentação emhttp://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteruleum tanto confuso, pois afirma "No contexto do VirtualHost, o padrão será inicialmente comparado à parte da URL após o nome do host e a porta e antes da string de consulta (por exemplo, "/app1/index.html"). Este é o ( %-decoded) URL-path.", mas no meu caso parece corresponder ao caminho local resolvido. Portanto, adicionar um RewriteCond para modificar o que RewriteRule reescreve (REQUEST_URI no meu caso) parece funcionar.

informação relacionada