biergaizi

biergaizi

V2EX member #42121, joined on 2013-07-15 14:01:48 +08:00
Today's activity rank 2108
Per biergaizi's settings, the topics list is hidden
Deals info, including closed deals, is not hidden
biergaizi's recent replies
> 每次前缀变化,LAN 客户端就会:生成新 GUA → 旧 GUA 变 deprecated → 新旧地址并存一阵 → 旧地址最终失效。这个 churn 过程就是“轮换都有问题”的直接原因

这个问题多年前就在 IETF 讨论过了。IETF 管它叫做“瞬间重编号”问题( Flash Renumbering )。当上游 ISP 发生瞬间重编号的时候,IPv6 地址过期不过期,由于 IPv6 地址默认有效期可以长达一周,导致 IPv6 瘫痪。

解决方法就是 2021 年提出的 RFC9096 [1] 中的瞬间重编号缓解措施:

1. 路由器必须动态计算地址有效期。如果地址有效期是静态的,那么下游的有效期可能比上游 DHCPv6 长。

2. 当检测到上游 IPv6 前缀变化的时候,路由器必须发 Router Advertisement 通知客户端,把旧前缀的有效期设置为 0 ,把过时地址踢掉:

> Any prefixes that were previously advertised by the CE router via PIOs in RA messages, but that have now become stale, MUST be advertised with PIOs that have the "Valid Lifetime" and the "Preferred Lifetime" set to 0 and the "A" and "L" bits unchanged.

3. 作为上述机制失效时的兜底,IPv6 的地址有效期应该设置为 45/90 分钟,而不是几天。

只要路由器软件不实现 RFC9096 ,那么这个问题永远无法解决。你可以说手动实现( 3 )。

解决方式就是装 OpenWrt 最新版,odhcpd 实现了 RFC9096 。这个 bug 还是我去年提交的[2][3][4]。所以理论上 OpenWrt 的 DHCPv6 PD 应该完全没问题了。如果你用 OpenWrt 还有问题,应该报告 bug 。

[1] https://www.rfc-editor.org/info/rfc9096/
[2] https://github.com/openwrt/odhcpd/issues/247
[3] https://github.com/openwrt/odhcpd/issues/248
[4] https://github.com/openwrt/odhcpd/pull/209
> @MYDB: 所以这是又造了一个代理?现有的代理协议和软件不够成熟吗?

没有新代理。它协议就是 SSH 端口转发,软件就是 tun2socks ,这就是十几年前就在用的经典工具。根据 IP 自动分流也是 chnroutes 十几年前就有的东西。现在不同在于,以前根本没有人会去写“管理器”封装,把这些工具用 shell 脚本拼起来就行,能有 90% 的功能。但现在 LLM 时代了,看来有人愿意为可有可无的 10% 的用户体验写前端软件,而且认为软件就“应该”有这些功能。

> 把远端 SSH 服务器当作出网跳板:本机建立一条 SSH 连接,用 tun2socks 在本地创建虚拟网卡

笑死,还 tun2socks……SSH 从 2006 年就原生支持 TUN 隧道了 [1],2008 年时,一个中文博客还转发过 [2]。2006 年大家都知道的东西,2026 年不知道了。

tun2socks 确实通用性比 SSH 隧道模式强,例如不需要管理员权限开启选项,而且兼容其他代理。为什么不跑 Shadowsocks ?

SSH 服务端 PermitTunnel: Specifies whether tun(4) device forwarding is allowed. The argument must be yes, point-to-point (layer 3), ethernet (layer 2), or no. Specifying yes permits both point-to-point and ethernet. The default is no. Independent of this setting, the permissions of the selected tun(4) device must allow access to the user.

SSH 客户端 Tunnel: Request tun(4) device forwarding between the client and the server. The argument must be yes, point-to-point (layer 3), ethernet (layer 2), or no (the default). Specifying yes requests the default tunnel mode, which is point-to-point.

TunnelDevice: Specifies the tun(4) devices to open on the client (local_tun) and the server (remote_tun). The argument must be local_tun[:remote_tun]. The devices may be specified by numerical ID or the keyword any, which uses the next available tunnel device. If remote_tun is not specified, it defaults to any. The default is any:any.

