命令行
本页是两个二进制程序的参考:独立代理 etemenanki-app,以及面板节点 agent katana。本页列出每个参数及其默认值、--test 试运行检查什么和检查不了什么、会改变程序行为的环境变量、退出码与信号处理,以及进程在协议代码之外打印的每一条消息的原文。
本页描述的是 etemenanki 2.0.2 版本(其中的 etemenanki-app 报告的版本仍为 2.0.0,构建时使用 etemenanki-protocols 2.0.2)和 katana 3.0.1(构建时使用 etemenanki-protocols 2.0.1)。如何把这两个程序作为服务运行,包括 systemd 单元和升级流程,请参阅生产环境运行。
etemenanki-app [-c <path>] [--test]etemenanki-app -h | --helpetemenanki-app -V | --version
katana [-c <path>] [--test]katana -h | --helpkatana -V | --version两个程序都在前台运行,直到收到 SIGINT 或 SIGTERM。它们都没有子命令、位置参数、守护进程模式或 PID 文件。
两个程序接受相同的四个选项,除此之外不接受其他任何选项。
| 选项 | 参数 | 默认值 | 作用 |
|---|---|---|---|
-c, --config |
路径 | config.toml |
要加载的 TOML 配置文件。相对路径按进程的工作目录解析。 |
--test |
无 | 关闭 | 构建完整配置,打印结果后退出,不绑定任何 socket,也不连接任何服务器。参见检查配置。 |
-h, --help |
无 | 把帮助文本打印到标准输出,并以状态 0 退出。 |
|
-V, --version |
无 | 打印程序名和版本,例如 etemenanki-app 2.0.0 或 katana 3.0.1,并以状态 0 退出。 |
路径可以写成参数解析器接受的任意一种形式:-c /etc/etemenanki/config.toml、-c/etc/etemenanki/config.toml、--config /etc/etemenanki/config.toml 或 --config=/etc/etemenanki/config.toml。选项顺序不限。
用法错误时,程序会向标准错误打印一条错误、用法行和一条提示,并以状态 2 退出,不会加载任何内容。
| 错误用法 | 消息 |
|---|---|
| 未知选项或多余的参数 | error: unexpected argument '--bogus' found |
-c 后没有路径 |
error: a value is required for '--config <CONFIG>' but none was supplied |
| 同一选项给了两次 | error: the argument '--test' cannot be used multiple times |
帮助文本很短。以下是两个程序各自打印的内容,供参考:
$ etemenanki-app --helpA minimal Xray-core-style proxy runtime
Usage: etemenanki-app [OPTIONS]
Options: -c, --config <CONFIG> Path to the TOML configuration file [default: config.toml] --test Validate the configuration and exit without binding any listener -h, --help Print help -V, --version Print version$ katana --helpXrayR-compatible proxy node agent on the Etemenanki kernel
Usage: katana [OPTIONS]
Options: -c, --config <CONFIG> Path to the TOML configuration file [default: config.toml] --test Validate the configuration and exit without binding any listener -h, --help Print help -V, --version Print version配置路径与工作目录
Section titled “配置路径与工作目录”默认值 config.toml 的含义是“当前工作目录下名为 config.toml 的文件”。在服务管理器下,工作目录通常是 /,因此请给 -c 传入绝对路径。
文件内部的每个相对路径同样按工作目录解析,而不是按配置文件所在的目录解析。这包括 cert_file、key_file、ca_file、geoip、geosite、rule_list_path 以及 Unix socket 的 listen 路径。
文件无法打开时,错误只有操作系统的原始消息,例如 No such file or directory (os error 2)、Permission denied (os error 13) 或 Is a directory (os error 21)。消息中不会重复路径;配置中引用的证书、CA 证书包或 geodata 文件缺失时,出现的也是同样的消息。请先检查 -c,再逐一检查文件中的每个路径。
运行期间,每个程序都会监视配置文件所在的目录,并在文件变化时重载。如果只给了文件名(例如默认值),该目录就是工作目录。参见 etemenanki-app 热重载和 katana 热重载。
对 etemenanki-app 而言,--test 执行与正常启动相同的构建过程,并在程序即将打开 socket 之前停止。对 katana 而言,它执行启动过程中不需要面板的那部分,外加对每个 Hysteria 2 节点本地设置的检查。两者都会读取构建所需的每个文件,因此请以服务运行时的用户身份、在服务的工作目录下运行它:这样一来,无法读取的私钥或错误的相对路径会在检查时失败,而不是在启动时才失败。
检查在遇到第一个错误时停止。修复后再次运行检查,才能发现下一个错误。
flowchart LR
P["读取并解析文件"] --> A{"有出站吗?"}
A -- "否" --> F["错误"]
A -- "是" --> D["DNS 解析器"]
D --> O["出站"]
O --> B["负载均衡器"]
B --> R["路由表"]
R --> I["入站"]
I --> OK["Configuration OK."]etemenanki-app --test 依次执行:
| 步骤 | 检查内容 | 读取的文件 |
|---|---|---|
| 解析 | 文件是 UTF-8 编码且是合法的 TOML,每个键都是已知的,每个值的类型都正确。入站或出站 settings 表内的键要等到该入站或出站构建时才检查。 |
配置文件 |
| 存在出站 | 文件中至少有一个 [[outbound]]。除非 [route].default 指定了其他出站,否则第一个出站就是默认路由。 |
|
| DNS | [dns] 指定了已知的后端,并提供了该后端所需的设置。 |
设置了 [dns].ca_file 时读取它 |
| 出站 | 每个 [[outbound]] 都能构建:协议、settings、密钥、stream 设置、TLS 选项。tag 不重复。 |
每个出站 TLS 的 ca_file,以及 Hysteria 2 出站的 ca_file |
| 负载均衡器 | 每个负载均衡器的 tag 都是新的,每个成员都指向一个出站,每个成员都有健康探测可以到达的上游,且策略是已知的。 | |
| 路由 | [route].default 和每条规则都指向已存在的出站或负载均衡器,且每个匹配条件都合法。 |
仅当有规则使用 geoip 匹配条件时读取 geoip 文件,仅当有规则使用 geosite 匹配条件时读取 geosite 文件 |
| 入站 | 每个 [[inbound]] 都能构建:协议、用户、监听地址、stream 设置。tag 不重复。 |
TLS 和 Hysteria 2 的证书与私钥 |
--test 不检查:
- 端口是否空闲,或进程是否有权绑定该端口;
- 进程能否创建 TUN 设备或安装其路由;
- 上游服务器或 DNS 服务器是否可达,其证书能否通过验证;
- 系统信任库能否加载(TLS 客户端和 Hysteria 2 客户端在连接时才读取它);
- Hysteria 2 出站的
ca_file中是否有可用的证书:--test会读取该文件,但其内容要到出站连接时才解析; [log].level,它从不经过校验(参见日志)。
正常启动执行相同的构建,然后绑定监听器。因此凡是 --test 会失败的情况,启动同样会失败;此外启动还可能因绑定错误和 TUN 设备错误而失败。
flowchart LR
P["读取并解析文件"] --> D["DNS 解析器与出站池"]
D --> N{"有节点吗?"}
N -- "否" --> F["错误"]
N -- "是" --> C["下一个节点:面板客户端"]
C --> R["路由表"]
R --> H{"是 Hysteria 2 节点吗?"}
H -- "是" --> V["本地 Hysteria 2 设置与证书"]
H -- "否" --> M{"还有节点吗?"}
V --> M
M -- "是" --> C
M -- "否" --> OK["Configuration OK"]katana --test 依次执行:
| 步骤 | 检查内容 | 读取的文件 |
|---|---|---|
| 解析 | 文件是 UTF-8 编码且是合法的 TOML,每个键都是已知的,每个值的类型都正确。 | 配置文件 |
| DNS | [dns] 指定了已知的后端,并提供了该后端所需的设置。 |
设置了 [dns].ca_file 时读取它,与后端无关 |
| 出站池 | 每个 [[outbound]] 都能构建。tag 不重复,且都不是保留名称:direct、block、freedom 或 blackhole。 |
|
| 存在节点 | 文件中至少有一个 [[node]]。 |
|
| 面板客户端(逐节点) | panel_type 为 NewV2board、V2board 或 SSPanel(不区分大小写),且 api.node_type 是已知的节点类型:V2ray、Vmess、Vless、Trojan、Shadowsocks、Hysteria2、Hysteria 或 Hy2(不区分大小写)。 |
|
| 路由(逐节点) | [node.route].default 和每条 [[node.route.rule]] 都指向出站池中的出站(未设置时默认为 direct),且每个匹配条件都合法。 |
仅当有规则使用 geoip 匹配条件时读取 geoip 文件,仅当有规则使用 geosite 匹配条件时读取 geosite 文件 |
| Hysteria 2(逐节点) | 仅针对 Hysteria 2 节点:[node.hysteria] 和证书能通过与启动时相同的代码构建出可用的服务端。[node.controller.cert].mode 必须为 "file"。 |
[node.controller.cert] 中的 cert_file 和 key_file |
--test 不检查:
- 任何需要面板的内容。katana 不会发送任何请求,因此错误的
api.host、api.key或node_id也能通过; - 任何由面板下发的内容,例如 V2ray、Trojan 或 Shadowsocks 节点的端口、传输层和 TLS 设置。这些在节点启动时才检查;
- 非 Hysteria 2 节点的证书文件。katana 要在面板表明该节点使用 TLS 时才读取它们;
rule_list_path,它在节点启动后读取,之后每次轮询时再次读取,除非设置了disable_get_rule。文件缺失或无法读取时记录为警告cannot read rule_list_path <path>: <error>,而不是错误;- 端口是否空闲,或进程是否有权绑定该端口;
[log].level,它从不经过校验(参见日志)。
--test 的输出
Section titled “--test 的输出”两个程序报告结果的方式不同。etemenanki-app 通过日志器输出错误,katana 则直接写到标准错误。
| etemenanki-app | katana | |
|---|---|---|
| 成功 | 标准输出打印 Configuration OK.,退出码 0 |
标准输出打印 Configuration OK(没有句点),退出码 0 |
| 失败 | 标准输出打印一条 ERROR 日志行 configuration invalid: <error>,退出码 1 |
标准错误打印 configuration error: <error>,退出码 1 |
| 解析错误前缀 | 无 | config parse error: |
| 非法 UTF-8 | invalid utf-8 sequence of 1 bytes from index 0 |
config not utf-8: invalid utf-8 sequence of 1 bytes from index 0 |
$ etemenanki-app --test -c config.tomlConfiguration OK.$ etemenanki-app --test -c config.toml2026-09-24T20:33:57.764733Z ERROR etemenanki_app: configuration invalid: TOML parse error at line 6, column 1 |6 | bogus=1 | ^^^^^unknown field `bogus`, expected one of `tag`, `protocol`, `listen`, `port`, `stream`, `address_family`, `sniffing`, `settings`其他常见的失败:
configuration invalid: 之后的消息 |
原因 |
|---|---|
No such file or directory (os error 2) |
配置文件或其中引用的某个文件在该路径下不存在。 |
config defines no outbounds |
文件中没有 [[outbound]]。空文件也会以这种方式失败。 |
duplicate outbound tag: <tag> |
两个 [[outbound]] 段使用了相同的 tag。 |
duplicate inbound tag: <tag> |
两个 [[inbound]] 段使用了相同的 tag。 |
outbound <tag>: unknown protocol "<name>" |
protocol 不是任何出站协议。 |
balancer <tag> references unknown outbound tag: <member> |
负载均衡器的某个成员不是出站 tag。 |
错误信息列出了每个配置段的消息。
$ katana --test -c config.tomlConfiguration OK$ katana --test -c config.tomlconfiguration error: config parse error: TOML parse error at line 26, column 1 |26 | bogus = 1 | ^^^^^unknown field `bogus`, expected one of `mode`, `cert_file`, `key_file`, `reject_unknown_sni`其他常见的失败:
configuration error: 之后的消息 |
原因 |
|---|---|
No such file or directory (os error 2) |
配置文件、[dns].ca_file 或某条规则所需的 geodata 文件不存在。 |
config defines no [[node]] entries |
文件中没有 [[node]]。空文件也会以这种方式失败。 |
duplicate/reserved outbound tag <tag> |
两个 [[outbound]] 段使用了相同的 tag,或者某个出站使用了 direct、block、freedom 或 blackhole。 |
unknown panel_type "<value>" |
panel_type 不是受支持的面板。消息中的值以小写显示。 |
unknown node_type "<value>" |
api.node_type 不是已知的节点类型。 |
route references unknown outbound tag: <tag> |
某条 [[node.route.rule]] 指向了不在出站池中的出站。 |
node <id>: <error> |
Hysteria 2 节点的本地设置或证书检查失败,例如 node 1: obfs_password must be at least 4 bytes for salamander 或 node 1: No such file or directory (os error 2)。 |
只有 Hysteria 2 检查会在消息前加上节点的 node_id。对于其他逐节点的错误,请根据消息中引用的值找到对应节点。
错误信息列出了每个配置段的消息。
在脚本中使用 --test
Section titled “在脚本中使用 --test”在新文件替换正在使用的文件之前先检查它。退出状态是可靠的信号:0 表示配置能构建成功,其他任何值都表示不能。
#!/bin/shset -eunew=/etc/etemenanki/config.toml.newlive=/etc/etemenanki/config.toml
if ! out=$(cd /etc/etemenanki && etemenanki-app --test -c "$new" 2>&1); then printf 'config rejected:\n%s\n' "$out" >&2 exit 1fimv "$new" "$live" # the running process notices the change and reloads用于 katana 时,替换路径和二进制名即可。请同时捕获两个输出流(2>&1),这样脚本既能看到 katana 写到标准错误的消息,也能看到 etemenanki-app 的日志行。
| 状态 | etemenanki-app | katana |
|---|---|---|
0 |
--test 通过;打印了 --help 或 --version;或在 SIGINT、SIGTERM 后正常停止。 |
同左。 |
1 |
--test 失败;或启动失败,原因是文件无法读取或解析、无法构建、某个入站无法绑定,或某个 TUN 入站无法创建设备。 |
--test 失败;或启动失败,原因是文件无法读取或解析、出站池无法构建、文件中没有 [[node]],或没有任何一个节点的面板客户端和路由表能构建成功。 |
2 |
命令行用法错误。 | 同左。 |
101 |
panic,例如 TOKIO_WORKER_THREADS 取值非法。 |
同左。 |
shell 中的 128 + n |
被信号 n 杀死,例如 SIGHUP 对应 129,SIGKILL 对应 137。 |
同左。 |
进程一旦运行起来,就只有信号能让它结束。此后发生的失败只会记录到日志,进程继续运行:
- 重载时文件无法读取、解析或构建,会保留旧配置,进程继续运行。在 etemenanki-app 中,重载期间无法绑定的入站会被略过,其他入站照常启动。
- katana 节点启动后,如果面板不再响应,会记录一条警告,并在下次轮询时重试。
- katana 节点首次启动失败(例如因为无法连接面板或无法绑定端口)时,会不断重试,直到启动成功。每次失败都会记录
node <id>: <reason>; retrying in <N>s,其中<reason>为node_info failed: …、panel returned no node info、panel returned port 0、user_list failed: …、panel returned no user list或initial start failed: …。第一次等待 1 秒,此后每失败一次翻倍,最长 60 秒;如果该节点的update_periodic更短,则以它为上限。修改该节点的[[node]]段会让它立即再试一次。节点重试期间 katana 不会退出,即使这是唯一的节点也是如此,因此服务管理器看到的是一个正在运行的进程。节点列出了这些错误。
两个程序都没有用于重载的信号。配置文件在磁盘上发生变化时即会重载。
SIGINT 和 SIGTERM 的处理器要在启动完成后才安装:etemenanki-app 在所有监听器绑定之后,katana 在所有节点派生之后。在此之前或在 --test 期间到达的信号,会按内核的默认动作立即终止进程。
| 信号 | etemenanki-app | katana |
|---|---|---|
SIGINT(Ctrl-C) |
正常停止,退出码 0 |
正常停止,退出码 0 |
SIGTERM |
正常停止,退出码 0 |
正常停止,退出码 0 |
SIGHUP |
不处理:进程立即被终止,不打印 shutting down 行 |
同左 |
SIGKILL |
立即终止 | 立即终止;尚未上报给面板的流量会丢失 |
正常停止时先记录 shutting down,然后:
- etemenanki-app 取消正在运行的配置:立即关闭所有监听器和所有打开的连接,不等待连接结束,然后退出。
- katana 取消所有节点。每个运行中的节点关闭其监听器和连接,使流量计数器定格,然后把计数器刷新到面板:如果有用户存在未上报的流量且
disable_upload_traffic未开启,就发送最后一次流量上报;如果有审计规则命中,就发送一次审计上报。每个请求最多耗时该节点的api.timeout,未设置或为0时为 5 秒。如果最后这次上报失败,katana 会记录node <id>: report traffic: <error>,这部分流量随之丢失,因为计数器只保存在内存中。所有节点都结束后,进程退出。
收到第一个 SIGINT 或 SIGTERM 后,程序会保留其处理器,因此之后的 SIGINT 和 SIGTERM 不会打断停止过程。停止过程卡住时,只有 SIGKILL 能结束它。
两个程序都不读取属于自己的环境变量。下列变量由它们所依赖的库读取。
| 变量 | etemenanki-app | katana | 作用 |
|---|---|---|---|
RUST_LOG |
是 | 是 | 日志过滤器。启动时如果能解析,就取代 [log].level。参见日志。 |
NO_COLOR |
是 | 是 | 任何非空值(即使是 0)都会去掉日志行中的 ANSI 颜色代码。 |
TOKIO_WORKER_THREADS |
是 | 是 | 异步运行时的工作线程数,默认等于 CPU 数。取值不是正整数时,进程会立即 panic 并以状态 101 退出,即使带了 --version 也是如此。 |
SSL_CERT_FILE, SSL_CERT_DIR |
是 | 是 | TLS 客户端查找受信任根证书的位置。参见受信任的根证书。 |
HTTPS_PROXY, HTTP_PROXY, ALL_PROXY, NO_PROXY(或小写形式) |
否 | 是 | katana 会像 curl 一样,通过这些变量指定的代理发送面板请求。因此服务环境中残留的代理变量也会承载面板流量。用户的代理流量不受影响。 |
受信任的根证书
Section titled “受信任的根证书”每个 TLS 客户端查找系统受信任根证书的方式各不相同,SSL_CERT_FILE 和 SSL_CERT_DIR 对它们的影响也各不相同。无论哪种情况,这些变量都是取代默认位置,而不是在其基础上追加。如果只想为某一个连接额外信任一个 CA,优先使用该出站或 [dns] 的 ca_file 键:它会把该 CA 添加到系统根证书之外。
| 客户端 | 程序 | 未设置变量时的根证书 | 设置了 SSL_CERT_FILE 或 SSL_CERT_DIR 时 |
|---|---|---|---|
出站 TLS([outbound.stream] 中 security = "tls")以及 [dns] 的 tls 和 https 后端 |
etemenanki-app | 系统 OpenSSL 库的默认文件和目录。在 Debian 和 Ubuntu 上,其中就是系统证书包。 | OpenSSL 读取 SSL_CERT_FILE 指定的文件以代替其默认文件,读取 SSL_CERT_DIR 指定的目录以代替其默认目录。 |
| Hysteria 2 出站 | etemenanki-app | 系统证书包,通过探测 /etc/ssl/certs 等常见位置找到。 |
只读取变量指定的文件和目录,跳过系统位置。SSL_CERT_DIR 可以列出多个目录,以 : 分隔。如果一个证书都加载不到,连接会以 hysteria2: no system root certificates could be loaded 失败,即使该出站设置了 ca_file 也是如此。 |
面板客户端(通过 HTTPS 访问 api.host) |
katana | 系统证书包,通过探测常见位置找到。 | 变量指定的文件或目录如果存在,就用来代替探测到的文件,并与探测到的目录一起使用。 |
[dns] 的 tls 和 https 后端 |
katana | OpenSSL 内置的默认位置 /usr/local/ssl |
与 etemenanki-app 相同:变量取代 OpenSSL 的默认位置。 |
两个程序都把日志写到标准输出,每个事件一行,包含 UTC 时间戳、级别、记录该行的模块和消息。即使标准输出不是终端,日志行中也带有 ANSI 颜色代码;设置 NO_COLOR=1 可以去掉它们。
2026-09-24T20:35:11.971456Z INFO etemenanki_app::instance: inbound socks-in listening on 127.0.0.1:10802026-09-24T20:35:13.967835Z INFO etemenanki_app: shutting down过滤器取自下列来源中第一个适用的:
RUST_LOG,前提是它已设置且能解析。无法解析的RUST_LOG会被整体忽略。已设置但为空的RUST_LOG会被解析为“没有任何指令”,从而屏蔽所有日志行。- 配置文件中的
[log].level。如果文件无法读取或解析,就跳过这一步,因此解析错误仍会被打印出来。 info。
变量和键使用相同的指令语法:以逗号分隔的列表,其中单独的级别设置默认值,target=level 针对某个模块覆盖默认值,例如 info,etemenanki_protocols=debug。target 是把 - 换成 _ 后的 crate 名:etemenanki_app、katana、etemenanki_protocols、etemenanki_environment 和 etemenanki_concepts。[log].level 中无法解析的单条指令(例如 =[)会在启动时被丢弃,并在标准错误打印 ignoring `=[`: invalid filter directive,其余指令照常生效。如果没有剩下任何指令,或 [log].level 是空字符串,就只记录 ERROR 行。
katana 还会在重载时应用变化后的 [log].level。它会取代来自 RUST_LOG 的过滤器;无法解析的值会被拒绝,并记录 invalid log level "<value>": <error>。etemenanki-app 只在启动时读取 [log].level。
| 键 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
level | string | 否 | "info" | 一条 tracing 的 EnvFilter 指令,语法与 RUST_LOG 相同:一个级别(off、error、warn、info、debug、trace,或 0 到 5 的数字,不区分大小写),后面可以跟按 target 覆盖的级别,例如 "warn,etemenanki_protocols=debug"。环境变量 RUST_LOG 只要能解析为过滤器,就会取代这个值;设为空字符串也算合法,结果是什么都不输出。这个值不做校验:不是级别的词(例如 "warning")会被当成 target 名,结果是所有日志(包括错误)都不再输出。值为空,或者没有一条指令能解析时,只输出错误日志。只在启动时读取一次,热重载时不生效。 |
| 键 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
level | string | 否 | "info" | 一条 tracing 的 EnvFilter 指令,语法与 RUST_LOG 相同:一个级别(off、error、warn、info、debug、trace,或 0 到 5 的数字,不区分大小写),后面可以跟按 target 覆盖的级别,例如 "info,katana=debug"。启动时,环境变量 RUST_LOG 只要是合法的过滤器就优先生效。--test 不校验这个值:启动时无法解析的指令会被跳过,并在 stderr 打印一行 ignoring ...;不是级别的词(例如 "warning")会被当成 target 名,结果是所有日志(包括错误)都不再输出。热重载时如果这个值变了,katana 会应用新值,并取代 RUST_LOG 设置的过滤器;新值无法解析时记录 invalid log level,保留当前的过滤器。 |
生产环境运行中有一张常用过滤器表,并说明了每个程序在运行时如何处理变化后的 [log].level。
以下是进程自身在启动、重载和关闭前后打印的日志行。协议、面板客户端和节点的消息在对应功能的页面以及错误信息中说明。表中的 <error> 代表底层错误文本,<tag> 代表入站或出站的 tag。
| 级别 | 消息 | 含义 |
|---|---|---|
INFO |
inbound <tag> listening on <bind> |
某个入站已就绪。<bind> 对 TCP 是 <host>:<port>,对 Hysteria 2 是 udp <host>:<port>,对 Unix socket 是 unix:<path>,对 TUN 是 tun <name>(或 tun auto)。 |
INFO |
inbound <tag> owns tun device <name> |
某个 TUN 入站创建了其设备。在 listening on 行之前打印。 |
ERROR |
failed to start: <error> |
启动失败,进程以 1 退出。绑定错误显示为 failed to start: inbound <tag> bind <bind> failed: <error>。 |
ERROR |
config hot-reload disabled: <error> |
无法监视配置目录。代理继续运行,但对文件的修改要到重启后才会生效。 |
INFO |
config reload: <changes> |
正在应用一次重载;<changes> 概括了变化的内容。 |
ERROR |
reload: cannot read <path>: <error> |
重载时无法读取文件,保留当前配置。 |
ERROR |
reload: parse failed, keeping current config: <error> |
新文件无法解析,保留当前配置。 |
ERROR |
reload: build failed, keeping current config: <error> |
新文件能解析但无法构建,保留当前配置。 |
ERROR |
inbound <tag> bind <bind> failed: <error> |
重载时某个入站无法绑定。其他入站在没有它的情况下启动。 |
INFO |
shutting down |
收到了 SIGINT 或 SIGTERM。 |
etemenanki-app 热重载详细解释了这些重载日志行。
| 级别 | 消息 | 含义 |
|---|---|---|
ERROR |
failed to load config: <error> |
启动时无法读取或解析文件。退出码 1。 |
ERROR |
failed to build outbounds: <error> |
[dns] 解析器或某个 [[outbound]] 无法构建。退出码 1。 |
ERROR |
config defines no [[node]] entries |
文件中没有 [[node]]。退出码 1。 |
ERROR |
node <id>: <error> |
仅在启动时:某个节点的面板客户端无法构建(例如 unknown panel_type "foo")。该节点被跳过。 |
ERROR |
node <id>: build router: <error> |
仅在启动时:某个节点的路由表无法构建。该节点被跳过。 |
ERROR |
no nodes could be started |
所有节点都被跳过。退出码 1。 |
ERROR |
config watcher disabled (no live reload): <error> |
无法监视配置目录。katana 继续运行,但对文件的修改要到重启后才会生效。 |
ERROR |
config reload failed, keeping current: <error> |
新文件无法读取或解析。 |
ERROR |
reload: bad outbounds, keeping current config: <error> |
新的出站池无法构建。新文件中的任何内容都不会被应用。 |
ERROR |
reload: node <node>: <error>; keeping current config |
新文件中的某个 [[node]] 无法构建:可能是本次重载新增节点的面板客户端或路由表,也可能是设置有变化的节点的面板客户端(例如 api.node_type 未知)。新文件中的任何内容都不会被应用。启动时被跳过的节点会在每次重载时重新构建,因此只要它仍有错误,每次重载都会被拒绝。 |
INFO |
reload: log level → <level> |
[log].level 发生了变化。删除该键时 <level> 为 info。即使新值被 invalid log level 拒绝,也会打印这一行。 |
ERROR |
invalid log level "<value>": <error> |
新的 [log].level 无法解析,保留当前过滤器。 |
INFO |
reload: outbound pool rebuilt |
[[outbound]] 列表发生了变化,所有节点现在都使用新的出站池。 |
INFO |
reload: removing node <node> |
某个 [[node]] 被删除,或其 panel_type、api.host、api.node_id 或 api.key 发生了变化,或者(对 NewV2board 和 V2board 而言)它向面板请求的节点类型发生了变化(api.node_type 除大小写以外的变化,或 V2ray、Vmess 节点的 api.enable_vless)。后一种情况下,该节点随后会被重新添加。 |
INFO |
reload: added node <node> |
启动了一个新的 [[node]]。 |
INFO |
reload: reconfigured node <node> |
现有节点的其他设置发生了变化,新设置已下发给该节点。如果 api.timeout 等 api 设置发生了变化,该节点会构建新的面板客户端。如果该节点的新路由表无法构建,它会保留正在使用的设置,并记录 node <id>: config edit refused, keeping the running one: <error>。 |
INFO |
shutting down |
收到了 SIGINT 或 SIGTERM。 |
<id> 是节点的 node_id。<node> 的格式为 <panel_type>@<api.host>#<node_id>,其中面板类型为小写。对 NewV2board 和 V2board,katana 会追加 /<node type>,即它向面板请求的节点类型:设置了 api.enable_vless = true 的 V2ray、Vmess 或 Vless 节点为 vless,其他情况为小写的 api.node_type,例如 newv2board@https://panel.example.com#1/v2ray。SSPanel 节点没有后缀,例如 sspanel@https://panel.example.com#1。katana 从不把 api.key 写入这些日志行。
katana 热重载详细解释了这些重载日志行,故障排查则介绍了启动之后出现的逐节点消息。
| 现象 | 原因 | 解决方法 |
|---|---|---|
配置文件明明存在,却报 No such file or directory (os error 2) |
文件中的相对路径是按工作目录解析的,或者缺少某个 geodata、证书或 CA 文件。 | 在相对路径所基于的目录下运行,或改用绝对路径。 |
--test 以 1 退出且不打印任何内容(etemenanki-app) |
RUST_LOG 或 [log].level 隐藏了 ERROR 行。 |
运行 env -u RUST_LOG etemenanki-app --test -c …,并修正 [log].level。 |
用 SIGHUP 重载时服务停止了 |
两个程序都不处理 SIGHUP。 |
改为保存配置文件;程序会自动重载。 |
katana 通过了 --test,但某个节点始终起不来 |
--test 不联系面板。该节点的首次面板请求或首次启动一直失败,节点在不断重试。 |
查看日志中该节点的 retrying in 行并排除故障。节点会在下一次尝试时启动,无需重启;参见故障排查。 |
| 面板请求发往了意料之外的主机(katana) | katana 的环境中设置了 HTTPS_PROXY、HTTP_PROXY 或 ALL_PROXY 变量。 |
删除该变量,或把面板主机加入 NO_PROXY。 |