DERP是Tailscale的中继服务器,负责交换客户端之间的连接信息和在无法直接连接时中继流量。其本身只负责协调和转发,不会解密协议承载的流量,因此使用官方的DERP服务器同样是安全的。但是,由于国内较为特殊的网络环境,官方的节点连接到中国大陆时延迟和稳定性均欠佳,而仅凭Headscale内置的单一节点有时是不满足需求的。
Tailscale Derper同样是一个官方开源软件的一部分,但是网上的教程多使用docker搭建,不是很适合在刁钻的环境下使用🥶,在此把博主的一些探索做一个简单的记录。
注意:这是一篇纯文字的流程记录,未添加详细的配图和说明,需要一定的基础进行实践。
一、编译DERP
DERP中继的docker搭建在互联网上已有大量的教程,并且操作非常简单。但是,docker下的derper
镜像中不包含tailscale客户端,如果需要对接入设备进行认证则需要将宿主中的tailscale映射至容器中,反而增加了一些麻烦。实际上,derper
程序本身也是一个基于go
构建的binary单文件,只是官方未提供预编译包,需要我们自己使用go
环境进行编译。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 从https://go.dev/dl/下载对应架构的go环境 wget https://go.dev/dl/go1.23.3.linux-amd64.tar.gz # 解压 tar -zxvf go1.23.3.linux-amd64.tar.gz # 移动到go环境目录 cd ./go # 从源码构建derper二进制文件 ./bin/go install tailscale.com/cmd/derper@main # 在go环境的bin路径下可以找到编译好的derper二进制文件,并进行测试 ./bin/derper -version # 提取文件(可选至指定目录) cp ./bin/derper /usr/bin/derper # 添加可执行权限 chmod +x /usr/bin/derper # 如不需要再次编译,可直接删除go环境 rm -rf /root/go |
在以上的方法中,我们只是临时使用go
环境,无需将其添加至环境变量,在使用后也可直接删除。在此获得derper二进制文件可以直接复制到任意同架构和系统版本的系统中运行,也就是你可以在任意同类的环境编译好后分再发到其他的服务器。
二、安装Tailscale
为了防止derper服务器被其他用户使用,我们需要在服务器上运行tailscale客户端接入自己的tailnet网络,来为开启了--verify-clients
的derp提供认证信息。
1 2 |
# 最简单地加入一个Tailnet tailscale up --login-server=https://my.headscale --accept-dns=false |
安装过程不再赘述,但需要特别注意在阿里云的ECS上,MagicDNS使用的100.100.100.100
地址与阿里云内网DNS冲突,会导致服务器联网出现问题。可以考虑切换服务器DNS至PublicDNS或修改Tailscale源码解除对该地址的占用。
三、运行DERPer
准备好derper
二进制包后,接下来可以进行一些运行的测试工作。在此假设所有文件都位于/home/derp
目录下,可以按照以下的方式选择一个合适你使用场景的命令。
1 2 3 4 5 6 7 8 9 10 11 |
# 独占443端口HTTPS访问,HTTP 80端口跳转HTTPS,并验证连接客户端 # 证书通过Let's Encrypt HTTP获取,必须具有独占的80和443端口 /home/derp/derper -c /home/derp/derper.conf -a :443 -http-port 80 -stun-port 3478 -hostname my.derp -certmode letsencrypt --verify-clients # 使用非标准端口HTTPS访问,手动更新证书,并验证连接客户端 # 证书手动放置于/home/derp中,文件名必须为主机名,如my.derp.crt和my.derp.key /home/derp/derper -c /home/derp/derper.conf -a :8443 -stun-port 3478 -hostname my.derp -certmode manual -certdir /home/derp --verify-clients # 监听本地HTTP端口,通过NGINX反代访问 # 证书配置在NGINX上,可与其他网站共存 /home/derp/derper -c /home/derp/derper.conf -a :8080 -stun-port 3478 --verify-clients |
搭配NGINX转发可以更好的隐藏服务特征,因此博主均使用第三种配置方式作为演示。对于使用systemd
的系统(如debian、ubuntu等),将其修改好写入对应位置后,依次进行以下配置实现授权、启动和开机自启:
文件路径:
/etc/systemd/system/derper.service
管理进程:service derper start|stop|status
开机自启:rc-upadte add derper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[Unit] Description=Derper Service After=network.target [Service] Type=simple User=root Restart=on-failure RestartSec=5s # 替换为上述测试好合适的启动命令 WorkingDirectory=/home/derp ExecStart=/home/derp/derper -c /home/derp/derper.conf -a :8080 -stun-port 3478 --verify-clients [Install] WantedBy=multi-user.target |
对于像Alpine一样使用init.d
和rc-local
的系统,将其修改好写入对应位置后,依次进行以下配置实现授权、启动和开机自启:
文件路径:
/etc/init.d/derper
文件提权:chmod +x /etc/init.d/derper
管理进程:/etc/init.d/derper start|stop|status
开机自启:rc-upadte add derper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#!/sbin/openrc-run supervisor=supervise-daemon name="derper" # 替换为上述测试好合适的启动命令 command="/home/derp/derper" command_args="-c /home/derp/derper.conf -a :8080 -stun-port 3478 --verify-clients" pidfile="/run/derper.pid" respawn_delay=5 respawn_max=0 depend() { need net after firewall use logger } |
NGINX在vhsot和证书配置好后,只需要为/derp
路径添加反向代理配置即可,无需对全局进行反向代理(也就是可以做到依附在某个网站上)。如果在headscale的derp.yaml
中设定了IP地址则该域名可以不进行DNS解析,具有非常好的隐蔽性。配置好后,直接访问对应的路径会有DERP的提示信息,如果确有需要还可以通过sub_filter
去掉。
1 2 3 4 5 6 7 8 9 10 11 |
location /derp { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_http_version 1.1; proxy_buffering off; } |
四、添加DERP
Headscale的搭建可以参考博主之前的文章(点击前往),首先需要在headscale的config.yaml
中derp
字段下取消注释paths:
并设置好其下的derp.yaml
路径,实现从该文件载入DERP列表。官方有提供derp.yaml
的示例(点击前往),按照derper
的实际信息进行填写。配置好后,重启headscale服务即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
regions: # 自建DERPER的RegionID设置区间为900-999,不会与官方节点冲突 900: regionid: 900 regioncode: sh-cmcc regionname: Shanghai Mobile nodes: - name: sh-cm-derp1 regionid: 900 # 主机名,可搭配NGINX反向代理使用 hostname: derp1.headscale.my # IP地址,注意IPv6需添加半角引号,没有时注释掉 # 使用DDNS的DERP时,请将ipv4和ipv6都注释掉 ipv4: 123.123.123.123 ipv6: "2001:da8::1" # STUN端口,设置为-1即关闭stun仅使用TCP,可在UDP QoS严重的场景尝试 stunport: 3478 # 设置为true仅开启STUN,不通过TCP转发 stunonly: false # 通信端口,必须为通过HTTPS访问的端口 derpport: 443 # 第一个地域配置完成后,可添加其他地域,同时一个地域也可有多台不同的节点 |
五、结语
添加结束后,可在客户端使用tailscale netcheck
检查是否添加成功,并获得延迟信息。由于Tailscale客户端以延迟排序选择DERP节点,可能需要暂时移除部分其他DERP节点以对其进行单独测试。当DERP节点不可用时Tailscale客户端会有很明显的报错出现,tailscale status
中的relay也会降级至其他节点。
由于博主的需求比较片面,其他未尽的内容和错误欢迎大家在评论区补充和指正~
*原创文章,转载请注明出处