> @Perry: 典型的有个锤子看啥都是钉子,AI slop

以前:这工具怎么用,我读读文档配置一下。
现在:我让 LLM 一句话写个新工具封装一下,重新实现它已经有的功能。

[1] https://web.archive.org/web/20060301033434/https://boingboing.net/censorroute.html
[2] https://www.chinagfw.org/2008/03/boing-boings-guide-to-defeating.html
延迟高低取决于路由,而路由至少取决于 8 个变量:

路由(
你的城市,
你的 ISP (AS),
你 ISP 路由表里的上游 ISP (transit)
你 ISP 路由表里的合作伙伴 (peering),
机房的城市,
机房的 ISP (AS)
机房 ISP 路由表里的上游 ISP (transit)
机房 ISP 路由表里的合作伙伴 (peering)
)

这么一组合,结果往往难以预测的。换一个 ISP ,线路变化是非常正常。某个云服务的日本机房,联通 IPv4 会把流量发到塔塔电信美国分公司,IPv6 更离谱,欧洲出口走 Cogent ,然后 Cogent 又把它发到美国,美国再把它发到 KDDI 。然而中国移动和教育网的路由就是直连。

解决方法要么是改变前四个变量,要么是改变后四个变量。除此之外没什么好办法。

改变后四个变量,那就是就是多租几台服务器,因地制宜,所有的云服务全部 ping/mtr 一遍,找到自己网络环境下最好用的……为了便于管理,这些机器可以不部署任何真实服务,部署 HAProxy 或者 iptables 之类转发到主力机上(国外的 IX/peering 发达,国外到国外的路由问题就少见),纯转发用。还有就是一堆大大小小的“中国优化型 VPS”。

改变前四个变量,可以是在国内租服务器,租一堆国内云服务器,然后继续 ping/mtr 一遍国外目标,找到好用的,配置流量转发。部分地区曾经还有所谓的“精品网”,相当于改了路由。
@FabricPath 了解了。确实是个有趣的发现,值得测试。
@FabricPath “正向的 ssh tunnel 和其他协议一样,只能跑到 400Mbps ,速度明显会低一截。”

这确实是很奇怪的现象。不过这真的是 ISP 的 QoS 造成的吗?

如果连接方向变化,速度就变,我最先怀疑的是 TCP 设置不对称的问题。例如说 TCP ECN ,在 Linux 内核中,net.ipv4.tcp_ecn 可以设置为 1 或者 2 。1 代表“始终启用”,2 代表“对方连接支持我就启用,但我不主动用”。如果服务器和客户端的 ECN 设置不同,那么一个方向发起的的连接,拥堵控制算法可能和另一个不同。我脑子不好用了,已经想不起来还有哪些 TCP 设置和连接方向有关系了,不过这是个排查方向。握手抓个包,看看两个方向的 TCP 参数是不是一样?

最好服务器和客户端跑一模一样的镜像,比如公版 Alpine 虚拟机,然后看看能不能复现。如果能,那确实可能是 QoS 的问题。
@yeyeye 确实,如今走 SSH 的协议的东西可能太多了,2014 年的管制难道真的放松了?例如我发现用 scp/sftp 偶尔大量上传下载文件确实没事,上传下载 Git 也没事。但我总觉得开隧道频繁使用会被封,我思维还停留在 2014 年。
笑死我了,SSH 隧道居然复活了!我这是上小学时候的上网方式,23333333333333333333333333333333 。不过想想就笑不出来了。首先是因为我居然也是能给网民讲故事的老人了,岁月是把杀猪刀。其次是因为,这段历史是中国网络安全领域最重要的历史,居然如今已经有新人不知道了,历史的速度消失惊人。

那就来讲讲故事吧,以防后人忘记了。

首先关于楼主的 SSH 隧道的评论:我上中学时候,SSH 就不能用了。众所周知,我们今天所知所有常用代理工具,几乎都是 SSH/OpenVPN 等工具在 2013-2014 年被封后的连锁反应。假如 SSH 没被封,今天估计人人还在用 SSH ,根本不会有过去十年的历史。

