我的目标是在公网任意位置(公司、移动网络、手机 APP 等)通过 HTTPS 协议可以访问到位于家中 NAS 上提供的 HTTPS 协议服务,譬如 Seafile (实际上 Seafile PC 客户端和手机客户端在 auth 认证阶段也是走 HTTPS 协议的),但是又不会被探测到,或者说即便探测到了,也无法在第三方进行复现,从而避开监管不给 G0v 添麻烦。
由于 `HTTPS` 协议中客户端发送的 `SNI` 会泄漏 `server_name`,可能会被 ISP 嗅探到,然后 `ESNI `也迟迟没有实装,再者即便实装了,大量客户端(譬如手机 App 、浏览器等)在没有得到 `DoH` 等安全 `DNS` 支持的情况下,大概率还是会直接发送 `server_name` 从而导致域名被泄漏,所以等 tls v1.3 esni 不现实。
然后我在测试机上部署且体验了 SNIProxy,也不是绝对满足需求,毕竟这玩意儿只能防止直连端口证书泄漏域名,但是正常访问握手时 client hello 发送 server_name 的问题还是没有解决。
至于 Frp 、SSH 、VPN 隧道等方案也不完美,不具备 **从任意设备,任意公网访问** 这个先决条件。
想了一个折中办法,实现上比较麻烦,也有一些小瑕疵,先抛砖引玉聊一聊?也或者如果有现成的类似的玩意儿也可以直接发给我玩玩?
首先,我们需要一个中间服务器,负责在上面跑一些自己写的脚本,但是这个服务器只作为一个类似前期握手的存在,并不参与具体的流量转发。所以一般来说服务器用最便宜的 VPS 即可,要求具有 IPv4 公网 IP 和低延迟+稳定,对硬件性能无要求。
然后,家里的 NAS 也需要进行一些调整,同样跑一个脚本执行一些额外操作。
最后,具体的实现是这样:
这样一套组合拳打下来,优缺点分别如下:
所以,如果你只是要访问家中的网页 https 服务,流量不那么大的那种,又不想被运营商扫到你的端口进行各种探测抓包的话,我这个方案似乎可行?
1
lookas2001 2020-05-08 17:31:00 +08:00 via Android
是维基百科的方案吗?
|
2
hlz0812 2020-05-08 17:32:49 +08:00 via Android
哪有那么多麻烦,按你这么说用联通家宽中转 v2 ws+tls 的不是都要死,说白了 https 非 443 端口几乎不管
|
3
KyonLi 2020-05-08 17:35:06 +08:00
我是开了一个代理端口,所有访问内网的走代理
|
4
chairuosen 2020-05-08 17:43:19 +08:00
家里公网出口 DDNS 到域名 1,但不处理域名 1 的请求,绑域名 2 的证书处理域名 2 的请求。
vps 部署一个 dnsmasq 写死域名 2 cname 到域名 1 任意地方想访问家里时,改本机 dns,再直接访问。 可防一般情况,不防绑 host 访问 |
6
binkcn OP @lookas2001 对维基百科并不了解。
@hlz0812 非 443 的 https 是否会触发 block 目前没有准确的说法,保险起见都默认 ISP 现在或者将来会这样做,所以我这个帖子主要讨论假定 ISP 会检测任意端口的 HTTPS 协议包。 @KyonLi 你这个方法的话对我没啥用,我如果在户外忽然想用手机 4G 网络打开 Seafile APP 看一下某个 PDF 的话就会很麻烦,而且家人用起来也不方便。 @ddsfeng 同上,这个方案也需要客户端额外做动作才可以,无法让客户端随时随地便捷访问。 @chairuosen 同上…… !!!注意:本帖讨论的目标是:客户端(即访问方,可能是手机 APP 等不受控的 Client )无需额外操作(譬如按需访问端口,譬如修改 HOST,譬如修改 DNS 等)就可以访问家里 NAS 上的 HTTPS 服务 。 |
7
wsy2220 2020-05-08 18:19:18 +08:00
双向 SSL 认证足够了
|
9
hlz0812 2020-05-08 18:31:35 +08:00 via iPhone
@binkcn 很多机场都是普通宽带中转,但是不清楚 https 网站和 v2 ws tls 的流量是不是完全一样,如果是完全一样,那真的没遇到非 443 被封的
|
10
ashong 2020-05-08 18:32:26 +08:00
只要不架设面向公众的内容几乎就不会管, 家宽本来也不是干这个的,这么折腾下去大家都别方便
|
11
chairuosen 2020-05-08 18:38:28 +08:00 via Android 1
@binkcn 你又想不让第三方复现,又想在任意设备不做改动访问,是不可能的。你手里的设备和第三方有何不同呢?
|
12
justs0o 2020-05-08 21:16:05 +08:00 1
说了 N 遍了,运营商是镜像流量的方式进行探测,就跟某设备的原理一样
|
13
CheekiBreeki 2020-05-09 08:09:56 +08:00 via Android
這麼麻煩,還不如 VPN 一步到位,又安全。你實名家寬整 web 被亂搞了就涼了
|
14
jiangyang123 2020-05-09 08:21:59 +08:00 via Android
都要用另外机器中转了,为啥不用 frp 这类工具呢
|
15
jzphx 2020-05-09 08:26:30 +08:00
难道没人知道上海家宽私设 web 被断网的事情吗,发帖的哪个是 443 的,直接扫端口,有 web 服务就断网
|
16
BlackHole1 2020-05-09 08:32:40 +08:00
有个疑问,在 302 跳转时,不会被监听到其中的 server_name 么
|
17
binkcn OP |
18
binkcn OP @chairuosen 注意看帖子,我讲的很清楚了,我自己的访问是先访问 A,由 A 通知 B 开门,然后 A 再引导我访问的 B 。
而抓包等方式只能抓到我访问 B 这个环节,第三方复现直接访问 B 是拒绝访问的。 |
19
binkcn OP |
20
binkcn OP @BlackHole1 从 VPS 302 到 NAS 的时候,ISP 抓包都是在电信宽带侧抓包,所以抓到的包只是 Client to NAS 的包,那么这个 HTTPS 里面的 server_name 是具有白名单无法直接访问的。
|
21
markmx 2020-05-09 10:10:57 +08:00
ipv6 不是可以互通吗。目前我是这样搞得。
|
22
brMu 2020-05-09 10:32:48 +08:00 1
总结楼主的核心:自动添加和移除白名单,即使 sni 被监听到,也无法访问 NAS 。
方案我觉得是可行的,就是不知道效率怎么样,另外定制化太多,不知道有没有人愿意开发。 再就是即使他无法主动探测出 https 网页,但是仍然能知道你是在进行 https 通信,如果仅凭这点就判你是滥用(不需要截图证据),那就没折了。 所以我觉得最稳妥的方案还是无特征连到家里再操作,手机也就多 2-3 下而已。 |
23
NeoChen 2020-05-09 10:39:56 +08:00
在家建个$$server,通过$$代理来访问内网资源,甚至...出国的时候还能作为国内代理用,这个会有什么问题么?
|
24
ghostwwg 2020-05-09 11:11:11 +08:00
需求:公网任意位置访问自家的 homelabs
方案: 起个 vpn 服务 优点:能实现外网链接服务后任意访问内网资源 缺点:如果你是不固定设备,那需要额外配置 那么问题来了: 通常你外网访问 homelabs 是固定设备么? |
25
AoTmmy 2020-05-09 11:16:02 +08:00 via Android
用 frp 的话进行访问的客户端不需要任何设置啊,为什么你说客户端还要设置,难不成是 nas 设置? frp 设置多简单,你这太复杂了
|
26
smallfount 2020-05-09 11:19:30 +08:00
所以搞那么复杂干嘛。。。直接 FRP 吧。。这样就不用管你宽带上用啥反正都是内网访问外部流量了。。
|
28
hymzhek 2020-05-09 14:18:03 +08:00
ddns 加 端口敲门 不用 vps https://wiki.archlinux.org/index.php/Port_knocking
|
29
KyonLi 2020-05-09 14:32:43 +08:00
如果必须当着你的面复现才能定罪那这个思路没问题,可是这样的话收到传唤出门前网线一拔不就行了
|
30
lifanxi 2020-05-09 19:29:08 +08:00 via Android
挺好的方法,局限性就是需要客户端支持 302 跳转。
我现在的出国服务器上就用了类似的端口敲门的方法,理论上可以规避一些扫描。 |
32
gy6221 2020-05-09 19:59:10 +08:00
这思路确实不错。。。
不知道群晖那一票 app 是否支持 302 |
33
leafleave 2020-05-09 20:24:50 +08:00
你这就是 port knock,只不过是敲邻居家的门,然后让邻居通知你家的服务器
|
34
jiangyang123 2020-05-09 21:23:21 +08:00
|
36
andynet 2020-05-10 09:12:01 +08:00
我的做法是家里的宽带和 VPS GRE
VPS 上 nginx proxy 内网的 IP 如果是跑其他应用的话就在 VPS 上用 iptables nat 到内网的端口上 写个脚本放在服务器上探测,一但 GRE 断了的话自动重取 DDNS 的 IP 地址重新建立 GRE 隧道 一般 VPS 是固定 IP,家里的服务器只需要确保到 VPS 端的 GRE 地址是 ping 的通的就可以。 缺点是 GRE 1.只适用于 IPv4 2.GRE 是透明的。如果需要增强安全性的话可以考虑在 GRE 后套 IPsec,如果只跑跑应用也就无所谓了。 优点是 Linux 的 IP 套件原生支持,部署成本比较小,几行命令就搞定了,也不需要写配置文件。 不知道我说清楚没,欢迎大家指正补充。 |
37
JoeoooLAI 2020-05-11 09:54:10 +08:00
未来估计都是搭隧道或者 frp 之类的中转才有机会。 那个某花生壳可能要再次流行了
|
39
binkcn OP @ghostwwg 非固定设备,其实我折腾这些主要是家里 nas 上现在在循环录制宝宝的监控视频,然后我又希望我的家人父母可以异地通过手机、PC 等方式随时查看监控或者视频回放。
所以开篇就直接 pass 掉了 frp vpn $$ 等手段。 |
40
binkcn OP |
41
binkcn OP @leafleave
@hymzhek 提到端口敲门的,我统一回复一下吧,经测试,port knocking 有一些局限性: 1 、需要在目标机器开多个端口,如果我程序跑在 nas 上的话,需要在网关路由器做多次端口映射。 2 、经测试,端口敲门逐一连接端口时,如果由于网络波动导致丢包的话,端口敲门失败率非常高。(中间有一个包没收到,顺序就会出错,导致敲门失败) 3 、端口敲门程序,成功敲门后白名单开放的是敲门人的 IP 地址(即我文中的 vps 地址),而我希望是另一个由 vps 指定的 ip 地址,即真正访问者的 IP 地址。 再说一次,我的目的不是单纯为了让我自己访问,而是让其他任意人都能便捷访问。 |
42
binkcn OP @jiangyang123 是的,又一个看懂我意思的。:)
理论上我这个方法可以让任意访问者无感直连 nas,且第三方即便抓包知道了 nas 的 ip 、port 、domian 。也无法在第三方客户端复现访问。 |
43
binkcn OP @andynet 如果我没看错的话,你这个方案和 FRP 大同小异,最终流量都是走的 VPS 。
我的方案如果部署完毕的话,VPS 只是相当于初期的一个“可信介绍人”,完成“介绍”(即白名单开启)动作后 VPS 不参与后续的事情。 |
45
LnTrx 2020-05-11 12:13:23 +08:00
@binkcn
对于端口敲门: 多个端口映射并不复杂,一般路由器的图形管理界面都支持 境内互联的网络波动不算大,通过设定好规则、多次敲门不至于连不上 端口敲门程序可以放在任意托管的静态网页里用 js 实现。用户访问这个页面,白名单开放的就是用户自己。js 检测到开放后,也可以执行跳转 端口敲门的真正问题是没法直接 302,对于非浏览器访问而言不够无缝 |
46
LnTrx 2020-05-11 12:16:09 +08:00 1
顺便一提,楼主的的设想用云函数计算应该就可以实现了,相比买 VPS 可以省不少钱
|
47
milkme 2020-05-11 14:49:37 +08:00
有个疑问:现在只要不主动申请,ISP 分配的都是内网 IP,那么在同城 /同 ISP 的情况下,AB 两个用户互联时应该是用的内网 IP,但是通过 VPS 添加的白名单 IP,确是公网 IP 。
|
48
binkcn OP @lifanxi
你是怎么测试的? 我这里 Seafile 的 /api/auth 认证登录接口也是 POST 的,但是可以跟随 302 跳转。 我是先做了一个地址 A,然后 302 到新的地址 B,用客户端时填写 A 地址,然后发起请求,最后地址 B 上也有 access log 。 |
49
binkcn OP @talarax7
1 、端口映射这个操作本身没有难度,主要是我不希望开放太多空白端口,哪怕这些端口本身没有任何卵用。 2 、境内波动是小,但是境内的 vps 一来价格贵,二来需要备案才能用域名;所以我这个方案中提到的 vps 一般都指国外那种非常非常廉价的 vps,而境外 vps 的话波动就难说了。 再有一个哪怕 vps 是境内的,但是既然 nas 要提供服务了,如果有多个人在线拉视频流的话,网关上出现丢包也在所难免,毕竟端口敲门这个方案没有什么可用性保障设计,丢包就是丢了。( ps:我测试 port knocking 的时候发现,如果丢包导致顺序出错,重发的时候第一个包会被上一个未完成的队列用来进行 check,然后抛出 error,也就是说短时间内的重试时第一个敲门包会无效化) 3 、js 这个方案也是我正在做的这个东西的最初想法,但是我思考之后决定放弃,一来纯 js 编写的话,端口敲门顺序是暴露的,我正在做的这个东西希望能支持一些简单的认证后再进行敲门和 302 。所以目前是 python 在写,提供一个 web server 监听,允许配置简单的认证( get/post 参数,或 header 头字段,或 basic auth ),认证通过后再通知 nas 开放白名单,并且还会验证是否开放成功,最后才 302 到 nas 上。 总的来说,我目前这个方案各个环节我本地已经跑通,就等慢慢撸代码然后开源发布了。 |
50
binkcn OP |
51
baozhuo 2020-05-11 23:12:50 +08:00
感觉理论上应该是可行的,等你开源了我去 star 一波,十一回去我也试试
|
53
smileawei 2020-05-12 10:38:29 +08:00
用证书验证的 openVPN 即可。握手的过程类似双向认证。只是所有流量都走在隧道内
|
55
whitegerry 2020-05-12 17:59:39 +08:00
如果 nas 只有 ipv6 地址能行不,手机也有 v6 地址?
|
56
binkcn OP @whitegerry
理论上是可以的,如果只有 ipv6 的话,需要注意的地方有 2 个: 1 、REDIRECT_URL = 'https://nas.yourdomain.com:1443' 重定向目标的域名你要自己解析到 nas 的 ipv6 地址上。 2 、SSH_ADDR = '127.0.0.1' NAS 的 SSH 地址这里,你填写 nas 的 ipv6 地址试试看? paramiko 的手册上 connect 方法我没有看到明确说是否支持 ipv6,只能你试试看了。 其他就没什么了。 |
57
whitegerry 2020-05-12 19:51:01 +08:00
@binkcn
vps 的 v6 没通,nas 没有公网 v4,手机和 nas 都有 v6,vps 可以通过隧道 ssh 到 nas,但是 vps 给到 nas 的是客户端 ipv4 吧,这样的话好像行不通了 |
58
myqoo 2020-05-12 20:05:09 +08:00
和我之前想的方案类似。不过我的方案更巧妙,不用 30X 跳转。
熟悉前端的朋友,可以猜猜如何实现~ |
59
myqoo 2020-05-12 20:08:43 +08:00
另外,iptables /白名单 最后其实也是用不着的(用我的方案)
|
60
noahzh 2020-05-13 08:15:23 +08:00
局端数据一看有大量数据上传,然后端口固定,直接就封你了,哪有你想的那么复杂,你在怎么折腾也是在人家的局域网内,局域网流量监控太成熟了,根本没有折腾必要.
|
63
myqoo 2020-05-13 14:16:10 +08:00
@binkcn 最简单的办法,就是套一个 100% 尺寸的 iframe,所以就不用重定向了~~
而且 iframe 可以任意端口,不用 443 。并且可以用不固定的泛域名,用泛域名作 token (里面绑定 IP,或者一次性的 id 等),这样就用不着 iptables 了~ 当然更高的办法就是用 Service Worker,这样 iframe 都不用了。 |
64
myqoo 2020-05-13 14:22:05 +08:00
当初用这个办法,给没有公网 ip (但可以 tcp hole )的家宽搭了个网站~
|
67
binkcn OP @myqoo
其实 30x 方案也不是完美的,主要一点就是 http 协议的 redirect 如果重定向出现跨域,那么 header 中的 Authorization/WWW-Authenticate/Cookie 是不会跟随重定向的。 所以今儿早上我手机客户端 Seafile 测试的时候,https api 拉取一直失败,随后 debug 发现 seafile 的 web api 要求在 header 中使用 Authorization 发送 token 做身份验证。 当然,机智如我,在 proxy-knocker 中增加了检查,如果有上述 header,那么将其转换为 GET 参数拼接到 请求的 uri 中,然后在真实服务器( nas )那边套了一层 nginx,判断如果 GET 中有这些特殊参数,那么将其转换为 header,并且用 proxy_set_header 专递给 proxy_pass 后端服务器。 最后问题解决了,手机客户端正常使用中。 回头再优化一些其他问题吧,譬如 ssh 连 nas 开 iptables,我觉得不安全;还有每次请求仍然会走一次 vps 做 redirect,性能上感觉有点不完美。 |
68
whitegerry 2020-05-13 17:51:14 +08:00
@binkcn ssh 这个绕一下应该可行吧,比如 nas 上给 ssh 开个普通帐号,vps 连 ssh 在该用户下写个文件,内容就是 ip 之类,然后 incron 监视这个目录修改,由 root 去修改 iptables 。
|
69
nereus 2020-05-13 23:09:07 +08:00 via iPhone
1.要用宽带的公网 ip 就不可能实现,https 流量与 tls 加密的其它流量没有区别,但是运营商可以用 ip 反响查域名,任何端口都没用。
2.可行的办法是经第三方 ip 中转,只要用了 tls 流量就无法区分,逐个试探全部端口不现实,反向 dns 查询也查不到 |
71
binkcn OP @whitegerry
这个办法也不是没有想过,但是既然始终都要在 nas 上额外做些什么了,不如直接再写个服务丢到 nas 上去,专门用来做这个事情,然后服务本身跑在一个低权限的 local 账户上确保安全。 这里姑且叫它“开门人”服务,这个服务本身收到消息后用私钥解出消息,拿到 ip 和有效时间,开通白名单后自己再管理这个 ip 的白名单过期时间,到期后 iptable -D 移除记录。 这样依赖 proxy-knocker 可以移除对 ssh 的依赖,更轻量化;而且还顺手解决了当前版本没有管理和移除过期白名单记录的问题。 |
72
binkcn OP |
73
binkcn OP |
75
andynet 2020-05-14 10:19:38 +08:00
是不是按照你们这种方案,连 VPS 都不用买,跑一个 js 在 cloudflare 的 worker 就好了?
|
76
nereus 2020-05-14 12:25:50 +08:00 via iPhone
@binkcn 呵,运营商主要就是靠域名逆解析来查水表,不管你有没有 web 界面,只要能够逆解析就警告。有逆解析之后会扫描你的端口,tcp 逐个链接,连上就算私设 web 不管你是不是 http
|
77
binkcn OP @nereus
首先,光是靠域名解析就查水表的话,岂不是可以随意栽赃别人?我觉得可能性不大,而且目前没有看到类似被查水表的案例。即便如此退一万步来讲,我这个方案的话,redirect 到 nas 这个步骤可以不用域名解析指向 nas,直接 IP:PORT 即可。 ip 在 nas 上用脚本定时检查更新到 vps 上(类似 ddns 方式),端口用前面说的随机协商方式就行了。 还有,这个方案中,不在防火墙白名单中,第三方 tcp 无法链接。 |
78
sadfQED2 2020-06-26 22:02:47 +08:00
|
79
DopaminePlz 2020-07-04 10:49:09 +08:00 via Android
学习学习
|
80
DopaminePlz 2020-07-04 11:13:00 +08:00 via Android
非 ITer 。能不能前段网页挂 VPS,NAS 不挂网页,只存储数据?即办公室电脑访问 VPS 只完成认证工作,并为办公室电脑访问 NAS 做好准备,完了办公室电脑直接将照片文档等数据存储到 NAS ?
|
81
binkcn OP @sadfQED2
哈哈哈,我代码已经实现了简单版本,算是可以用了,目前我自己已经愉快的用上了。 后续还需要完善一些附属功能,比如:自动清理过期的 iptables 这种,不过并不是特别紧急的东西,有空再弄。 |
82
binkcn OP |
83
1996cyj 2020-11-19 16:17:03 +08:00
目前套了层 cf,防火墙仅允许 cf 的 ip 段及端口访问。
|