通过 HeadScale(TailScale开源服务端) 多平台实现内网穿透

本文最后更新于:2024年3月20日 下午

HeadScale 服务端搭建

HeadScale 是一个开源的 TailScale 服务端实现,可以实现多平台的内网穿透。

准备工作

docker-compose.yaml 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3.9'
services:
headscale:
# 镜像版本
image: headscale/headscale:0.23.0-alpha5
# 容器名称
container_name: headscale
# 挂载目录根据自己的需求进行修改(宿主机目录:容器目录)
# 其中 /headscale/config 为配置文件目录,/headscale/data 为数据目录,/headscale/run 为运行目录
volumes:
- /headscale/config:/etc/headscale
- /headscale/data:/var/lib/headscale
- /headscale/run:/var/run/headscale
# 端口号根据自己的需求进行修改(宿主机端口:容器端口)
ports:
- 8080:8080
# 此处最新版的命令行必须使用 server 命令,之前版本为 headscale serve
command: serve
restart: unless-stopped

创建目录及配置文件:

1
2
3
4
5
6
7
8
9
10
# 创建宿主机挂载目录
mkdir -p /headscale/config
mkdir -p /headscale/data
mkdir -p /headscale/run
cd /headscale

# 创建配置文件(通过wget)
wget -O ./config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
# 或者通过curl
curl https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml -o ./config/config.yaml

修改配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
# config.yaml(此处就讲几个关键配置,其他基本不用修改)
# 修改 server_url 为你的域名
server_url: https://proxy.your-domain.com/

# 监听地址(如果上边容器端口被修改此处也要修改)
listen_addr: 0.0.0.0:8080

# 当 magic_dns 为 true 时,HeadScale 会自动为你的设备分配一个域名(也就是下边的base_domain,可以在内网环境访问,而不需要通过IP)
magic_dns: true
base_domain: base_domain.com

# 随机化客户端端口
randomize_client_port: true

启动 Docker 容器:

1
2
# 在 docker-compose.yaml 所在目录下启动服务
docker-compose up -d

WEB-UI管理工具

这类服务端一般都有一个 WEB-UI 管理工具,HeadScale 也不例外。

此处用 headscale-admin 做演示,其他的管理工具也是类似的。

使用 Docker 运行容器:

1
2
# 宿主机端口随意
docker run -p 8000:80 goodieshq/headscale-admin:latest

反向代理配置

