Skip to content

Instantly share code, notes, and snippets.

@junaire
Created July 17, 2024 02:55
Show Gist options
  • Save junaire/b66301960c622796d636612d8133124a to your computer and use it in GitHub Desktop.
Save junaire/b66301960c622796d636612d8133124a to your computer and use it in GitHub Desktop.
Tailscale Self Host DERP Server Notes

tailscale 介绍

tailscale 是一个免费强大的内网穿透服务,可以将多个处在不同网络环境下的设备组成子网,使其表现于位于同一局域网中。使用 tailsacle 的一个场景是你可以随时随地 ssh 到你位于家中或办公室的 Linux 主机中。

tailscale 工作原理

tailscale 一般情况下会尝试点对点通信(打洞),如果能成功那你的延迟将非常低(几到几十毫秒)。但这并不总是能成功的,如果失败了,tailscale 将使用中继服务器(DERP)进行中转通信。一个问题是 tailscale 的 DERP 服务器都处于国外,延迟相对较高。但 tailscale 是允许自建 DERP 服务的,下面将介绍下整个过程以及各种坑。

准备

为了自建 DERP 服务,你至少需要准备:

  1. 一台你访问起来延迟较低的服务器,一般是国内服务器。
  2. 一个域名,二级域名即可。(假设你用国内服务器,需要备案)
  3. 一个 SSL 证书,这个非常关键,下面会介绍如何申请。

声明

为了避免隐藏的坑,这里简单介绍下我的情况:

  1. 服务器使用的是阿里云 2c2g 的国内服务器。
  2. 域名使用的是二级 com 域名,这里假设为 a.b.com。(我没有备案所以问朋友要的)
  3. 服务器系统为 Ubuntu22.04 LTS。

自建详细过程

由于下面所有操作都使用了 docker 进行,所以需要安装下 docker:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

申请证书

docker run -it --rm --name certbot -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" -p 80:80 certbot/certbot certonly

运行后会进行交互式命令行,第一个选择 1,第二个输入对应的域名即可,这里假设为 a.b.com

启动 DERP 服务

docker run --restart always \
  --name derper -p 443:443  -p 3478:3478/udp \
  -e DERP_CERT_MODE=manual \
  -v /etc/letsencrypt/live/a.b.com/fullchain.pem:/app/certs/a.b.com.crt \
  -v /etc/letsencrypt/live/a.b.com/privkey.pem:/app/certs/a.b.com.key \
  -e DERP_ADDR=:443 \
  -e DERP_STUN=true \
  -e DERP_DOMAIN=a.b.com \
  -e DERP_HTTP_PORT=-1 \
  -d ghcr.io/fredliang44/derper:latest

启动后可以使用下面命令检查情况:

docker logs -f derper

如果显示下面输出即为成功:

2024/06/4 1:01:1 no config path specified; using /var/lib/derper/derper.key
2024/06/4 1:01:1 STUN server listening on [::]:3478
2024/06/4 1:01:1 derper: serving on :443 with TLS

还可以在浏览器中访问 a.b.com,应该显示:

image

配置 DERP

最后你需要配置下 tailscale,让它使用你的自建服务。访问 https://login.tailscale.com/admin/acls/file ,加上下面的配置即可:

	"derpMap": {
		"OmitDefaultRegions": false, // 是否忽略默认的服务器,在测试时可以设为 true 方便观察。
		"Regions": {"902": {
			"RegionID":   902,
			"RegionCode": "shanghai", // 服务器区域代码,随便填
			"RegionName": "self-hosted", // 服务器名字,随便填
			"Nodes": [{
				"Name":     "1",
				"RegionID": 902,
				"HostName": "a.b.com", // 域名,不能错。
				"DERPPort": 443, // 端口,这里用的是 443
			}],
		}},
	},

最后应该长这样:

image

如此便完成了整个配置,可以在终端中测试:

# 应该显示你自建的 DERP 服务器
tailscale netcheck

# 除了显示你所有连接上 tailscale 的设备外,不应该有其它任何提示
tailscale status

# 调试你的 DERP 服务器,在 INFO 中显示成功建立连接,并返回 IPv4 STUN response。Errors 中显示 IPv6 错误是正常的。
sudo tailscale debug derp shanghai

# 尝试 ping 自己的设备
tailscale ping 100.106.123.123

整个流程看起来似乎非常简单,但是!!!在我跑完所有流程后尝试 ping 却总是显示超时!我以为是某个地方错了于是不断重试检查,最后摆烂不管了第二天发现就可以了???强烈怀疑它有一个生效时间,这个时间可长可短因人而异,如果都显示正常却无法连接到其它设备请耐心等待一段时间吧(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment