基于物理机【纯IP】

1. 安装Go环境

wget https://go.dev/dl/go1.23.6.linux-amd64.tar.gz
sudo tar -xf go1.23.6.linux-amd64.tar.gz -C /usr/local
echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a /etc/profile
# 应用
source /etc/profile
# 查看版本
go version

2. 部署步骤

下载derp源码
go install tailscale.com/cmd/derper@latest
禁用域名校验

进入文件夹~/go/pkg/mod/[tailscale]/cmd/derper, 注释or直接删除cert.go中如下内容:

if hi.ServerName != m.hostname && !m.noHostname {
  return nil, fmt.Errorf("cert mismatch with hostname: %q", hi.ServerName)
}
编译

注意:一定要在~/go/pkg/mod/[tailscale]/cmd/derper文件夹下再执行如下命令编译

go build -o /etc/derp/derper
申请10年有效期的自签证书

注意:derp.wonde.cc可用随意更改

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout /etc/derp/derp.wonde.cc.key \
  -out /etc/derp/derp.wonde.cc.crt \
  -subj "/CN=derp.wonde.cc" \
  -addext "subjectAltName=DNS:derp.wonde.cc"
配置Derp服务

vim /etc/systemd/system/derp.service

注意:

  1. derp.wonde.cc可用随意更改【但需要与申请证书时的域名保持一致】

  2. 10000为端口号,也可随意更改

  3. --verify-clients为开启防白嫖功能,即只有连接到tailscale的设备才能使用这个Derp【如果不需要可以直接删除】

  4. 如果端口3478无法正常访问【比如NAT服务器】,那么就不能用默认UPD端口,需要指定STUN端口了

ExecStart=/etc/derp/derper -hostname derp.wonde.cc -a :10000 -certmode manual -certdir /etc/derp --verify-clients
改为
ExecStart=/etc/derp/derper -hostname derp.wonde.cc -a :10000 -stun -stun-port 10001 -certmode manual -certdir /etc/derp --verify-clients
[Unit]
Description=TS Derper
After=network.target
Wants=network.target

[Service]
User=root
Restart=always
ExecStart=/etc/derp/derper -hostname derp.wonde.cc -a :10000 -certmode manual -certdir /etc/derp --verify-clients
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
启动并配置开机自启
chmod +x /etc/derp/derper
systemctl enable derp
systemctl start derp
systemctl status derp

基于Docker容器【纯IP】

之前直接用yangchuansheng大佬构建好的镜像ghcr.io/yangchuansheng/ip_derper就能用了,但最近好像不行了。启动会报错:

writing new private key to '/app/derp/127.0.0.1.key'
-----
2025/02/07 01:22:37 no config path specified; using /var/lib/derper/derper.key
2025/02/07 01:22:37 invalid mesh key: key must contain exactly 64 hex digits

然后我就没去研究了。可以根据大佬博客自己去构建镜像。Tailscale 基础教程:部署私有 DERP 中继服务器 · 云原生实验室

2025-02-08:研究了下是镜像ID为:90228cdfa744d的用不了了,之前的老版本53661cb5d094的可以正常使用

这边提供下老版本的镜像包:ip_derper.tar

下载好后直接docker load -i ip_derper.tar即可导入镜像

Docker运行

docker run -d \
  --name derper \
  --restart always \
  -p 20480:20480 \ # 将宿主机端口20480映射到容器的20480端口
  -p 20481:3478/udp \ # 将宿主机的20481端口映射为容器内3478/STUN端口(UDP)
  -v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \ # 挂载本地路径,通过tailscale客户端验证连接
  -e DERP_ADDR=:20480 \ # 需保证与上述一致
  -e DERP_CERTS=/app/certs \ 
  -e DERP_VERIFY_CLIENTS=true \ # 开启客户端验证,防偷
  ghcr.io/yangchuansheng/ip_derper:latest

DockerCompose运行

services:
  derper:
    image: ghcr.io/yangchuansheng/ip_derper:latest
    container_name: derper
    restart: always
    ports:
      - "20480:20480" # 将宿主机端口20480映射到容器的20480端口
      - "20481:3478/udp" # 将宿主机的20481端口映射为容器内3478/STUN端口(UDP)
    volumes:
      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock # 挂载本地路径,通过tailscale客户端验证连接
    environment:
      - DERP_ADDR=:20480 # 需保证与上述一致
      - DERP_CERTS=/app/certs
      - DERP_VERIFY_CLIENTS=true # 开启客户端验证,防偷

基于物理机【域名】

关于证书申请,可以点击这里查看:通过ACME免费申请SSL证书

与上面提到的基于物理机【纯IP】步骤一样,只是不需要进行禁用域名校验步骤,直接编译就行了。

