biergaizi

biergaizi

V2EX member #42121, joined on 2013-07-15 14:01:48 +08:00
Today's activity rank 7022
Per biergaizi's settings, the topics list is hidden
Deals info, including closed deals, is not hidden
biergaizi's recent replies
> @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 位清零后再匹配,这个设置在许多图形界面上根本无法完成)。
不同操作系统 TCP/IP 栈的设置与差异,有时候也会导致离奇的网络问题。最常见的有 MTU/MSS 大小、ECN 开与关、TCP 拥塞控制算法是 Reno, CUBIC 还是 BBR ,TCP 的 Timestamp 选项开关、SACK 设置等等,理论上都可能有问题。我曾经遇到过有些机器死活打不开某些国外网站,有些机器就可以。没有时间调查,大概率是 DNS 的问题,但有一次我记得我用 /etc/hosts 固定 IP 后依然有这种现象,不得不怀疑是 Middlebox 对不同 TCP/IP 特征有差别对待。如果下次我再遇到这个问题,我会桥接网络跑不同虚拟机测试。

好在这次的问题解决简单,OP 说“用 Mac 连 2.4G wifi 速度就正常了。 大无语。”
About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2105 Online   Highest 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 10ms · UTC 14:44 · PVG 22:44 · LAX 06:44 · JFK 09:44
♥ Do have faith in what you're doing.