本文发自 http://www.binss.me/blog/how-i-access-my-lan/,转载请注明出处。

今年为了降本增效,从 299元/月 的电信换到了 30元/月 的联通。除了速度降低外,最大的影响莫过于失去了公网 IP:一方面,在过年过节回老家的日子里,我没办法通过 moonlight 直接串流家里的 PC 打游戏、没法在路上连接家里的 NAS 观看 Plex 里的视频。另一方面,一系列私有云的服务也不得不切换到服务提供商提供的中转上,比如群晖的 diskstation、photos、drive 。

原有方案

虽然群晖自带的 quickconnect 中转能部分解决访问内网中群晖的问题。但有时候突然需要访问下家里的服务,远程桌面连下家里的电脑,就懵逼了。为此我采用了中转的方案:

这个方案核心有两个组件: frp ,用于内网穿透和流量转发。ss (或其他客户端),主要用于端到端加密。最终实现外网的 client 能够以内网的 Server 为代理,访问内网服务的目的。

公网中转服务器 配置

拥有公网 ip 的 1.2.3.4 VPS 运行 frps:./frps -c ./frps.ini

frps.ini 配置如下:

# frps.ini
[common]
bind_port = 12345
token = frp_password

表示 frp 监听 12345 端口。

若使用的是公有云的 VPS,请检查端口是否联通,不通的话需要到控制面板的防火墙放行对应的端口。

内网 Server 配置

位于内网、用于穿透的服务器运行 frps 和 ss-local 。分别通过 ./frpc -c ./frpc.iniss-server -c ./config.json -u -d 223.5.5.5,114.114.114.114,1.2.4.8 启动。

frpc.ini 内容为:

# frpc.ini
[common]
server_addr = 1.2.3.4
server_port = 12345
token = frp_password
login_fail_exit = false
user = nas

[shadowsocks]
type = tcp
local_port = 8888
remote_port = 12346

config.json 内容为:

{
    "server": "0.0.0.0",
    "server_port": 8888,
    "password": "ss_password",
    "timeout": 300,
    "method": "chacha20-ietf-poly1305",
}

于是位于内网的 Server 会通过 frp 连接到公网中转服务器 1.2.3.4:12345,告诉它将发往 12346 端口的请求转发到自己的 8888 端口。

客户端配置

位于外网的客户端运行 ss client 类代理软件,我用的是 Surge,其他代理软件同理:

# surge.conf
[Proxy]
Home = ss, 1.2.3.4, 12346, encrypt-method=chacha20-ietf-poly1305, password=ss_pasword

[Rule]
IP-CIDR,192.168.10.110/32,Home,no-resolve

这样当在 client 机器上访问 192.168.10.110 时,这个请求会被不加解析地转发到位于公网的中转服务器 1.2.3.4 的 12346 端口。然后被 frp 转发到内网 Server 的 8888 端口。这个端口被 ss-server 监听,其收到这个请求后,会进行代理,在内网请求 192.168.10.110 。

小结

以上方案用了大半年,比较稳定。但成本还是挺高的。我买的是腾讯云的 Lighthouse ,3M 带宽一个月 45 元。这种带宽意味着只能简单连个远程桌面,看下 1080P 电影。至于 Moonlight 串流打游戏就不太可能了,4k 串流游戏至少要求 20M 带宽,每个月要上千。

更换路由器

不爽于原有方案的小水管,最近我开始研究新的方案。我发现,虽然拿不到公网 ipv4,但可以拿到 ipv6 。那么能不能直接通过 ipv6 访问呢?

tplink 告诉你:打咩。我用的是 tplink xdr6080,去年 1000 大洋买的,算是他家的中高端产品了。结果这个路由器对 ipv6 访问的策略是 BLOCK 。这意味着请求顺着公网 ipv6 来到路由器前,然后被路由器策略给拒绝了,无法访问到内网(这里的前提是光猫已经改桥接,路由器直接拨号)。网上说官方后续固件会支持放行,结果等了快两年了,不要说支持这个特性,连固件都没更新过。

所以对于非小白用户,我是不建议买 tplink 路由器的,无论是他家的低端还是高端路由器。虽然很稳定,硬件上用料也很足。但是他家是一锤子买卖,后续再无软件售后。

