2026 技术实测:域前置(Domain Fronting)未死?EdgeOne 的深度“奇技淫巧”

看来你的实验非常成功!在许多主流 CDN 纷纷对域前置(Domain Fronting)围追堵截的今天,腾讯云 EdgeOne (EO) 依然展现出了极高的“灵活性”。

你的测试结果证明了:即使 SNI 指向的是 geetest.com(极验),只要 HTTP Host 头部设置为你在 EdgeOne 绑定的实际域名,请求依然能成功穿透并到达目标。

以下我为你撰写了一篇技术博客草案,旨在分析这一现象背后的原理与实战价值。


2026 技术实测:域前置(Domain Fronting)未死?EdgeOne 的深度“奇技淫巧”

引言

在网络安全界,域前置 (Domain Fronting) 曾是一种被广泛用于流量伪装的神技。然而,随着 Cloudflare、AWS、Google 等大厂在 2018 年后相继收紧策略,大家普遍认为这一技术已进坟墓。

但最近的一项实测显示,腾讯云旗下的下一代 CDN 产品 EdgeOne (EO),似乎在协议栈的处理上保留了某种“兼容性”,允许我们实现完美的 SNI 伪装。


技术原理回顾

简单来说,域前置利用了 HTTPS 请求中两个不同层级的“域名”不匹配:

  1. TLS 层 (SNI): 暴露在明文握手中的域名(防火墙可见)。
  2. HTTP 层 (Host): 加密在 TLS 隧道内部的域名(防火墙不可见)。

当 CDN 节点只检查证书合法性而不强制匹配 Host 头部时,流量伪装就达成了。


实测证据:基于 EdgeOne 的伪装

我们来看博主提供的这一段硬核 curl 命令:

curl -v -I https://geetest.com \
--resolve "geetest.com:443:43.174.246.40" \
-H "host:********************************************"

关键参数解析:

  • https://geetest.com: 设置 TLS 握手阶段的 SNI。在中间设备看来,你正在访问一个正常的合规网站。
  • --resolve: 强制将 geetest.com 解析到 EdgeOne 的边缘节点 IP(如 43.174.246.40)。
  • -H "host:...": 在加密隧道内,将真实的业务域名塞进 HTTP Host

实验结果:

HTTP/2 200
eo-log-uuid: 12339217614574395953
eo-cache-status: HIT
server: deno/gcp-europe-west2

结论: EdgeOne 节点成功接收了 SNI 为 geetest.com 的请求,但在处理内部 HTTP 逻辑时,却根据 Host 头部将请求准确分发到了对应的后端服务(这里看起来是一个运行在 Deno 上的服务)。


为什么 EdgeOne 可以做到?

  1. 统一调度池: EdgeOne 的节点通常承载了海量的站点。为了效率,其边缘网关(Edge Proxy)在处理 TLS 卸载后,会重新读取 Host 字段进行路由,而没有严格执行 SNI == Host 的强校验。
  2. 证书信任链: 在握手阶段,EdgeOne 返回的是通配符证书(如 *.cdn.myqcloud.com 或站点专属证书),只要证书验证通过,TLS 链路建立,后续的 Host 头部便获得了“信任”。
  3. IPv6 兼容性: 根据测试,EdgeOne 的 IPv6 节点(如 240d:c010...)同样支持此特性,这为绕过某些仅监控 IPv4 流量的网关提供了新思路。

这种“发现”有什么意义?

  • 蓝队/红队演练: 在渗透测试中,可以利用 EdgeOne 的高信誉度 IP 和伪装 SNI 来隐藏 C2 控制流量,规避 IDS/IPS 的检测。
  • 隐私保护: 在敏感网络环境下,保护真实访问目标不被监测。
  • CDN 性能调试: 验证 CDN 节点在处理非对等请求时的行为边界。

⚠️ 风险提示

尽管目前测试可行,但这种行为通常处于 CDN 服务商的“灰色地带”。

  • 策略封杀: 一旦该技术被滥用,腾讯云可能会像 Cloudflare 一样引入 Error 1013 强制校验。
  • 合规风险: 建议仅用于合法的技术研究和授权的安全测试。

总结

EdgeOne 作为腾讯云的明星产品,其强大的边缘处理能力无庸赘述。但对于安全研究者来说,这种“灵活性”才是最迷人的地方。

下次当你觉得某个域名被“重点关照”时,不妨试试把 EdgeOne 当作你的隐形斗篷。


博主注: 你在测试中用到的 geetest.com 也是一个 EdgeOne 的用户吗?或者说,你是否想知道如何寻找更多类似的“白名单”域名来作为前置跳板?


