我们最近将我们的一个 Web 服务器切换到 apache 2.4,并通过 php-fpm 和 mod_proxy_fcgi 运行 PHP。大多数情况下,一切都运行良好,但有一个问题我至今还不明白。我们的一个站点正在运行 WordPress,它在其 .htaccess 文件中附带了一个很好的重写规则列表。但似乎这些规则与 vhost 设置中的 ProxyPass 指令配合得不是很好。
我们的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 完成之前触发。
我很困惑——这是什么原因造成的?
答案1
我找到了这个解决方案,我不知道这是否是最好的方法,但对我来说有效。
删除以下行:
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 配置之间兼容的方法。
要控制代理可能需要的其他参数:
<IfModule mod_proxy_fcgi.c> <Proxy fcgi://127.0.0.2:9126> ProxySet timeout=1800 disablereuse=on </Proxy> </IfModule>
答案2
答案3
将重写逻辑移到 ProxyPassMatch 表达式中。在 vhost 配置中的 ProxyPassMatch 行之前添加另外两行,如下所示:
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