将无后缀文件作为 PHP 脚本执行

问题描述

我正在尝试在不重写旧网站的情况下复活它(目前)。该站点依赖于将特定的无后缀文件(例如,corporate)作为 PHP 脚本执行。最初(很久 以前),我在 .htaccess 文件中使用了以下内容

<Files corporate>
  SetHandler PHP-script
</Files>

因此,http://my_site.com/corporate 会将 corporate内容作为 PHP 脚本执行。效果很好,但那是很久以前的事了。

我正在尝试使用 Plesk 版本 18、PHP 7.1 运行 Apache/Nginx(不使用 .htaccess)并使用 PHP FPM 袜子来执行此操作。我期望将以下内容添加到 Plesk 中的 Apache 指令:

<Files "corporate">
  SetHandler proxy:unix:///run/plesk/PHP-fpm.sock|fcgi://127.0.0.1:9000
</Files>

没用。

文件 /run/plesk/PHP-fpm.sock 存在,但它是一个符号链接,似乎没有指向任何地方。 (我谦虚地承认,我不太了解 PHP FPM 的工作原理。)我执行了 service plesk-PHP71-fpm status 并得到以下结果:

Redirecting to /bin/systemctl status plesk-PHP71-fpm.service
● plesk-PHP71-fpm.service - The PHP 7.1.33 FastCGI Process Manager
   Loaded: loaded (/usr/lib/systemd/system/plesk-PHP71-fpm.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/plesk-PHP71-fpm.service.d
           └─limit_nofile.conf
   Active: active (running) since Tue 2021-07-13 07:36:31 MST; 6h ago
  Process: 13239 ExecReload=/bin/kill -USR2 $MAINPID (code=exited,status=0/SUCCESS)
 Main PID: 879 (PHP-fpm)
   Status: "Processes active: 0,idle: 1,Requests: 292,slow: 0,Traffic: 0req/sec"
   CGroup: /system.slice/plesk-PHP71-fpm.service
           ├─  879 PHP-fpm: master process (/opt/plesk/PHP/7.1/etc/PHP-fpm.conf)
           └─13243 PHP-fpm: pool plesk-PHP71-fpm.plesk-service.localdomain

Jul 13 12:30:28 216-55-178-166.phx.dedicated.codero.com sendmail[28593]: plesk sendmail[28593]: SKIP during call 'check-quota' handler
Jul 13 12:41:09 216-55-178-166.phx.dedicated.codero.com check-quota[30562]: Starting the check-quota filter...
Jul 13 12:41:09 216-55-178-166.phx.dedicated.codero.com sendmail[30561]: plesk sendmail[30561]: handlers_stderr: SKIP
Jul 13 12:41:09 216-55-178-166.phx.dedicated.codero.com sendmail[30561]: plesk sendmail[30561]: SKIP during call 'check-quota' handler
Jul 13 13:21:28 216-55-178-166.phx.dedicated.codero.com check-quota[5502]: Starting the check-quota filter...
Jul 13 13:21:28 216-55-178-166.phx.dedicated.codero.com sendmail[5501]: plesk sendmail[5501]: handlers_stderr: SKIP
Jul 13 13:21:28 216-55-178-166.phx.dedicated.codero.com sendmail[5501]: plesk sendmail[5501]: SKIP during call 'check-quota' handler
Jul 13 13:37:01 216-55-178-166.phx.dedicated.codero.com check-quota[9506]: Starting the check-quota filter...
Jul 13 13:37:01 216-55-178-166.phx.dedicated.codero.com sendmail[9505]: plesk sendmail[9505]: handlers_stderr: SKIP
Jul 13 13:37:01 216-55-178-166.phx.dedicated.codero.com sendmail[9505]: plesk sendmail[9505]: SKIP during call 'check-quota' handler

这似乎表明 FPM 运行良好。

该网站的 error_log 文件显示 [Tue Jul 13 13:54:44.985803 2021] [cgid:error] [pid 13876:tid 140420794103552] [client 174.45.172.27:49322] End of script output before headers: cgi_wrapper 我找不到这意味着什么的解释。

测试站点的 FPM 错误文件中没有任何内容。我的网络浏览器只是报告“内部服务器错误”。我目前正在使用 corporate 的测试文件,其中包含以下简单内容<?PHP echo "This is a test."; ?>

有没有办法配置 Apache/Nginx 以允许 PHP-fpm 作为脚本执行特定的无后缀文件(例如 corporate)?

Nginx.conf


#user  Nginx;
worker_processes  1;

#error_log  /var/log/Nginx/error.log;
#error_log  /var/log/Nginx/error.log  notice;
#error_log  /var/log/Nginx/error.log  info;

#pid        /var/run/Nginx.pid;

include /etc/Nginx/modules.conf.d/*.conf;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  /var/log/Nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    #tcp_nodelay        on;

    #gzip  on;
    #gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    server_tokens off;

    include /etc/Nginx/conf.d/*.conf;
}

# override global parameters e.g. worker_rlimit_nofile
include /etc/Nginx/*global_params;

Nginx 规则

Timeout 600;
ProxyTimeout 600;
<IfModule mod_proxy_fcgi.c>
        <Directory /var/www/vhosts/my-site.com/web>
                <Files ~ .(?i:inc|html|htm)$>
                        SetHandler proxy:unix:///run/plesk/PHP-fpm.sock|fcgi://127.0.0.1:9000
                </Files>
                <Files "corporate">
                        SetHandler proxy:unix:///run/plesk/PHP-fpm.sock|fcgi://127.0.0.1:9000
                </Files>
                <Files ~ "(store|pchart\.png|returns)">
                        SetHandler proxy:unix:///run/plesk/PHP-fpm.sock|fcgi://127.0.0.1:9000
                </Files>
        </Directory>
</IfModule>

解决方法

Plesk 的技术人员弄清楚发生了什么

正如我在问题中提到的,我不是 Nginx 专家。我的理解是 Nginx 没有使用 .htaccess 文件,事实上,我对该文件所做的任何更改似乎都被忽略了。

直到 Plesk Obsidian V18,虽然他们没有解释为什么会发生这种情况,但他们的解决方案确实有效。需要注意的是,此时我仍然不知道为什么从 Plesk V17 到 V18 的更改会导致这种情况……只是确实如此。 (据我所知,同时更新了其他内容,导致此问题与 Plesk 无关。)

事实证明,.htaccess 文件中的条目...

<Files corporate>
  SetHandler php-script
</Files>

...还在那里。 它在文件中的存在创建了一个冲突的规则条件,由于我无法解释的原因,导致有用的错误消息被打印。

该语句被注释掉后,服务器 error_log 文件中会出现以下错误消息:

[Tue Jul 13 20:36:02.986967 2021] [proxy_fcgi:error] [pid 5020:tid 140329181173504] [client 91.204.25.4:57246] AH01071: Got error 'Access to the script '/var/www/vhosts/my-site.com/web/corporate' has been denied (see security.limit_extensions)\n'

好的!我以前从未设置过 security.limit_extensions,这表明当使用 <Files...></Files> 指令显式定义文件时,有关 Apache 或 Nginx 的某些内容忽略了该值。但是,无论出于何种原因,现在情况并非如此。我必须清除 Plesk 的 PHP 设置“附加指令”字段中参数的默认值:

[php-fpm-pool-settings]
security.limit_extensions =

还有繁荣!一切又开始工作了。

作为最后一个请求(如果有人可以给我留言或引导我了解更多信息),我可以在不到 5 分钟的 Google 搜索中找到有关清除 security.limit_extensions 的默认值的所有信息...

您应该只将 FPM 限制为 .php 扩展名,以防止恶意用户使用其他扩展名来执行 php 代码。 (Source)

我找不到任何如何会发生的例子。请注意,除了拥有硬件的 Codero.com 之外,我是唯一登录到此服务器(它是我的)的人。我不为其他人托管网站。谁能告诉我使用如图所示的参数是否对我有实际风险?