使用EasyTier异地组网

(封面图源EasyTier官网)
TL;DR
异地组网,我一直以来都有这个需求,便于在各种情况下访问我的所有内网设备。在曾经的折腾一番CloudFlare DDNS一文中我提到了使用开源的VPN协议进行异地组网,但这一直有几个弊端:
- 必须依赖中继服务器
- 只能单向访问,如需双向访问则还要另开一个ssh端口转发。
- 每多一个子网,就得多一条VPN连接。
正好,在同学的安利下,碰到了这款叫EasyTier的开源项目。好耶,甚至是Rust开发的!
架构思路
在EasyTier中,没有客户端、服务器的概念,只有节点的概念,因为它是一个去中心化的网络架构。每个设备都是一个节点,EasyTier把每个节点放在同一个网段下,节点以局域网地址来访问另一节点的指定端口。
在工作的时候,需要一个公网服务器,用作STUN打洞,亦或做流量中转。
搭建目标
我要把公网服务器、手机、笔记本电脑放在同一个局域网下,其中手机通过流量上网,笔记本通过校园网WiFi上网。
其中手机和笔记本电脑要保证能正常走流量代理的情况下又不影响EasyTier组网,还要保证手机在校外能访问校内的一台服务器(10.1.2.3/16)。
因为EasyTier是以本地应用程序运行的,如果在电脑上直接裸跑,就会让系统防火墙在局域网内直接被架空,所以我们要部署到docker容器里做到网络隔离,又要保证能正常组网。
开始搭建
文件准备
我们先去release页面下载app-universal-release.apk和easytier-linux-x86_64-v2.4.5.zip两个包,一个是给安卓手机用的,一个是给我们的服务器和电脑用的。
解压后,我们只需要easytier-cli和easytier-core两个就行,core用来组网,cli用来管理状态。
截止写稿,最新版本是
2.4.5,请根据实际情况下载。
除安卓端,启动命令都是./easytier-core -c config.toml,后续默认你已将easytier-cli和easytier-core放在工作目录,并已cd进去。后续是每个端上的配置文件。
公网服务器端
1 | |
笔记本电脑端
1 | |
安卓端
打开app,在basic settings里填入你这台设备的虚拟局域网ip地址,或者也可选择是否DHCP获取。Network Name和Network Secrect填入和上面配置文件里一样的。Networking Method选择Public Server,然后地址填写tcp://your_ip_or_domain:your_port,也和上面配置文件一样。
重点来了,你如果要在组网的同时使用别的代理软件,就要打开No TUN Mode并添加Socks5 Server,然后去第三方代理软件里添加一条路由规则,这个会在文章最后讲到。
然后直接Run Network即可。
笔记本端的安全策略: 使用Docker隔离网络访问
因为EasyTier是以本地应用程序运行的,如果在电脑上直接裸跑,就会让系统防火墙在局域网内直接被架空,所以我们要部署到docker容器里做到网络隔离,又要保证能正常组网。
现假设你的电脑上运行着
ssh服务(监听1919端口)和nginx页面(监听9180端口),并且这两个端口已被防火墙放通。
Docker容器
创建一个Docker容器,把1145端口(就是上面笔记本配置文件里的socks5_proxy端口)映射出来。或者可以直接抄我的作业:
1 | |
这样在容器里运行easytier的话,别的节点通过局域网ip访问你的时候是无法直接访问宿主机对应端口的服务的(实际访问的是容器里对应的端口),所以我们要用端口转发器把流量从容器里转发到宿主机上。即使宿主机对应端口被防火墙拦了,别的节点也无法访问该服务,对别的节点来说是无感的了。
我们使用socat进行端口转发,这样更通用,因为在我的环境下,alpine容器里装iptables无法修改转发规则。
使用socat转发流量只须这一行命令即可(容器中宿主机ip是172.17.0.1):
1 | |
或者使用这个脚本启动,可以自动管理socat和easytire-core的生命周期:
1 | |
和其他TUN代理的冲突问题
如果你开了easytier的tun模式,会和其他基于tun实现的代理软件对冲(在安卓上系统会限制只允许有一个VPN Service导致互挤);如果你部署到docker容器里的话,会导致无法连上宣告服务器。所以我们要进行如下处理:
假设你的容器已将socks5端口1145转发出来。
在代理软件里新增一个节点,地址是127.0.0.1:1145,设置代理软件的路由规则,发往10.1.0.0/16和172.16.32.0/24的流量通过该节点出站。
(安卓不用做这一步)然后设置排除网卡,把docker0排除掉即可。
