Назад | Перейти на главную страницу

mod_rewrite в Debian Stretch нарушает работу php7.0-fpm с помощью AH01071: Получена ошибка «Неизвестный первичный скрипт \ 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 conf:

$ 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. Если мы вручную включим index.php в URL-адрес, он будет обслуживать правильный файл:

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

Есть ли какие-то изменения в apache для FPM между Debian 8 и 9, которые вызывают это? Есть ли обходной путь?

Это проблема Apache от 2.4.21 до 2.4.25 (включительно), как описано Дизассемблер в ответ на https://serverfault.com/a/847750

См. Также mod_proxy_fcgi документы

Похоже, что Stretch застрял на Apache 2.4.25, а соответствующий патч еще не был перенесен - я предполагаю, что этого никогда не будет.

Помимо компиляции вашего собственного Apache для Stretch, лучшим решением будет либо обновление до Buster, либо использование PHP через модуль Apache вместо FPM.