TailScale 之 Derp 保姆级搭建教程

:rocket: 本教程的特点

  • 无需域名纯 IP搭建 :white_check_mark:
  • 简单配置连接验证,防止被偷 :white_check_mark:
  • Docker 一键部署 :white_check_mark:

1. 前言

Tailscale 的 Derp 搭建教程网上有很多,有的是直接教你在宿主机上一步一步安装GO,申请证书来,有的是打包好镜像直接用但是没有连接验证,有的是简单概括指点方向就没下文,经过我两天的分析,一步一步踩坑终于实现上面所说的特点部署,完美运行,废话不多说下面开始教程。

2. 申请 TailScale Auth Key

点我申请KEY,进入网址找到 Keys - Auth keys - Generate auth key… 按钮,Description 随便取一个名字,点击 Generate Key 按钮,将 Key 复制到一旁待会使用。

3. 部署 Derp 服务

3.1 拉取并部署 Derp 服务

docker run -d \
  --name derper \
  --restart unless-stopped \
  -p 9003:9003 \
  -p 9004:9004/udp \
  -e DERP_PORT=9003 \
  -e STUN_PORT=9004 \
  -e DERP_HOSTNAME="这里填VPS的公网IP" \
  -e TAILSCALE_AUTH_KEY="这里填AUTH_KEY" \
  hengxin007/tailscale-derper

参数说明

9003:Derp 服务端口,TCP 类型,需要放开安全组
9004:STUN 端口,UDP 类型,给 Derp 服务检测 Nat 类型用的,需要放开安全组
DERP_HOSTNAME: 填写你的公网 IP
TAILSCALE_AUTH_KEY: 这里填写刚才在 Tailscale 申请的 KEY

等待上面执行完后,控制台应该能看到该设备了:

3.2 查看证书哈希值

docker logs derper |& grep sha256-raw

