如何利用 Caddy 搭建 Tailscale 的 Custom DERP Servers

2022年10月8日 488点热度 0人点赞 0条评论

为什么用 Tailscale

由于众所周知的原因,国内的宽带网络拿到的 IP 基本都是大内网地址,根本无法在公网被访问,而此时访问家庭内网的资源将非常麻烦。而租用云服务器作为主要服务载体则也存在很多问题,比如说带宽、性能、延迟等等。因此目前来说,很多朋友会使用 frp 等针对特定协议和端口的内网穿透方案,但是这一方案也存在配置繁琐、无法访问家庭内网中任意资源、速度和延时取决于某一个中继服务器等问题。

而针对无法访问家庭内网中任意资源这一痛点,我们可以考虑使用 Wireguard 来搭建 VPN,强烈不建议其他的 VPN 协议。有了 Wireguard 搭建 VPN,我们可以做到使用 VPN 来访问家庭内的所有资源,甚至不需要改变 IP,可以直接使用内网 IP 访问。

同时由于 Wireguard 可以不配置传统 VPN 网关性质的节点,因此可以做到所有节点之间都 P2P 连接的全互联模式。但是如果某个节点没有公网 IP 的话还是得找台中继服务器充当网关才能访问(也有利用 Netmaker 进行 P2P 打洞的做法,但是痛点在于如果打洞失败无法自动改为中继)。

上述方案我大概用了一年多,过程中也遇到了诸如中继服务器挂掉需要重新配置、中继速度慢等等问题。因此也开始寻找解决方案,最终找到了 Tailscale。

Tailscale 是什么

Tailscale 是一个基于 Wireguard 的 VPN 服务。直接使用 Wireguard 会比 Tailscale 性能更好,在 Linux 上,Wireguard 可以作为内核模块,而 Tailscale 是利用 userspace 的 WireGuard 来实现功能。但是经过我的测试发现,两者差距在绝大部分情况下并不大,且在复杂网络环境下 Tailscale 的表现更好。对我来说 Tailscale 相对于 Wireguard 最大的优势有 3 点:

  1. 配置简单

  2. 支持 P2P 和中继自动切换

  3. 支持自建中继节点

另外,关于费用:Tailscale 是收费服务,但是免费服务支持 20 台设备,一个子网网段,完全是够用的(有一个开源的 Headscale,感兴趣可以自己了解)。

可能在我介绍完 Tailscale 之后,有人会说 Zerotier 不也能实现么,为啥不用 Zerotier 呢?其实我在很早之前是用过的,但是在之前我用到的版本中无法强制通过自建 Moon 节点走流量、手机客户端更是不支持加入自建 Moon,所以无奈只能选择放弃了。而且根据我个人的测试,Tailscale 的打洞成功率和性能表现都会相对更加好一点点,当然这个取决于个人网络环境等外在因素,仅供参考。

这里给大家介绍一下 Tailscale 在 2020 年发布的 https://tailscale.com/blog/how-nat-traversal-works/。其中讲述了 NAT 穿透是如何工作的,文章写得很细致,说实话我喜欢 Tailscale 的一个原因就是他们的博客 0.0。这里是这篇文章的中文翻译:https://arthurchiao.art/blog/how-nat-traversal-works-zh/。

如何利用 Caddy 搭建 Tailscale 的 Custom DERP Servers

关于 Tailscale 具体怎么使用可以看官方帮助文档,写得很细(本身也简单),所以下面主要介绍一下如何利用 Caddy 搭建 Tailscale 的 Custom DERP Servers

准备工作

  • 一台服务器

  • 一个域名

部署 Custom DERP Servers

# 有 443 端口权限,建议可以配合 caddy 或 nginx 使用,不然 derper 独占一个 443 端口太浪费了docker run -d --restart=always \  -p 3478:3478/udp \  -e DERP_DOMAIN=<your domain> \  -e DERP_ADDR=":23479" \  fredliang/derper# 然后安装 caddy 代理到 23479 即可,Caddyfile 下面有示例

# 没有 443 端口权限,就需要自定义证书(更换了镜像)docker run -dit --restart=always \ -p 3478:3478/udp \ -p 23479:23479 \ -v ../derper/cert:/cert \ -e DERP_DOMAIN=<your domain> \ -e DERP_ADDR=":23479" \ -e DERP_CERT_MODE=manual \ -e DERP_CERT_DIR=/cert \ fredliang/derper# ../derper/cert 中存放 SSL 证书

# 3478 是默认的 stun 端口# 23479 是自定义的 derper 端口

如果获取 SSL 证书

因为没有 443 端口的权限,所以无法做到自动生成证书,只能手动处理。因此建议不要用持续时间太短的 SSL 证书,建议起码一年期。可以考虑使用腾讯云等云服务商提供的一年免费证书服务。

生成完成后,下载 Nginx 版本

然后解压下载的文件,并将其中文件名中的 “_bundle” 去掉并上传到 <cert path>,这样就可以使用非 443 端口提供 Derper 服务了。

示例文件

示例 docker-compose.yaml

version: "3.7"
services: # 有 443 端口权限 derper: image: fredliang/derper restart: always ports: - 3478:3478/udp environment: DERP_DOMAIN: <your domain> DERP_ADDR: ":23479"
caddy: image: {{编译后的镜像}} ports: - 80:80 - 443:443 ç volumes: - ../caddy/Caddyfile:/etc/caddy/Caddyfile - ../caddy/data:/data - ../caddy/config:/config

# 无 443 端口权限时,这里可以无需用到 caddy derper: image: fredliang/derper restart: always ports: - 3478:3478/udp - 23479:23479 volumes: - ../derper/cert:/cert environment: DERP_DOMAIN: <your domain> DERP_ADDR: ":23479" DERP_CERT_MODE: manual DERP_CERT_DIR: /cert

示例 Caddyfile

假如使用上面的 docker-compose.yaml 进行部署,那么 Caddyfile 可以按照下面的方式进行编写:

https://{{your-domain}} {    tls {        get_certificate tailscale    }    reverse_proxy http://derper:23479    # reverse_proxy http://<derper 容器 IP>:<derper 容器 端口>}

配置 Access Controls

// Example/default ACLs for unrestricted connections.{  // Declare static groups of users beyond those in the identity service.  "groups": {    "group:example": ["[email protected]", "[email protected]"],  },  // Declare convenient hostname aliases to use in place of IP addresses.  "hosts": {    "example-host-1": "100.100.100.100",  },  "acls": [    // Match absolutely everything. Comment out this section if you want    // to define specific ACL restrictions.    {"Action": "accept", "Users": ["*"], "Ports": ["*:*"]},  ],  // derper 配置主要是下面这段  "derpMap": {    "OmitDefaultRegions": true, // 是否只连接自建 derper 节点    "Regions": {      "901": {        "RegionID":   901, // 整数,自定义        "RegionCode": "sz", // 字符串,代表地区        "RegionName": "Shenzhen",// 字符串,代表地区        "Nodes": [          {            "Name":     "", // 字符串,自定义            "RegionID": 901, // 整数,上面的 RegionID            "HostName": "your domain", // 字符串,域名            "STUNPort": 3478, // 整数,stun 端口            "DERPPort": 23479, // 整数,自定义的 derper 端口          },        ],      },    },  },}

参考资料

https://tailscale.com/kb/1118/custom-derp-servers/

https://pkg.go.dev/tailscale.com/tailcfg#DERPMap

https://www.yumenaka.net/2022/03/11/caddy2_tailscale_derper/

92520如何利用 Caddy 搭建 Tailscale 的 Custom DERP Servers

这个人很懒,什么都没留下

文章评论