Docker 搭建 headscale 异地组网完整教程

前言

之前写过 Zerotier 搭建私有根服务器及创建虚拟局域网,阿蛮君也是一直在使用自建的 zerotier,但是为什么还要折腾 headscale 呢?最大的原因是 zerotier 创建根服务器只能使用 ip,这对迁移不是非常方便,并且自己也想了解下 headscale,所以折腾了几天总算有了结果。

一、搭建headscale服务端

1.创建相关文件并配置

这里需要手动创建 db.sqlite,这是根服务器的数据库文件。另外,还需要下载官网给的配置文件示例,然后需要修改一部分。

mkdir -p /home/docker/headscale/config && \
mkdir -p /home/docker/headscale/data && \
touch /home/docker/headscale/data/db.sqlite && \
wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O /home/docker/headscale/config/config.yaml

修改相关配置文件,比如配置文件中配置 127.0.0.1 的话,那么就只能本机访问。这里修改为 0.0.0.0 那么就所有的 ip 都能访问。

sed -i 's/127.0.0.1/0.0.0.0/g' /home/docker/headscale/config/config.yaml
# 这将修改以下几个地方,其中server_url还需要另外修改
# 1. server_url: http://0.0.0.0:8080
# 2. listen_addr: 0.0.0.0:8080
# 3. metrics_listen_addr: 0.0.0.0:9090
# 4. grpc_listen_addr: 0.0.0.0:50443

另外因为server_url是对外访问和登录的地址,如果你需要使用域名并开启https,那么照我如下配置。如果你仅仅使用ip,那么这个地址修改为ip+端口的方式即可。

域名填自己的

sed -i 's#http://0.0.0.0:8080#https://headscale.amjun.com#g' /home/docker/headscale/config/config.yaml

修改 dns 配置文件,如果不进行修改,那么登录时选择接受服务器的 dns 地址就会出现域名无法解析的情况。注意,这里的 dns 地址可以有多个,如果有需要自行添加即可。

sed -i 's/1\.1\.1\.1/114.114.114.114/g' /home/docker/headscale/config/config.yaml

客户端可以通过 主机名 + 用户 + 基础域名 访问任意一台终端,所以这里修改下基础域名,根据自己的实际域名进行填写。

域名填自己的

sed -i 's/example.com/amjun.com/' /home/docker/headscale/config/config.yaml

设置客户端随机端口,这里是听见有说不开机随机端口可能出现只能加入一台客户端的情况,为了保险还是选择开启。

sed -i 's/randomize_client_port: false/randomize_client_port: true/' /home/docker/headscale/config/config.yaml

启用内嵌的derp

当然你可以使用官方提供的 derp 服务器,但如果你想搭建自己的 derp 服务器,又不想另外搭建一个 derp 服务器,那么这是有必要的。

注意:使用此 derp 服务器,需要有域名并配置 ssl,否则请参考:Docker 搭建中继服务器 derp - 纯 IP 实现 。

# /home/docker/headscale/config/config.yaml
derp:
  server:
    # xxx
    enabled: true
    # xxx
    region_id: 999
    # xxx
    region_code: "headscale"
    region_name: "Headscale Embedded DERP"
    # xxx
    stun_listen_addr: "0.0.0.0:3478"

enabled 选项默认为 false,需要设置为 true。

3.启动headscale服务端

docker run -d \
--name headscale \
--restart always \
-v /home/docker/headscale/config:/etc/headscale/ \
-v /home/docker/headscale/data:/var/lib/headscale \
-p 8080:8080 \
-p 9090:9090 \
-p 3478:3478/udp \
--restart always \
headscale/headscale:0.22.3 \
headscale serve

下面是一些相关的命令:

以前是 namespace 的概念,现在似乎改为 user 了。

# 查看用户
docker exec -it headscale headscale users ls
# 创建用户
docker exec -it headscale headscale users create hz
# 生成apikey
docker exec -it headscale headscale apikey create
# 查询apikey
docker exec -it headscale headscale apikey ls

二、搭建web-ui

这一步是搭建 headscale 的 web-ui 界面,这不是必要的,因为阿蛮君更多使用命令,这只是有助于更好的查看相关信息。

docker run -d \
--name headscale-webui \
--restart always \
-v /home/docker/headscale/config:/etc/headscale/:ro \
-v /home/docker/headscale/web-ui/data:/data \
-u root \
-p 5000:5000 \
-e HS_SERVER=https://headscale.amjun.com \
-e DOMAIN_NAME=https://headscale.amjun.com \
-e SCRIPT_NAME=/admin \
-e AUTH_TYPE=Basic \
-e BASIC_AUTH_USER=admin \
-e BASIC_AUTH_PASS=admin \
-e KEY="2uHP6BSVocX+wcWU5mzuXA7JvnZA70UaTadB8L1heOo=" \
--restart always \
ifargle/headscale-webui:latest

其中 /home/docker/headscale/config 为上面服务端的映射目录,这两个目录需要一致。HS_SERVERDOMAIN_NAME 填写自己的域名1。KEY 是用来加密待会需要保存的 apikey 的字符串,使用命令 openssl rand -base64 32 生成。

