客户端访问Nginx HTTPS出现ERR_CONNECTION_CLOSED

背景

最近在Nginx接入了一个域名,配置好https证书之后,在本地浏览器访问发现提示ERR_CONNECTION_CLOSED。把排查过程大概记录一下,主要是贴一下这里的一些报错。如果之后有人也遇到了,搜两行日志也许能找到这篇文章,省下点时间。

太长不看版

在服务器本地用curl测试能否访问,若不能,则不是本文要解决的问题;若能,则有可能是云服务提供商发送了TCP重置包阻断了连接。是不是没有备案?是不是存在攻击行为被封禁了?

排查过程

Nginx配置好之后,先用Chrome访问一下,发现提示ERR_CONNECTION_CLOSED;用Safari访问一下,发现提示“Safari无法与服务器建立安全连接”。奇怪啊,用curl测试:

foo@macbook ~ % curl -v "https://www.mysite.com/"       
*   Trying 47.93.**.**:443...
* Connected to www.mysite.com (47.93.**.**) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: Connection reset by peer in connection to www.mysite.com:443 
* Closing connection 0
curl: (35) OpenSSL SSL_connect: Connection reset by peer in connection to www.mysite.com:443 

看了一下连接的IP没问题,DNS没问题,端口没问题。再用openssl测一下(一定要带-servername否则默认不发送SNI):

