问题
做测试的时候有个偶然发现
curl 显示的头部信息竟然与 nginx 中的配置不一样
又去看了一眼 nginx 配置参数,我并不认为有什么错误的地方。
配置文件
全局配置 nginx.conf
http {
......
# 禁止被嵌入框架
add_header X-Frame-Options DENY;
# 防止在IE9、Chrome和Safari中的MIME类型混淆攻击
add_header X-Content-Type-Options nosniff;
# 防止 XSS 跨站攻击
add_header X-Xss-Protection "1; mode=block";
......
include /etc/nginx/conf.d/*.conf;
}
子域配置 blog.conf
server{
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
}
分析
显然只有 server 块中的 add_header 被实现,http 块中添加的响应头并没有出现,马上对另外几个子域测试了一下,并没有出现这种情况。
第一反应觉得可能是 http 块不支持 add_header ,但仔细想想马上就否定了这个可能,首先不说 http 块不支持添加响应头不合理,即便不支持那也应该会当场报错才对。
CDN 当然也可以排除,因为我根本没用 CDN ,而且 CDN 一般也不会做这种事。
有意思的是,http 访问也能正常出现响应头,我配置了全站 https 因此 http 访问是单独在一个 server 进行重定向的。
而值得注意的是,先前在还未实现对 http(s) 访问的全局配置时,为了实现 HSTS Preload 标准,我将 HSTS 响应头写进了 server 块中,并且只写到了主域的配置中,之后一直没改过来。
而 http 块中的 add_header 在申请 HSTS 之前就已经加入也一直正常。
那么问题只能出在不同层级的指令继承上
解决
试着编辑子域配置,先将配置中的 add_header 内容注释掉,再执行 nginx -s reload
,查询响应头信息,这时 http 块中的响应头果然正常显示。
原因
这是在 解决HSTS Warning: Unnecessary HSTS header over HTTP 时引发的错误
事实上在 nginx.org 的 Module ngx_http_headers_module 中,有这样一段内容
There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.
可能会存在多个add_header指令。当且仅当当前级别没有定义add_header指令时,这些指令才从上一级继承。
也就是说,我在 server 块中添加了 HSTS 响应头,就把上一层级 http 中的 add_header 信息就被丢弃了。而我在其他子域中未加入 HSTS 响应头,所以才不会出现这一情况。
这么做的优点大概就是便于控制响应头添加位置吧,但有时候确实有些麻烦,如果有多个子层级使用同一响应头信息,又要额外配置不同 header 时就不得不只能重复写同一指令。
本文由 CloverGit 发表
本站文章未注明出处均为本站原创
采用 知识共享署名-相同方式共享 4.0 (CC BY 4.0) 国际许可协议进行许可
转载时务必遵守许可协议进行署名
最后编辑于: 2020 年 9 月 20 日 03 时 27 分