DERP Server
Tailscale 的终极目标是让两台处于网络上的任何位置的机器建立 点对点连接 (直连),但现实世界是复杂的,大部份情况下机器都位于 NAT 和防火墙后面,这时候就需要通过打洞来实现直连,也就是 NAT 穿透。
Tailscale 的私钥只会保存在当前节点,因此 DERP server 无法解密流量,它只能和互联网上的其他路由器一样,呆呆地将加密的流量从一个节点转发到另一个节点,只不过 DERP 使用了一个稍微高级一点的协议来防止滥用。
Tailscale 官方内置了很多 DERP 服务器,分步在全球各地, 惟独不包含中国大陆 ,原因你懂得。这就导致了一旦流量通过 DERP 服务器进行中继,延时就会非常高。而且官方提供的 DERP 服务器是万人骑,存在安全隐患。
为了实现低延迟、高安全性,我们可以参考 Tailscale 官方文档自建私有的 DERP 服务器。有两种部署模式,一种是基于域名,但国内大环境下域名需要备案;本文讲解的是另外一种不需要域名,可以直接使用 IP,不过需要一点黑科技。
# 以下视频演示环境:
Windows:OpenWrt软路由Tailscale网络
Android TV:OpenWrt软路由Tailscale网络
Android手机:电信手机卡4G流量
# 演示内容
使用Android手机4G流量 进行设备互访(文件传输、adb远控、后台访问)
以下DERP Server基于Ubuntu搭建
# 更新软件源
apt update && apt upgrade
# 安装相关依赖
apt install -y wget git openssl curl
# 拉取go 可打开https://go.dev/dl/查看最新版本
cd /root
wget https://go.dev/dl/go1.20.7inux-amd64.tar.gz
# 解压
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz
# 查看版本
export PATH=$PATH:/usr/local/go/bin
go version
# 添加环境变量
echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
source /etc/profile
# 让go使用国内代理源(国外主机忽略)
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
# 拉取并编译derper
go install tailscale.com/cmd/derper@main
# 进入到编译好的文件夹(不要直接复制命令,按实际情况填写)
cd /root/go/pkg/mod/tailscale.com@v1.1.1-xxxx/cmd/derper/
# 打开cert.go文件
vi cert.go
# 注释以下信息
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)
// }
# 编译并输出到/etc/derp/
go build -o /etc/derp/derper
# 查看是否存在derper文件
cd /root
ls /etc/derp
# 自签域名(derp.myself.com可随意编写,命令中四处需要一致)
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout /etc/derp/derp.myself.com.key -out /etc/derp/derp.myself.com.crt -subj "/CN=derp.myself.com" -addext "subjectAltName=DNS:derp.myself.com"
# 自行开放33445(tcp)、2478(udp)端口
设置开机自启
复制全部内容到命令行粘贴
cat > /etc/systemd/system/derp.service <<EOF
[Unit]
Description=TS Derper
After=network.target
Wants=network.target
[Service]
User=root
Restart=always
ExecStart=/etc/derp/derper -hostname derp.myself.com -a :33445 -http-port 33446 -certmode manual -certdir /etc/derp
RestartPreventExitStatus=1
[Install]
WantedBy=multi-user.target
EOF
# 设置开机自启
systemctl enable derp
# 启动derp服务
systemctl start derp
验证DERP服务
浏览器打开:https://ip+33445 页面正常显示DERP即可
打开Tailscale控制台,按照图中位置添加以下内容:
其中 IPv4、IPv6、RegionCode、RegionName 填写自己的
"derpMap": {
//"OmitDefaultRegions": false,
"OmitDefaultRegions": true,
"Regions": {"901": {
"RegionID": 901,
"RegionCode": "EndlessJY",
"RegionName": "EndlessJY Derper",
"Nodes": [{
"Name": "901a",
"RegionID": 901,
"IPv4": "xxxx",
"IPv6": "xxxx",
"DERPPort": 33445,
"InsecureForTests": true,
}],
}},
},
进一步验证是否使用DERP中转
进入装有Tailscale的Linux客户端(教程以OpenWRT为例)输入以下命令:
登陆账号
tailscale up
访问局域网设备&开启流量代理
tailscale up --advertise-exit-node --advertise-routes=10.0.0.0/24
# 控制台-打开设备的Subnet routes和Exit node开关
# 当以上配置文件中"OmitDefaultRegions": true时表示只启用自建DERP Server
[root@OpenWrt:01:01 PM ~] # tailscale netcheck
Report:
* UDP: true
* IPv4: yes, xxxx:xxx
* IPv6: yes, [xxxx]:xxx
* MappingVariesByDestIP:
* HairPinning: false
* PortMapping:
* Nearest DERP: EndlessJY Derper
* DERP latency:
- EndlessJY: 56.3ms (EndlessJY Derper)
# 当以上配置文件中"OmitDefaultRegions": false时表示启用全部(官方和自建)DERP Server
# 此时Tailscale会自动选择延迟最低节点
[root@OpenWrt:01:03 PM ~] # tailscale netcheck
Report:
* UDP: true
* IPv4: yes, xxx:xxx
* IPv6: yes, [xxx]:xxx
* MappingVariesByDestIP: false
* HairPinning: false
* PortMapping:
* Nearest DERP: EndlessJY Derper
* DERP latency:
- EndlessJY: 55ms (EndlessJY Derper)
- hkg: 56.4ms (Hong Kong)
- tok: 108.4ms (Tokyo)
- syd: 178.8ms (Sydney)
- sea: 181.1ms (Seattle)
- lax: 202.1ms (Los Angeles)
- sfo: 208.9ms (San Francisco)
- sin: 231.2ms (Singapore)
- ord: 233.1ms (Chicago)
- den: 234.9ms (Denver)
- dfw: 237.7ms (Dallas)
- nyc: 246.8ms (New York City)
- tor: 261.2ms (Toronto)
- mia: 262.1ms (Miami)
- hnl: 262.6ms (Honolulu)
- lhr: 266.6ms (London)
- par: 269.1ms (Paris)
- ams: 272.9ms (Amsterdam)
- blr: 273.7ms (Bangalore)
- fra: 285.5ms (Frankfurt)
- mad: 285.7ms (Madrid)
- waw: 295ms (Warsaw)
- dbi: 330.6ms (Dubai)
- nai: 344ms (Nairobi)
- sao: 371.2ms (São Paulo)
- jnb: 443.7ms (Johannesburg)
# 输入tailscale status没报错表示正常
[root@OpenWrt:01:01 PM ~] # tailscale status
100.77.30.111 openwrt xxx@ linux idle; offers exit node
100.90.52.54 chromecast xxx@ android active; direct 192.168.0.7:35438, tx 376380 rx 542548
100.81.86.84 mi-10s xxx@ android active; offers exit node; relay "EndlessJY"; offline, tx 234632 rx 125324
100.69.195.132 mi-8-lite xxx@ android offline
# 输入tailscale status报错为以下内容,请仔细检查配置
[root@OpenWrt:01:06 PM ~] # tailscale status
100.77.30.111 openwrt xxx@ linux idle; offers exit node
100.90.52.54 chromecast xxx@ android active; direct 192.168.0.7:35438, tx 406008 rx 584984
100.81.86.84 mi-10s xxx@ android active; offers exit node; relay "EndlessJY"; offline, tx 245436 rx 125324
100.69.195.132 mi-8-lite xxx@ android offline
# Health check:
# - not connected to home DERP region 901