文章目录
原因简述
由于浏览器的 HSTS 策略,开启指定网站的 HTTPS 访问导致浏览器强制使用 HTTPS 访问面板。
点我立即跳到修复方法
背景详情
今天在使用 1Panel 配置网站的时候,给域名上传了 SSL 证书、开启了 HTTPS 访问。
然后面板就死活进不去了,浏览器报告连接不安全。
本来以为是 OpenResty 把所有访问该域名的请求都重定向到了 HTTPS。(当然该猜测是错误的,一个成熟的软件哪会有这么严重的问题)
发生这件事有以下几个条件:
- 正在配置的网站域名和面板域名相同,都是 xxx.example.com 。
- 面板先前没有开启 HTTPS 访问。
- 配置 HTTPS 时选择了 HTTP 自动访问 HTTPS(如下图)。
- 配置完成后对 https://xxx.example.com 进行了访问。
经过研究发现,其实这是浏览器 HSTS(HTTP Strict Transport Security)策略导致的问题。
其直接原因是 1Panel 在 OpenResty 配置文件中为我们默认添加了如下的响应头:
add_header Strict-Transport-Security "max-age=31536000";
我们在首次访问 http://xxx.example.com 以后,OpenResty 会通过如下指令将请求重定向到 https://xxx.example.com/
if ($scheme = http) {
return 301 https://$host$request_uri;
}
301 重定向访问 https 后,浏览器就会收到上述的 Strict-Transport-Security Header,并记录下来,有效期是一年。
下次使用 HTTP 协议访问 xxx.example.com 域名,浏览器就会自动进行 307 重定向到 HTTPS。而前面提到,面板没有开启 HTTPS,导致面板无法进入。
你甘心让自己的面板持续一年无法访问吗?(笑)如果不是的话,就看看下面的修复步骤吧~
修复步骤
1、移除该域名的 HSTS 记录
对于 Chrome,可以访问 chrome://net-internals/#hsts;
对于 Edge,可以访问 edge://net-internals/#hsts;
对于其它浏览器,可以自行搜索一下在哪配置 HSTS ~
找到 Delete
字眼,输入域名,按下 Delete
按钮,删除记录!
删除完成后,面板就可以正常访问了!!!!!
但是,还没完!
2、方案1:立即给面板添加 https 访问(最优)
只需在1Panel→面板设置→安全→HTTPS,开启并选择之前传过的证书就好。
设置完以后面板就安全了,也不会再因为上述问题导致无法访问。
至此,问题解决。
2、方案2:删除 Strict-Transport-Security 响应头
删除响应头意味着以后的 HTTP 访问都需要经过一次 301 重定向,不推荐。
当然,如果确实有同域名不同端口的服务无法启用 HTTPS 访问,那也只能这样了。
① 修改配置文件 /opt/1panel/apps/openresty/conf/conf.d/xxx.example.com.conf
如下:
# ...
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# !注释掉下面这行
# add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
proxy_set_header X-Forwarded-Proto https;
# ...
② 重载 OpenResty 服务,详见 附录:重载OpenResty服务
附录
重载 OpenResty 服务
当前版本的 1Panel 是支持在面板上进行重载的,直接在面板上操作即可。以下是手动重载的方法。
提示:执行 docker 命令,如果不是 root 用户,记得加上 sudo ~
① 首先,使用 docker ps | grep -i openresty
查看容器的名称/ID
$ docker ps | grep -i openresty
第一串字符是容器 ID、1Panel 开头的是容器名称,这俩都能用作容器的标识
② 进入容器,执行命令:
# 进入容器CONTAINER_ID的命令行
$ docker exec -it CONTAINER_ID /bin/bash # docker exec -it 2931c7b68ebc /bin/bash
# 检查配置文件确认配置修改正确
$ openresty -t
# nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
# nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
# 见到ok字样后重载配置文件, 立即生效;如果没有ok, 说明配置文件有问题, 根据提示修改!
$ openresty -s reload
至此,服务重载完成。
(错误的)修改配置文件
警告:此步骤是多余的,是因为刚开始自己对这个问题的理解不够透彻。保留在此只是为了记录在哪修改、Nginx 如何进行多条件判断。
1Panel 的 OpenResty 是在容器中运行的,文件持久化保存在 /opt/1panel/apps/openresty/
我们需要手动修改配置文件,找到 /opt/1panel/apps/openresty/conf/conf.d/xxx.example.com.conf
,修改配置文件如下:
# 如此写是因为,nginx的配置不支持&&和嵌套if
# 当http且80端口时,才强制https
set $flag 0;
if ($scheme = http) {
set $flag "${flag}1";
}
if ($server_port = 80) {
set $flag "${flag}2";
}
if ($flag = 012) {
return 301 https://$host$request_uri;
}
# 以下的原来的配置
# if ($scheme = http) {
# return 301 https://$host$request_uri;
# }
其实 1Panel 添加的 server 配置块里是有指定 listen 80;
的,其它端口不会访问这个 server 块,在此问题中并不需要这样子操作。