背景回顾
前几年,基于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
本文永久链接:https://liuzhicong.cn/index.php/guide/78.html
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
如有版权疑问交流,请给我留言:oneisall8955@gmail.com
本文永久链接:https://liuzhicong.cn/index.php/guide/78.html