curl -v -I https://geetest.com --resolve "geetest.com:443:43.174.246.40" -H "host:*********************************************"
Note: Using embedded CA bundle, for proxies (230814 bytes)
* Added geetest.com:443:43.174.246.40 to DNS cache
* Hostname geetest.com was found in DNS cache
*   Trying 43.174.246.40:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* SSL Trust Anchors:
*   CAfile: E:\迅雷下载\curl-8.17.0_4-win64-mingw\bin\curl-ca-bundle.crt
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*   subject: CN=*.cdn.myqcloud.com
*   start date: May 23 00:00:00 2025 GMT
*   expire date: Jun 10 23:59:59 2026 GMT
*   issuer: C=CN; O="TrustAsia Technologies, Inc."; CN=TrustAsia DV TLS RSA CA 2025
*   Certificate level 0: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type ? (4096/128 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   subjectAltName: "geetest.com" matches cert's "geetest.com"
* SSL certificate verified via OpenSSL.
* Established connection to geetest.com (43.174.246.40 port 443) from **************************** port 52840
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://geetest.com/
* [HTTP/2] [1] [:method: HEAD]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: *********************************************]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.17.0]
* [HTTP/2] [1] [accept: */*]
> HEAD / HTTP/2
> Host:*********************************************
> User-Agent: curl/8.17.0
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
HTTP/2 200
< content-security-policy: upgrade-insecure-requests
content-security-policy: upgrade-insecure-requests
< content-type: text/html; charset=utf-8
content-type: text/html; charset=utf-8
< link: </assets/client-entry-D_I2vPol.js>; rel="modulepreload"; as="script", </assets/fresh-island__AISummary-BlpGClK3.js>; rel="modulepreload"; as="script"
link: </assets/client-entry-D_I2vPol.js>; rel="modulepreload"; as="script", </assets/fresh-island__AISummary-BlpGClK3.js>; rel="modulepreload"; as="script"
< via: http/2 edgeproxy-h
via: http/2 edgeproxy-h
< server: deno/gcp-asia-southeast1
server: deno/gcp-asia-southeast1
< accept-ranges: bytes
accept-ranges: bytes
< strict-transport-security: max-age=31104000;includeSubDomains;preload
strict-transport-security: max-age=31104000;includeSubDomains;preload
< date: Tue, 03 Feb 2026 08:06:12 GMT
date: Tue, 03 Feb 2026 08:06:12 GMT
< eo-log-uuid: 14782413020394596744
eo-log-uuid: 14782413020394596744
< eo-cache-status: MISS
eo-cache-status: MISS
< nel: {"success_fraction":0.1,"report_to":"eo-nel","max_age":604800}
nel: {"success_fraction":0.1,"report_to":"eo-nel","max_age":604800}
< report-to: {"endpoints":[{"url":"https://nel.teo-rum.com/eo-cgi/nel"}],"group":"eo-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https://nel.teo-rum.com/eo-cgi/nel"}],"group":"eo-nel","max_age":604800}
<

* Connection #0 to host geetest.com:443 left intact



curl -v -I https://geetest.com --resolve geetest.com:443:[240d:c010:132:4::c6] -H "host:*********************************************"
Note: Using embedded CA bundle, for proxies (230814 bytes)
* Added geetest.com:443:[240d:c010:132:4::c6] to DNS cache
* Hostname geetest.com was found in DNS cache
*   Trying [240d:c010:132:4::c6]:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* SSL Trust Anchors:
*   CAfile: E:\迅雷下载\curl-8.17.0_4-win64-mingw\bin\curl-ca-bundle.crt
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Unknown (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*   subject: CN=*.cdn.myqcloud.com
*   start date: May 23 00:00:00 2025 GMT
*   expire date: Jun 10 23:59:59 2026 GMT
*   issuer: C=CN; O="TrustAsia Technologies, Inc."; CN=TrustAsia DV TLS RSA CA 2025
*   Certificate level 0: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type ? (4096/128 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type ? (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   subjectAltName: "geetest.com" matches cert's "geetest.com"
* SSL certificate verified via OpenSSL.
* Established connection to geetest.com (240d:c010:132:4::c6 port 443) from ************************************* port 51506
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://geetest.com/
* [HTTP/2] [1] [:method: HEAD]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: *********************************************]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.17.0]
* [HTTP/2] [1] [accept: */*]
> HEAD / HTTP/2
> Host:*********************************************
> User-Agent: curl/8.17.0
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
HTTP/2 200
< content-security-policy: upgrade-insecure-requests
content-security-policy: upgrade-insecure-requests
< content-type: text/html; charset=utf-8
content-type: text/html; charset=utf-8
< link: </assets/client-entry-jDLWmvJY.js>; rel="modulepreload"; as="script", </assets/fresh-island__AISummary-BlpGClK3.js>; rel="modulepreload"; as="script"
link: </assets/client-entry-jDLWmvJY.js>; rel="modulepreload"; as="script", </assets/fresh-island__AISummary-BlpGClK3.js>; rel="modulepreload"; as="script"
< vary: Accept-Encoding
vary: Accept-Encoding
< server: deno/gcp-europe-west2
server: deno/gcp-europe-west2
< content-length: 18071
content-length: 18071
< accept-ranges: bytes
accept-ranges: bytes
< strict-transport-security: max-age=31104000;includeSubDomains;preload
strict-transport-security: max-age=31104000;includeSubDomains;preload
< date: Tue, 03 Feb 2026 08:05:42 GMT
date: Tue, 03 Feb 2026 08:05:42 GMT
< age: 59721
age: 59721
< eo-log-uuid: 12339217614574395953
eo-log-uuid: 12339217614574395953
< eo-cache-status: HIT
eo-cache-status: HIT
< nel: {"success_fraction":0.1,"report_to":"eo-nel","max_age":604800}
nel: {"success_fraction":0.1,"report_to":"eo-nel","max_age":604800}
< report-to: {"endpoints":[{"url":"https://nel.teo-rum.com/eo-cgi/nel"}],"group":"eo-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https://nel.teo-rum.com/eo-cgi/nel"}],"group":"eo-nel","max_age":604800}
<

* Connection #0 to host geetest.com:443 left intact


posted @ 2026-02-03 16:09  masx200  阅读(1)  评论(0)    收藏  举报