如何强制Tailscale走Derp中转

本教程将详细介绍如何在Linux和Windows系统上,通过简单的环境变量设置,强制Tailscale优先使用DERP中转,从而确保更稳定、更快速的连接。

Tailscale 在网络直连时,默认使用 UDP 协议进行通信。然而,在国内复杂的网络环境下,UDP 包很容易受到运营商的QOS策略影响,导致连接速度慢、延迟高等问题。当通过DERP服务器进行中转时,Tailscale 会切换为TCP协议。

Tailscale官方给出了自建Derp的教程 custom derp servers,搭配200M轻量云食用非常丝滑。

但是,当 Tailscale 检测到通过UDP打洞可以直连时,即使直连的性能不佳(直连的网络体验不如经过BGP优化后的 DERP 中转),它也会强制优先使用直连。

原理

通过查阅 Tailscale 的代码仓库,可以发现官方预留了一个用于调试的环境变量 TS_DEBUG_ALWAYS_USE_DERP。将其设置为 true,即可强制 Tailscale 优先使用 DERP 中转,不再尝试 UDP 直连。代码链接

重要提醒

截至 Tailscale 1.84.2 版本,由于 bug ,如果同一台 Linux 服务器既作为 DERP 中转服务器,又运行 Tailscale 客户端并启用强制中转,那么该客户端自身的 Tailscale 会出现掉线问题。
请勿在 DERP 服务器上启用强制中转,否则会导致其自身的 Tailscale 服务中断。

在 Windows 端强制启用/禁用 DERP 中转

启用强制 DERP 中转

以管理员权限打开Powershell执行下列命令开启强制中转

$reg = "HKLM:\SYSTEM\CurrentControlSet\Services\Tailscale"
$val = "TS_DEBUG_ALWAYS_USE_DERP=true"
if (Get-ItemProperty -Path $reg -Name Environment -ErrorAction SilentlyContinue) {
  $cur = Get-ItemPropertyValue -Path $reg -Name Environment
  if ($cur -notcontains $val) {
    Set-ItemProperty -Path $reg -Name Environment -Value ($cur + $val)
  }
} else {
  New-ItemProperty -Path $reg -Name Environment -Value $val -PropertyType MultiString
}
Restart-Service Tailscale -Force

禁用强制 DERP 中转

执行以下脚本关闭强制中转(这个脚本的Restart-Service时间可能会比较长,耐心等待即可)

$reg = "HKLM:\SYSTEM\CurrentControlSet\Services\Tailscale"
$val = "TS_DEBUG_ALWAYS_USE_DERP=true"
if (Get-ItemProperty -Path $reg -Name Environment -ErrorAction SilentlyContinue) {
  $cur = Get-ItemPropertyValue -Path $reg -Name Environment
  $new = $cur | Where-Object { $_ -ne $val }
  if ($new.Count -eq 0) {
    Remove-ItemProperty -Path $reg -Name Environment
  } else {
    Set-ItemProperty -Path $reg -Name Environment -Value $new
  }
}
Restart-Service Tailscale -Force

在 Linux 端强制启用/禁用 DERP 中转

启用强制 DERP 中转

sudo权限执行以下脚本开启强制中转

sudo mkdir -p /etc/systemd/system/tailscaled.service.d
echo -e "[Service]\nEnvironment=TS_DEBUG_ALWAYS_USE_DERP=true" | sudo tee /etc/systemd/system/tailscaled.service.d/override.conf
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart tailscaled

禁用强制 DERP 中转

执行以下脚本关闭强制中转(脚本执行时间可能比较久)

sudo rm -f /etc/systemd/system/tailscaled.service.d/override.conf
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart tailscaled

欢迎更好的优化方案在评论区讨论

23 个赞

确实存在,肥肠有用

tailscale后台,access control添加下面内容就行了:

"derpMap": {
	"OmitDefaultRegions": true,
	"Regions": {
		"900": {
			"RegionID":   900,
			"RegionCode": "myderp",
			"RegionName": "自己的REGION名,随意",
			"Nodes": [
				{
					"Name":     "YOUR_DERP_NAME",
					"RegionID": 900,
					// "HostName": "server.domain",
					"IPv4":             "SERVER_IP_ADDRESS",
					"DERPPort":         DERP_PORT,
					"STUNPort":         STUN_PORT,
					"InsecureForTests": true,
				},
			],
		},
	},
},

编辑:审题错误,lz说的是强制中转,我说的是强制使用自己的derp服务器

感谢分享

这个只是屏蔽官方Derp,文档里有写

不然楼主长篇大论如果提的是这个

那感觉不怪尴尬的 :tieba_087:

哈哈哈,没事,回头有空我搓一篇自建Derp的教程发出来。最近在折腾Tailscale

不懂,话说tailscale走的不是wg协议吗?wg不是只能udp吗?怎么做到走tcp的?感谢解答

先引用下Tailscale的原文

Tailscale can only establish direct connections if the device supports sending and receiving UDP packets. If a device can only use TCP connections, all connections go through the DERP relay servers. For the DERP links, Tailscale encapsulates the WireGuard frames in a TLS stream over TCP.

当直连能通的时候,tailscale直接用Wireguard发UDP包。当直连不通时,Tailscale将发出去的包先用Wireguard封装好,然后把这个包再包裹一层TLS,通过TCP发出去

感谢大佬解惑

linux 一直走的derp, 原来windows也可以, 这个脚本是保存为.ps1后缀管理员执行?

直接复制粘贴到终端也行

1 个赞

ok 。厉害了

私有derp部署。 认证非要再装个客户端也是挺麻烦的

可以用 --verify-client-url 自建一个简单的HTTP Server和Derp放一起就行,网上之前看到过教程

这个不错,研究下起个http服务还是容易的

不错,很有用,感谢分享

赞,我之前都是屏蔽到目标地址的UDP :rofl:

Linux 端也可以选择修改 /etc/default/tailscaled 文件,这是 tailscaled 的环境变量文件,在里面加上一行 TS_DEBUG_ALWAYS_USE_DERP=true,然后重启 tailscaled 即可

2 个赞