虚拟局域网,嗯,局域网。
是的,它的大名叫虚拟专用网,或者你更熟悉它的三字母名:VPN. 不过在现在的网络环境下这个名字多少有点变味了,所以我还是取了「虚拟局域网」这个小名。
我们的目标也很简单:你有一堆可以联网的电脑,但是它们不在同一个路由器下,其中有些甚至没有公网 IP。在这种条件下,有没有办法让它们之间可以组成一个逻辑上的局域网,这样可以方便管理和实现在这些电脑之间通信呢?
之前,我描述过的方案是通过 FRP 实现内网穿透。不过 FRP 一次只能放行一个端口,而且你还需要手动设置所有终端才能把这一个服务打通。以及更关键的是:FRP 不会自动选择延迟更小的路径,或者说 FRP 总是会依赖一个公网上的中枢服务器做流量转发,即使有很多情况下两台设备之间可以直接通信。
这也就意味着:假如你有一台台式机和一台笔记本各自配置好了 FRP, 即使笔记本和台式机已经处于同一个局域网下,这个服务的访问也仍然会绕一圈公网再回来。
我选择的方案是自建 Tailscale 服务,毕竟手动配置 WireGuard 实在是太烦人了。自建 Tailscale 服务主要是自建一个 Tailscale 控制服务器,可以使用 Headscale 这个开源实现。
前置准备我们需要以下内容:
一台在公网上的服务器(作为网络控制器) 需要是 Linux 机器,最好是 Debian 系的 (Debian/Ubuntu...)如果支持 IPv4/v6 双栈最好没了。
配置控制器之下所有的配置都假定你的控制服务器运行 Debian/Ubuntu.
安装 Headscale登录公网服务器,下载 Headscale 的安装包并安装:
wget https://github.com/juanfont/headscale/releases/download/v0.25.1/headscale_0.25.1_linux_amd64.deb
sudo dpkg -i ./headscale_0.25.1_linux_amd64.deb
注意第一条 wget 指令的版本不一定是最新的,你需要去 Headscale 的 GitHub 页面查看一下最新的版本号是多少。
配置 Headscale默认情况下,Headscale 的配置文件在 /etc/headscale/config.yaml. 以 Root 身份打开编辑。我们主要关心以下配置项目:
server_url: https://headscale.my.server.arpa # 这里改成访问你的控制器的 URL
listen_addr: 127.0.0.1:14443 # 这里改一下端口号,避免和其他程序冲突
prefixes:
v4: 100.64.0.0/10 # Tailscale 内网地址前缀
v6: fd7a:115c:a1e0::/48 # 内网 v6 地址前缀
allocation: sequential # 地址分配逻辑,sequential 代表按顺序自增,random 代表随机分配
如果没有特殊情况,不需要开启 DERP 服务,保留文件剩下的部分不更改即可。
保存该配置文件,并启动 Headscale 服务:
sudo systemctl enable headscale --now
配置反向代理Headscale 默认只接收来自回环地址的访问流量,我们需要配置一下 HTTP 反向代理来架设通信。
以 Nginx 为例:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name headscale.my.server.arpa; # 这里改成你的域名
ssl_certificate "???"; # 改成你的证书路径
ssl_certificate_key "???";
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:14443; # 这里的端口号需要和上面配置的一致
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_redirect http:// https://;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
}
添加用户完成上述步骤后,就可以向系统里添加用户了:
sudo headscale users create 你的用户名
为了配置的方便,用户名最好只使用英文字母和数字,且不以数字开头。
之后可以通过列出用户的方式确认添加成功:
sudo headscale users list
ID | Name | Username | Email | Created
1 | | dousha | | 2025-05-01 13:19:37
^ 这里会是你的用户名
加入虚拟局域网其他的节点可以通过 Tailscale 客户端直接加入。需要注意的是:即使是在 Windows 下,也需要使用 tailscale 命令来加入自建的网络。在通过 MSI 安装 Tailscale 客户端后,你可以通过 ❖ Win + x, a 来打开管理员终端,并通过 tailscale 指令控制 Tailscale 客户端。
和 Tailscale 官方服务器不同,默认情况下,所有加入了虚拟局域网的节点都不会过期。要设置节点的过期,需要手动使用 headscale expire 命令,此处不再赘述。
交互式加入在使用 tailscale up 命令时,可以指定控制服务器地址:
sudo tailscale up --login-server https://headscale.my.server.arpa # 记得改域名
执行此命令后,Tailscale 客户端会生成一个验证 URL 以供你在浏览器内打开。在打开后,你会得到另一串需要你在之前的控制服务器后台中执行的指令。需要注意的是,这份指令中,你需要将 USERNAME 部分替换成你之前创建好的用户名。
预授权加入如果觉得这样在多个窗口中横跳有些麻烦,也可以通过预授权密钥添加节点。
在控制服务器上通过此指令生成一个预授权密钥:
sudo headscale preauthkeys create --user 你的用户名
Headscale 将会生成一个默认过期时间为 1 小时的预授权密钥。将密钥复制下来,进入你需要添加的节点后台,执行此指令:
sudo tailscale up --login-server https://headscale.my.server.arpa --authkey 之前生成的密钥
此时节点将直接获得授权,无需额外的浏览器授权操作。