一、我的需求
自己在家有一台主力机,在办公室还有一台笔记本电脑。主要是希望随时可以访问到公司的内网.又可以在公司访问自己的主力机
为了满足这个需求,就需要 NAT 穿透,正好最近 mesh vpn 的概念很火,又看到 Tailscale 正好对个人用户免费,于是就想试试看了。之前也有用Zerotier,其实已经很好用了.只是偶尔有断连的问题。但是很多真的挺方便的。主要是自己用的K2P的固件里面直接就支持了。
后续更新:
在使用Tailscale的过程中,我遇到这么一件事。如果你有解决方案的话,麻烦和我说一下。事情是这样的,我在使用的过程中,发现一旦重启了电脑之后,我就没有办法远程登陆了。用Remote就是提示无法访问。我必须本地登录后,才可以远程登陆。我一直以为是Win系统的问题。后来我发现,使用Zerotier就没有这个问题。就算我重启了电脑,之后还是可以远程登陆。不知道有没有人同样的情况,有没有更好的解决方案。
二、TailScale 是什么
VPN 是什么?
虽然国人看到 VPN 第一反应应该是“翻墙”,但 VPN 最初应该也是最普遍的用途应该是用来做内网打通, 这也是其名字虚拟私有网络的用意,VPN 让你可以在公开的网络线路上建立一个私有的子网, 然后将所有接入的机器都分配一个私有的内网地址,让他们可以通过 VPN 的私有网络互联。
比如最常见的需求就是,公司有一个内网办公环境,当你外出办公时,也希望你的电脑能够接入办公网络。 因为外网的机器和内网的机器不能互联,所以一般会有一个中心服务器, 所有的子节点都和中心服务器相连,然后中心服务器转发所有的流量。
这样做的缺点显而易见,首先是中心服务器(hub)会成为瓶颈。 其次,某种极端情况下,如果节点 A 和 节点 B 距离非常近,但是都离 hub 很远, 这样就会导致非常高的延迟。
那么我们就会想,能不能让节点间直接互联呢? 这就是 mesh VPN,其实现就是 wireguard。
wireguard 的每一个节点都会存储其他所有节点的信息,并且和其他所有的节点都建立 tls 连接。 如果涉及到内网穿透的话,那么你需要找到一台处于网关位置的节点(内外网都可达),将其设置为 coordinator, 扮演类似于 hub 的角色, 分发穿透内外网的流量。
wireguard 的缺点在于:
- 配置比较繁琐
- 维护也比较困难,增删节点都需要改动所有节点的配置
基于上述这些痛点,tailscale 做了一些改进:
- 在原有的 ICE、STUN 等 UDP 协议外,实现了 DERP TCP 协议来实现 NAT 穿透
- 基于公网的 coordinator 服务器下发 ACL 和配置,实现节点动态更新
- 通过第三方(如 Google) SSO 服务生成用户和私钥,实现身份认证
简而言之,我们可以认为 tailscale 是更为易用版的、功能封装更为完善的 wireguard。
TailScale的另外一个优势就是MagicDNS
MagicDNS,现在还在测试阶段,确实很方便,你不再需要去记那些IP地址,而是只需要记住机器的名字,比如说你把家里的服务器命名为,Homecompueter,连Remote的时候,你就只需要输入Homecomputer,大大的方便你连接服务。
三、TailScale 能做到什么
只要你的机器可以连到公网,tailscale 可以让所有的机器连接到同一个私有子网内。 你可以像在同一个局域网里那样,随时随地的连接你的任意设备。
比如现在我的台式机和我的笔记本都登录了同一个 tailscale 账号, 它们都共享同一个 100.64/10
的子网,也就是可以随时随地的互联。 即使我的笔记本在公司内网之中,无法和家里台式机直连,但是依靠 relay 转发流量, 两者依然可以畅通无阻的直接连接。
1、传输文件
tailscale 内置 taildrop,可以在设备间传输文件,因为 tailscale 支持 android/ios/mac/windows/linux,所以实际上这也是一个很好用的全平台文件传输工具。 而且如果设备处在同一个局域网的话,传输速度也会非常快。
2、远程办公
比如说,我们办公室的Sage50,我们就开通了多人模式,这样子,我就可以通过TailScale组成的局域网,直接打开数据库,相比较而言,速度更快,而且也不需要使用Remote的模式。如果你不是Windows的服务器版本,你可以开Remote的链接数是有限制的。只能通过其他手段(superRDP这些软件)进行破解。但是你的Windows系统一旦升级,就有可能失效,而且对服务器的压力更大。
另外一个优势,就是可以使用局域网内的共享网盘,这样做的一大优点是,台式机硬件的售价非常便宜,比如金士顿 32G 内存只要 880, 金士顿 1TB M2 SSD 也只要 800。WD 4TB 蓝盘不到 1 千,18 TB 黑盘也只要 2k。 也就是说,你可以用很低的成本组装一台超强配置的机器。 而同样的价钱去选购笔记本的话,只能买到很差的配置。
再说,我认为移动办公的精髓应该在与你可以随时随地的连接上一个统一且强大的工作环境, 而不是抱着同一台笔记本走南闯北。
3、代理
tailscale 节点间是点对点 tls 连接,所以实际上也可以用来做网络代理。 比如我在境外服务器上安装一个 tailscale 的节点,然后再在境外服务器上安装一个 cow(用来做 http proxy server)。 那我就可以在任意一台机器上,访问境外服务器的 tailscale 子网 IP + cow 端口的形式实现 HTTP/SOCKS 代理。
cow 的安装很简单:
curl -L git.io/cow | bash
我选择将其安装到 /usr/local/bin/cow
,然后配置文件 /home/laisky/.cow/rc
只需要一行:
listen = http://100.118.165.101:17777
可以将其添加进 systemd:
sudo vi /etc/systemd/system/cow.service
[Unit]
Description=cow service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=laisky
ExecStart=/usr/local/bin/cow -c /home/laisky/.cow/rc
[Install]
WantedBy=multi-user.target
用 cow 当代理服务器是因为安装最方便,再说我此前本来也在用 cow,就顺便了。
四、安装、部署
参照这个官方页面安装,然后登录即可:https://tailscale.com/download
如果只是Win系统的话,只要一步一步安装。很快就可以用了。
1、自建中继
tailscale 提供的 relays 数量有限,而且全部在国外。 你也可以自建中继。
安装 derper
自建中继服务器被称为 derper,是用 go 开发的,建议先安装 go 环境。
go 是预编译的,安装起来很简单,下载、解压即可。
拿 AMD64 linux 举例:
wget https://golang.org/dl/go1.17.2.linux-amd64.tar.gz
tar -xzf go1.17.2.linux-amd64.tar.gz
sudo mv go /opt/go
sudo ln -s /opt/go/bin/* /usr/local/bin/
export GOROOT=/opt/go
export GOPATH=/home/laisky/.go
go version
其他安装方式参考:https://golang.org/doc/install
derper 的安装方式为:
# 安装
go install tailscale.com/cmd/derper@main
# 启动
sudo derper -c=/root/derper.conf -hostname=xx.xx.xx -a=:443 -stun
启动 derper 的参数:
-hostname
:有效的公网域名,derper 会自动为这个域名申请 letsencrypt tls 证书。-a
:指定 derper 监听的 tcp 端口,默认为 443,修改为其他端口的话似乎转发流量会有问题。-stun
:stun 协议的 udp 端口,health check 的时候会用到。
需要注意的是,因为 derper 会申请公网 TLS 证书,如果你的服务器在国内,那么域名必须要备案。 而且由于中国封锁了 letsencrypt,所以你的 derper 在启动一会儿后,很可能会报这样的错:
http: TLS handshake error from client-a-ip:34379: acme/autocert: missing certificate
上述错误表示证书申请失败,如果你有自己的证书的话,可以用 -certmode=manual -certdir=xxx
的形式指定证书文件夹。
顺带一提,如腾讯云这样的国内云服务器提供商,会审查 TLS handshake 里的 SNI 信息, 如果发现 SNI 域名未备案,会阻断 TLS 握手。 所以,我曾经也尝试过用一个境外服务器的域名,然后指向到境内服务器 IP 的形式尝试绕过备案, 然而短暂的用了几分钟后,就遇到了 tls handshake reset 的问题。 目前看来,只要你想用境内服务器,那么备案就是绕不过的问题。
Ps. 如果你有备案域名,那么可以用 nginx stream 反向代理的形式做 443 端口 4 层转发。 nginx stream 可以在四层探测 SNI 信息,然后分发到不同的后端,这样你 derper 的 443 和其他域名的 443 就可以共存在同一个服务器上了。
Ps2. 实际用下来之后,发现建设国内 derper 实际上也有问题。虽然因为境内延迟超低,在国内做穿透的时候会非常得爽。 但是如果要做跨境穿透,因为境内的 derper 和境外的 relays 通信也有干扰,很可能导致境内外的两个节点始终无法协商到同一个 relay 上。 综合而言,如果你仅有境内穿透的需求,那么搭一个境内 derper 会很爽;但如果你要跨境,那么在境外 HK、SG 等地搭一个 derper 可能更好。
因为 tailscale 的协议时常会更新,官方建议时不时重新执行一下 go install tailscale.com/cmd/derper@main
以更新 derper server。
derper 也可以加到 systemd 里自启动:
➜ ~ sudo vi /etc/systemd/system/derper.service
[Unit]
Description=derper service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/home/laisky/.go/bin/derper -c=/root/derper.conf -hostname=x.x.x.x -a :443 -stun
[Install]
WantedBy=multi-user.target
你也可以在 go dockerfile 里执行上述步骤,然后以容器的形式运行 derper。 不过需要注意的是,因为 derper 会在后台申请 letsencrypt,你不要太频繁地对同一个域名创建运行容器, 否则很容易触发 letsencrypt 的频率限制(168hr 内申请 5 次。)
配置 ACL
安装好 derper 后,需要在网页上配置服务器信息,地址在 https://login.tailscale.com/admin/acls
在其中加上一段 derpMap
:
"derpMap": {
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "REGION_NAME",
"Nodes": [
{
"Name": "NODE_NAME",
"RegionID": 900,
"HostName": "xxx.xxx.com",
// IPv4 可以不填,填的话可以绕过对域名的 DNS 解析
"IPv4": "x.x.x.x",
}
]
}
}
}
其中 RegionID 必须是数字,而且必须是 9xx。
为了调试自己的 derper 是否可用,你可以先把官方的所有中继都禁用了:
"derpMap": {
"OmitDefaultRegions": true,
}
在节点服务器上,需要重启 tailscaled 才能生效,win/mac 的话可以直接退出 tailscale 程序再重新打开。
linux 上,可以用:
sudo systemctl restart tailscaled
重新进程后,可以查看 tailscale 网络的状态:
# 查看 relays 节点的列表和延迟,应该能看到你自己安装的 derper 节点
sudo tailscale netcheck
# 查看当前 derper 和其他 derper 节点的连接状态
sudo tailscale status
顺带一提,tailscale netcheck 实际上只 check 3478/udp 的端口, 就算 netcheck 显示能连,也不一定代表 443 端口可以转发流量。 最简单的办法是直接打开 https://x.x.x.x 的域名,如果看到如下页面,且地址栏的 SSL 证书标签显示正常可用,那才是真没问题了。
本文是参考网络资料修改而成,有一些我都忘记是从那里取来的。如果有侵犯,请指出来,我会注明。