不过楼主引入反向连接,可能还是有创新的——也许反向隧道的检测力度真的不大?或者是因为 SSH 隧道正因为被封了,很少有人用了,检测力度反而下降了?反向隧道也几乎不检测了?又或者说,SSH 只有动态代理模式( ssh -D )频繁建立连接而特征明显,容易被检测,固定静态隧道反而特征少一些?很遗憾,我在 2014 年技术太差,不然我一定会测试反向连接 + 静态隧道好不好用。当年被封的都是正向隧道,反向隧道我个人没听说过有人用。所以这事情已经成了历史谜案,当年这么用究竟会不会被封呢?

然后我们来讲故事。

正向 SSH 的 Socks5 代理( ssh -D <port>)是中国大陆最早流行的代理服务器,在 2007-2013 年间非常流行,见 [1]。我记得当时的标配,一个是 Firefox 浏览器:当年大多数软件只支持 SOCKS 4 ,不支持 OpenSSH 的 SOCKS 5 ,也不支持用代理做 DNS 解析。Firefox 是必须的,而且要进入 about:config 手动开启 network.proxy.socks_remote_dns ;另一个就是 MyEntunnel:Windows XP 下的 SSH 前端,不会输入命令行也能使用。

服务器都预装了 SSH ,默认允许转发流量。有普通账号就能用,不需要权限,曾火遍全网。当年网上能找到一堆来路不明的免费 SSH 账号网站。[2]

当年另一种常见的使用方法是购买 GoDaddy, Bluehost, DreamHost 等公司入门级的个人主页托管业务,开通 SSH 登录。当时还没有 GitHub Pages 等免费静态网站托管,静态生成器也不流行。当年重度网民几乎人人都有 PHP 个人主页,于是同时解决上网与个人网站两个需求。

但这样做的性能并不好。SSH 协议开销大,特别是 -D 动态转发,效率格外低下。静态转发和 TUN 模式可能效率高(如楼主的做法),但我没用过。在后期,许多人都换成了 OpenVPN 做 NAT ,配合 chnroute 项目 [3] 维护的一份巨大的 IP 封禁路由表,决定是否走 VPN 。

然后从 2012 年末到 2013 年初,GFW 开始检测 OpenVPN 的 TLS 握手,看到证书就发 RST ,OpenVPN 暴毙。[4] 如果频繁更换端口,还会导致 IP 被封禁,我的 IP 就被封了。[5] 人们开始改用没有完整握手的静态密钥连接 OpenVPN 。但在我印象中,稳定性并不好。当时的网络传闻说,封禁使用了方滨兴等人在论文《网络流量分类研究进展与展望》[6] 中的技术,但我表示怀疑,实时部署机器学习模型成本似乎过高了。但毫无疑问的是,在 2013-2014 年的某个时刻(不太好查了),GFW 拥有了基于流量特征封禁 SSH 的技术,只要用 SSH 跑隧道,流量大必然封 IP ,但系统管理不受影响。我在 2014 年 7 月,就因为“手贱”在学校开 ssh -D ,导致 IP 被封了。[7]

同样在 2013 年,雪中送炭的是,就在 OpenVPN 检测全面推行时,Tor Project 对抗流量分析的 obfs2proxy 代理登场( 2012 年完成开发)[8],SSH/OpenVPN 套一层 obfs2proxy ,直接复活![6] 但这个协议有漏洞,后来一直改进到 obfs3 [9], obfs4 [10]。至今 obfs4 依然被认为是里程碑,没有明显漏洞。但是 obfsproxy 的性能依然差,而且由于需要编译 C 程序,还要自行叠加代理应用,其影响力仅仅局限于网络安全圈子,而不是普通的开发者圈。

就在这样的时代背景下,2012 年,clowwindy 在 v2ex.com 论坛(也就是这里)发表《发一个自用了一年多的翻墙工具 shadowsocks 》[11],本来是一个非常简易的 Python 脚本,就是把 socks 的内容过一遍 AES ,不支持公钥也不支持完整性校验,但恰恰因为协议极简,对称加密无握手特征,而且采用可移植的 Python ,易于传播。在 2013 年,在 VPN/SSH 等标准协议被封禁后,Shadowsocks 天时地利人和,迅速被大量应用。(也正是因为协议简易,也为日后的各种安全漏洞埋下了伏笔——但此时矛盾还未爆发)。

