Ubuntu 22.04 安装 OpenZiti 指南

Ubuntu 22.04 安装 OpenZiti v2.0.8 全流程实测:二进制部署 controller/router/tunneler 与 APT 软件包安装 ziti-edge-tunnel 双方案、systemd 托管、端到端服务验证,以及 11 条 v2.0 部署排障实录。

OpenZiti零信任VPN安全网络配置2026/10/21

Ubuntu 22.04 安装 OpenZiti 指南

一、环境信息

本文所有命令与回显均在以下环境实测(2026-10-20),其他环境请按实际情况替换 IP、主机名与口令:

项目值
操作系统Ubuntu 22.04.5 LTS(x86_64,systemd 249.11 托管服务)
主机名 / 地址ziti-srv / 10.89.57.2(内网静态地址,请按实际替换)
OpenZiti 版本ziti v2.0.8(2026-10-20 官方最新稳定版,GitHub releases/latest 重定向实测)
ziti-edge-tunnel 版本v1.18.7(二进制与 APT 软件包均为该版本)
基础工具bash 5.1.16、curl 7.81.0、GNU tar 1.34
安装路径二进制 /usr/local/bin/ziti;配置与数据 /opt/ziti/;软件包形态的隧道器 /opt/openziti/
端口规划controller 1280(API)、6262(集群控制通道);router 3022(边缘接入)、10080(链路)

版本选择说明:OpenZiti v2.0 起默认启用基于 Raft 的 HA 控制器,移除了 v1 的 ziti controller init 引导命令,v1 时代的多数安装教程已不适用。本文按 v2.0.8 的官方流程组织。

二、前置条件

  1. 一台具有 sudo 权限的 Ubuntu 22.04 服务器,能访问公网(下载二进制或软件包);
  2. 已安装 curl(本例 7.81.0);方案 B 还需要 gnupg;
  3. 若需要客户端隧道器接管系统 DNS,系统使用 systemd-resolved(Ubuntu 22.04 默认启用);
  4. 服务器时间已同步(证书校验对时间敏感)。

三、安装方案 A:官方二进制包安装(含 controller/router/tunneler 全组件)

3.1 下载并安装 ziti CLI

# 下载官方 Linux amd64 包
curl -sL -o /tmp/ziti.tar.gz "https://github.com/openziti/ziti/releases/download/v2.0.8/ziti-linux-amd64-2.0.8.tar.gz"

# 校验并查看包内容
sha256sum /tmp/ziti.tar.gz
tar -tf /tmp/ziti.tar.gz

实测回显:

cf016a9fa19124f1932c1d73435e68e398bae15d6d5c3fef9688a22df61f7aba  /tmp/ziti.tar.gz
ziti

包内只有一个 ziti 可执行文件,解压并安装到 PATH:

cd /tmp && tar -xzf ziti.tar.gz
mv ziti /usr/local/bin/ziti
chmod +x /usr/local/bin/ziti
ziti version

实测回显:

v2.0.8

3.2 规划目录

mkdir -p /opt/ziti/controller /opt/ziti/router /opt/ziti/tunnel

注意:后续所有 ziti create config 命令都必须在设置了 ZITI_HOME 的会话中执行,否则生成的配置文件里证书路径会变成 //raft、/ziti-srv.key 这类空根路径,controller 启动直接失败(见第八节排障 2)。

3.3 生成 controller 配置

export ZITI_HOME=/opt/ziti/controller
ziti create config controller --ctrlPort 6262 --output $ZITI_HOME/controller.yaml

生成的 controller.yaml 关键内容(逐字段解读见《OpenZiti 2.0.8 配置参数详解》):

v: 3

cluster:
  dataDir:         "/opt/ziti/controller/raft"

identity:
  cert:        "/opt/ziti/controller/ziti-srvclient.chain.cert"
  server_cert: "/opt/ziti/controller/ziti-srv.server.chain.cert"
  key:         "/opt/ziti/controller/ziti-srv.key"
  ca:          "/opt/ziti/controller/ziti-srv.ca"