所以最简单的办法是换个支持放行 ipv6 的路由器。经过一番搜索,如果不想整什么软路由刷 Openwrt,确定支持的只有 ASUS 。但他家的产品确实高贵,稍微看得过去的路由器(带 4x4 MU-MMIO)都 1000 起跳,并且还有些上了 N 年的老家伙混迹其中(比如 RT-AX86U)。经过一番搜索,发现今年年中刚上了一款新品,天选游戏路由(TX-AX6000),非常的二次元,孩子很喜欢,JD 自营 900 拿下。

查了下资料,是 MTK Filogic 830 的方案,也就是 MTK7986 + MT7976AN + MT7976GN 。采用相同方案的有小米 Ax6000,JD 自营只需 400。所以硬件值 400,LOGO 值 400,二次元小姐姐值 100 。

Anyway,更换路由器后,终于有了放行 ipv6 请求的能力,经过测试,能够通过 ipv6 访问内网机器。所以我的新方案调整如下:

防火墙配置

同样采用 ss 进行端到端加密。在路由器上,在 ipv6 防火墙选项中,放行 ss 端口 8888,如图:

详细配置可参考 官方文档

remote ip 留空,不对来源进行限制。但这个本地 IP 要怎么填呢?这个 ip 是内网 Server 公有 ipv6 地址,但它不是我们自己分配的,可能会变。变了的话这条规则就失效了。经过一番搜素,在 正确地配置 IPv6 防火墙和 DDNS 以在公网访问设备 中,作者介绍了 EUI-64 地址,它的特性是后缀固定不变、前缀实时更新。

  1. 找到目前用于连接互联网的网络适配器。
  2. 找到一个 IP 地址,它应该类似于 2001:2002:2003:2004:****:**ff:fe**:****,它就是该设备的 EUI-64 地址。
  3. 记下 ****:**ff:fe**:**** 的部分,下文假设它是 1:20ff:fe77:2077
  4. 使用 EUI-64:<需要暴露的主机的后缀>/::ffff:ffff:ffff:ffff,如 ::1:20ff:fe77:2077/::ffff:ffff:ffff:ffff

查询 Server 的 ipv6 地址,以 EUI-64 地址的形式填入即可。

ss 配置

ss 需要开启 ipv6 支持,配置修改如下:

{
    "server": ["[::0]", "0.0.0.0"],
    "server_port": 8888,
    "password": "ss_password",
    "timeout": 300,
    "method": "chacha20-ietf-poly1305",
    "ipv6_first": true,
}

客户端

位于外网的客户端运行 ss client 类代理软件,我用的是 Surge,其他代理软件同理:

# surge.conf
[Proxy]
Home = ss, 2001:2002:2003:2004:1:20ff:fe77:2077, 8888, encrypt-method=chacha20-ietf-poly1305, password=ss_pasword

[Rule]
IP-CIDR,192.168.10.110/32,Home,no-resolve

这样当在 client 机器上访问 192.168.10.110 时,这个请求会被不加解析地转发到内网 Server 2001:2002:2003:2004:1:20ff:fe77:2077 的 8888 端口。这个端口被 ss-server 监听,其收到这个请求后,会进行代理,在内网请求 192.168.10.110 。

Surge Ponte

作为 Surge 老用户,被割了一次又一次韭菜。但它确实是苹果生态中该类目的 Top1。针对内网穿透方案,它也有自己的解决方案,叫 Surge Ponte

它是 Surge 提供的一种在运行 Surge Mac 和 iOS 设备之间的私有 mesh 网络,可以用来实现内网穿透。

Surge Ponte 有三种模式:

  1. 直接 NAT 穿透:通过打洞的方式进行内网穿透。这要求运行 Surge 的 Mac 是处于 full cone 的 NAT 下。不幸的是,市面上绝大多数路由器 nat type 都是 restrict NAT ,导致无法打洞。要么购买支持 full cone 的路由器(目前了解到官方固件只有华硕的高端型号支持,要么就是第三方固件比如梅林或则 Openwrt)。要么在路由器上设置 Mac 为 dmz 主机,但这样做会让 Mac 直接暴露在外网,安全性难以保证。

  2. 通过代理 NAT 穿透:通过一台公网的机器进行中转。这和我之前的内网穿透方案一样,缺点是受限于中转机器的带宽。

  3. 静态端口转发:如果有公网 IP ,可通过端口转发的方式进行内网穿透。但都有公网了,还说啥穿透

可以发现 Surge Ponte 无非就是把内网穿透过程集成到 Surge 的图形化界面里面,简化了配置流程,并没有什么 fancy 的地方,因此不做深入讨论。如果你像我一样 Surge IOS 和 Mac 都买了,可以通过这套解决方案多配一条路作为保险。