foo@macbook ~ % openssl s_client -debug -connect 47.93.**.**:443 -servername www.mysite.com
CONNECTED(00000003)
write to 0x600003010000 [0x157017c00] (320 bytes => 320 (0x140))
0000 - 16 03 01 01 3b 01 00 01-37 03 03 64 7e 74 e6 ed   ....;...7..d~t..
0010 - 54 8a f1 4e b9 86 bd 0f-96 6c 4a 6a ef 85 72 19   T..N.....lJj..r.
0020 - 4e ee 8d 47 7f e5 d8 68-42 6e b7 20 35 bb 2c 50   N..G...hBn. 5.,P
0030 - 56 6e c3 74 eb 3d c9 ea-37 e2 40 c8 a5 59 f2 4a   Vn.t.=..7.@..Y.J
0040 - 44 61 53 d8 71 6a 77 71-f6 ed ab 46 00 3e 13 02   DaS.qjwq...F.>..
0050 - 13 03 13 01 c0 2c c0 30-00 9f cc a9 cc a8 cc aa   .....,.0........
0060 - c0 2b c0 2f 00 9e c0 24-c0 28 00 6b c0 23 c0 27   .+./...$.(.k.#.'
0070 - 00 67 c0 0a c0 14 00 39-c0 09 c0 13 00 33 00 9d   .g.....9.....3..
0080 - 00 9c 00 3d 00 3c 00 35-00 2f 00 ff 01 00 00 b0   ...=.<.5./......
0090 - 00 00 00 13 00 11 00 00-0e 77 77 77 2e 6d 79 73 .........www.mys
00a0 - 69 74 65 2e 63 6f 6d 00-0b 00 04 03 00 01 02 00   ite.com.........
00b0 - 0a 00 16 00 14 00 1d 00-17 00 1e 00 19 00 18 01   ................
00c0 - 00 01 01 01 02 01 03 01-04 00 23 00 00 00 16 00   ..........#.....
00d0 - 00 00 17 00 00 00 0d 00-2a 00 28 04 03 05 03 06   ........*.(.....
00e0 - 03 08 07 08 08 08 09 08-0a 08 0b 08 04 08 05 08   ................
00f0 - 06 04 01 05 01 06 01 03-03 03 01 03 02 04 02 05   ................
0100 - 02 06 02 00 2b 00 09 08-03 04 03 03 03 02 03 01   ....+...........
0110 - 00 2d 00 02 01 01 00 33-00 26 00 24 00 1d 00 20   .-.....3.&.$... 
0120 - 29 4e cf fa 6e ff 7e 4a-8d 0f 0b 2b 65 bf e6 bc   )N..n.~J...+e...
0130 - 87 0d 69 65 26 35 2b 4c-c0 3a 13 a1 5b 31 9b 15   ..ie&5+L.:..[1..
read from 0x600003010000 [0x15700e803] (5 bytes => -1)
write:errno=54
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
read from 0x600003010000 [0x15600e000] (8192 bytes => 0)

看了一下,连接中断的时候,服务器还没offer证书,刚到Client hello阶段就断了。难道是Nginx配置有问题所以发送了重置包?上服务器打开nginx调试日志,再请求一下:

[foo@bar-server nginx]# tail -fn0 /var/log/nginx/error.log
2022/03/16 14:14:40 [debug] 15709#0: epoll: fd:8 ev:0001 d:0000561CDAD9EE30
2022/03/16 14:14:40 [debug] 15710#0: epoll: fd:8 ev:0001 d:0000561CDAD9EE30
2022/03/16 14:14:40 [debug] 15708#0: epoll: fd:8 ev:0001 d:0000561CDAD9EE30
2022/03/16 14:14:40 [debug] 15708#0: timer delta: 39727
2022/03/16 14:14:40 [debug] 15710#0: timer delta: 39726
2022/03/16 14:14:40 [debug] 15708#0: worker cycle
2022/03/16 14:14:40 [debug] 15710#0: worker cycle
2022/03/16 14:14:40 [debug] 15709#0: timer delta: 39727
2022/03/16 14:14:40 [debug] 15708#0: epoll timer: -1
2022/03/16 14:14:40 [debug] 15710#0: epoll timer: -1
2022/03/16 14:14:40 [debug] 15709#0: worker cycle
2022/03/16 14:14:40 [debug] 15709#0: epoll timer: 60000
2022/03/16 14:14:40 [debug] 15709#0: epoll: fd:17 ev:0001 d:0000561CDAD9F1F0
2022/03/16 14:14:40 [debug] 15709#0: *1 SSL ALPN supported by client: h2
2022/03/16 14:14:40 [debug] 15709#0: *1 SSL ALPN supported by client: http/1.1
2022/03/16 14:14:40 [debug] 15709#0: *1 SSL ALPN selected: h2
2022/03/16 14:14:40 [debug] 15709#0: *1 SSL_do_handshake: -1
2022/03/16 14:14:40 [debug] 15709#0: *1 SSL_get_error: 5
2022/03/16 14:14:40 [info] 15709#0: *1 peer closed connection in SSL handshake (104: Connection reset by peer) while SSL handshaking, client: 100.1.**.**, server: 0.0.0.0:443
2022/03/16 14:14:40 [debug] 15709#0: *1 close http connection: 17
2022/03/16 14:14:40 [debug] 15709#0: *1 event timer del: 17: 3578671
2022/03/16 14:14:40 [debug] 15709#0: *1 reusable connection: 0
2022/03/16 14:14:40 [debug] 15709#0: *1 free: 0000561CDAD85B20, unused: 112
2022/03/16 14:14:40 [debug] 15709#0: timer delta: 22
2022/03/16 14:14:40 [debug] 15709#0: worker cycle
2022/03/16 14:14:40 [debug] 15709#0: epoll timer: -1

日志显示nginx在刚收到SSL ALPN的阶段时,连接被重置。为了进一步排除nginx配置问题,直接在服务器本地用curl测试访问一下,一切正常。

这下确认不是ng的配置问题,那现在服务端客户端都说被重置,难道是有防火墙之类的东西在中间阻断了连接吗?检查了一下iptables/firewalld之类的都没有开启,如果是云端安全组之类的原因,那应该根本连不上,而不是握手握一半。

测试到这里,仿佛陷入僵局,怎么也想不出来了。吃了个饭,回来试了一下不带ssl,直接访问http,提示域名未备案被阻断连接… 瞬间开窍了,应该是阿里云给阻断了...

结论

在TLS握手的client hello阶段,客户端会发送多种信息,其中就包括SNI和ALPN。一般情况下,只要Nginx支持,客户端就会发送SNI。SNI用于在TLS握手之前将要认证的域名明文发送给服务器,便于服务器正确提供不同vhost的证书。然而,在SNI把域名明文发给服务器的过程中,同时也可以被中间人(云服务提供商)监听到。只要这个域名没有备案,他们就会出手断掉。

这次排查花的原因比较久。原因有几个

  1. nginx上本来有别的域名,一开始出问题的时候还以为是SNI的原因。
  2. 这个域名本来是在其他的提供商备过案的,这次解析到阿里云,根本没往备案的方向想。事实上跨提供商备案是不通用的,必须重新接入备案。
  3. 记得以前的各种云好像只封标准HTTP 80端口的备案。有一段时间没有申新域名,不知从什么时候开始,HTTPS竟也开始封了。

后话

事实上,即使禁用SNI,也只能确保客户端不发送明文的域名信息。当服务器出示证书的时候,明文的证书里依然会包含域名(Common Name)。虽然现在有扩展加密SNI(ESNI)的技术,但是并不能完全保护HTTPS域名的信息不泄露。而且这个ESNI因为一些不能说的原因,可能难以快速普及。

参考资料

  1. What happens in a TLS handshake?
  2. A walk-through of an SSL handshake
  3. 阿里云未备案网站的封锁策略是?
  4. 关于云服务商屏蔽未备案域名的问题
  5. 什么是加密的 SNI(ESNI)?
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容