Tailscale, headsacle, headscale webui 配置(上)

Tailscale/Headsacle

Tailsacle是一款基于Wireguard的虚拟组网工具,可以实现在公网、内网间建立基于Wireguard的Full Mesh虚拟网络。区别于传统的VPN, Tailscale 没有中心服务器,所有节点以全互联方式连接,在保证安全的前提下尽可能提高速度,是下一代的VPN产品。

Tailscale解决的问题是内网间、内网与云、公网混合的虚拟组网和安全问题。我们常见的问题如:公司内部开发环境从外部访问不方便、多个云、不同内网之间互联困难、内网中存在大量不符合安全规范的服务、传统VPN配置复杂,效率低下。Tailscale以虚拟组网的方式把不同云、内网的设备连接起来,使用起来逻辑上等于在同一内网中,全互联又提高了速度,并且不需要复杂的VPN设置。

Tailsacle是一款收费服务,免费版受到一定限制。如果你想完全实现“自主可控”的同时还不用花费成本,可以使用开源的Headscale,它与Tailscale的客户端兼容。

Headscale & Headscale webui 安装前准备

下面以Headscale服务器 + Web UI控制面板为例,设置一组示例的Headsacle服务器和客户端,实现虚拟组网。

下面案例至少需要3个服务器和2个域名:

1,Headscale 控制服务器,仅从事控制用途,本身不承载流量(不开启流量转发)

2,内网服务器 192.18.2.1,位于公司内部,可以与公司内网中的其他机器连接

3,公网服务器 12.34.56.78

两个域名都解析到headscale控制服务器上。

域名A,headscale控制服务器API headscale.mydomain.com

域名B,headscale 控制面板 headscalewebui.mydomain.com

客户端(用户)可以在Internet上的任意位置。

首先安装Headsacle控制服务器。

在翻阅了大量的网上“教程”后,我认为由于开源软件的特性,必然会存在很多问题,需要进行一些改动。以下内容都是基于最新版(Headsacle 0.22.1)。

首先进行一些准备:这个Headscale的控制器有一些问题,很多东西需要进行不必要的操作。在Linux下直接安装可以参考这篇教程(云原生实验室)。Docker版的安装教程也很多,但同样麻烦。经过实验,我认为还是docker版好点,至少错了方便改,一次成功几乎不可能。

最可笑的是先要手工建立目录:假设加载volume的目录是 /docker/headscale, 在后面手工添加config子目录。然后在config子目录里添加一个空白的sqlite文件。

mkdir -p ./headscale/config
touch ./config/db.sqlite

接下来下载配置文件模板到config目录中

wget -O ./config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml

修改以下配置文件,其中不需要修改的部分没有列出。还有一部分(DNS相关)会在下部中列出。

server_url: https://headscale.mydomain.com
#使用外部的nginx反代和申请免费的SSL,如果需要在这里直接做https,要预先准备证书。
listen_addr: 0.0.0.0:8080
# Address to listen to /metrics, you may want
# to keep this endpoint private to your internal
# network
metrics_listen_addr: 0.0.0.0:9090
#这个是调试工具,不需要看的话设为127.0.0.1
grpc_listen_addr: 127.0.0.1:50443
#不需要的话不要改
ip_prefixes:

#虚拟IP的范围 
#  - fd7a:115c:a1e0::/48   #没有IPV6的话关闭,有的话可以打开。
  - 100.64.0.0/10
derp:
  server:
    # If enabled, runs the embedded DERP server and merges it into the rest of the DERP config
    # The Headscale server_url defined above MUST be using https, DERP requires TLS to be in place
    enabled: false
#中转服务,不需要的话关闭
randomize_client_port: true
#这里需要改成true

配置文件中关于DNS的部分在下篇中再说,这里先按照默认值不做改动。

docker 安装 headscale 和 headscale webui

起一个 docker compose

version: '3.1'

services:
  headscale:
    image: headscale/headscale
    container_name: headscale
    volumes:
      - /home/docker/headscale/config:/etc/headscale
      - /home/docker/headscale/data:/var/lib/headscale
      - /home/docker/headscale/run:/var/run/headscale
    environment:
      - VIRTUAL_HOST=headscale.mydomain.com
      - VIRTUAL_PORT=8080
      - LETSENCRYPT_HOST=headscale.mydomain.com
      - [email protected]
    networks:
      - interconnect      
    ports:
      - 9090:9090 #调试工具,可以不开
      - 8080:8080 #nginx反代443,实际上不需要从8080访问。
    command: headscale serve
    restart: unless-stopped