# 你应该会看到
{"Name":"custom","RegionID":900,"HostName":"x.x.x.x","CertName":"sha256-raw:xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

sha256-raw:xxxx 复制到一旁,待会使用

4. 配置 Derp ACL

进入 Access controls 控制台,将下面的内容直接全选复制粘贴到对应的输入框中覆盖内容,然后根据我下面的提示替换参数即可。

// Example/default ACLs for unrestricted connections.
{
	// Declare static groups of users. Use autogroups for all users or users with a specific role.
	// "groups": {
	//  	"group:example": ["[email protected]", "[email protected]"],
	// },

	// Define the tags which can be applied to devices and by which users.
	// "tagOwners": {
	//  	"tag:example": ["autogroup:admin"],
	// },

	// Define grants that govern access for users, groups, autogroups, tags,
	// Tailscale IP addresses, and subnet ranges.
	"grants": [
		// Allow all connections.
		// Comment this section out if you want to define specific restrictions.
		{"src": ["*"], "dst": ["*"], "ip": ["*"]},

		// Allow users in "group:example" to access "tag:example", but only from
		// devices that are running macOS and have enabled Tailscale client auto-updating.
		// {"src": ["group:example"], "dst": ["tag:example"], "ip": ["*"], "srcPosture":["posture:autoUpdateMac"]},
	],

	// Define postures that will be applied to all rules without any specific
	// srcPosture definition.
	// "defaultSrcPosture": [
	//      "posture:anyMac",
	// ],

	// Define device posture rules requiring devices to meet
	// certain criteria to access parts of your system.
	// "postures": {
	//      // Require devices running macOS, a stable Tailscale
	//      // version and auto update enabled for Tailscale.
	// 	"posture:autoUpdateMac": [
	// 	    "node:os == 'macos'",
	// 	    "node:tsReleaseTrack == 'stable'",
	// 	    "node:tsAutoUpdate",
	// 	],
	//      // Require devices running macOS and a stable
	//      // Tailscale version.
	// 	"posture:anyMac": [
	// 	    "node:os == 'macos'",
	// 	    "node:tsReleaseTrack == 'stable'",
	// 	],
	// },

	// Define users and devices that can use Tailscale SSH.
	"ssh": [
		// Allow all users to SSH into their own devices in check mode.
		// Comment this section out if you want to define specific restrictions.
		{
			"action": "check",
			"src":    ["autogroup:member"],
			"dst":    ["autogroup:self"],
			"users":  ["autogroup:nonroot", "root"],
		},
	],

	// 自定义derpMap
	"randomizeClientPort": false, // 随机端口, 防止被NAT或防火墙限制
	"derpMap": {
		"OmitDefaultRegions": false, // 只用自己的节点不用官方节点。
		"Regions": {
			"900": {
				"RegionID":   900, // tailscale 900-999 是保留给自定义 derper 的
				"RegionCode": "alicloud", // 随便命名
				"RegionName": "alicloud GuangZhou", // 随便命名
				"Nodes": [
					{
						"Name":     "900", //复制自derper的输出信息
						"RegionID": 900, //复制自derper的输出信息
						"HostName": "12.34.56.78", // 改成服务器公网IP
						"DERPPort": 9003, // Derp 服务端口
						"STUNPort": 9004, // STUN 端口
						"CertName": "sha256-raw:xxxxxxx", // 改成日志中查询的哈希值
						"IPv4":     "12.34.56.78", // 改成服务器公网IP
					},
				],
			},
			"1": null,
			"2": null,
			// "3": null, // Singapore
			"4": null,
			// "5": null, // Sydney
			"6": null,
			// "7": null, // Tokyo
			"8":  null,
			"9":  null,
			"10": null,
			"11": null,
			"12": null,
			"13": null,
			"14": null,
			"15": null,
			"16": null,
			"17": null,
			"18": null,
			"19": null,
			// "20": null, // Hong Kong
			"21": null,
			"22": null,
			"23": null,
			"24": null,
			"25": null,
		},
	},

	// Test access rules every time they're saved.
	// "tests": [
	//  	{
	//  		"src": "[email protected]",
	//  		"accept": ["tag:example"],
	//  		"deny": ["100.101.102.103:443"],
	//  	},
	// ],
}

找到 derpMap 节点,根据注释替换参数,然后点击保存即可。

5. 测试结果

5.1 检查 Derp 是否搭建成功

电脑和手机连接 Tailscale,已经连上的重新连接,手机用流量不要用WIFI。

# 查看是否 derp 节点添加成功
tailscale netcheck

# 结果
C:\Users\xx-user>tailscale netcheck
Report:
        * Time: 2025-09-18T09:54:25.7235281Z
        * UDP: true
        * IPv4: yes, 1.2.3.4:29019
        * IPv6: no, but OS has support
        * MappingVariesByDestIP: true
        * PortMapping:
        * CaptivePortal: false
        * Nearest DERP: alicloud GuangZhou
        * DERP latency:
                - alicloud: 32.2ms  (alicloud GuangZhou) # 延迟最小,排在第一个的就是我们部署的Derp节点,正常显示且有延迟
                - nue: 173ms   (Nuremberg)
                - iad: 207.5ms (Ashburn)
                - hel: 232.1ms (Helsinki)
                - tok: 244.9ms (Tokyo)
                - hkg: 275.2ms (Hong Kong)
                - syd: 285.6ms (Sydney)
                - sin: 312.7ms (Singapore)
C:\Users\xxx>

5.2 检查 Derp 节点是否可用

# 1. 查看设备连接情况
tailscale status

C:\Users\xx-user>tailscale status
100.2.105.1  xx-user            zyhlovedsq@  windows -
100.12.174.2  derp-alicloud-guangzhou zyhlovedsq@  linux   -
100.112.176.9   iphone-15-pro        zyhlovedsq@  iOS     offline
100.112.86.4    xiaoxin-air15        zyhlovedsq@  windows -

# 2. 通过 tailscale ping 查看连接情况
tailscale ping 100.119.176.9

C:\Users\hcsy-user>tailscale ping 100.119.176.9
pong from iphone-15-pro (100.119.176.9) via DERP(alicloud) in 71ms
pong from iphone-15-pro (100.119.176.9) via DERP(alicloud) in 27ms
pong from iphone-15-pro (100.119.176.9) via DERP(alicloud) in 85ms
pong from iphone-15-pro (100.119.176.9) via DERP(alicloud) in 94ms
pong from iphone-15-pro (100.119.176.9) via DERP(alicloud) in 24ms
pong from iphone-15-pro (100.119.176.9) via DERP(alicloud) in 73ms

6. 其他

最后说一下我的搭建经验,其实不需要验证连接这个功能的话挺简单的,网上有好多大佬打包好了现成的镜像,就是那个验证功能摸索大半天才摸索明白,

一开始以为是网上说的要映射一个 tailscale 登录后的 tailscaled.sock 会话文件,然后加一个 --verify-clients 参数,但是我这样操作死活无法使用,后面又根据另一个大佬说的,只需要下载 tailscale 不需要登录就行,直接启动 derp 服务,然后加一个参数 -verify-clients 参数,然后也不行。经过测试,其实上面说的都是正确的,只不过一直没有将信息完整话,要开启验证功能要满足下面几个条件:

  1. derp 服务需要携带 -verify-clients 参数来开启安全验证功能
  2. 服务器需要登录 tailscale
  3. Tailscale 后台需要填写 "CertName": "sha256-raw:xxxxxxx

7. 参考来源

53 个赞

这个用来内网穿透的吧,和ipv6+ddns,或者cf的tunnel对比来说哪个更快

[!note]

支持喂饭教程:heart:

2 个赞

ipv6+ddns:看你想暴露什么服务,如果是MC联机这种给别人用的,那还可以;如果是私人相册这种就不安全,其次需要ipv6,ipv6也不是很普及的那种,域名虽然也不贵但也是一个硬性条件,而且我这个省运营商封IPV6的80和443端口,速度的话挺快的,但我的评价是路边一条。
cf tunnel 我没用过,但是我能感觉到应该不太行,不然都去用了。
最好的方案就是 私人化这一块你用 zerotier/tailscale 优先打洞,打不了就用自己搭建的节点走中转。
共享化这块,优先上面,不想用上面的,直接上Frp。
如果想折腾,可以研究一下其他的方案,喜欢GUI的考虑EasyTier,喜欢更折腾的搭建 Zerotier Planet 或 Tailscale 的 tailscale headscale,如果我有很多时间我会去研究并使用 tailscale headscale。

2 个赞

好好学习下,谢谢分享

感谢教程

2 个赞

感谢大佬教程

1 个赞

srds淘宝好像非常便宜
反正是p2p的,数据不经过服务器

支持这个观点,暴露在公网本身就不安全

2 个赞

那么问题来了,有没有时候适合搭建derp 的大流量高带宽的服务器推荐

感谢老哥的教程,但是我之前在用阿里云搭建的时候发现如果启动tailscale会导致阿里云workbench直接被阻断,设置了半天还是卸载了tailscale客户端,只是保留了derp
网上翻了一下基本没有简单的办法能做到两全其美,搞的我都想换服务商了

感谢佬的分享,帖子非常实用,学到了!

国内大流量高带宽的真不多吧,运营商都扣成什么样了。也不是所有client都要会用 derp 中转,能直连成功的话就不会走derp 了。之前用腾讯云小鸡搭的,不scp 感觉没事儿

不验证连接,容易被白嫖,验证连接,有的地区的服务器屏蔽了tailscale :joy:

嗯,就是有台设备在大内网,也没有 IPV6,必须强依赖 derp 中转或者 frp

2 个赞

收藏了,试了下可以。不过传文件还是在30M左右,不知道这个带宽取决于什么

1 个赞

如果能p2p打洞,就取决于目标机器宽带上行速度,不能就取决于中转机器网络速度

2 个赞

Tailscale 使用的 100.64.0.0/10 是一个运营商级网络地址转换(CGNAT)网段,这个网段是一个私有 IP 范围,不用于公共互联网,因此一些云服务商如阿里云等也使用这个网段作为内网网段,这样在阿里云服务器使用 Tailscale 的时候就会出现冲突,表现为启用 Tailscale 开启后阿里云的 DNS、软件源等 100 网段的服务都无法使用

https://blog.hellowood.dev/posts/解决阿里云和-tailscale-的-100-网段冲突的问题/

2 个赞

感谢分享,非常有用

1 个赞

Health check:
- Tailscale could not connect to the ‘alicloud GuangZhou’ relay server. Your Internet connection might be down, or the server might be temporarily unavailable.

这个是啥问题呀