1 前言
- Tailscale 提供了一个完整的、托管的解决方案,简化了 VPN 配置和管理,适合大多数用户,尤其是需要快速设置和稳定服务的用户。
- Headscale 是 Tailscale 的开源替代品,适用于那些希望自行托管并完全控制其 VPN 网络的用户。
- DERP 是 Tailscale 的中继节点,用于处理设备之间无法直接连接时的通信问题。
1.1 tailscale
Tailscale
是一个基于 WireGuard 的个人 VPN 网络解决方案,旨在让用户可以方便地连接不同设备(例如,个人电脑、手机、服务器等),并通过一个简单的配置创建一个安全的网络。其主要特点包括:
- 自动化网络配置:通过 Tailscale,设备可以通过点对点的 WireGuard 连接自动互联,省去了传统 VPN 配置的繁琐。
- 跨平台支持:Tailscale 支持多种操作系统,包括 Windows、macOS、Linux、Android、iOS 等。
- 身份验证:Tailscale 使用 OAuth 和身份验证系统,如 Google、GitHub、Microsoft 等,来简化用户身份管理,保证安全。
- 中继节点:Tailscale 提供了“DERP”节点(后面解释)作为中继,如果设备无法直接通过端到端的方式连接,它们会使用这些中继节点。
1.2 headscale
官网:headscale.net
开源仓库:github
Headscale
是 Tailscale 的一个开源替代方案,用于管理和控制基于 WireGuard 的私有 VPN 网络。与 Tailscale 提供的托管服务不同,Headscale 让用户可以自己托管 VPN 的控制平面。简而言之,它是一个自己搭建的 Tailscale 控制服务。
- 完全开源:Headscale 允许用户自己控制和管理 Tailscale 网络,无需依赖 Tailscale 公司提供的云服务。
- 控制节点:它提供类似于 Tailscale 的功能,但可以部署在自己的服务器上,实现对连接的设备和身份进行管理。
- 灵活性:由于它是开源的,Headscale 可以根据个人需求定制和扩展,尤其适合那些需要在不依赖第三方服务的情况下建立私有网络的用户。
1.3 derper
DERP
是 Tailscale 使用的中继服务器("Designated Endpoint Relay Protocol"),当两个设备无法直接建立点对点连接时(例如,由于 NAT、防火墙或网络地址转换的原因),它们会通过 DERP 服务器进行通信。
- 中继功能:DERP 作为一个安全的中继节点,允许跨越 NAT 或防火墙阻隔的设备进行通信。
- 全球分布:Tailscale 提供了多个 DERP 服务器,分布在全球范围内,以确保低延迟和高可用性。
- 透明性:如果设备之间可以直接连接,DERP 不会被使用,只有当点对点连接失败时,DERP 才会介入。
2 docker容器部署
本文仅提供docker容器部署方式,如需其他方式请参考其他博客。
2.1 准备
- 云服务器
- 备案的域名
- 若干主机
2.2 headscale服务端部署
配置相关文件
# 创建配置文件夹
mkdir -p /docker/headscale/config
# 创建数据文件夹
mkdir -p /docker/headscale/data
# 下载配置文件(根据自己的版本进行下载)
# development version
wget -O /docker/headscale/config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
# 0.23.0 version
wget -O /docker/headscale/config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/v0.23.0/config-example.yaml
# 创建sqlite数据库文件
touch /docker/headscale/data/db.sqlit
config.yaml
需要修改以下几项
server_url
:外部访问以及登录地址,可以使用域名或者ip+端口
的形式。listen_addr
:指定了 HeadScale 服务监听的 TCP/IP 地址和端口,用于控制远程 API 的访问地址。建议修改成0.0.0.0:8080
metrics_listen_addr
:HeadScale 服务收集和提供性能指标所监听的地址和端口,用于监控系统资源使用情况、性能监控等。建议修改成0.0.0.0:9090
grpc_listen_addr
:HeadScale 服务使用的 gRPC 协议的监听地址和端口。gRPC 是一个高性能、跨语言的 RPC 框架,通常用于需要在客户端和服务端之间进行高效通信的场景。建议修改成0.0.0.0:50443
部分配置项可以参考以下:
server_url: http://headscale.XXXX.cn
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 0.0.0.0:50443
grpc_allow_insecure: false
noise:
private_key_path: /var/lib/headscale/noise_private.key
prefixes:
v6: fd7a:115c:a1e0::/48
v4: 100.64.0.0/10
allocation: sequential
disable_check_updates: true
ephemeral_node_inactivity_timeout: 30m
database:
type: sqlite
debug: false
gorm:
prepare_stmt: true
parameterized_queries: true
skip_err_record_not_found: true
slow_threshold: 1000
sqlite:
path: /var/lib/headscale/db.sqlite
write_ahead_log: true
dns
magic_dns: false
base_domain: example.com
nameservers:
global:
- 114.114.114.114
- 8.8.8.8
- 2606:4700:4700::1111
randomize_client_port: true
创建headscale容器
docker run -d \
--name headscale \
--restart always \
-v /docker/headscale/config:/etc/headscale/ \
-v /docker/headscale/data:/var/lib/headscale \
-p 8080:8080 \
-p 9090:9090 \
--restart always \
headscale/headscale:latest \
serve
结合配置文件对应相应端口。如果使用内嵌的
Derp
需要加上-p 3478:3478/udp
,也可以自己再部署一个Derp
服务。
相关命令参考
# 查看用户
docker exec -it headscale headscale users ls
# 创建用户
docker exec -it headscale headscale users create [username]
# 生成apikey
docker exec -it headscale headscale apikey create
# 指定apikey过期时间(eg:1000day过期)
docker exec -it headscale headscale apikey create -e 1000d
# 查询apikey
docker exec -it headscale headscale apikey ls
# 查询节点
docker exec -it headscale headscale nodes ls
# 创建授权密码
docker exec -it headscale headscale preauthkeys create -e [expire time] --reusable -u [username]
#查看授权密码
docker exec -it headscale headscale preauthkeys list -u [username]
apikey
用于保护 HeadScale 的 HTTP API(headscale服务的登录)
preauthkeys
用于保护通过 SSH 进行预授权的连接(SSH连接的授权机制,使用密钥避免认证过程)
2.3 部署 headscale-webui
不是必须,只是为
headscale
增加一个可视化的ui界面
使用openssl
生成一个密钥用来对key进行加密
openssl rand -base64 32
docker run -d \
--name headscale-ui \
--restart always \
-v /docker/headscale/config:/etc/headscale/:ro \
-v /docker/headscale/web-ui/data:/data \
-u root \
-p 5000:5000 \
-e HS_SERVER=http://headscale.XXXX.cn \
-e DOMAIN_NAME=http://headscale.XXXX.cn \
-e SCRIPT_NAME=/web \
-e AUTH_TYPE=Basic \
-e BASIC_AUTH_USER=admin \
-e BASIC_AUTH_PASS=admin \
-e KEY="ogVAjy40B/my8oqJbFM8LBFmzBfPe/lCI4BQG7CqSvQ=" \
--restart always \
ifargle/headscale-webui:latest
配置反向代理(nginx为例)
将
/
目录映射到http://127.0.0.1:8080
将/web
目录映射到http://127.0.0.1:5000
具体端口根据自己容器映射到宿主机的端口修改
生成密钥后登录到 Web
生成apikey
docker exec headscale headscale apikey create -e 1000d
浏览器打开网址http://headscale.XXXX.cn/web
将生成的
apikey
粘贴,可以进入到界面首页错误处理
如果查看machines出现以下ERROR时,请进行以下修改
# 进入容器
docker exec -it headscale-ui sh
# 替换文件
cd /app && \
wget -nc https://raw.githubusercontent.com/wenco/headscale-webui/main/headscale.py && \
wget -nc https://raw.githubusercontent.com/wenco/headscale-webui/main/renderer.py && \
cd /app/static/js && \
wget -nc https://raw.githubusercontent.com/wenco/headscale-webui/main/static/js/custom.js
# 重启容器
docker restart headscale-ui
2.4 derp部署
运行容器
docker run --restart always --name derper -d \
-p 12345:12345 -p 3478:3478/udp \
-e DERP_CERT_MODE=manual \
-v /docker/headscale/certs:/app/certs \
-e DERP_ADDR=:12345 \
-e DERP_STUN_PORT=3478 \
-e DERP_DOMAIN=derp.xxxx.cn \
-e DERP_VERIFY_CLIENTS=true \
-v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \
fredliang/derper
注意:
- 服务器要放行
UDP
协议的3478
端口DERP_VERIFY_CLIENTS
:通过本地的 tailscaled 实例验证连接到此 DERP 服务器的客户端,防止被别人白嫖,但是需要先在服务器安装tailscale
,-v tailscaled.sock
指定的是服务器客户端的目录DERP_CERT_MODE
:获取证书的模式,可选项:manual(手动),letsencrypt
修改headscale配置项
修改/docker/headscale/config/config.yaml
中的derp
配置项
#........
derp:
service:
enable: false
# ...........
# urls 使用的是tailscale的官方derp,国内延迟比较高,可以注释掉
# urls:
# - https://controlplane.tailscale.com/derpmap/default
# 配置自定义的derp配置项路径
paths:
- /etc/headscale/derp.yaml
新建/docker/headscale/config/derp.yaml
regions:
901:
regionid: 901
regioncode: CN
regionname: China
nodes:
- name: aaa # [自己设置个名称]
regionid: 901
hostname: derper.XXXX.cn # DERP_DOMAIN
stunport: 3478 # DERP_STUN_PORT 端口
derpport: 12345 # DERP_ADDR 端口
stunonly: false # 当不支持udp协议时使用tcp协议(http连接)
设置反向代理、域名证书
先设置反向代理,然后申请相关证书,将证书放到/docker/headscale/certs
文件夹下
注意证书名称要跟域名一样(例如:headscale.XXXX.cn.crt 和 headscale.XXXX.cn.key)
可以使用以下脚本加入到定时任务中实现自动更新域名证书(宝塔面板为例)
#!/bin/bash
source_crt="/www/server/panel/vhost/cert/derper.XXXX.cn/fullchain.pem"
target_crt="/docker/headscale/certs/derper.XXXX.cn.crt"
source_key="/www/server/panel/vhost/cert/derper.XXXX.cn/privkey.pem"
target_key="/docker/headscale/certs/derper.XXXX.cn.key"
# 检查文件是否相同
if diff -q "$source_crt" "$target_crt" &> /dev/null; then
echo "文件内容相同,无需复制。"
else
cp "$source_crt" "$target_crt"
cp "$source_key" "$target_key"
echo "文件已复制。"
fi
重启容器后,查看derp状态
# 重启容器
docker restart headscale derp
# 查看 derp 状态
tailscale netcheck
出现上图情况即为成功
3 tailscale 的安装
headscale 相当于是重新实现了 tailscale 的服务端,客户端还是需要用 tailscale。
windows 安装
下载地址:download
linux 安装
curl -fsSL https://tailscale.com/install.sh | sh
docker 安装
docker run -d \
--name=tailscaled \
-v /docker/tailscale/:/var/lib \
-v /dev/net/tun:/dev/net/tun \
-e TS_STATE_DIR=/var/lib/state/ \
--network=host \
--restart always \
--privileged tailscale/tailscale:latest \
tailscaled --tun=tailscale0 -no-logs-no-support=true
登录
-
生成
preauthkeys
# headscale 服务端运行 docker exec headscale headscale preauthkeys create -e 1000d -u default --reuseable # --reuseable 参数设置这个key可以多次使用,否则每个设备登录都要使用新的key
-
客户端登录
tailscale up --login-server http://headscale.XXXX.cn --authkey [上一步生成的 preauthkeys ] --accept-dns=false --accept-routes # 注意事项: # server 是 headscale 服务端的地址,不是 derp 服务的地址 # --netfilter-mode=off 关闭自动添加防火墙功能,因为该功能会影响新版本的防火墙配置。 # --accept-dns=false 关闭接受 dns 通告,不接受服务器的dns。 # --accept-routes接受其他子网路由器以及作为子网路由器的任何其他节点的通告路由。 # --advertisse-routes 将物理子网路由公开到整个 Tailscale 网络。