目录

为TailScale部署私有DERP中继服务器

什么是 TailScale

后面再补充,先写重点的 TailScale DERP 中继服务器。

关键词:UDP打洞,NAT,点对点连接,大局域网。

好处/场景:待补充

怎么用 TailScale:待补充

什么是 TailScale DERP 中继服务器

前面提到,TailScale 的作用是实现多设备点到点的直连通讯。所以相比 frp 这种星形的穿透,TailScale 不会存在传输速度被中转服务器限制的问题。

但有的时候,打洞会失败,这个时候就只能老老实实通过中继服务器来转发流量了。也就是说,DERP 的作用是打洞失败的兜底。

值得一提的是,TailScale 的中继服务器还有另外一个作用,在两个客户端刚建立连接的时候,TailScale会先使用 DERP 快速建立一条可用的连接,然后再尝试打洞,如果打洞成功,就会切换到直连。

为什么要自建 DERP 中继服务器

!
速度!速度!还是TMD的速度!

TailScale 是默认提供了中继服务器的,因为某些原因,国内没有中继,所以如果打洞失败的时候,延迟能达到几百上千 ms。

我们可以使用 tailscale netcheck 命令来看看所有的(官方和自建)中继服务器的延迟。

如何搭建

先决条件
  1. 一台公网服务器
  2. 最好拥有一个备案了的域名

主要基于 docker compose 来安装,如果你喜欢折腾 Kubernetes,也可以配一下 Ingress 什么的(未测试)。

证书准备

准备一个域名,并签发证书,放到某个独立文件夹(用于挂载到容器内)。

假如我们的子域名是 derp.example.com,文件夹是 /home/xxx/infra/derper/certs

证书签发可以使用 acme.sh

泛域名的证书可以直接给子域名用,但是要注意证书名要和子域名一致。即,文件夹内要有 derp.example.com.crtderp.example.com.key 两个文件。

注:如果已经有 cert-manager 签发证书了,也可以偷懒直接把 Secret 复制过来改个名字(就是可能要手动定期更新证书)。或者尝试直接用 K8s 部署 DERP,把 Secret 挂到容器里。

Compose 文件

话不多说,直接准备 docker-compose.yml 文件。

version: '3.3'
services:
    derper:
        environment:
            - DERP_DOMAIN=derp.example.com # DERP 域名,请解析到自己的服务器,并确保域名已备案
            - DERP_CERT_MODE=manual # 证书模式,请设置成手动模式,自动的我貌似会有问题
        ports:
            - '80:80' # 这个端口貌似用不太到,一般不会用 http
            - '443:443'
            - '3478:3478/udp'
        image: fredliang/derper
        volumes:
          - /home/xxx/infra/derper/certs:/app/certs # 冒号左边的是证书在宿主机内存放的路径,右边的不要改,建议用绝对路径

按需修改,注释说得挺详细,这里主要说一下端口:

  1. 如果冲突的话,改掉冒号左边的端口,并暴露出去就好。
  2. 亲测443端口可以改成8888什么的,可用。
  3. 3478 的这个我没改过,但理论上也可以改。

最后 docker compose up -d 或者 docker-compose up -d 就 OK 了!

配置 TailScale 客户端使用 DERP 服务器

网页登录 TailScale 账号,打开 控制台的 Access Control 页面,添加这样一段注释(也就是在原来的 json 里加个 "derpMap" 的 key)

{
  // 这里是其他的原有的一些 key
  "derpMap": {
    // "OmitDefaultRegions": true,
    "Regions": {
      "900": {
        "RegionID":   900,
        "RegionCode": "my-derp",
        "RegionName": "这里一般写机房的位置(纯标示用)",
        "Nodes": [
          {
            "Name":     "自己的derp",
            "RegionID": 900,
            "DERPPort": 443,
            "STUNPort": 3478,
            "HostName": "derp.example.com",
          },
        ],
      },
    },
  },
}

主要就是改三个字段,一个是 HostName,一个是 DERPPortSTUNPort

完整的配置详见 go package ERPNode

测试

终端运行 tailscale netcheck 看看 DERP 有没有正常显示出来

也可以用 tailscale ping 节点名 看看走的什么中继(还是直连),以及延迟

甚至可以把上面的 json 被注释掉的 "OmitDefaultRegions": true 反注释了,然后保存。这样就是只用自己的 derp 节点,不用官方的。

出问题了的话,可以 docker compose logs 看看日志。(常见错误可能有:端口没开,证书无效,域名在A服务商备案了没在B备案导致直接被拦截等)

后记/资料

  1. 官方 DERP 文档
  2. 按照本文操作的话,只要别人知道你的域名和端口就能用你的DERP,耗你带宽。可以通过在 DERP 服务器上也装一个 TailScale 并在 DERP 启动的时候 加上 --verify-clients 参数来防止白嫖。具体的可以参考网上资料
  3. 这里还有一个不用域名只用 IP 来搭建 DERP 的教程,相对复杂,有兴趣的可以看看