部署私有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配置源
# 国外 |
Docker安装
sudo yum install docker-ce docker-ce-cli containerd.io |
Docker启动
sudo systemctl enable 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 |