ctrl:
  options:
    advertiseAddress: tls:ziti-srv:6262
  listener:             tls:0.0.0.0:6262

edge:
  api:
    sessionTimeout: 30m
    address: ziti-srv:1280
  enrollment:
    signingCert:
      cert: /opt/ziti/controller/ziti-srv.signing.cert
      key:  /opt/ziti/controller/ziti-srv.signing.key
    edgeIdentity:
      duration: 180m
    edgeRouter:
      duration: 180m

web:
  - name: client-management
    bindPoints:
      - interface: 0.0.0.0:1280
        address: ziti-srv:1280
    identity:
      ca:          "/opt/ziti/controller/ziti-srv.ca"
      key:         "/opt/ziti/controller/ziti-srv.key"
      server_cert: "/opt/ziti/controller/ziti-srv.server.chain.cert"
      cert:        "/opt/ziti/controller/ziti-srvclient.chain.cert"
    options:
      minTLSVersion: TLS1.2
      maxTLSVersion: TLS1.3
    apis:
      - binding: edge-management
      - binding: edge-client
      - binding: fabric
      - binding: edge-oidc

生成配置中 identity、web[].identity、edge.enrollment.signingCert 都引用 ZITI_HOME 下待生成的证书文件——下一步先用 ziti pki 生成它们,再把路径替换为实际位置。

3.4 生成 controller 证书(PKI)

