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

2023-08-18 10:48:49 +08:00
 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 服务,是否能规避一定程度上的运营商主动探测?

望各位朋友不吝赐教

3726 次点击
所在节点    宽带症候群
33 条回复
cheneydog
2023-08-18 11:14:48 +08:00
你是哪里的?哪个运营商管这么多么?
dzdh
2023-08-18 11:29:00 +08:00
就是把根路径变变?
YGBlvcAK
2023-08-18 11:39:03 +08:00
我也是类似的方式,我用的 caddy ,非白名单路径直接 abort ,可以看我之前的主题 /923605

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

error_page 400 =444 /;
在 OP 原有配置的基础上加上这条,应该可以解决此问题。
YGBlvcAK
2023-08-18 13:52:16 +08:00
@hingle 有意思,我发现我的 caddy (跑 webdav )没有任何返回,又试了试 www.163.com 有返回:HTTP/1.1 400 Bad Request
pupboss
2023-08-18 14:04:27 +08:00
很管用,还能让一些爬虫抓瞎,因为爬虫也拿不到 444 这个状态码,只会发现连接被中止了,不懂 TCP 只知道 HTTP 皮毛的脚本小子完全不知道发生了什么
LinePro
2023-08-18 14:09:03 +08:00
说起这个我想起了某防火墙的主动探测原理 233
理论上探测者可以一个字节一个字节地把 GET / HTTP/1.1\r\n 和底下的请求头发过去,观察服务端在何时断开连接来判断是否为 HTTP 服务。
laozhoubuluo
2023-08-18 14:21:20 +08:00
一般来说建立 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
2023-08-18 14:25:59 +08:00
我估计要是运营商用的是流量镜像的方式审查,你这没啥用。我以前给一个某个地级市运营商做实施的时候,机房的网工直接指着一个核心交换机的光口跟我说,这个口就是做流量镜像接给公安审查的。
LinePro
2023-08-18 14:29:04 +08:00
@laozhoubuluo #14

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

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