接下来需要创建 headscale 服务器的 api-key,这里设置一个比较久的过期时间。

三、配置nginx和web-ui

1.配置nginx

如果前面server_url没有配置 ssl 加密,那这一步也不是必要的。

添加如下配置:

server {
    listen       443 ssl;
    listen  [::]:443 ssl;
    server_name  headscale.amjun.com;
    ssl_certificate  /etc/nginx/conf.d/cert/amjun.com.cer;
    ssl_certificate_key /etc/nginx/conf.d/cert/amjun.com.key;

    location ^~/ {
        proxy_pass http://localhost:8080/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $server_name;
        proxy_redirect https:// https://;
        proxy_buffering off;
        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 $http_x_forwarded_proto;
    }

    location ^~/admin/ {
        proxy_pass http://localhost:5000/admin/;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen 80;
    server_name  headscale.amjun.com;
    rewrite ^(.*)$ https://$host:443$1 permanent;
}

保存配置后重启 nginx,如果配置正确,那么通过 https://域名/admin 应该可以访问到 web-ui 界面,输入容器启动时配置的用户名密码即可进入。

64990a476d089

2.配置web-ui

上面提示输入 apikey,这个需要 headscale 服务端生成,这里设置一个比较长的时间,根据自己的需要即可。

docker exec -it headscale headscale apikeys create -e 10000d

运行命令后将生成的 key 输入,点击 save 即可,概览页面如下:

64990b3b849e2

四、创建用户和授权密钥

headscale 个人理解是用户就是命名空间,进行网络隔离,所以需要先创建用户。

#  创建用户
docker exec -it headscale headscale users create hz

授权密码的作用是,客户端登陆时不需要再服务端进行确认,阿蛮君总是喜欢使用简单的方式,所以就选择这种方式了。

# reusable 参数代表可以重复使用,不加的话密钥只能用来一个客户端加入
docker exec -it headscale headscale preauthkeys create -e 10000d --reusable -u hz
# 查看密钥 
docker exec -it headscale headscale preauthkeys list -u hz

这里记得记录好授权密钥,下面将会用到。

五、客户端安装

headscale 相当于是重新实现了 tailscale 的服务端,客户端基本还是用的 tailscale。

tailscale 客户端下载地址:https://tailscale.com/download/

1. windows

1.1 安装客户端

下载 windows 客户端并进行安装。

1.2 安装注册表

访问 https://headscale.amjun.com/windows,可以看见配置的教程。

提示需要修改注册表,这里可以直接 curl https://headscale.amjun.com/windows/tailscale.reg 下载文件后,双击运行文件进行安装即可。

1.3 登录

在 tailscale 的安装目录下使用 cmd 打开,输入命令:

tailscale login --login-server https://headscale.amjun.com --authkey b6a9b4f4e9c3a7c7e7b9b1a3a6b9e6b7a5e7c2a1e3a0a4a1 --accept-dns=false --accept-routes

这里的 authkey 是第四步生成的,然后在服务器使用命令查看。

docker exec -it headscale headscale nodes ls

2. linux

2.1 脚本安装

curl -fsSL https://tailscale.com/install.sh | sh && \
tailscale login --login-server https://headscale.amjun.com --authkey b6a9b4f4e9c3a7c7e7b9b1a3a6b9e6b7a5e7c2a1e3a0a4a1 --accept-dns=false --accept-routes

这里仅仅安装方式不同,登录的命令完全一样。

2.2 docker安装

docker run -d \
--name=tailscaled \
-v /home/docker/tailscale/:/var/lib \
-v /dev/net/tun:/dev/net/tun \
-e TS_STATE_DIR=/var/lib/state/ \
--network=host \
--privileged tailscale/tailscale:v1.44.0 \
--restart always \
tailscaled --tun=tailscale0 -debug=:8088 -no-logs-no-support=true

这里需要将 TS_STATE_DIR 指定的文件夹持久化,否则删除容器再新建后,在服务端能看见重复的设备。并且需要指定 --tun=tailscale0,不然似乎不能在宿主机创建网卡。

然后使用如下命令进行登录。

docker exec tailscaled tailscale login --login-server https://headscale.amjun.com --accept-dns=false --accept-routes=false --authkey b6a9b4f4e9c3a7c7e7b9b1a3a6b9e6b7a5e7c2a1e3a0a4a1 --advertise-routes=172.21.9.0/24,172.30.1.0/24,172.26.1.0/24,172.20.2.0/23

根据自己网络情况设置 --advertise-routes,我这是需要通过这台内网机器访问公司其他网络。

3. 安卓

3.1 安装并配置

目前官方暂不可以自定义登录链接,需要下载可以自定义登录链接的安卓客户端,阿蛮君这里提供了一份可以使用的客户端,链接放在后面。

安装后,点击右上角三个设置自定义登录地址:

64991ac900b81

点击保存并重启,再点击 sign in,将看见如下内容。

64991b2bd4fb6

3.2 服务端注册

根据提示在服务端运行命令:

docker exec -it headscale headscale nodes register --user hz --key nodekey:xxxx

注意这里的 USERNAME 需要修改为自己刚刚创建的用户名。

阅读剩余
THE END