了解 apache 2.4 mod_proxy_fcgi 和 htaccess 中的 RewriteRules

了解 apache 2.4 mod_proxy_fcgi 和 htaccess 中的 RewriteRules

我们最近将我们的一个 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

我找到了这个解决方案,我不知道这是否是最好的方法,但对我来说有效。

  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 代理。

    并且“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文件将被忽略。请尝试使用FilesMatchSetHandler,如所述这里这里

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

相关内容