记一次图片访问异常排查过程

共 970 字 约 3 分钟 1 年前 2 评论

本文首发于掘金,为了后续统一管理,现搬回我的博客,部分内容有更新。

几个月前,收到掘友反馈无法查看自己的头像图片(p*-passport.byteacctimg.com),站内其他图片(p*-juejin.byteimg.com)正常。

掘金用户头像直接使用公司公共的 Passport CDN 地址,按说不应该有问题,本地无法复现,反馈量也不大,一周几条,但一直持续。

排查过程

考虑到掘金用户大部分都是程序员,让掘友协助排查最高效。在反馈后评论留言,很快就联系到两名掘友。

可以 Ping 通域名

图片无法访问首先要怀疑 DNS 和网络连通性。让掘友 Ping 头像域名,一切正常,返回的 ip 没有被劫持,DNS 和网络连通没有问题。

ping

浏览器提示连接被重置

再让掘友用 Chrome 浏览器直接访问图片 URL,报错信息为 ERR_CONNECTION_RESET

chrome err connection reset

网络环境阻断了连接

两名掘友都表示,只有在公司访问掘金才出现问题,结合浏览器给出的“连接被重置”信息,怀疑所在网络对该域名进行了拦截。

一个小知识点:拦截 HTTPS 请求经常会用到 SNI 信息。

为了在同 IP 部署多个 HTTPS 服务,TLS 提供名为 SNI(Server Name Indication)的扩展,现代浏览器都支持 SNI。浏览器发送 Client Hello 握手时,会把请求 URL 中的 Host 明文放在 SNI 扩展中传给服务器,便于服务器返回正确域名的 HTTPS 证书。通过 SNI 信息,防火墙可以轻松拦截特定 Host 的 HTTPS 连接。

via:https://mailseason.com/post/sth-about-switch-to-https-2.html#toc-2

先让掘友用 curl 进行了测试:

curl -vvv https://p3-passport.byteacctimg.com/img/user-avatar/05f83c4592a0bf379722fbe74730238c~300x300.image

可以看到,TCP 连接正常,但 TLS 握手过程被中断,这与在浏览器中的表现一致,这也说明该问题与浏览器无关。

curl failed

又让掘友测试了不带 SNI 的 TLS 握手(OpenSSL 1.1.1 及之后的版本默认发送 SNI,可通过 -noservername 参数禁用):

openssl s_client -connect p3-passport.byteacctimg.com:443 -noservername

可以看到,不带 SNI 时,顺利完成 TLS 握手,服务端返回了 TLS Session Tikect。

tls without sni

再让掘友测试带 SNI 的 TLS 握手(OpenSSL 1.1.1 之前的版本,可通过 -servername 参数发送 SNI 信息):

openssl s_client -connect p3-passport.byteacctimg.com:443 -servername p3-passport.byteacctimg.com

可以看到,这次 TLS 握手失败(Cipher 为空)。

tls with sni

由此可以判断,掘友网络环境针对 p*-passport.byteacctimg.com 域名进行了阻断。

问题解决

查明原因之后,临时解决方案是更换域名。新域名替换上线后,掘友反馈一切恢复正常。

为什么有些网络环境会屏蔽 byteacctimg.com?我没有最终结论,但大概率是被当成广告域名来拦截了:

用来上报日志的域名很容易被广告 / 隐私过滤规则库收录,从而被拦截。上报日志场景最好申请单独域名,不要与业务内容域名混用。估计是 byteacctimg.com 某个子域曾被用于上报日志,导致被 adblock list 收录。

另外,为了解决 SNI 明文传输的问题,TLS 提供了 ESNI(Encrypted SNI)、ECH(Encrypted Client Hello)等扩展,这里不过多介绍,有兴趣的同学可以点击:https://blog.cloudflare.com/encrypted-client-hello/

本文链接:https://mailseason.com/post/an-avatar-issue.html参与评论 »

--EOF--

专题「HTTP 相关」的其他文章 »

Comments

Waline 评论加载中...