基于IP和DDNS两种方式自建 Tailscale DERP 服务器

Tailscale 在大多数情况下都能打洞成功,在极端情况打洞不成功的时候,会自动使用Tailscale官方的derp服务器进行中转流量。但是官方的derp服务器都在国外,网速很慢,用户体验很不好,所以有条件的话最好用国内服务器自建Tailscale DERP 中转服务器。

一般情况下,自建DERP服务器需要你有一个域名、一个固定公网IP、一个正规SSL证书。为了省钱和简单,可以不要求域名和正规的SSL证书,只要一个固定公网IP,加上自签的SSL证书就行。

注意事项:

1、网上有些教程提到使用自签的SSL证书的时候,需要修改derper程序的源码,去掉ssl证书的验证。大体是修改源码里的这几行:

func (m *manualCertManager) getCertificate(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
	if hi.ServerName != m.hostname {
		return nil, fmt.Errorf("cert mismatch with hostname: %q", hi.ServerName)
	}
	return m.cert, nil
}

但是在新版本的derper程序里,已经不需要修改这个了,增加了一个参数 “`-certmode manual“` 即可使用自签的SSL证书。

2、网上有些教程提到使用自签的SSL证书的时候,需要在ACL设置里面将 “`InsecureForTests“` 参数设置为true,以绕过证书检测。这个方法有很大的风险,日常使用建议不要设置为true。

下面说一下正确的设置方法。以debian/ubuntu服务器为例。

请务必先在服务器上安装好tailscale客户端,这个就不多说了。

一、基于固定公网IP自建Tailscale DERP 服务器

这是最常见的方式,一般服务器都会有固定公网ip。

1、安装derper程序。tailscale官方没有直接提供derper程序,所以我们需要自己编译,但是也很简单。

(1) 在服务器上安装go。

wget https://go.dev/dl/go1.25.3.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.25.3.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
source ~/.bashrc

(2) 编译derper

go install tailscale.com/cmd/derper@latest
#生成的derper在当前目录的 ./go/bin/derper 复制到 /usr/local/bin/
cp ./go/bin/derper /usr/local/bin/
chmod +x /usr/local/bin/derper

(3) 生成自签ssl证书

mkdir -p /opt/ssl
# 将 3.3.3.3 改成你服务器的真实IP,下同
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes   -keyout /opt/ssl/3.3.3.3.key   -out /opt/ssl/3.3.3.3.crt   -subj "/CN=3.3.3.3"   -addext "subjectAltName=IP:3.3.3.3"

(4) 运行derper

/usr/local/bin/derper --hostname=3.3.3.3 --a :16370 --stun-port=13886 --http-port=-1 --certmode=manual --certdir=/opt/ssl --verify-clients=true &

执行这条命令行,会输出类似 {“Name”:”custom”,”RegionID”:900,”HostName”:”45.125.15.11″,”CertName”:”sha256-raw:***”} 的日志,其中 *** 是一长串小写或者大写的英文加数字字符串,是证书的指纹,因为我们用的是自签证,要把这个指纹添加tailscale后台ACL里面,以便程序可以验证。把这个记下来,自行转换成小写。

如果没有输出这些日志,使用以下命令获取:

openssl x509 -in /opt/ssl/3.3.3.3.crt -fingerprint -sha256 -noout | sed 's/SHA256 Fingerprint=//' | tr -d ':' | sed 's/^/sha256-raw:/'

会输出类类似 “sha256-raw:sha256 Fingerprint=***” 其中 *** 是一长串小写或者大写的英文加数字字符串,记下来,转换成小写。

(5) 到tailscale后台添加ACL规则:

"derpMap": {
	// 只使用自建的节点
	"OmitDefaultRegions": true,
	"Regions": {
		"994": {
			"RegionID":   994,
			"RegionCode": "aliyun-beijing",
			"RegionName": "aliyun-beijing",
			"Nodes": [
				{
					"Name":     "aliyun-beijing",
					"RegionID": 994,
					"HostName": "3.3.3.3",
					"DERPPort": 16370,
					"CertName": "sha256-raw:***", // 用日志中的完整值(替换 *** 为实际)
					"STUNPort": 13886,
				},
			]
		},
	
	},
},

(6) 服务器防火墙需要开放16370和13886端口

二、基于动态域名DDNS自建Tailscale DERP 服务器

有些廉价的服务器没有固定公网IP,官方提供DDNS域名以供连接,或者你想用动态公网IP的宽带在家里部署derp服务器。

1、安装derper程序。tailscale官方没有直接提供derper程序,所以我们需要自己编译,但是也很简单。

(1) 在服务器上安装go。

wget https://go.dev/dl/go1.25.3.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.25.3.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
source ~/.bashrc

(2) 编译derper

go install tailscale.com/cmd/derper@latest
#生成的derper在当前目录的 ./go/bin/derper 复制到 /usr/local/bin/
cp ./go/bin/derper /usr/local/bin/
chmod +x /usr/local/bin/derper

(3) 生成自签ssl证书

mkdir -p /opt/ssl
# 将 ddns.mydomain.com 改成你服务器的真实ddns域名,下同
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes   -keyout /opt/ssl/ddns.mydomain.com.key   -out /opt/ssl/ddns.mydomain.com.crt   -subj "/CN=ddns.mydomain.com"   -addext "subjectAltName=IP:ddns.mydomain.com"

(4) 运行derper

/usr/local/bin/derper --hostname=ddns.mydomain.com --a :16370 --stun-port=13886 --http-port=-1 --certmode=manual --certdir=/opt/ssl --verify-clients=true &

获取证书指纹:

openssl x509 -in /opt/ssl/ddns.mydomain.com.crt -fingerprint -sha256 -noout | sed 's/SHA256 Fingerprint=//' | tr -d ':' | sed 's/^/sha256-raw:/'

会输出类类似 “sha256-raw:sha256 Fingerprint=***” 其中 *** 是一长串小写或者大写的英文加数字字符串,记下来,转换成小写。

(5) 到tailscale后台添加ACL规则:

"derpMap": {
	// 只使用自建的节点
	"OmitDefaultRegions": true,
	"Regions": {
		"994": {
			"RegionID":   994,
			"RegionCode": "aliyun-beijing",
			"RegionName": "aliyun-beijing",
			"Nodes": [
				{
					"Name":     "aliyun-beijing",
					"RegionID": 994,
					"HostName": "ddns.mydomain.com",
					"DERPPort": 16370,
					"CertName": "sha256-raw:***", // 用日志中的完整值(替换 *** 为实际)
					"STUNPort": 13886,
				},
			]
		},
	
	},
},

(6) 服务器防火墙需要开放16370和13886端口

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注