Понимание apache 2.4 mod_proxy_fcgi и RewriteRules в htaccess

9

Недавно мы переключили один из наших веб-серверов на Apache 2.4 и работали с PHP через php-fpm и mod_proxy_fcgi. Почти все работает довольно хорошо, но есть одна проблема, которую я пока не понимаю. Один из наших сайтов работает под управлением WordPress, который содержит хороший список правил переписывания в своем файле .htaccess. И кажется, что они не очень хорошо работают с директивой ProxyPass в настройке vhost.

Наш vhost содержит следующую конфигурацию:

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

Это работает в большинстве случаев.

Теперь файл htaccess делает, помимо прочего, следующее:

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]

Поскольку сайт представляет собой мультиблог в подкаталогах, я прочитал, что URL /blogname/wp-admin/load-styles.php?xxxx должен быть переписан как wp-admin / load-styles.php? Xxx (второе правило перезаписи). Но, глядя на журнал mod_proxy, фактически передается запрос /blogname/wp-admin/load-styles.php.

Я прочитал это как проблему с приоритетом - правило ProxyPass срабатывает до того, как все RewriteRules были отработаны.

Я в тупике - в чем может быть причина?

Конрад Нойвирт
источник
Вы пробовали помещать переписанные данные в vhost, а не в .htaccess? (Обязательно позаботьтесь о
главном слэше,
Это может быть только временное решение: программное обеспечение, которое пишет правила перезаписи, - это сам WordPress. Он используется для обновления правил время от времени (и быть в процессе обновления), поэтому я не могу полностью скрыть их из веб-пространства.
Конрад Нойвирт
@KonradNeuwirth Правильно ли работает, когда вы переключаетесь на прокси через флаг RewriteRuleс [P]флагом ниже других правил?
Шейн Мэдден

Ответы:

12

Я нашел это решение, я не знаю, является ли это лучшим способом, но работает для меня.

  1. Удалить строку:

    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.2:9126/<path>/$1
    
  2. Добавьте это в вашу директиву:

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

    Все настоящие php файлы будут перенаправлены на fcgi proxy.

    И « RewriteOptions InheritBefore » Это заставляет текущую конфигурацию наследовать конфигурацию родителя, но применяются до правил, указанных в дочерней области (.htaccess в каталоге). Это единственный способ совместимости между конфигурацией fcgi и конфигурацией клиента .htaccess.

  3. Для управления другими параметрами вам может понадобиться прокси:

    <IfModule mod_proxy_fcgi.c>
        <Proxy fcgi://127.0.0.2:9126>
            ProxySet timeout=1800 disablereuse=on
        </Proxy>
    </IfModule>
    
Габриэль Перес С.
источник
2

С ProxyPassMatch, .htaccessфайлы игнорируются. Попробуйте использовать FilesMatchи SetHandlerвместо этого, как описано здесь и здесь .

Питер Нови
источник
Пожалуйста, не размещайте один и тот же ответ несколько раз. Вместо этого, когда это применимо, проголосуйте / отметьте вопросы как дубликаты.
Свен
Это то, что я искал. Это позволяет использовать mod_rewrite в контексте htaccess.
Дэвид
0

Переместите логику перезаписи в выражения ProxyPassMatch. Добавьте две дополнительные строки ProxyPassMatch перед строкой в ​​конфигурации vhost следующим образом:

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
Маршалл
источник