/ DEVOPS

nginx php 报错 Primary script unknown 原因分析以及解决方案

服务器被人扫描,收到报警,FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream

一看是有人在扫描,什么 wp-login.php 了,什么 phpmyadmin 了,真无聊,之前都是一直忽略,但是真的很烦,又不能关了报警。改了下配置,世界清静了。

报警如下

2017/07/26 07:39:27 [error] 20176#20176: *24531518 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 220.163.104.13, server: example.com, request: "GET //phpmyadmin/xiaobai.php HTTP/1.1", upstream: "fastcgi://ip:port", host: "example.com", referrer: "http://example.com//phpmyadmin/xiaobai.php"

2017/07/26 07:39:27 [error] 20176#20176: *24531518 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 220.163.104.13, server: example.com, request: "GET //phpmyadmin/xmm.php HTTP/1.1", upstream: "fastcgi://ip:port", host: "example.com", referrer: "http://example.com//phpmyadmin/xmm.php"

2017/07/26 07:41:56 [error] 20175#20175: *24532136 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 24.21.192.221, server: example.com, request: "GET /wp-login.php HTTP/1.1", upstream: "fastcgi://ip:port", host: "example.com"

FastCGI sent in stderr: "Primary script unknown" 报错原因

报这个错是说找不到脚本执行文件,经常出现在错误的 root 配置,文件目录错误等情况。

举个例子,域名 example.com,nginx 配置 root /var/wwwphp 文件位于 /var/www/public/index.php,访问 example.com/index.php 则会报这个错误,因为 nginx 会根据配置去寻找 /var/www/index.php 文件,当然报错了。

一般情况下,一个 phpnginx 项目只有一个入口文件 index.php 解析所有请求,其它目录都是伪静态过去的。那么其实我们根本没有必要去解析其它文件。

因此,我们只需要把目前的配置改一下。

我猜测你的 nginx 文件是这么配置的,或者跟这个很像,因为这个是 nginx 官方的配置文件

	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
	#
	#location ~ \.php$ {
	#	fastcgi_split_path_info ^(.+\.php)(/.+)$;
	#	# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
	#
	#	# With php5-cgi alone:
	#	fastcgi_pass 127.0.0.1:9000;
	#	# With php5-fpm:
	#	fastcgi_pass unix:/var/run/php5-fpm.sock;
	#	fastcgi_index index.php;
	#	include fastcgi_params;
	#}

如果你的项目从来没有请求成功过,安装完就报这个错误,不是别人攻击。那么尝试增加一个 fastcgi_param 配置项fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;location 试试。

如果跟我一样,只是为了解决被人扫描的烦恼,可以把解析所有 php 文件改为只解析入口文件 index.php 或者其它需要执行的 php 文件。

FastCGI sent in stderr: "Primary script unknown" 解决方案

第一步,只解析入口 php 文件

1,把 location ~ \.php$ 改为 location ~ ^/index\.php$ {,这样 nginx 就只能解析入口文件了。

此时,其实很不安全,一旦你的 nginx serverroot 目录内包含 php 文件,只要知道你的相对路径,就可以下载到源码了。所以还需要禁止访问除了入口文件外的 php

第二步,禁止其它 php 文件被直接访问

2,禁止 php 文件被直接访问。

location ~ \.php$ {
    return 403;
}

从此,世界安静了,其实,也真的安全了,鬼知道哪天临时上传一个东西恰好被人扫描到了。比如第三方编辑器,经常附带 php 示例代码,然后前端就直接给上传到服务器了。(其实就是身边的小事儿)