nginx ingress controller 的HSTS配置

今天遇到一个奇怪的问题,在k8s里通过nginx ingress controller设置的ingress 里使用tls字段设置了https证书之后,在浏览器里所有的子域名都被定向到了https,而我们的证书不支持泛域名,所以访问就会报错

定位了一番,发现是nginxHSTS配置导致的,HSTSHTTP Strict Transport Security,是现代浏览器都支持的Web安全协议, 作用是强制客户端使用HTTPS与服务器创建连接.

采用HSTS协议的网站将保证浏览器始终连接到该网站的HTTPS加密版本,不需要用户手动在URL地址栏中输入加密地址,而这与在服务端做重定向不同(nginx与大部分负载均衡可以配置将http请求定向到https)

HSTS的作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接。服务器开启HSTS的方法是,当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含Strict-Transport-Security字段。非加密传输时设置的HSTS字段无效。

比如,https://xxx 的响应头含有Strict-Transport-Security: max-age=31536000; includeSubDomains。这意味着两点:
在接下来的一年(即31536000秒)中,浏览器只要向xxx或其子域名发送HTTP请求时,必须采用HTTPS来发起连接。比如,用户点击超链接或在地址栏输入 http://xxx/ ,浏览器应当自动将 http 转写成 https,然后直接向 https://xxx/ 发送请求。
在接下来的一年中,如果 xxx 服务器发送的TLS证书无效,用户不能忽略浏览器警告继续访问网站

nginx ingress controller 默认开启了HSTS并且启用了includeSubDomains, 这导致了我描述的问题,解决的方法很简单,就是在nginx的配置configMap里添加hsts-include-subdomains: "false",注意:不能加在annotations里,参考文档

附上在Chrome里检查HSTS的方法, 访问chrome://net-internals/#hsts,在Query HSTS/PKP domain里输入域名即可查询

可惜的是没找到好的方法清空已经获取的HSTS配置,默认是15724800 秒(半年),即便是清空浏览器缓存也不行,已经踩坑的苟且方法是可以用浏览器的隐身模式访问