Tailscale 组网 - 自建 DERP

  • Tailscale 自建 DERP

  • 资料来源:

    <>

  • 更新

    1
    2022.12.11 初始

导语

Tailscale 的中继服务器也能自建,这样等于所有流量都不过 Tailscale 官方服务了.

  • 隐私怪大喜 更主要的是 Tailscale 在国内没有服务器,中继/打洞效果不好.

DERP

DERP = Detoured Encrypted Routing Protocol 是 Tailscale 自研协议

  • 通用 http
  • 公钥加密,无法解密流量
  • 先中继再打洞直连
  • 官方解释 -> NAT 穿透是如何工作的:技术原理及企业级实践(Tailscale, 2020

官方教程 -> Custom DERP Servers

  • 官方教程貌似会独占 443 端口

其他资料

  • 如何利用 Caddy 搭建 Tailscale 的 Custom DERP Servers: Caddy 如何搭建 DERP,大部分内容参考自此
  • Tailscale 基础教程:部署私有 DERP 中继服务器: 排查故障专用 😂,写的很详细.
  • headscale保底设施之DERP中继服务器自建
  • 基于 Caddy2 部署私有 DERP 中继服务器:
  • 我的服务器系列:tailscale使用自定义derper服务器(docker部署)
  • 创建 Tailscale derper

方案

DERP 的部署和使用方式有好多种,这里只说自己搭建的.

  • 域名 443 + 安全验证
  • derper 不负责证书维护,交给 Caddy 前端, 流量反向代理到 derper.
  • 需要 v4 + v6 .

建立 DERP

前置条件

  • 域名指向服务器

Docker

用的比较多的是 fredliang44/derper-docker

  • 唯一不支持是自定义 Stun 的端口,因此小改一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
FROM golang:latest AS builder
WORKDIR /app

# https://tailscale.com/kb/1118/custom-derp-servers/
RUN go install tailscale.com/cmd/derper@main

FROM ubuntu
WORKDIR /app

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
apt-get install -y --no-install-recommends apt-utils && \
apt-get install -y ca-certificates && \
mkdir /app/certs

ENV DERP_DOMAIN your-hostname.com
ENV DERP_CERT_MODE letsencrypt
ENV DERP_CERT_DIR /app/certs
ENV DERP_ADDR :443
ENV DERP_STUN true
ENV DERP_STUN_PORT 3478
ENV DERP_HTTP_PORT 80
ENV DERP_VERIFY_CLIENTS false

COPY --from=builder /go/bin/derper .

CMD /app/derper --hostname=$DERP_DOMAIN \
--certmode=$DERP_CERT_MODE \
--certdir=$DERP_CERT_DIR \
--a=$DERP_ADDR \
--stun=$DERP_STUN \
--stun-port=$DERP_STUN_PORT \
--http-port=$DERP_HTTP_PORT \
--verify-clients=$DERP_VERIFY_CLIENTS

配置

derper 配置

  • 需要监听 v4+v6 网络只能选择 host 模式
  • DERP_VERIFY_CLIENTS 是安全验证,后面会提到.
  • docker-compose 如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
derper:
build:
context: ./derper
image: derper:latest
container_name: derper
network_mode: "host"
restart: always
environment:
DERP_DOMAIN: derp.domain.com
DERP_ADDR: ":5050"
DERP_STUN_PORT: "3478"
DERP_VERIFY_CLIENTS: "true"
volumes:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock # 共享 tailscaled.sock

Caddy 自 2.5 版本以后支持了 tailscale 插件,因此证书申请方便多了.

  • 转发到 derper
1
2
3
4
5
6
derp.domain.com {
tls {
get_certificate tailscale
}
reverse_proxy http://127.0.0.1:5050
}

headscale 配置

参考自 -> Tailscale 基础教程:部署私有 DERP 中继服务器

  • 有两种方式导入 DERP, 本地 yaml 和 在线的 json,这里 选择 yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# /etc/headscale/derp.yaml
regions:
900:
regionid: 900
regioncode: thk
regionname: Tencent Hongkong
nodes:
- name: 900a
regionid: 900
hostname: xxxx
ipv4: xxxx
ipv6: xxxx
stunport: 3478
stunonly: false
derpport: 443
- name: 900b
regionid: 900
hostname: xxxx
ipv4: xxxx
ipv6: xxxx
stunport: 3478
stunonly: false
derpport: 443
901:
regionid: 901
regioncode: hs
regionname: Huawei Shanghai
nodes:
- name: 901a
regionid: 901
hostname: xxxx
ipv4: xxxx
ipv6: xxxx
stunport: 3478
stunonly: false
derpport: 443
  • regions 是 YAML 中的 对象, 下面的每一个对象表示一个 可用区,每个可用区里面可设置多个 DERP 节点,即 nodes.
  • 每个可用区的 regionid 不能重复.
  • 每个 nodename 不能重复.
  • regionname 服务器所在地区 regioncode 地区缩写
  • ipv4 ipv6 服务器 ip ,正确配置 dns 后可以留空.
  • stunonly 服务器是否只支持 stun
  • stunport stun port
  • derpport derp port 这里是 443
    • 必须是访问能显示一个网页: DERP This is a Tailscale DERP server.

headscale 配置中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# /etc/headscale/config.yaml
derp:
# List of externally available DERP maps encoded in JSON
urls:
# - https://controlplane.tailscale.com/derpmap/default

# Locally available DERP map files encoded in YAML
#
# This option is mostly interesting for people hosting
# their own DERP servers:
# https://tailscale.com/kb/1118/custom-derp-servers/
#
# paths:
# - /etc/headscale/derp-example.yaml
paths:
- /etc/headscale/derp.yaml

# If enabled, a worker will be set up to periodically
# refresh the given sources and update the derpmap
# will be set up.
auto_update_enabled: true

# How often should we check for DERP updates?
update_frequency: 24h
  • 可以删掉 urls 不再使用官方服务器.

安全性

默认是全部人都能用,只有域名方式才能鉴权.

  • 有 Tailscale 且已加入网络.
  • 启动时 –verify-clients -> DERP_VERIFY_CLIENTS: "true"
  • 这样 derp 只会让你自己网络的客户端通过.

需要将 /var/run/tailscale/tailscaled.sock 映射到 docker,让容器内能检测到 tailscaled.

验证

在客户端查看 tailscale netcheck

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ tailscale netcheck

Report:
* UDP: true
* IPv4: yes, 192.168.100.1:49656
* IPv6: no
* MappingVariesByDestIP: true
* HairPinning: false
* PortMapping: UPnP
* Nearest DERP: Home Hangzhou
* DERP latency:
- home: 9.7ms (Home Hangzhou)
- hs: 25.2ms (Huawei Shanghai)
- thk: 43.5ms (Tencent Hongkong)
  • 会显示已下发的 derp ,并显示延迟.
  • 这里延迟仅仅是 stun 端口 udp 的延迟,并不代表 derp 一定可用.

tailscale status 显示各个客户端状态

1
2
3
4
tailscale status
coredns default linux active; direct xxxx:45986; offline, tx 131012 rx 196020
oneplus-8t default android active; relay "home"; offline, tx 211900 rx 22780
openwrt default linux active; direct 192.168.100.254:41641; offline, tx 189868 rx 4074772
  • relay 代表了走 derp 中继

tailscale ping 测试到客户端延迟,通常是 先 derp 再走打洞的直连.

一些内容有写到 derp 尚不稳定,需要定时重启,这种情况暂时未遇到.

结语

自建 DERP V4 打洞测试

  • 教育网的重重 NAT
  • 移动/联通/电信 4G 5G
  • 移动家宽 墙中墙(可能现在电信也是)

以上基本都能是 v4 打洞直连,稳定性与网络对 udp 限制有关.

为啥没 v6 的? v6 还需要测吗