MENU

ZTNET 搭建 zerotier planet 私有根教程

October 28, 2024 • Read: 149 • 教程·折腾

背景回顾

前几年,基于zerotier+ztncui搭建了私有planet。开源的 ztncui 客户端比较简陋,核心功能齐全,有些小bug,当时没有别的更好的可以选择(zero-ui也很简陋),将就用着,反正也是初始化网络,调整路由,新设备接入才打开后台使用。
这里先回顾下过往历程:

  • 21年在v2上摸鱼看到这个贴子五分钟自建 ZeroTier 的 Planet/Controller,第一次知道zerotier可以自建,相关概念很模糊,帖子介绍的是搭建controller,并非真实的私有根。后续找了搭建planet+controller的教程跟着搭建起来 zerotier的planet服务器(根服务器)的搭建踩坑记。无需zerotier官网账号 那时候搭建需要手动修改mkworld.cpp源码,填写自己的ip,编译cpp才有world.bin(就是planet),服务端用systemd管理。
  • 22年服务器到期,需要迁移,把90%以上的服务docker容器化。于是基于docker重新搭建了一套docker-zerotier-planet,原理和第一次搭建是一样的,这次新增了下载planet接口api,不需要手动编译,不过客户端还是ztncui。
  • 2024年4月无意间发现,有另外一个很美观功能完善的开源客户端: ztnet GitHub地址。简直是太符合我的胃口了,除了存储使用postgres,会占用多一点内存,如果能优化为sqlite3就完美了。

ZTNET 官方 docker-compose

官方docker-compose文档:https://ztnet.network/installation/docker-compose

services:
  postgres:
    image: postgres:15.2-alpine
    container_name: postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: ztnet
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - app-network

  zerotier:
    image: zyclonite/zerotier:1.14.0
    hostname: zerotier
    container_name: zerotier
    restart: unless-stopped
    volumes:
      - zerotier:/var/lib/zerotier-one
    cap_add:
      - NET_ADMIN
      - SYS_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    networks:
      - app-network
    ports:
      - "9993:9993/udp"
    environment:
      - ZT_OVERRIDE_LOCAL_CONF=true
      - ZT_ALLOW_MANAGEMENT_FROM=172.31.255.0/29

  ztnet:
    image: sinamics/ztnet:latest
    container_name: ztnet
    working_dir: /app
    volumes:
      - zerotier:/var/lib/zerotier-one
    restart: unless-stopped
    ports:
      - 3000:3000
    # - 127.0.0.1:3000:3000  <--- Use / Uncomment this line to restrict access to localhost only
    environment:
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: ztnet
      NEXTAUTH_URL: "http://localhost:3000" # !! Important !! Set the NEXTAUTH_URL environment variable to the canonical URL or IP of your site with port 3000
      NEXTAUTH_SECRET: "random_secret"
      NEXTAUTH_URL_INTERNAL: "http://ztnet:3000" # Internal NextAuth URL for 'ztnet' container on port 3000. Do not change unless modifying container name.
    networks:
      - app-network
    links:
      - postgres
    depends_on:
      - postgres
      - zerotier

  ############################################################################
  #                                                                          #
  # Uncomment the section below to enable HTTPS reverse proxy with Caddy.    #
  #                                                                          #
  # Steps:                                                                   #
  # 1. Replace <YOUR-PUBLIC-HOST-NAME> with your actual public domain name.  #
  # 2. Uncomment the caddy_data volume definition in the volumes section.    #
  #                                                                          #
  ############################################################################

  # https-proxy:
  #   image: caddy:latest
  #   container_name: ztnet-https-proxy
  #   restart: unless-stopped
  #   depends_on:
  #     - ztnet
  #   command: caddy reverse-proxy --from <YOUR-PUBLIC-HOST-NAME> --to ztnet:3000
  #   volumes:
  #     - caddy_data:/data
  #   networks:
  #     - app-network
  #   links:
  #     - ztnet
  #   ports:
  #     - "80:80"
  #     - "443:443"

volumes:
  zerotier:
  postgres-data:
  # caddy_data:

networks:
  app-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.31.255.0/29

官方docker-compose解释

使用了3个组件

  • postgres: 存储持久层,端口5432千万不要映射到公网
  • zerotier: 作为controller+planet,提供api给ztnet,需要暴露9993 UDP 端口
  • ztnet: 类似ztncui,作为控制器的前端,端口为3000

优化搭建过程

基于官方的思路,可以很简单的自定义自己的运行场景。这里做出几点优化:

  • 由于postgres是数据库基础组件,可以单独出来。如果已经存在,就不需要搭建;如果新搭建,后续其他服务也可以复用。
  • 数据持久化,使用目录映射方式而非docker volumes,便于后续备份,存储的目录均为/opt/software/xxx下。
  • docker 网络先默认提前设置好,而非在docker-compose中定义。
  • 反向代理使用nginx,nginx如果是容器化,也提前加入同一个网络,这样不需要暴露3000端口