networks:
  interconnect:
    external: true    

解释: Docker环境已经预先配置好了nginx-proxy 和 acme companion,可以自动反代容器的http请求并自动申请acme.sh 的LE证书。指定的networks是为了将这个容器与nginx连接。

*这里把headscale的8080反代到nginx的443,但是配置文件中的地址是https协议,配置文件中并未指定证书,实际上docker 0.0.0.0:8080 仍然是http协议。会报错缺少证书,但不影响使用。

9090如果不需要可以不映射。

如果headscale运行成功,那么就可以安装webui控制台了。我们还需要做一点准备:

生成两个key:

1,headscale API KEY

docker exec -it headscale headscale apikeys create

得到的API KEY 形如: 148BCRqjsg.5uhNpBohlpRRExxgxAsrR2I2c_Q4OIG0435522x

2, headscale webui encryption key

openssl rand -base64 32

得到一个字符串如: tPosHiEni60fXnyxxxxxNCUE362pexAlDzPxxxxLqKpo=

然后按照说明安装headscale webui,还是采用docker方式:

起一个docker compose 文件:

version: "3"
services:
  headscale-webui:
    image: ghcr.io/ifargle/headscale-webui:v0.6.1
    #latest 0.7.0 have bugs 这里无法使用0.7.0,暂时存在bug
    container_name: headscale-webui
    environment:
      - TZ=Asia/Tokyo    
      - COLOR=red                              # Use the base colors (ie, no darken-3, etc) - 
      - HS_SERVER=https://headscale.mydomain.com    # headscale控制服务器的地址
      - DOMAIN_NAME=https://headscalewebui.mydomain.com  # 这个webui的地址.
      - SCRIPT_NAME=/admin                     # 启动位置 /admin  可以自己改 Remove if you are hosing at the root /
      - KEY="tPosHiEni60fXnyxxxxxNCUE362pexAlDzPxxxxLqKpo="             # Generate with "openssl rand -base64 32" - 刚才第二个key
      - AUTH_TYPE=basic                         # AUTH_TYPE is either Basic or OIDC.  Empty for no authentication - 身份验证
      - LOG_LEVEL=info                         # Log level.  "DEBUG", "ERROR", "WARNING", or "INFO".  Default "INFO"
      # ENV for Basic Auth (Used only if AUTH_TYPE is "Basic").  Can be omitted if you aren't using Basic Auth
      - BASIC_AUTH_USER=user                   # Used for basic auth 用户名
      - BASIC_AUTH_PASS=password                   # Used for basic auth 密码
      # ENV for OIDC (Used only if AUTH_TYPE is "OIDC").  Can be omitted if you aren't using OIDC
      #- OIDC_AUTH_URL=https://auth.$DOMAIN/.well-known/openid-configuration # URL for your OIDC issuer's well-known endpoint      
      #- OIDC_CLIENT_ID=headscale-webui         # Your OIDC Issuer's Client ID for Headscale-WebUI
      #- OIDC_CLIENT_SECRET=YourSecretHere      # Your OIDC Issuer's Secret Key for Headscale-WebUI
      - VIRTUAL_HOST=headscalewebui.mydomain.com
      - VIRTUAL_PORT=5000   #容器内端口5000,反代出去
      - LETSENCRYPT_HOST=headscalewebui.mydomain.com
      - [email protected]            
    volumes:
      - /home/docker/webui:/data                         # Headscale-WebUI's storage.  Make sure ./volume is readable by UID 1000 (chown 1000:1000 ./volume)
      - /home/docker/headscale/config/:/etc/headscale/:ro # 这里是headscale的config目录位置
    ports:
      - 5000:5000    #经过测试无问题后可以不需要暴露HTTP 5000端口
    networks:
      - interconnect
    restart: always
networks:
  interconnect:
    external: true  

是否需要把配置文件改成chown 1000,我不知道,如果不改可能也没事。

*最新版本存在bug,只能使用0.6版本,后续可以升级。

