Chrome 访问域名错误 ERR_SSL_PROTOCOL_ERROR

2023-11-29
3分钟阅读时长
1360字
阅读

最近时间, 偶然发现曾经正常服务的某个 HTTPS 域名无法正常打开, 提示 ERR_SSL_PROTOCOL_ERROR 错误。

问题表现

Chrome 访问特定域名(https) 页面显示系统错误页:

This site can't provide a secure connection
....
ERR_SSL_PROTOCOL_ERROR

排查过程

  1. 无脑的习惯预判 SSL 证书 过期了 或 忘更新了

搂了一眼, 并不是

  1. 于是再次习惯性的预判是 nginx 配置问题

查看了下 nginx 的 vhost 站点 ssl 配置, 并无明显问题, 但还是尝试调整了 ssl_protocolsssl_ciphers 的设置,然并卵, 依旧无用。

开始觉得问题可能没那么简单了

  1. 思索了几秒, 判断大概率服务器自身问题了

毕竟是 SSL 错误, 如果 nginx 设置没问题,那么很可能是系统 openssl 版本问题

核查了下系统版本:

$ openssl version -a

OpenSSL 1.0.1e-fips 11 Feb 2013
built on: Thu Nov  6 12:33:36 UTC 2014
platform: linux-x86_64
options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/etc/pki/tls"
engines:  rdrand dynamic

好像文字也无法描述此时的表情(早期系统的运维很薄弱很随意, so)

于是, 就 自以为是 的决定换上常用的 1.1.1w 版本应该就会好

# 准备 & 下载
cd /usr/local/src
wget --no-check-certificate https://www.openssl.org/source/openssl-1.1.1w.tar.gz
tar -xvzf openssl-1.1.1w.tar.gz

# 编译安装
cd openssl-1.1.w
set OPENSSL_HOME=/usr/local/server/openssl-1.1.1w
./config shared \
    --openssldir=$OPENSSL_HOME \
    --prefix=$OPENSSL_HOME
make && make install

# 备份
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak

# 替换
ln -s $OPENSSL_HOME/bin/openssl /usr/bin/openssl

# 注册更新
touch /etc/ld.so.conf.d/openssl.conf
echo "$OPENSSL_HOME/lib" >> /etc/ld.so.conf.d/openssl.conf

ldconfig -v | grep openssl

一顿操作猛如虎, 然而, 奇迹并未发生, WTF ~ 总不能重新编译 nginx 尝试修正吧 ~ 毕竟是生产机器, 上面服务和站点非常多, 不到万不得已先不这么搞(好吧,给自己刨坑了)

  1. 遂, 祭出搜索大法, 没有什么问题是搜索解决不了的

浑浑噩噩 2B 搬砖的这些年, 虽然还在保持着与时俱进,尽力站在前沿,尽力撑住广度的认知, 但各种不可抗力 以及 可抗(可不抗) 因素也时刻缠绕, 也许我真的已经不是曾经的那个少年了。

发现这个问题出现一段时间了, 但并不久远, 说明可能是某种更新行为引起的。 网上各种说法和解法也是参差不齐,最终我觉得应该是 chrome 搞出来的事。

  1. 换了个电脑使用 Chrome 访问一切正常

访问正常的 chrome 版本不是最新, 比有问题的 chrome 版本落后了好几个版本。 那么,基本是确定了,是由于 Chrome 更新了跟安全相关的某些功能调整引起的兼容问题。

同时看到一篇文章里提到最终的祸首: Disable SHA1 in TLS server handshakes by default

由于 chrome 的这次更新后, 默认禁用了 TLS 握手时的 SHA1 的加密方式, 但一些 系统(比如 现在这台)仍旧使用着 低版本 的 openssl, 而 低版本 的 openssl 存在 BUG,会 强制使用 SHA1 那么,问题就是这么产生的了

最简单处理 (掩耳盗铃), 客户端浏览器修改配置:

Allow SHA-1 server signatures in TLS. 的配置项改为 Disabled

chrome系统配置选项

  1. 尝试最终修正

话说回来, 一开始就给服务器升级了 openssl1.1.1, 为什么没作用呢, 想了许久,突然返过味儿来了,毕竟是 nginx 提供的 web 服务, SSL 错误不见得是配置问题,应该是 nginx 的编译配置问题。

于是核查 nginx 编译配置

$ nginx -V

nginx version: nginx/1.6.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/server/nginx --error-log-path=/data/log/nginx/error.log --http-log-path=/data/log/nginx/access.log --http-client-body-temp-path=/usr/local/server/nginx/cache/client_temp --http-proxy-temp-path=/usr/local/server/nginx/cache/proxy_temp --http-fastcgi-temp-path=/usr/local/server/nginx/cache/fastcgi_temp --http-uwsgi-temp-path=/usr/local/server/nginx/cache/uwsgi_temp --http-scgi-temp-path=/usr/local/server/nginx/cache/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'

果然, 没有 --with-openssl 配置

那么只能重新编译更新了

cd /usr/local/src/nginx1.6.1

./configure \
--prefix=/usr/local/server/nginx \
--error-log-path=/data/log/nginx/error.log \
--http-log-path=/data/log/nginx/access.log \
--http-client-body-temp-path=/usr/local/server/nginx/cache/client_temp \
--http-proxy-temp-path=/usr/local/server/nginx/cache/proxy_temp \
--http-fastcgi-temp-path=/usr/local/server/nginx/cache/fastcgi_temp \
--http-uwsgi-temp-path=/usr/local/server/nginx/cache/uwsgi_temp \
--http-scgi-temp-path=/usr/local/server/nginx/cache/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-ipv6 \
--with-http_spdy_module \
--with-cc-opt='-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' \

# 增加 openssl 源码目录
--with-openssl=/usr/local/src/openssl-1.1.1w

# 仅编译 (不 install)
make

结果, 编译失败!!!

  1. 修正编译

发现 nginx 与 openssl 也存在一定的 版本匹配问题

nginx 肯定不能随便升级, 那么只能降低 openssl 的版本, nginx 当时编译时依赖的 1.0.1 的 openssl, 那么需要降低到 1.0.x 系列的最新版应该就行 (实际也是如此, 当时这 BUG 也是在 1.0.2 就被官方补丁修正了)

# 重新下载 openssl
cd /usr/local/src
wget --no-check-certificate https://www.openssl.org/source/openssl-1.0.2u.tar.gz
tar -xvzf openssl-1.0.2u.tar.gz

# 重新编译 nginx
cd /usr/local/src/nginx
./configure \
# ...其他参数略
--with-openssl=/usr/local/src/openssl-1.0.2u

# 备份 nginx
cp /usr/local/server/nginx/sbin/nginx /usr/local/server/nginx/sbin/nginx_bak

# 热更 nginx
cd /usr/local/src/nginx
make upgrade
  1. chrome 浏览器重新访问确认已正常

结束手工

Avatar
zfkun 喜欢游戏、热爱技术、追求艺术、崇尚自由、渴望精彩、最爱唠叨