docker创建网络及存储目录

网络名称:docker_app_default
子网访问:10.254.1.0/24

docker network create docker_app_default --driver=bridge --subnet=10.254.1.0/24
mkdir -p /opt/software/postgres/data
mkdir -p /opt/software/zerotier/data

postgres

  • postgres的docker-compose文件
services:
  postgres:
    image: postgres:15.2-alpine
    container_name: postgres
    restart: unless-stopped
    environment:
      - TZ=Asia/Shanghai
      - POSTGRES_PASSWORD=POSTGRES
      - POSTGRES_USER=POSTGRES
    volumes:
      - /opt/software/postgres/data:/var/lib/postgresql/data

networks:
  default:
    name: docker_app_default
    external: true
  • 创建zenet数据库
docker exec -it postgres psql -U POSTGRES -c "\l" # 查看数据库列表
docker exec -it postgres psql -U POSTGRES -c "CREATE DATABASE ztnet" # 创建数据库
docker exec -it postgres psql -U POSTGRES -c "\l" # 再次查看数据库列表

当然,为了安全性,可以为数据库创建专门的用户及密码,这里不做展开。

zerotier+ztnet

services:
  zerotier:
      image: zyclonite/zerotier:1.14.0
      hostname: zerotier
      container_name: zerotier
      restart: unless-stopped
      volumes:
        - /opt/software/zerotier/data:/var/lib/zerotier-one
      cap_add:
        - NET_ADMIN
        - SYS_ADMIN
      devices:
        - /dev/net/tun:/dev/net/tun
      ports:
        - "9993:9993" # 暴露多一个tcp,其实可以删掉
        - "9993:9993/udp"
      environment:
        - ZT_OVERRIDE_LOCAL_CONF=true
        - ZT_ALLOW_MANAGEMENT_FROM=0.0.0.0/0 # 限制管理controller的子网,为了更安全可以填写上面创建的 10.254.1.0/24

  ztnet:
    image: sinamics/ztnet:latest
    container_name: ztnet
    working_dir: /app
    volumes:
      - /opt/software/zerotier/data:/var/lib/zerotier-one
    restart: unless-stopped
    ports:
      - 3000:3000 # 可选,不经过反向代理,直接暴露3000端口来访问,需要打开端口映射,同时开放主机防火墙和安全策略组
    environment:
      POSTGRES_HOST: postgres
      POSTGRES_PORT: 5432
      POSTGRES_USER: POSTGRES
      POSTGRES_PASSWORD: POSTGRES
      POSTGRES_DB: ztnet
      NEXTAUTH_URL: "https://ztnet.example.com" # 这里填写外网控制,如果经过反向代理,则填写域名,如果没有,则填写http://ip:3000
      NEXTAUTH_SECRET: "random_secret"
      NEXTAUTH_URL_INTERNAL: "http://ztnet:3000"

networks:
  default:
    name: docker_app_default
    external: true

nginx反向代理

  • 直接http访问nginx,nginx加入ztnet同一个网络(例如cloudflare小云朵,自动ssl)
server {
    listen 80;
    listen [::]:80;
    server_name ztnet.example.com;
    client_max_body_size 20m;
    charset utf-8;
    resolver 127.0.0.11 valid=30s;
    set $backend "ztnet:3000";
    location / {
        proxy_pass http://$backend;
        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;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
        client_max_body_size 20m;
        proxy_cache off;
        proxy_buffering off;
        proxy_http_version 1.1;
    }
}
  • 本机nginx接管ssl,并且nginx没有加入ztnet同一个网络
server {
    listen 80;
    listen [::]:80;
    server_name ztnet.example.com;

    # 将 HTTP 请求重定向至 HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name ztnet.example.com;

    # include /opt/software/nginx/conf.d/example.com.ssl.conf.incl;
    ssl_certificate /opt/software/nginx/ssl.d/example.com/cert.pem;
    ssl_certificate_key /opt/software/nginx/ssl.d/example.com/key.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security max-age=15768000;
    ssl_stapling on;

    access_log  /opt/software/nginx/logs/ztnet.access.log;
    error_log  /opt/software/nginx/logs/ztnet.error.log;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Range $http_range;
        proxy_set_header If-Range $http_if_range;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:3000;
    }
}

使用

搭建好后,打开 ztnet.example.com 或 http://ip:3000 注册第一个用户为管理账号。
私有根的使用,详见官网 https://ztnet.network/usage/private_root


本文由 ONE 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
如有版权疑问交流,请给我留言:oneisall8955@gmail.com
本文永久链接:http://liuzhicong.cn/index.php/guide/78.html

Last Modified: October 30, 2024
Archives QR Code Tip
QR Code for this page
Tipping QR Code