Entendendo o apache 2.4 mod_proxy_fcgi e RewriteRules no htaccess

9

Recentemente, trocamos um de nossos servidores da web para o apache 2.4 e executando o PHP via php-fpm e mod_proxy_fcgi. Quase tudo funciona muito bem, mas há um problema que ainda não entendi. Um de nossos sites está executando o WordPress, que traz uma boa lista de regras de reescrita em seu arquivo .htaccess. E parece que esses não funcionam tão bem com a diretiva ProxyPass na configuração do vhost.

Nosso vhost contém a seguinte configuração:

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.2:9126/<path>/$1

Isso funciona na maioria dos casos.

Agora, o arquivo htaccess faz, entre outras coisas, isso:

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule  ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule  ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

Como o site é um multiblog em subdiretórios, li que o URL /blogname/wp-admin/load-styles.php?xxxx deve ser reescrito como wp-admin / load-styles.php? Xxx (a segunda regra de reescrita). Mas olhando para o log mod_proxy, a solicitação que é passada na verdade é /blogname/wp-admin/load-styles.php.

Eu li isso como um problema de precedência - a regra ProxyPass é acionada antes que todas as RewriteRules tenham sido resolvidas.

Estou frustrado - qual pode ser a causa?

Konrad Neuwirth
fonte
Você já tentou colocar as reescritas no vhost e não no .htaccess? (Certifique-se de cuidar da barra à esquerda se o fizer.)
Ladadadada
Isso poderia ser apenas uma solução paliativa: o software que escreve as regras de reescrita é o próprio WordPress. Ele é usado para atualizar as regras de vez em quando (e no processo de uma atualização), por isso não posso escondê-las totalmente do espaço da web.
precisa
@KonradNeuwirth Funciona corretamente quando você muda para o proxy via a RewriteRulecom a [P]bandeira, abaixo das outras regras?
Shane Madden

Respostas:

12

Encontrei esta solução, não sei se é a melhor maneira, mas funciona para mim.

  1. Remova a linha:

    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.2:9126/<path>/$1
    
  2. Adicione isso na sua diretiva:

    <Directory /var/www/yoursiste.com>
        Options -Indexes +FollowSymLinks -ExecCGI +MultiViews
    
        AllowOverride All
    
        <IfModule mod_proxy_fcgi.c>
            RewriteEngine On
            RewriteBase /
            RewriteOptions InheritBefore
            RewriteCond %{REQUEST_FILENAME} -f
            RewriteRule ^([^\.]+\.php)$ fcgi://127.0.0.2:9126/var/www/yoursite.com/$1 [L,P]
        </IfModule>
    
        Order allow,deny
        allow from all
    
        <IfVersion >= 2.4>
            Require all granted
        </IfVersion>
    </Directory>
    

    Todos os arquivos php reais serão redirecionados para o proxy fcgi.

    E o " RewriteOptions InheritBefore " Isso força a configuração atual a herdar a configuração do pai, mas é aplicada antes das regras especificadas no escopo filho (.htaccess no diretório). É a única maneira que eu encontrei para ter compatibilidade entre a configuração do fcgi e a configuração do cliente .htaccess.

  3. Para controlar outros parâmetros que você pode precisar para o proxy:

    <IfModule mod_proxy_fcgi.c>
        <Proxy fcgi://127.0.0.2:9126>
            ProxySet timeout=1800 disablereuse=on
        </Proxy>
    </IfModule>
    
Gabriel Pérez S.
fonte
2

Com ProxyPassMatch, os .htaccessarquivos são ignorados. Tente usar FilesMatche SetHandler, como descrito aqui e aqui .

Peter Nowee
fonte
Não poste a mesma resposta exata várias vezes. Em vez disso, quando aplicável, vote / sinalize as perguntas como duplicadas.
Sven
Era isso que eu estava procurando. Permite usar mod_rewrite no contexto htaccess.
David
0

Mova a lógica de reescrita para as expressões ProxyPassMatch. Adicione duas linhas ProxyPassMatch adicionais antes da linha na sua configuração do vhost da seguinte maneira:

ProxyPassMatch ^/([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes)/.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/<path>/$2    
ProxyPassMatch ^/([_0-9a-zA-Z-]+/)?(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/<path>/$2
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/<path>/$1
Marshall
fonte