我有一张 2015 年 6 月的服务器登录截图,上面写着:请勿使用 "ssh -D" 开代理,请使用 "ss-server"。可见当时 ss-server 就是 SSH 的平替(上面还打趣的写着:如果你想开代理,请交 450 元/10 万元/70 万,左侧还有一个红白动漫角色的字符画——这是三个当时动漫圈的梗,留给读者作为练习)。[12]

2015 年,当局迫使 Clowwindy 停止开发工作。[13] 但 Clowwindy 退出的影响有限。由于 Shadowsocks 恰好赶上了后来的智能手机普及,以及 Node, Go, libev 等协程/异步编程新框架的普及,它极简的协议立刻成为网络编程的典型项目,被各种编程语言实现,被各种 iOS/Android 开发者实现。这使得 Shadowsocks 成为一举多得的项目:编程语言推广、网络编程、业余移动 App 、跨境代理,让它成为全网最流行的代理。

剩下的故事,正如人们所说的——就是历史了。

[1] https://www.chinagfw.org/2007/10/myentunnel.html
[2] https://www.chinagfw.org/2010/09/ssh_17.html
[3] https://github.com/fivesheep/chnroutes
[4] https://www.chinagfw.org/2012/12/openvpngfw.html
[5] https://tomli.blog/archives/2013/02/1621.html
[6] https://doi.org/10.12146/j.issn.2095-3135.201205006
[7] https://tomli.blog/archives/2014/07/1874.html
[8] https://github.com/Yawning/obfsproxy/blob/master/doc/obfs2/obfs2-protocol-spec.txt
[9] https://github.com/Yawning/obfsproxy/blob/master/doc/obfs3/obfs3-protocol-spec.txt
[10] https://github.com/Yawning/obfs4/blob/master/doc/obfs4-spec.txt
[11] https://v2ex.com/t/32777
[12] https://web.archive.org/web/20261109102557/https://misskey-taube.s3.eu-central-1.wasabisys.com/files/10572e04-1782-4f22-bfa3-1f2b7ee6e52e.jpg
[13] https://www.eff.org/deeplinks/2015/08/speech-enables-speech-china-takes-aim-its-coders
233333333333333333333
@someonesnone SS 里面现在都是 99% 都是 TLS 了,能监听出什么来?十年前大家争 SS 的密码学是否符合最佳实践,安不安全,骂战血雨腥风。再过几年,等 ECH 开箱即用之后,SS 改用凯撒加密都行(滑稽)。
“虽然可以设置防火墙但是精细控制每个设备和端口太麻烦了。”——并不需要每个机器都装防火墙(虽然这样最好)。防火墙的正常功能本来就是在网关处阻止入站连接,和内网外网无关。就算防火墙后面的设备全是公网 IPv6 ,防火墙也是有效的。最常见的配置就是出站开 conntrack ,入站开“允许 conntrack 的连接进入”,NAT 本质就是从防火墙的 conntrack 功能改造来的。运行公网服务,照样需要调整防火墙设置的,只不过换了个名字,不叫“端口转发”,叫“端口放行”,换汤不换药。

NAT66 还是有优点的,只不过优点并不是“不需要太多防火墙”。如果你想保证换了 ISP 或者 ISP 分配的 IPv6 前缀变化后,所有配置文件都不报废,那 NAT66 确实是合理选择。原生 IPv6 时,这种情况下的配置需要非常小心。例如服务器只能监听 [::] 而不是固定 IP 地址(靠登录/证书/防火墙保证其他网络不能访问,不靠监听 IP ),否则换 ISP 就作废了。网关开放端口时,防火墙最好也不要匹配完整 IPv6 ,而应该匹配 IPv6 的后 64 位(用 iptables/nftables 的掩码功能,把 IP 的前 64 位清零后再匹配,这个设置在许多图形界面上根本无法完成)。
About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   980 Online   Highest 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 13ms · UTC 22:13 · PVG 06:13 · LAX 14:13 · JFK 17:13
♥ Do have faith in what you're doing.