Nginx默认配置导致CDN源站泄露

最近查看nginx访问日志的时候,发现不少直接访问源站的请求。网站接入CDN后,如果源站地址没有发布或者泄露,理论上只有CDN会去请求源站。怎么会那么多直接访问源站的请求呢?

发现异常

在Nginx日志中,发现不少直接访问源站的请求。起初还以为是被扫描工具扫描到了源站,没怎么在意。

后来发现nginx日志中部分访问源站的请求来自搜索引擎(HTTP Referer)。随后在搜索引擎一搜索,才发现源站已经被搜索引擎收录了,囧~

开始排查

整理了一下思路:

  • 博客地址:www.web-security.cn
  • 源站地址: hexo.web-security.cn
  • CDN:腾讯云CDN(内容加速网络)
  • 博客是纯静态页面,没有PHP代码
  • 博客文章中的链接使用的是相对路径,没有出现域名

源站地址即没有出现在博客文章中,又没有提交到搜索引擎,怎么会被搜索引擎收录呢?

直到昨天,才发现原因。
发布了一篇文章后,按照惯例,打开网站看看是否可以正常访问。

结果点开文章内容的时候,发现浏览器地址栏的域名从www.web-security.cn变成了源站域名hexo.web-security.cn

按下F12查看网络记录,才发现产生了一个301重定向:

点击文章:
https://www.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu

301跳转至:
http://hexo.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu/

查看HTTP响应头:

1
2
3
4
5
HTTP/1.1 301 Moved Permanently
Server: nginx/1.17.3
......
Location: http://hexo.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu/
......

从HTTP响应头中的Location字段可以看到,301跳转到了源站。

原理分析

访问的地址如果是一个文件夹,且没有以”/“结尾,nginx就会发送一个301重定向,重定向后的地址加上了“/”。而CDN回源时使用域名hexo.web-security.cn,所以跳转时就直接跳转到hexo.web-security.cn这个域名了。

解决方案

经过测试,以下三种方案,使用以下任意一种方法均可解决问题:

设置nginx重定向为相对重定向(推荐)

nginx重定向时默认为绝对重定向,即重定向地址中带有域名,例如:

1
Location: http://hexo.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu/

在nginx配置文件的server段中,配置absolute_redirectoff即可:

1
2
3
4
5
server{
absolute_redirect off;

// 其它配置...
}

配置后重定向的地址不带域名:

1
Location: /install_php7.3_nginx_mariadb_on_ubuntu/

在CDN中开启301/302回源跟随(不建议)

301/302回源跟随的意思时,如果源站响应了一个重定向,则CDN节点直接获取跳转后的资源返回给用户,浏览器不会收到301/302跳转。

不过不建议使用这种方法解决,有以下限制:

  1. CDN需要支持301/302回源跟随这个选项;
  2. 网站中的链接时相对链接(否则,点击网页上的链接后,就直接请求源站了)。

加速域名和回源域名使用相同的域名(不建议)

以本站为例,加速域名和回源域名均使用www.web-security.cn,源站地址使用hexo.web-security.cn或服务器IP。域名解析不用变,修改nginx配置,将源站域名设置为www.web-security.cn

设置以后,依然会出现301跳转,只不过跳转后还是同一个域名。

跳转流程更复杂了:

  1. 访问:
    https://www.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu

  2. 结尾没有加“/”,301跳转至:
    http://www.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu/

  3. 没有使用HTTPS,302跳转至目的地址:
    https://www.web-security.cn/install_php7.3_nginx_mariadb_on_ubuntu/