在 Nginx 中配置反向代理,将 HeadScale 服务端的 8080 端口映射到 443 端口。想偷懒就直接通过面板管理工具添加一个反向代理。配置完毕记得重载 Nginx。其他WEB服务器也是类似的。

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
server {
listen 443 ssl http2;
# 你的域名(自行修改)
server_name proxy.your-domain.com;

# 证书路径(自行修改)
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

location / {
# 代理地址,如果上边映射的宿主机端口被修改此处也要修改
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# WEB-UI 管理工具, 访问地址为 https://proxy.your-domain.com/admin
location /admin {
# 代理地址,如果上边映射的宿主机端口被修改此处也要修改
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

不出意外的话,HeadScale 服务端就搭建完成了。出意外就在下边留言吧。😊

现在就可以通过 https://proxy.your-domain.com/admin 访问 HeadScale 的 WEB-UI 页面了。

PS: 直接访问 https://proxy.your-domain.com 没效果。

WEB-UI 配置

首先,生成一个新的 API 密钥,然后将其添加到页面中。

1
2
# 在 HeadScale 服务端所在的宿主机上执行。执行完毕后会生成一个 API 密钥。
docker exec -it headscale headscale apikeys create

然后点击页面的保存按钮,出现左侧的菜单就算成功了。

HeadScale-Admin

TailScale 客户端配置

下载并安装 TailScale 客户端。

在 WEB-UI 这里添加用户,然后生成一个临时的key,后边要用到。

添加用户

生成PreAuthKey

然后根据你当前设备平台,选择安装不同的客户端。要修改 URL 为你的 HeadScale 服务端域名。

Linux 客户端部署

此处以 CentOS 为例(参考官方文档):

1
2
3
4
5
# 已经是 root 用户就不用输入 sudo 了。
sudo dnf config-manager --add-repo https://pkgs.tailscale.com/stable/centos/8/tailscale.repo
sudo dnf install tailscale

sudo systemctl enable --now tailscaled

主要是后续步骤不同,这里打开 WEB-UI 页面,选择 Deploy,复制生成的命令行:

deploy

如果只需要通过内网IP进行访问,就不需要勾选 –accept-dns 了。

1
2
# 在你的设备上执行(此处仅作为参考,根据实际情况修改)
tailscale up --login-server=https://proxy.your-domain.com --reset --authkey=xxx --accept-dns --accept-routes
1
2
# 查看状态
tailscale status

然后现在客户端就部署成功了,可以通过内网IP进行访问了。其他平台的部署参考官方文档,也是类似的。
例如:AndroidiOSWindows 等。

客户端提供很多功能,例如可以通过内网传输文件、远程桌面、远程调试等,另外还可以通过公网服务器反向代理访问内网服务器,用于数据处理等。

1
2
# 部署了多台设备之后,可以通过Ping测试一下(此处修改为你需要PING的设备内网IP)
tailscale ping xxx.xxx.xxx.xxx

当然,如果你可能发现访问速度可能会有点慢,可以通过配置 Derp 中继服务器来解决,可以快速打洞,如果不成功也能进行兜底。

Derp 服务端部署

可参考 derper-docker,docker-compose.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
version: '3.5'
services:
derper:
container_name: derper
image: fredliang/derper
restart: always
volumes:
# 此处修改为你的证书目录(例如letsencrypt的证书,目录需要包含fullchain.pem、privkey.pem 等文件)
- ./cert:/cert
# handscale.sock
- 'headscale/run/handscale.sock:/var/run/tailscale/tailscaled.sock:ro'
ports:
# 记得防火墙开放端口(云服务器同样)
- 3478:3478/udp
- 23479:23479
environment:
# 此处修改为你的域名
DERP_DOMAIN: derp.your-domain.com
# 端口号根据自己的需求进行修改
DERP_ADDR: ':23479'
# 此处修改为你的证书目录
DERP_CERT_DIR: /cert
# 证书模式(这里请参考上边的 derper-docker)
DERP_CERT_MODE: 'letsencrypt'

运行 Docker 容器:

1
2
# 在 docker-compose.yaml 所在目录下启动服务
docker-compose up -d

然后设置反向代理,例如把你的 derp.your-domain.com 代理到 127.0.0.1:23479,https协议,此处不再赘述。

此时访问你的 https://derp.your-domain.com 页面会显示相关信息,说明部署成功了。

配置完毕后在 config.yaml 所在目录 /headscale/config 下添加 derp.yaml 文件,并修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# derp.yaml
# If you plan to somehow use headscale, please deploy your own DERP infra: https://tailscale.com/kb/1118/custom-derp-servers/
regions:
900:
regionid: 900
regioncode: 地域代码
regionname: 地域名称
nodes:
- name: 900a
regionid: 900
hostname: derp.your-domain.com
ipv4: 你的公网IP
stunport: 3478
stunonly: false
derpport: 443

修改 HeadScale 服务端的配置文件,添加 Derp 配置路径:

1
2
3
4
5
6
7
8
# config.yaml
derp:
# 将默认的 DERP 服务器注释掉
urls:
# - https://controlplane.tailscale.com/derpmap/default
# 自定义 DERP 服务器路径
paths:
- /etc/headscale/derp.yaml

配置完毕后通过 docker restart 重启 HeadScale 服务端。再然后在客户端重新运行 tailscale 。

1
2
tailscale down
tailscale up

网络检查:

1
tailscale netcheck

如果展示如下信息,说明配置成功了。

derp

现在,内网穿透就配置完成了,可以通过公网IP访问内网服务器了,速度也会提升巨大。

Enjoy it! 🎉

参考


通过 HeadScale(TailScale开源服务端) 多平台实现内网穿透
https://toflying.com/2024/03/20/12-intranet-penetration-headscale/
作者
KingChen
发布于
2024年3月20日
更新于
2024年3月20日
许可协议