前几天给服务器重装了系统,然后选择了1panel面板。
先部署了几个静态网站,接下来我们以netessx.com为例。

问题描述

每次访问netessx.com,都有概率出现两种情况:正常访问和404页面;接着反复刷新,正常页面和404页面就会交替出现。

如视频中所示

前提环境

到达服务器的每一次请求,请求都会经过以下路径:

Request --> Cloudflare --> Safeline(雷池) --> Nginx

在我翻看了雷池和Nginx的日志后,我发现了一个奇怪的现象:
我请求了10次,其中,5次是404,5次正常。而在雷池的日志中,记录到了10次200响应;在nginx对应的站点日志中,只有5次请求日志,并且都是200;所有日志中都没有404响应,全都是200。
这说明另外5次请求通过了雷池,但是在nginx中并没有被匹配到netessx.com这个站点,至于为什么没有404的日志...当时我也一头雾水。

排查问题

于是我集中注意检查nginx的配置。
1panel的openresty容器的nginx配置文件位于/usr/local/openresty/nginx/conf中,打开其中的nginx.conf,发现在http块中有以下三行

include /usr/local/openresty/nginx/conf/conf.d/*.conf;
include /usr/local/openresty/nginx/conf/default/*.conf;
include /usr/local/openresty/1pwaf/data/conf/waf.conf;

其中,conf.d是映射的宿主机的/opt/1panel/www/conf.d目录,其中存放每个站点的nginx配置文件
而default目录,是映射的/opt/1panel/apps/openresty/openresty/conf/default目录。
waf.conf肯定不是造成问题的关键,而conf.d也没有什么大问题,于是我打开default目录,其中有两个文件

00.default.conf  default.conf

default.conf就是来监听本地请求的
00.default.conf同时监听了443端口,server_name也被设置成了默认,其中的监听语句如下:

    listen 81 ; 
    listen [::]:81 ; 
    listen 444 ssl ; 
    listen [::]:444 ssl ; 
    server_name _; 
    index 404.html; 
为了避免与safeline冲突,我设置nginx默认监听81和444端口

打开对应目录下的404.html,修改其中内容,发现访问时404页面的内容也随之改变。
于是我终于能确认,返回404页面的请求被nginx路由到了这个默认配置的server块下,而之所以没404日志,是因为默认配置设置了404页面为index。原来是这样,哈哈哈...

真相水落石出...了吗?

可是,为什么会这样?请求netessx.com为什么会被默认的server块截获?又为什么会出现反复横跳的情况?

注意到在00.default.conf的配置中,同时监听了

    listen [::]:81 ; 
    listen [::]:444 ssl ; 

这代表着监听ipv6
而我站点配置中,并没有监听ipv6

而在请求到达nginx时,会随机出现ipv4或者ipv6地址的访问。如果是ipv4,那就成功进入到站点对应的server块;可如果是ipv6,由于站点没有监听ipv6,就会被路由到默认配置的server块中,展示404页面。这就是真正的原因。

那么解决方案就很简单了,只需要在1panel创建站点时勾选监听ipv6,就可以避免这种情况。或者是在站点配置文件中手动监听ipv6地址。

结语

一定要有耐心...