Debian Stretch 上的 mod_rewrite 因 AH01071 破坏了 php7.0-fpm:出现错误“主脚本未知\n”

Debian Stretch 上的 mod_rewrite 因 AH01071 破坏了 php7.0-fpm:出现错误“主脚本未知\n”

我们刚刚构建了一个新的 Debian 9.8 服务器来替换我们的 8.11 服务器,以便测试和升级到 php7。我们已经安装了 apache2、php7.0-fpm 并引入了现有的虚拟主机配置,其中包含以下内容:

<Directory "${virtualhost_path}/public_html">
    Require all granted
    AllowOverride None
    Options FollowSymLinks

    <IfModule mod_rewrite.c>
        RewriteEngine On

        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^/?(.*)$ /index.php/$1 [L]
    </IfModule>
</Directory>

这是(库存、标准) php-fpm 配置:

$ cat /etc/apache2/conf-enabled/php7.0-fpm.conf 

# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php7.c>
<IfModule proxy_fcgi_module>
    # Enable http authorization headers
    <IfModule setenvif_module>
    SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
    </IfModule>

    <FilesMatch ".+\.ph(p[3457]?|t|tml)$">
        SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
    </FilesMatch>
    <FilesMatch ".+\.phps$">
        # Deny access to raw php sources by default
        # To re-enable it's recommended to enable access to the files
        # only in specific virtual host or directory
        Require all denied
    </FilesMatch>
    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
        Require all denied
    </FilesMatch>
</IfModule>
</IfModule>

但是,重写似乎无法正常工作。当我们发出此请求时,我们得到了以下结果(在浏览器中,我们只看到“文件未找到”):

$ curl -I https://hostname/services/login

HTTP/1.1 404 Not Found
Date: Fri, 29 Mar 2019 02:32:01 GMT
Server: Apache/2.4.25 (Debian)
Content-Type: text/html; charset=UTF-8

我们在日志中看到这一点:

[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3f0a0/initial] [perdir /home/jay/online/public_html/] add path info postfix: /home/jay/online/public_html/services -> /home/jay/online/public_html/services/login
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3f0a0/initial] [perdir /home/jay/online/public_html/] strip per-dir prefix: /home/jay/online/public_html/services/login -> services/login
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3f0a0/initial] [perdir /home/jay/online/public_html/] applying pattern '^/?(.*)$' to uri 'services/login'
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3f0a0/initial] [perdir /home/jay/online/public_html/] rewrite 'services/login' -> '/index.php/services/login'
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3f0a0/initial] [perdir /home/jay/online/public_html/] trying to replace context docroot /home/jay/online/public_html with context prefix 
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3f0a0/initial] [perdir /home/jay/online/public_html/] internal redirect with /index.php/services/login [INTERNAL REDIRECT]
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3dc00/initial/redir#1] [perdir /home/jay/online/public_html/] add path info postfix: /home/jay/online/public_html/index.php -> /home/jay/online/public_html/index.php/services/login
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3dc00/initial/redir#1] [perdir /home/jay/online/public_html/] strip per-dir prefix: /home/jay/online/public_html/index.php/services/login -> index.php/services/login
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3dc00/initial/redir#1] [perdir /home/jay/online/public_html/] applying pattern '^/?(.*)$' to uri 'index.php/services/login'
[hostname/sid#7f0e8fd47d30][rid#7f0e8fc3dc00/initial/redir#1] [perdir /home/jay/online/public_html/] pass through /home/jay/online/public_html/index.php
[hostname/sid#7f0e8fd47d30][rid#7f0e8830a0a0/subreq] [perdir /home/jay/online/public_html/] add path info postfix: /home/jay/online/public_html/services -> /home/jay/online/public_html/services/login
[hostname/sid#7f0e8fd47d30][rid#7f0e8830a0a0/subreq] [perdir /home/jay/online/public_html/] strip per-dir prefix: /home/jay/online/public_html/services/login -> services/login
[hostname/sid#7f0e8fd47d30][rid#7f0e8830a0a0/subreq] [perdir /home/jay/online/public_html/] applying pattern '^/?(.*)$' to uri 'services/login'
[hostname/sid#7f0e8fd47d30][rid#7f0e8830a0a0/subreq] [perdir /home/jay/online/public_html/] rewrite 'services/login' -> '/index.php/services/login'
[hostname/sid#7f0e8fd47d30][rid#7f0e8830a0a0/subreq] [perdir /home/jay/online/public_html/] trying to replace context docroot /home/jay/online/public_html with context prefix 
[hostname/sid#7f0e8fd47d30][rid#7f0e8830a0a0/subreq] [perdir /home/jay/online/public_html/] internal redirect with /index.php/services/login [INTERNAL REDIRECT]
AH01071: Got error 'Primary script unknown\n'

出现根据日志正确重写所有内容,但它似乎没有按预期提供正确的 index.php 文件PATH_INFO。如果我们手动在 URL 中包含 index.php 文件,它会提供正确的文件:

$ curl -I https://hostname/index.php/services/login

HTTP/1.1 200 OK
Date: Fri, 29 Mar 2019 02:35:13 GMT
Server: Apache/2.4.25 (Debian)
Content-Type: text/html; charset=UTF-8

但是,此配置的重点在于避免index.php在 URL 中出现。

Debian 8 和 9 之间的 apache FPM 是否有一些变化导致此问题? 有什么解决方法吗?

答案1

这是 Apache 2.4.21 - 2.4.25(含)版本中的一个问题,具体描述如下:反汇编程序在答案中https://serverfault.com/a/847750

另请参阅mod_proxy_fcgi 文档

Stretch 似乎停留在 Apache 2.4.25 上,并且相关补丁尚未被反向移植 - 我认为它永远不会被反向移植。

除了为 Stretch 编译自己的 Apache 之外,最好的解决方案似乎是升级到 Buster 或通过 Apache 模块而不是 FPM 使用 PHP。

相关内容