编译好后,直接去配置Derp服务就行了

vim /etc/systemd/system/derp.service

[Unit]
Description=TS Derper
After=network.target
Wants=network.target

[Service]
User=root
Restart=always
ExecStart=/etc/derp/derper -hostname derp.wonde.cc -a :20480 -certmode manual -certdir /etc/derp --verify-clients
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target

注意:证书名称需要变成为【域名.key、域名.crt】

比如:/etc/derp文件夹下就要有【derp.wonde.cc.key、derp.wonde.cc.crt两个文件】

chmod +x /etc/derp/derper
systemctl enable derp
systemctl start derp
systemctl status derp

基于Docker容器【域名】

Docker运行

docker run -d \
  --name derper \
  --restart always \
  -p 20480:20480 \ # 将宿主机端口20480映射到容器的20480端口
  -p 20481:3478/udp \ # 将宿主机的20481端口映射为容器内3478/STUN端口(UDP)
  -v /home/derp/:/app/certs
  -v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \ # 挂载本地路径,通过tailscale客户端验证连接
  -e DERP_ADDR=:20480 \ # 需保证与上述一致
  -e DERP_CERT_MODE=manual \
  -e DERP_DOMAIN=sb.baidu.com \ 
  -e DERP_VERIFY_CLIENTS=true \ # 开启客户端验证,防偷
  ghcr.io/yangchuansheng/derper:latest

DockerCompose运行

services:
  derper:
    image: ghcr.io/yangchuansheng/derper:latest
    container_name: derper
    restart: always
    ports:
      - "20480:20480" # 将宿主机端口20480映射到容器的20480端口
      - "20481:3478/udp" # 将宿主机的20481端口映射为容器内3478/STUN端口(UDP)
    volumes:
      - /home/derp/:/app/certs
      - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock # 挂载本地路径,通过tailscale客户端验证连接
    environment:
      - DERP_ADDR=:20480 # 需保证与上述一致
      - DERP_CERT_MODE=manual
      - DERP_DOMAIN=sb.baidu.com # 域名
      - DERP_VERIFY_CLIENTS=true # 开启客户端验证,防偷

配置 Tailscale

基于IP

登录Tailscale并进入Access Controls,把如下内容粘贴到acls上面

"derpMap": {
	"OmitDefaultRegions": true, // 可以设置为 true,这样不会下发官方的 derper 节点,测试或者实际使用都可以考虑打开
	"Regions": {
		"901": {
			"RegionID":   901,
			"RegionCode": "MyDerp",
			"RegionName": "MyDerp",
			"Nodes": [
				{
					"Name":             "901a",
					"RegionID":         901,
					"DERPPort":         10000, // 更换为自己的端口号[与<配置Derp服务>时配置的端口号保持一致]
					"IPv4":             "217.141.128.9", // 更换为自己的 IPv4 地址
					"IPv6":             "10ba:a9b0:9991:5c0b:fbd2:::9976", // 更换为自己的IPv6地址[如果没有v6可用直接删除这一行]
					"InsecureForTests": true, // 允许非 SSL 连接
				}
			],
		},
	},
},

注意:如果变更了STUN的端口那么这边也要指定端口【不写默认是3478】

"STUNPort":         10001,

基于域名

"derpMap": {
	"OmitDefaultRegions": true, // 可以设置为 true,这样不会下发官方的 derper 节点,测试或者实际使用都可以考虑打开
	"Regions": {
		"901": {
			"RegionID":   901,
			"RegionCode": "MyDerp1",
			"RegionName": "MyDerp1",
			"Nodes": [
				{
					"Name":             "901a",
					"RegionID":         901,
					"DERPPort":         10000, // 更换为自己的端口号[与<配置Derp服务>时配置的端口号保持一致]
					"IPv4":             "217.141.128.9", // 更换为自己的 IPv4 地址
					"IPv6":             "10ba:a9b0:9991:5c0b:fbd2:::9976", // 更换为自己的IPv6地址[如果没有v6可用直接删除这一行]
					"InsecureForTests": true, // 允许非 SSL 连接
				}
			],
		},
		"902": {
			"RegionID":   902,
			"RegionCode": "MyDerp2",
			"RegionName": "MyDerp2",
			"Nodes": [
				{
					"Name":             "902a",
					"RegionID":         902,
					"DERPPort":         20480, // 更换为自己的端口号[与<配置Derp服务>时配置的端口号保持一致]
					"HostName":         "sb.baidu.com", // 更换为自己申请的域名
					"InsecureForTests": true, // 允许非 SSL 连接
				}
			],
		},
	},
},

注意:如果变更了STUN端口那么这里一样也要指定STUN端口