v2.0 官方引导流程要求 controller 证书携带 SPIFFE ID(spiffe://<信任域>/controller/<控制器ID>),单节点部署按以下命令生成:

cd $ZITI_HOME
ziti pki create ca --trust-domain ziti.example.com --pki-root pki --ca-file root-ca --ca-name "Ziti Root CA"
ziti pki create intermediate --pki-root pki --ca-name root-ca --intermediate-file ziti-srv --intermediate-name "Ziti Controller Signing Cert"
ziti pki create server --pki-root pki --ca-name ziti-srv --dns "localhost,ziti-srv" --ip "127.0.0.1,::1" --server-name ziti-srv --spiffe-id "controller/ziti-srv"

三条命令的实测回显格式相同(各为两行):

Success
Using CA name:  ziti-srv

生成结果位于 pki/ 目录(实测文件树节选):

pki/root-ca/certs/root-ca.cert
pki/ziti-srv/certs/server.chain.pem
pki/ziti-srv/certs/server.cert
pki/ziti-srv/certs/ziti-srv.cert
pki/ziti-srv/certs/ziti-srv.chain.pem
pki/ziti-srv/keys/server.key
pki/ziti-srv/keys/ziti-srv.key

OpenZiti 的 PKI 工具生成的证书不限制 ExtKeyUsage,服务端证书可直接当客户端证书使用(官方文档"单证书双角色"变体),因此本例不再单独生成 client 证书,identity.cert 与 identity.server_cert 都指向 server.chain.pem,避免客户端/服务端证书密钥错配。

把配置中的占位路径替换为实际文件(sed 或手工编辑均可):

sed -i -e "s|/opt/ziti/controller/ziti-srvclient.chain.cert|/opt/ziti/controller/pki/ziti-srv/certs/server.chain.pem|g" \
       -e "s|/opt/ziti/controller/ziti-srv.server.chain.cert|/opt/ziti/controller/pki/ziti-srv/certs/server.chain.pem|g" \
       -e "s|/opt/ziti/controller/ziti-srv.key|/opt/ziti/controller/pki/ziti-srv/keys/server.key|g" \
       -e "s|/opt/ziti/controller/ziti-srv.ca|/opt/ziti/controller/pki/ziti-srv/certs/ziti-srv.chain.pem|g" \
       -e "s|/opt/ziti/controller/ziti-srv.signing.cert|/opt/ziti/controller/pki/ziti-srv/certs/ziti-srv.cert|g" \
       -e "s|/opt/ziti/controller/ziti-srv.signing.key|/opt/ziti/controller/pki/ziti-srv/keys/ziti-srv.key|g" \
       $ZITI_HOME/controller.yaml

3.5 启动 controller 并初始化管理员

v2.0 的引导顺序是:先启动 controller(此时它处于等待初始化状态),再用 ziti agent cluster init 创建默认管理员。

export ZITI_HOME=/opt/ziti/controller
ziti controller run $ZITI_HOME/controller.yaml > $ZITI_HOME/controller.log 2>&1 &
sleep 12
grep -m1 checkEdgeInitialized $ZITI_HOME/controller.log

实测日志(未初始化状态的关键行,JSON 格式日志):

{"file":"github.com/openziti/ziti/v2/controller/server/controller.go:275","func":"github.com/openziti/ziti/v2/controller/server.(*Controller).checkEdgeInitialized","level":"warning","msg":"the controller has not yet been initialized, no default admin exists. Add this node to a cluster using 'ziti agent cluster add tls:ziti-srv:16262' against an existing cluster member, or if this is the bootstrap node, run 'ziti agent cluster init' to configure the default admin and bootstrap the cluster","time":"2026-10-20T16:57:08.215Z"}

提示:日志地址中的端口随配置而异(上例来自备用端口 16262 的复现实例),只要出现 has not yet been initialized 即为正常等待状态。初始化集群管理员(口令按等保要求自行设定):

ziti agent cluster init admin 'q1w2e3r4' ziti-srv

初始化完成后再执行 ziti agent cluster list 验证。注意:本机同时跑着 controller 与 router 时,agent 类命令需要用 -i <控制器ID> 指定目标,否则报 too many processes found matching filter:

ziti agent cluster list -i ziti-srv

实测回显:

╭──────────┬───────────────────┬───────┬────────┬─────────┬───────────┬───────────╮
│ ID       │ ADDRESS           │ VOTER │ LEADER │ VERSION │ CONNECTED │ PREFERRED │
├──────────┼───────────────────┼───────┼────────┼─────────┼───────────┼───────────┤
│ ziti-srv │ tls:ziti-srv:6262 │ true  │ true   │ v2.0.8  │ true      │ false     │
╰──────────┴───────────────────┴───────┴────────┴─────────┴───────────┴───────────╯

登录验证:

ziti login https://127.0.0.1:1280 -u admin -p 'q1w2e3r4' -y

实测回显:

Saving identity 'default' to /root/.config/ziti/ziti-cli.json

-y 表示信任自签名证书。登录态保存在 /root/.config/ziti/ziti-cli.json,后续 CLI 命令无需重复登录。

3.6 创建并注册边缘路由器

export ZITI_HOME=/opt/ziti/router
# 在控制面注册路由器并签发注册 JWT(-t 表示启用隧道器绑定)
ziti create edge-router ziti-er1 -t -o $ZITI_HOME/ziti-er1.jwt
# 生成路由器配置(此命令成功时无输出)
ziti create config router edge --routerName ziti-er1 --tunnelerMode host --output $ZITI_HOME/ziti-er1.yaml

第一条命令实测回显:

New edge router ziti-er1 created with id: X1fqRSZEB-
Enrollment expires at 2026-10-20T19:49:32.838Z

注册 JWT 有效期 24 小时(回显的到期时间),过期需重新创建。随后用 JWT 完成注册并启动:

ziti router enroll $ZITI_HOME/ziti-er1.yaml -j $ZITI_HOME/ziti-er1.jwt
ziti router run $ZITI_HOME/ziti-er1.yaml > $ZITI_HOME/router.log 2>&1 &
sleep 12
grep -c '"level":"error"' $ZITI_HOME/router.log || true

注册命令实测回显(节选最后 2 行):

{"file":"github.com/openziti/ziti/v2/router/enroll/enroll.go:233","func":"github.com/openziti/ziti/v2/router/enroll.(*RestEnroller).Enroll","level":"info","msg":"deleting existing router data model save file","path":"/opt/ziti/router/ziti-er1.yaml.proto.gzip","time":"2026-10-20T16:49:32.952Z"}
{"file":"github.com/openziti/ziti/v2/router/enroll/enroll.go:242","func":"github.com/openziti/ziti/v2/router/enroll.(*RestEnroller).Enroll","level":"info","msg":"registration complete","time":"2026-10-20T16:49:32.952Z"}

验证路由器上线:

ziti list edge-routers

实测回显:

╭────────────┬──────────┬────────┬───────────────┬──────┬────────────╮
│ ID         │ NAME     │ ONLINE │ ALLOW TRANSIT │ COST │ ATTRIBUTES │
├────────────┼──────────┼────────┼───────────────┼──────┼────────────┤
│ X1fqRSZEB- │ ziti-er1 │ true   │ true          │    0 │            │
╰────────────┴──────────┴────────┴───────────────┴──────┴────────────╯
results: 1-1 of 1

3.7 安装 ziti-edge-tunnel 隧道器

# 下载官方 Linux x86_64 包(与 ziti 主程序无强制版本绑定,取官方最新即可)
curl -sL -o /tmp/zt.zip "https://github.com/openziti/ziti-tunnel-sdk-c/releases/download/v1.18.7/ziti-edge-tunnel-Linux_x86_64.zip"
unzip -o /tmp/zt.zip -d /opt/ziti/tunnel
chmod +x /opt/ziti/tunnel/ziti-edge-tunnel

解压产物(实测):

Archive:  /tmp/zt.zip
  inflating: /opt/ziti/tunnel/config.json
  inflating: /opt/ziti/tunnel/ziti-edge-tunnel

创建客户端身份并注册:

ziti create identity ziti-tun1 -a dialers -o /opt/ziti/tunnel/ziti-tun1.jwt
cd /opt/ziti/tunnel
./ziti-edge-tunnel enroll -j ziti-tun1.jwt -i ziti-tun1.json -n ziti-tun1

创建身份的实测回显:

New identity ziti-tun1 created with id: z-AqRSZEB
Enrollment expires at 2026-10-20T19:50:03.440Z

注册的实测回显(退出码 0):

(5692)[        0.000]    INFO ziti-sdk:utils.c:200 ziti_log_set_level() set log level: root=3/INFO
(5692)[        0.000]    INFO ziti-sdk:utils.c:171 ziti_log_init() Ziti C SDK version 1.18.7 @gabc980e(HEAD) starting at (2026-10-20T16:50:18.543)
(5692)[        0.000]    INFO ziti-sdk:ziti_enroll.c:124 ziti_enroll() Ziti C SDK version 1.18.7 @gabc980e(HEAD) starting enrollment at (2026-10-20T16:50:18.543)
(5692)[        0.002]    INFO ziti-sdk:ziti_ctrl.c:643 ziti_ctrl_init() ctrl[https://ziti-srv:1280] controller initialized
(5692)[        0.009]    INFO ziti-sdk:ziti_ctrl.c:643 ziti_ctrl_init() ctrl[https://ziti-srv:1280] controller initialized

注册成功会生成身份私钥文件 ziti-tun1.json(0600 权限),请妥善备份;对已存在的 JSON 重复执行 enroll 会报 failed to open file ziti-tun1.json: File exists(见第八节排障 7)。

运行隧道器(需要 root 与 /dev/net/tun):

mkdir -p /dev/net && [ -e /dev/net/tun ] || mknod /dev/net/tun c 10 200
chmod 666 /dev/net/tun
nohup ./ziti-edge-tunnel run -i ziti-tun1.json > tunnel.log 2>&1 &
sleep 8
ip -br addr | grep ziti

实测回显:

ziti0            UNKNOWN        100.64.0.1/32

隧道器会接管服务名 DNS:系统若启用 systemd-resolved 会自动注册;否则把 100.64.0.2(隧道器内置 DNS)放到解析链首位,详见 7.5 节。

四、安装方案 B:软件仓库安装(仅 ziti-edge-tunnel)

官方维护 Ubuntu/Debian APT 仓库,提供 ziti-edge-tunnel 及其 systemd 服务,适合"只做接入端"的服务器。

4.1 添加仓库并安装

apt-get update && apt-get install -y gnupg
# 导入签名公钥
curl -sSLf https://get.openziti.io/tun/package-repos.gpg | gpg --dearmor --output /usr/share/keyrings/openziti.gpg
chmod -c +r /usr/share/keyrings/openziti.gpg
# 配置 jammy(Ubuntu 22.04)仓库源
echo "deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable jammy main" | tee /etc/apt/sources.list.d/openziti.list
apt-get update
apt-cache policy ziti-edge-tunnel

实测回显(节选):

ziti-edge-tunnel:
  Installed: (none)
  Candidate: 1.18.7
  Version table:
     1.18.7 500
        500 https://packages.openziti.org/zitipax-openziti-deb-stable jammy/main amd64 Packages
apt-get install -y ziti-edge-tunnel

安装完成后(实测):

  • 二进制:/usr/bin/ziti-edge-tunnel(ziti-edge-tunnel version 输出 v1.18.7);
  • 专用系统用户与用户组:ziti;
  • 配置目录:/opt/openziti/(身份目录 /opt/openziti/etc/identities);
  • systemd 单元:ziti-edge-tunnel.service(WantedBy=multi-user.target)。

4.2 启用服务并添加身份

systemctl enable --now ziti-edge-tunnel.service
systemctl is-active ziti-edge-tunnel.service
# 用注册 JWT 添加身份(无需重启服务)
ziti-edge-tunnel add --jwt "$(< /opt/ziti/tunnel/ziti-tun2.jwt)" --identity ziti-tun2

第三条命令实测回显:

{
  "Success":true,
  "Code":0
}

添加后隧道器创建 TUN 接口(实测接口名 ziti1,接口编号在多个隧道器实例间递增),查看:

ip -br addr | grep ziti
ziti1            UNKNOWN        100.64.0.1/32

两种形态区别:软件包版以 ziti 用户运行并配合 --identity-dir /opt/openziti/etc/identities 自动加载目录下全部身份;二进制版以 root 手工运行、逐个指定身份 JSON。生产建议用软件包版。add 成功后身份 JSON 会出现在 /opt/openziti/etc/identities/ 目录,服务重启时自动加载。

五、方案对比与选择建议

维度方案 A:二进制包方案 B:APT 软件仓库
组件范围controller / router / ziti-edge-tunnel 全组件仅 ziti-edge-tunnel
版本GitHub Releases 任意版本可固定仓库最新版(1.18.7)
升级方式替换二进制apt 升级
服务托管需自写 systemd 单元(第六节)官方单元开箱即用
适用角色服务端(控制器/路由器)与客户端均适用仅客户端接入

建议:服务端用方案 A 固定版本部署,客户端用方案 B 获取自动更新。

六、systemd 服务托管(controller 与 router)

方案 A 的 controller/router 建议托管为 systemd 服务。单元文件(实测可用):

/etc/systemd/system/ziti-controller.service:

[Unit]
Description=OpenZiti Controller
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Environment=ZITI_HOME=/opt/ziti/controller
ExecStart=/usr/local/bin/ziti controller run /opt/ziti/controller/controller.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

/etc/systemd/system/ziti-router.service:

[Unit]
Description=OpenZiti Edge Router
After=network-online.target ziti-controller.service
Wants=network-online.target

[Service]
Type=simple
User=root
Environment=ZITI_HOME=/opt/ziti/router
ExecStart=/usr/local/bin/ziti router run /opt/ziti/router/ziti-er1.yaml
Restart=on-failure
RestartSec=5
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

启用并验证:

systemctl daemon-reload
systemctl enable ziti-controller.service ziti-router.service
systemctl start ziti-controller.service && sleep 10
systemctl start ziti-router.service && sleep 8
systemctl status ziti-controller.service --no-pager -n 3

实测回显(节选):

Synchronizing state of ziti-controller.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable ziti-controller
Created symlink /etc/systemd/system/multi-user.target.wants/ziti-controller.service → /etc/systemd/system/ziti-controller.service.
Created symlink /etc/systemd/system/multi-user.target.wants/ziti-router.service → /etc/systemd/system/ziti-router.service.
● ziti-controller.service - OpenZiti Controller
     Loaded: loaded (/etc/systemd/system/ziti-controller.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2026-10-20 04:44:23 UTC; 15s ago
   Main PID: 6724 (ziti)
      Tasks: 14 (limit: 4543)
     Memory: 40.0M
        CPU: 1.366s
     CGroup: /system.slice/ziti-controller.service
             └─6724 /usr/local/bin/ziti controller run /opt/ziti/controller/controller.yaml

注意:如果手工 nohup 拉起过 controller/router,托管前先停掉旧进程,避免端口冲突。停止 ziti 进程请用 pkill -x ziti(精确匹配进程名);pkill -f "ziti controller run" 会匹配到执行命令的 shell 自身导致误杀(实测返回退出码 143)。systemd 托管后日志进入 journal,用 journalctl -u ziti-router -f 查看,不再写入 nohup 时代的 router.log。

七、验证与快速开始

7.1 检查监听端口

ss -ltn | grep -E ':(1280|6262|3022|10080) '

实测回显:

LISTEN 0      4096               *:10080            *:*
LISTEN 0      4096               *:3022             *:*
LISTEN 0      4096               *:1280             *:*
LISTEN 0      4096               *:6262             *:*

7.2 发布第一个服务(服务端承载)

在本机起一个测试后端,并创建服务与策略:

nohup python3 -m http.server 8000 --bind 127.0.0.1 > /opt/ziti/http80.log 2>&1 &
ziti create config webtest-host host.v1 '{"protocol":"tcp","address":"127.0.0.1","port":8000}'
ziti create config webtest-int intercept.v1 '{"protocols":["tcp"],"addresses":["webtest.svc.ziti"],"portRanges":[{"low":80,"high":80}]}'
ziti create service webtest -a webtest -c webtest-host,webtest-int
ziti create service-policy webtest-bind Bind --service-roles "#webtest" --identity-roles "@ziti-er1"
ziti create service-policy webtest-dial Dial --service-roles "#webtest" --identity-roles "#dialers"
# v2.0 必须显式创建以下两类路由器策略,否则拨号报 NO_EDGE_ROUTERS_AVAILABLE(见第八节排障 5)
ziti create service-edge-router-policy all-serp --edge-router-roles "#all" --service-roles "#all"
ziti create edge-router-policy all-erp --edge-router-roles "#all" --identity-roles "#all"

各命令实测回显:

New config webtest-host created with id: 77agKDQb3R65BgGueKRF1C
New config webtest-int created with id: 70syNFnSyoE2KaSyG89VjP
New service webtest created with id: 5ns6cgf8tyRZe6UUn7mUhb
New service policy webtest-bind created with id: 4QScvLu1UTPggnZSOSesPq
New service policy webtest-dial created with id: 3pfhBNDsOMZNNSVOfmop9S
New service edge router policy all-serp created with id: SLoYjHlJZEMHrrUh0VnzB
New edge router policy all-erp created with id: 5Spnyax9gnotI6FLeoPvZl

host.v1 配置若使用 forwardAddress: true 等透明转发字段,会触发 if/then 模式校验(要求配套 allowedProtocols 等字段),最小可用写法就是上面这种静态 protocol/address/port 组合。

7.3 端到端拨号验证

隧道器身份 ziti-tun1/ziti-tun2 携带 #dialers 属性并已注册,等待策略同步与终结器建立(实测约 20~40 秒)后验证:

dig +short webtest.svc.ziti
for i in 1 2 3; do curl -s -o /dev/null -w "第${i}次: HTTP %{http_code} %{time_total}s\n" http://webtest.svc.ziti/ --max-time 20; done

实测回显:

100.64.0.3
第1次: HTTP 200 0.044270s
第2次: HTTP 200 0.080374s
第3次: HTTP 200 0.080529s

访问 http://webtest.svc.ziti/ 返回的正是 8000 端口后端的响应(python http.server 的目录页 HTML),链路为 curl → ziti-edge-tunnel(TUN 拦截)→ edge router → host.v1 转发 → 127.0.0.1:8000,服务端全程未暴露任何公网端口。

7.4 策略诊断

若拨号不通,用策略顾问检查"身份 → 服务"链路:

ziti edge policy-advisor identities ziti-tun2 | tail -1

正常时实测回显:

OKAY : ziti-tun2 (1) -> webtest (1) Common Routers: (1/1) Dial: Y Bind: N

7.5 DNS 解析模型

隧道器在 TUN 网段内置 DNS(默认 100.64.0.2),负责把授权服务名解析为拦截地址:

  • systemd-resolved 启用时:隧道器自动注册,无需手工配置;
  • 未启用或需要显式控制时:把隧道器 DNS 放到解析链第一位,未匹配的服务名查询会被隧道器以 REFUSE 拒绝、解析器继续问后续上游。/etc/systemd/resolved.conf.d/upstream.conf 示例(实测):
[Resolve]
DNS=100.64.0.2 8.8.8.8 1.1.1.1

实测两种域名都正常解析:dig +short webtest.svc.ziti → 100.64.0.3,dig +short github.com → 20.205.243.166。

八、常见问题与排障实录

1. ziti controller init 命令不存在

v2.0 移除了该命令(ziti controller --help 子命令列表中无 init),改为启动 controller 后执行 ziti agent cluster init <用户名> <口令> <名称>。v1 教程照抄会一直停在"controller 未初始化"日志。

2. 生成的配置里路径是 //raft、/ziti-srv.key

ziti create config 按环境变量 ZITI_HOME 展开路径,未设置时占位符为空。实测启动报错:

unable to load identity (no file found at [/opt/ziti/controller/ziti-srv.key] but a new key spec was not provided)

解决:export ZITI_HOME=/opt/ziti/controller 后重新生成配置,并按 3.3/3.4 节替换证书路径。

3. controller 启动即退出,日志只有 identity 加载失败

原因是配置引用的证书文件不存在。确认 3.4 节三条 ziti pki 命令都已执行、find pki -type f 能看到 server.cert/server.key/server.chain.pem/ziti-srv.cert 等文件,再核对 controller.yaml 中 identity 与 web[].identity 的路径。

4. ziti pki create client 报 a bundle already exists for the name ... within CA ...

PKI 工具不允许覆盖同名 bundle。对策:改用别的名称(如 ziti-srv-client),或直接采用 3.4 节"单证书双角色"变体,用 server 证书兼任 client 证书(OpenZiti 证书不限制 ExtKeyUsage,官方文档认可此做法)。

5. 拨号报 NO_EDGE_ROUTERS_AVAILABLE - No edge routers are assigned and ...

v2.0 不再默认创建 #all 的 Edge Router Policy 与 Service-Edge-Router Policy(实测 ziti list edge-router-policies 仅有路由器自建的一条)。按 7.2 节补建 all-erp 与 all-serp 后恢复。诊断路径:ziti edge policy-advisor identities <身份名>,若显示 Identity has no edge routers assigned 即身份侧缺 ERP。

6. 策略正确但仍报 service ... has no terminators

承载端(bind)需要边缘路由器数据模型同步完成才能建立终结器,实测从创建策略到终结器可用约 20~40 秒,期间隧道器日志持续出现 failed to connect, reason=service ... has no terminators;路由器 journal 中 queuing terminator → terminator established 即就绪,等待后重测即可。

7. ziti-edge-tunnel enroll 报 failed to open file ...: File exists

enroll 不覆盖已存在的身份 JSON。删除同名 JSON 后重新执行,或换名注册。

8. 同机多个隧道器实例互相抢占路由

手工运行的隧道器被杀后 TUN 接口(如 ziti0)可能残留并持有 100.64.0.0/10 路由,新实例(ziti1)的拨号会被路由到死接口,表现为 curl 秒失败(实测 0.0008s 返回 HTTP 000)。排查:ip route | grep 100.64 看路由落在哪个接口,ip link del ziti0 删除残留接口后重启隧道服务。多实例场景建议只保留软件包服务这一种形态。

9. 软件包隧道器启动失败 failed to open network interface: open /dev/net/tun failed

服务以 ziti 用户运行,需要 /dev/net/tun 对其可读写(常规桌面/服务器由 udev 置为 0666)。最小化环境若手工 mknod 创建过设备,执行 chmod 666 /dev/net/tun 后 systemctl restart ziti-edge-tunnel.service。

10. 服务名解析 NXDOMAIN

隧道器 DNS 未生效或未被优先查询。确认 resolvectl status ziti0(或对应接口)能看到 DNS Servers 100.64.0.2,并按 7.5 节把 100.64.0.2 置首;也可直接向隧道器 DNS 查询验证:dig +short webtest.svc.ziti @100.64.0.2。

11. 批量停止 ziti 进程时 shell 被误杀

pkill -f "ziti controller run" 会匹配到包含该字符串的命令行(包括正在执行的 shell),实测返回 143。用 pkill -x ziti(按进程名精确匹配)替代。

九、卸载与清理

# 停止并移除 systemd 单元
pkill -x ziti || true
systemctl disable --now ziti-controller.service ziti-router.service 2>/dev/null
rm -f /etc/systemd/system/ziti-controller.service /etc/systemd/system/ziti-router.service
systemctl daemon-reload

# 方案 A 产物
rm -f /usr/local/bin/ziti
rm -rf /opt/ziti

# 方案 B 产物
systemctl disable --now ziti-edge-tunnel.service 2>/dev/null
apt-get remove -y ziti-edge-tunnel
rm -f /etc/apt/sources.list.d/openziti.list /usr/share/keyrings/openziti.gpg
rm -rf /opt/openziti
apt-get update

十、参考链接

  1. OpenZiti 官方下载页(含 get.openziti.io 安装脚本说明):https://openziti.io/docs/downloads/
  2. HA 集群初始化文档(ziti agent cluster init):https://openziti.io/docs/reference/ha/bootstrapping/initialization/
  3. 控制器证书与 SPIFFE 信任域文档:https://netfoundry.io/docs/openziti/reference/ha/bootstrapping/certificates
  4. Linux 隧道器 Debian 软件包文档(仓库与 resolver 配置):https://openziti.io/docs/reference/tunnelers/linux/debian-package/
  5. ziti v2.0.8 发布页:https://github.com/openziti/ziti/releases/tag/v2.0.8
  6. ziti-edge-tunnel v1.18.7 发布页:https://github.com/openziti/ziti-tunnel-sdk-c/releases/tag/v1.18.7
  7. 站内相关文档:《OpenZiti 介绍与选型指南》、《OpenZiti 2.0.8 配置参数详解》、《OpenZiti 2.0.8 常用 CLI 命令详解(ziti CLI)》