这里容易出错的地方很多,详细按照说明进行安装。

安装完毕后如果运行无误,就可以通过 https://headscalewebui.mydomain.com/admin 来进行设备管理了。

进入后输入刚才设置的用户名/密码,再输入headscale 的API KEY,就可以通过webui进行管理了。

首先第一件事是建立网络,在user里面增加一个用户。 同一个用户,就是同一个网络。同一个username名下的设备可以互通,否则不可以。

注册设备并加入网络

下面注册设备并加入网络。上面所说的两台服务器,一台在内网,一台在公网。先设置内网的服务器。

内网服务器内网地址为 192.168.2.1,可以与内网其他机器连接,要求加入网络,并作为192.18.2.0/24的路由,转发所有通往 192.168.2.0/24的信息。

假设服务器都是Ubuntu系统。

设备使用的客户端程序,直接使用tailscale的客户端(两者是兼容的)。

按照tailsacale公司的教程在Ubuntu上安装程序。

tailscale up --login-server=https://headscale.mydomain.com --accept-routes=true --accept-dns=true

等终端出出现以下内容:

To authenticate, visit: https://headscale.mydomain.com/register/nodekey:2d71ab2822852a458e320…..

复制这个URI,用浏览器访问一下。访问后 会提示:

headscale
Machine registration
Run the command below in the headscale server to add this machine to your network:headscale nodes register –user USERNAME –key nodekey: 2d71ab2822852a458e320….

此时直接回到WebUI,选择设备,添加设备,选择网络名,把 nodekey:2d71ab2822852a458e320……. 输入到后面的nodekey里面,就可以激活设备了。注意 “nodekey:”不能省略。

后面的key就是nodekey.

添加完毕后终端会显示Success,这样设备就添加完毕了。添加完毕后,设备应该可以在设备列表中可见,并被分配了虚拟网络地址。

开启路由转发和出口节点功能

接下来把这个设备设置为路由,向192.168.2.0/24网段转发。

*所有作为转发或出口的服务器都要开启IP转发 sysctl net.ipv4.ip_forward

回到Ubuntu的终端:

tailscale up --accept-dns=true --accept-routes --advertise-routes=192.168.2.0/24 --login-server=https://headscale.mydomain.com

回到headscale webui控制台,选择“Routes”, 可以看到上面的route: 192.168.2.0/24, click on the dot right side to enable the route.

这样这台机器就具有了向内网转发的功能*。

客户端连接headscale网络后,可直接访问 192.168.2.2,路由会自动从192.168.2.1服务器转发。

在另一台服务器(公网 12.34.56.78)上,开启出口节点功能,使能将客户端全部(不含虚拟内网中)的流量转发到该服务器并通过该服务器路由出去,实现代理上网功能。

在该服务器上安装tailscale并注册网络后,输入以下命令开启出口节点:

tailscale up --advertise-exit-node --accept-dns=true --accept-routes --login-server=https://headscale.mydomain.com

同样再回到webui控制台,route下面有 exit node,看到申请的服务器已经出现,点右边的点 enable。

客户端连接headscale网络后,选择Exit node,就可以将全部非内网流量转发到该exit node,实现通过该exit node 代理上网的目的。

客户端安装

按照headscale github 上的要求安装客户端。

这里说一下windows客户端的问题:

访问控制服务器的URI, https://headscale.mydomain.com/windows 会出现安装提示。

新版的tailscale windows client 已经不需要修改注册表,只要按照提示的要求输入命令即可。同样输入命令注册机器,访问授权代码,在webui中粘贴nodekey授权。

tailscale windows 安装后可以在 Windows console 里面输入命令,但可以从右键菜单上直接选择 exit node和dns控制方式,不需要每次都输入。

Reference & bugs

*nginx ssl 反代后可以使用https 访问headscale 控制服务器,但注册机器不能使用https uri的问题

参考了以下内容:

Setting up Tailscale on Ubuntu 20.04 LTS

Running headscale on Linux

Tailscale 基础教程:Headscale 的部署方法和使用教程

【Headscale】自部署 Tailscale 服务端

在linux下开启IP转发的方法

Tailscale高级用法,route与exit-node实现局域网穿透与代理出口功能

发表回复

您的电子邮箱地址不会被公开。