Недавно мы переключили один из наших веб-серверов на 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 будут отработаны.
Я в тупике - в чем может быть причина?
Я нашел это решение, не знаю, лучший ли это способ, но у меня работает.
Удалите строку:
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.2:9126/<path>/$1
Добавьте это в свою директиву:
<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.
И "RewriteOptions InheritBefore"Это заставляет текущую конфигурацию наследовать конфигурацию родителя, но применяются до правил, указанных в дочерней области (.htaccess в каталоге). Это единственный способ, которым я обнаружил совместимость между конфигурацией fcgi и клиентским .htaccess config.
Для управления другими параметрами прокси может потребоваться:
<IfModule mod_proxy_fcgi.c>
<Proxy fcgi://127.0.0.2:9126>
ProxySet timeout=1800 disablereuse=on
</Proxy>
</IfModule>
С участием ProxyPassMatch
, .htaccess
файлы игнорируются. Попробуйте использовать FilesMatch
и SetHandler
вместо этого, как описано Вот и Вот.
Переместите логику перезаписи в выражения 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