Nginx 的 444 命令(强制切断 TCP 连接),用于对抗运营商检测家宽开服务是否有帮助?

266 天前
 MFWT

背景

我知道 VPN ,我也在用 VPN ,VPN 确实很方便,连上之后直接访问内网地址就可以获取到各项服务

但是,能不能再直接一点呢,比如临时给朋友开个 Web 页面传个文件什么的,用 VPN 还得教他半天,如果能直接浏览器打开那确实是挺好的

考虑到有朋友说路由器管理页面被主动探测到,又有朋友说 ocserv 运行几年毛事没有,也有朋友说裸 TLS 连接(内部没有 HTTP 协议,浏览器无法直接访问)也没啥问题,猜测运营商对于『家宽开 Web 服务』(此处仅讨论非标端口,80/443 就不必说了)大概可能会有这几种:

  1. 对于裸 TLS 连接拦截较少
  2. 模拟浏览器访问(比如 curl ),看看有没有内容(比如 HTTP 头)返回
  3. 同 1 ,但是判定更严谨,检查返回码是不是 200 (或者其他方式来判定是不是可以直接访问)

测试

以下测试都假定已有可用的 TLS 环境(毕竟直接裸 HTTP 连接的话,是个人都知道你在干啥)

nginx 对于拒绝非合法访问,有个选项是 deny all ,但是实测 deny all 也会返回 HTTP 403 ,在某些运营商那里可能会被判定为情况 2 。因此我测试了一下 return 444 ,对于非白名单路径(实例是 private_path_as_a_token )指示 nginx 直接切断连接

相关配置如下

  location / {
    keepalive_timeout 0;
    return 444;
  }
  
  location /private_path_as_a_token {
    root /home/html;
    index index.html;
  }

测试发现,在访问非白名单路径的时候(比如此时的根目录)确实会直接切断 TCP 连接,站在浏览器的角度看就是,这并非一个 HTTP 服务器:


* Trying 10.0.0.233:8000...
* Connected to 10.0.0.233 (10.0.0.233) port 8000 (#0)
> GET / HTTP/1.1
> Host: 10.0.0.233:8000
> User-Agent: curl/8.0.1
> Accept: */*

>
* Empty reply from server
* Closing connection 0
curl: (52) Empty reply from server

现在的问题是,如果我通过这个方式,在公网 IP (我的是公网 v6 )上开放 HTTPS 服务,是否能规避一定程度上的运营商主动探测?

望各位朋友不吝赐教

3292 次点击
所在节点    宽带症候群
33 条回复
cheneydog
266 天前
你是哪里的?哪个运营商管这么多么?
dzdh
266 天前
就是把根路径变变?
YGBlvcAK
266 天前
我也是类似的方式,我用的 caddy ,非白名单路径直接 abort ,可以看我之前的主题 /923605

你这如果是其它路径,返回什么?比如/aaa ,也是 return 444 吗?
hingle
265 天前
也许有可能防止运营商通过 HTTP 主动探测,但防不了用 TCP 主动探测,试试下面的命令
echo hello | nc 10.0.0.233 8000
deorth
265 天前
有,帮助不大。就算是 https 他镜像你流量看 sni 就知道你在干嘛了
deorth
265 天前
我现在的做法就是搞个 svcb 记录,自用的终端全都走 h3 。现在他们应该还没有 quic 流量的分析能力。后面看看什么时候服务端和终端都支持起来了,搞一波 ech
MFWT
265 天前
@cheneydog 广东移动
MFWT
265 天前
@YGBlvcAK 是,这么写的话实测非指定路径会回落到根路径,然后就 444
MFWT
265 天前
@hingle 确实是个问题,nginx 直接返回 HTTP 信息了
LinePro
265 天前
@hingle #4
@MFWT #9

error_page 400 =444 /;
在 OP 原有配置的基础上加上这条,应该可以解决此问题。
YGBlvcAK
265 天前
@hingle 有意思,我发现我的 caddy (跑 webdav )没有任何返回,又试了试 www.163.com 有返回:HTTP/1.1 400 Bad Request
pupboss
265 天前
很管用,还能让一些爬虫抓瞎,因为爬虫也拿不到 444 这个状态码,只会发现连接被中止了,不懂 TCP 只知道 HTTP 皮毛的脚本小子完全不知道发生了什么
LinePro
265 天前
说起这个我想起了某防火墙的主动探测原理 233
理论上探测者可以一个字节一个字节地把 GET / HTTP/1.1\r\n 和底下的请求头发过去,观察服务端在何时断开连接来判断是否为 HTTP 服务。
laozhoubuluo
265 天前
一般来说建立 TLS 握手的时候是要传证书过去的,需要考虑服务器发过去的证书有没有穿帮的可能性。

```
# curl -vvv https://www.example.com
* Server certificate:
* subject: C=US; ST=California; L=Los Angeles; O=Internet▒Corporation▒for▒Assigned▒Names▒and▒Numbers; CN=www.example.org
* start date: Jan 13 00:00:00 2023 GMT
* expire date: Feb 13 23:59:59 2024 GMT
* subjectAltName: host "www.example.com" matched cert's "www.example.com"
* issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
* SSL certificate verify ok.
```
idontnowhat2say
265 天前
我估计要是运营商用的是流量镜像的方式审查,你这没啥用。我以前给一个某个地级市运营商做实施的时候,机房的网工直接指着一个核心交换机的光口跟我说,这个口就是做流量镜像接给公安审查的。
LinePro
265 天前
@laozhoubuluo #14

帮 OP 补充一下 nginx 关于这个问题的配置:
新一些的 nginx 可以用 ssl_reject_handshake on; 规避这个问题。
老版 nginx 的话可以随便自签个虚假证书给 default_server

当然只要 sni 不加密,运营商可以从流量中获取合法的 sni ,那么这方面配置对于 OP 所提的这个题目《用于对抗运营商检测家宽开服务是否有帮助?》而言意义不大。
villivateur
265 天前
如果运营商不是通过探针的方式检查,而是直接看你流量特征,那你这样就没意义了。
starryloki
265 天前
@LinePro OP 的方法并不完全使用域名来防止探测,还使用了路径,路径对于防火墙设备是不可见的
MFWT
265 天前
@LinePro
实测有效,估计如果有其他错误状态码也可以依葫芦画瓢
MFWT
265 天前
@LinePro

SNI 是肯定能获取的了(毕竟没有开 eSNI ),但是这个情况就不在本文考虑范围内了,本文主要考虑是『运营商不对 TLS 流量额外探测,仅主动探测此端口是否为 HTTP(S)服务器』的情况

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/966348

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX