部署私有DERP中继服务器

科普

NAT

NAT 的类型可以非常细分(例如 Full Cone→NAT1、Restricted Cone→NAT2、Port Restricted Cone→NAT3、Symmetric NAT→NAT4)

但对于穿透问题来说,关键在于 NAT 或有状态防火墙是否会严格检查数据包的目标 Endpoint。

NAT测试工具 https://github.com/HMBSbige/NatTypeTester

Easy NAT

典型例子包括 Full Cone NAT 和部分 Restricted Cone NAT。

  • 宽松检查
    Easy NAT 不会对入站数据包的目标地址和端口进行严格检查。只要某个出站连接曾经建立过,返回的数据包即使来自不同的远程端口或地址,也能被允许通过。
  • 映射稳定
    通常,这类 NAT 的映射关系对所有外部目标保持一致,也就是说,一个内网 IP/端口对应的映射在发送给不同目标时不会变化。这使得通过 STUN 协议获得的映射信息能够直接用于点对点连接建立。
  • 穿透难度低
    由于检查宽松,NAT 穿透技术(如 ICE 协商、STUN 等)通常能够顺利建立直连连接,避免了额外的中继步骤。

Hard NAT

典型例子包括 Symmetric NAT

  • 严格检查
    Hard NAT 对入站数据包的目标 Endpoint(即目的 IP 和端口)的匹配要求严格。只有当数据包的目标与 NAT 建立的出站连接完全一致时,才会允许进入。
  • 映射针对性强
    在这种情况下,针对不同的外部目标,NAT 会建立不同的映射关系。这样一来,通过简单的映射信息无法保证数据包能通过防火墙或 NAT 的检查。
  • 穿透难度高
    由于严格的检查机制,直接的 NAT 穿透往往难以成功。这时需要依赖 TURN 或 DERP 这样的中继服务,通过中继服务器转发数据包,才能实现连接建立。

中继

以实时通信为例,当直接穿透 NAT 无法成功时,可以采用 TURN(Traversal Using Relays around NAT)协议来实现中继。TURN 服务器会接收一端发送的数据,然后将其转发给另一端,从而实现通信。虽然这种方式会增加一定的延迟和带宽开销,但它能确保在各种网络环境下都能建立可靠的连接。

TURN

TURN(Traversal Using Relays around NAT)是最常见的中继协议。客户端通过 TURN 服务器获得一个中继地址,然后所有的数据均通过该服务器转发。这种方式能确保在各种网络环境下都能实现连接,但可能增加延迟和带宽消耗。

Derp

Tailscale 自研协议 DERP( Detoured Encrypted Routing Protocol)。在 Tailscale 这样的 VPN 或点对点网络中,节点之间通常会优先尝试直接建立连接(比如通过 NAT 穿透技术),但当直接连接不可行时,就会使用 DERP 中继服务器来转发加密的数据包,从而确保网络中各节点之间依然可以通信。

derp server部署

Docker配置源

# 国外
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 国内
yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo

Docker安装

sudo yum install docker-ce docker-ce-cli containerd.io

Docker启动

sudo systemctl enable docker
sudo systemctl start docker

DERP Server

只用ip无域名docker镜像

docker pull yangchuansheng/ip_derper:latest

运行

docker run -d -p 3478:3478 -p 3478:3478/udp -p 端口:443 --name derper --restart=always ghcr.io/yangchuansheng/ip_derper

浏览器访问https://ip:端口/ 出现下面内容则成功

DERP

This is a [Tailscale](https://tailscale.com/) DERP server.

It provides STUN, interactive connectivity establishment, and relaying of end-to-end encrypted traffic for Tailscale clients.

Documentation:

- [About DERP](https://tailscale.com/kb/1232/derp-servers)
- [Protocol & Go docs](https://pkg.go.dev/tailscale.com/derp)
- [How to run a DERP server](https://github.com/tailscale/tailscale/tree/main/cmd/derper#derp)

配置acl

根据官方derp清单可以知道不同ID对应的derp区域,然后通过配置文件覆盖,优选延迟低的区域,这里直接把其他区域屏蔽,只走自建节点。

打开地址进行配置,以下内容追加到配置文件中的ssh后面既可。

"randomizeClientPort": true,
"derpMap": {
"OmitDefaultRegions": false,
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "xx",
"RegionName": "xxxx",
"Nodes": [
{
"Name": "901",
"RegionID": 901,
"HostName": "你的ip",
"DERPPort": 端口,
"IPv4": "你的ip",
"InsecureForTests": true,
"STUNPort": 3478,
},
],
},
"1": null,
"2": null,
"3": null,
"4": null,
"5": null,
"6": null,
"7": null,
"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,
"21": null,
"22": null,
"23": null,
"24": null,
"25": null,
"26": null,
"27": null,
"28": null,
},
},

更换了derp节点需要客户端重启tailscale才能生效

测试

tailscale ping 目标ip