headscale+derp+tailscale异地组网
异地组网许多人都有需求,我也一样。最日常的应用场景是比如我希望,随时随地我可以在家里电脑,公司电脑,手机上访问家里和公司的局域网。之前尝试过Zerotier,但一来国内体验不好,当时我还在云服务上搭建了Moon但不知道什么原因也并没有改善,二来是还是需要在官网注册账号使用,这样就不是完全可控的。
最近发现tailscale的方案,本来tailscale的控制服务器不开源,他只是开源了客户端代码,也需要注册账号使用,但有个欧洲航天局的哥们开源个替代的控制服务器headscale,而且居然官方也认可。这样这个方案就完全可控。所以赶紧部署了一套使用。
控制服务器搭建在云服务器上,理论上应该最好是有IPv4+IPv6的双栈服务器,但我现在的服务器没有IPv6,等租期到了再考虑换,关于IPv6的作用后面再讨论
最方便的我还是采用docker部署,我这里是用nginx反向代理443到headscale,因为服务器的443端口还有其他作用
nginx的关键配置
stream {
map $ssl_preread_server_name $backend_name {
xx.xxxxx.com xxx;
headscale.xxxxx.com headscale;
default xxx;
}
# xxx
upstream xxx {
server 127.0.0.1:8443;
}
# headscale 这里是将特定域名的https请求转到9443的服务
upstream headscale {
server 127.0.0.1:9443;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $backend_name;
ssl_preread on;
}
}
http{
map $http_upgrade $connection_upgrade {
default keep-alive;
'websocket' upgrade;
'' close;
}
server {
listen 9443 ssl http2;
server_name headscale.xxxxx.com;
ssl_certificate /path/xxxx.crt;
ssl_certificate_key /path/xxxx.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://headscale:8080;
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 $http_x_forwarded_proto;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
#headscale是默认就开启了api接口的swagger文档,不知道怎么关,安全起见屏蔽了
location /swagger {
return 403;
root html;
index index.html index.htm;
}
#headscale是默认就开启了api接口,我这里并不想使用网页控制,安全起见屏蔽了
location /api {
return 403;
root html;
index index.html index.htm;
}
}
}
headscale容器docker-compose的关键配置
headscale:
image: headscale/headscale:latest-alpine
volumes:
- ./headscale/conf:/etc/headscale/
- ./headscale/data:/var/lib/headscale
ports:
- 3478:3478/udp
command: headscale serve
restart: always
cap_add:
- NET_ADMIN
- NET_RAW
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
headscale的关键配置
---
# 这个地址是告诉客户端需要访问的地址, 所以这个地址也必须写成反向代理前的访问地址
server_url: https://headscale.xxxxx.com
# Headscale 实际监听ip和端口,这个就是上面nginx反向代理到容器IP的端口
listen_addr: 0.0.0.0:8080
# grpc 监听地址,存疑,不知道有啥用,暂时没映射出容器
grpc_listen_addr: 0.0.0.0:50443
# 给vpn客户端分配的vpn网段
ip_prefixes:
- fd7a:115c:a1e0::/48
- 100.64.0.0/10
# 存疑,headscale的内置derp,但是否支持IPv6,是否会被白嫖还不清楚
derp:
server:
enabled: true
region_id: 999
region_code: "headscale"
region_name: "Headscale Embedded DERP"
stun_listen_addr: "0.0.0.0:3478"
其中最大的疑问是headscale内置的derp,网上很多教程都是不开,另外搭个derp容器,但那样很麻烦,我就希望headscale和derp部署在同一个机器上,那样做是否有必要?目前是先直接开启内置derp来用,也可以用,但有几个问题找不到答案:
- 内置derp是否可以防止被白嫖,是否需要做什么配置才可以防止?
- 内置derp是否支持IPv6,我尝试过临时租用了一台IPv4+IPv6的双栈服务器部署,但客户端依然显示
ipv6: no, but os has support
,是否stun_listen_addr
配置问题?
部署好服务端后,先创建个命名空间(似乎新版本可以用user代替)
headscale namespaces create mynet
客户端有两种认证方式
通过nodekey接入
客户端获取nodekey后在服务端运行headscale -n mynet nodes register --key nodekey:xxxxxxxxxxxxxx
通过Pre-Authkeys接入
首先在服务端生成 pre-authkey 的 token,有效期可以设置为 24 小时headscale preauthkeys create -e 24h -n mynet
各种设备的客户端都可以使用tailscale的官方客户端
- 安卓手机客户端
Android 客户端从 1.30.0 版本开始支持自定义控制服务器(即 coordination server),可以通过 Google Play 或者 F-Droid 下载最新版本的客户端。
需要反复不停地点开再关闭右上角的“三个点”,重复三四次之后,便会出现一个 Change server 选项,填写自己的headscale服务地址后打开浏览器页面,显示nodekey,服务端使用命令通过nodekey接入 Windows客户端
其实通过访问部署好的headscale服务页面:https://headscale.xxxxx.com/windows
有详细说明,包括如何在注册表添加相关内容,按照说明注册表修改好后,安装官方tailscale的windows客户端,然后可以通过CMD进行Pre-Authkeys接入cd "C:\Program Files\Tailscale\" .\tailscale.exe up --login-server=https://headscale.xxxxx.com --accept-dns=false --advertise-routes="192.168.1.0/24,192.168.2.0/24" --authkey=xxxxxxxxxx --accept-routes=true --reset
此处我还添加了公司网段的路由,在服务器上也需要做运行路由转发操作:
先查询接入设备ID headscale nodes list 然后查看该设备注册的路由 headscale routes list -i 2 再允许注册路由 headscale routes enable -i 2 -r "192.168.1.0/24,192.168.2.0/24"
这样操作后,接入该headscale私网的设备就可以访问公司网段
群晖tailscale客户端
不使用套件中心的tailscale客户端,会有诸多限制问题,使用docker部署。
我是DSM7.1版本,先启用虚拟网络设备tun,通过配置服务的方式自启动sudo curl -sL https://raw.githubusercontent.com/TRaSH-Guides/Synology-Templates/main/script/tun.service -o "/etc/systemd/system/tun.service" sudo systemctl enable /etc/systemd/system/tun.service sudo systemctl start tun sudo systemctl status tun
开启IPV4/IPV6转发
echo 'net.ipv4.ip_forward = 1' | tee -a /etc/sysctl.conf echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.conf sysctl -p /etc/sysctl.conf
通过tailscale官方docker镜像启动客户端容器
sudo docker run -d --name=ts \ -v /volume1/docker/tailscale:/var/lib \ -v /dev/net/tun:/dev/net/tun \ -e TS_STATE_DIR=/var/lib/state/ \ --restart unless-stopped \ --cap-add NET_ADMIN \ --cap-add NET_RAW \ --cap-add SYS_MODULE \ --network=host \ tailscale/tailscale:latest \ tailscaled --tun=tailscale0 -no-logs-no-support=true
在容器中,通过接入
docker exec -it ts tailscale login --login-server https://headscale.xxxxx.com --accept-dns=false --authkey xxxxxxx --advertise-routes=192.168.10.0/24 --accept-routes=true
同样的,注册了家里网段的路由后,也需要在服务端进行允许操作
希望在家里的其他电脑也可以通过这个群晖访问到刚才配置的windows客户端的公司网段,需要配置iptables,可以将其写入计划任务,开机自动执行
iptables -I FORWARD -i eth0 -j ACCEPT
iptables -I FORWARD -o eth0 -j ACCEPT
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
iptables -I FORWARD -i tailscale0 -j ACCEPT
iptables -I FORWARD -o tailscale0 -j ACCEPT
iptables -t nat -I POSTROUTING -o tailscale0 -j MASQUERADE
同时在家里路由器中添加公司网段的静态路由,指向群晖。
通过这一些操作后,就可以实现手机/家里/公司电脑,都可以互相访问,并且可以访问到家里网段和公司网段的其他电脑。
并且如果打洞成功,是P2P连接,如果打洞不成功,也会走derp转发。比如公司网络环境复杂,其实就走了derp转发,而手机端和家里网络是P2P直连。
新盘首开 新盘首开 征召客户!!!coinsrore.com
字里行间饱含人文关怀,温暖而有力。