IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    JerryQu 的小站发表于 2023-04-28 21:55:16
    love 0

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

    几个月前,收到掘友反馈无法查看自己的头像图片(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://imququ.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?我没有最终结论,但大概率是被当成广告域名来拦截了:

    • 沟通中了解到,一些公司所处行业非常注重隐私,猜测管理员会在网关配置隐私 / 广告过滤规则,用来过滤数据上报请求;
    • 搜索发现,这个 adblock list 包含 byteacctimg.com 规则,文件来自于这个项目:https://github.com/badmojr/1Hosts(注:写这篇文章时,我们给项目提 issue 去掉了这个域名);
    • 一些广告过滤软件,例如 AdGuard,确实会通过匹配 SNI 的方式来达到拦截广告的效果。例如:https://forum.adguard.com/index.php?threads/adblocking-with-sni-filtering-inspection.40906/(注:链接已失效);

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

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

    本文链接:https://imququ.com/post/an-avatar-issue.html,参与讨论



沪ICP备19023445号-2号
友情链接