跳转到内容

快速上手

本页带你从一台空服务器开始,搭出一个为真实用户提供服务的 katana 节点。你将在 Xboard 面板中创建一个 VMess 节点(任何兼容 newV2board 的面板做法都一样),在服务器上放好 TLS 证书,写一份简短的配置文件并检查它,启动 katana,然后确认面板收到了流量数据。

katana 和面板各有分工。面板决定节点是什么样的:协议、端口、传输层、WebSocket 路径、是否启用 TLS,以及哪些用户可以连接。配置文件则说明 katana 服务于哪个面板的哪个节点、证书放在哪里、监听哪个地址。因此节点的大部分形态都在面板中设置,配置文件可以保持简短。

sequenceDiagram
    participant P as 面板
    participant K as katana
    participant C as 客户端
    K->>P: GET 节点配置(端口、ws 路径、TLS)
    K->>P: GET 用户列表
    Note over K: 绑定 TCP 端口
    C->>K: VMess over WebSocket + TLS
    loop 每 update_periodic 秒
        K->>P: GET 节点配置和用户列表
        K->>P: POST 各用户流量
    end

你需要:

  • 一台 Linux 服务器,有公网地址,并且有 root 权限或其他能绑定 443 端口的方式(见第 6 步)。
  • 一个解析到该服务器的域名,用于申请证书。本页使用 proxy.example.com。
  • 面板的管理员权限。 本页使用 Xboard。V2board 以及其他支持 newV2board UniProxy API 的面板做法相同。SSPanel 使用的配置项不同,见 SSPanel。
  • 放行端口。 客户端使用 TCP 443;用 HTTP 验证方式申请证书期间还需要 TCP 80。服务器还必须能通过 HTTPS 访问面板。
  1. 在面板中创建节点。 在 Xboard 中添加一个 VMess 节点,按下表设置。Xboard 管理界面上的标签可能与下面的描述不完全一致,所以表中同时给出了 Xboard 存储的字段名:

    面板设置(Xboard 字段) 本页取值 katana 如何使用
    客户端连接的地址(host) proxy.example.com 不使用,供客户端使用。
    客户端连接的端口(port) 443 不使用,供客户端使用。
    服务端监听的端口(server_port) 443 绑定这个 TCP 端口。
    TLS 开启 用你的证书为监听器套上 TLS。
    传输协议(network) ws 通过 WebSocket 提供 VMess。
    WebSocket 路径 /ws 只在这个路径上接受 WebSocket 升级,其他路径一律返回 404。
    权限组(group_ids) 至少一个 这些组里的用户就是该节点的用户。

    Xboard 为每个节点保存两个端口。katana 绑定的是 server_port;port 只写进订阅。除非 katana 前面有设备把一个端口转发到另一个端口,否则两者都设为 443。

    然后记下配置文件要用的两个值:

    • 节点 ID,显示在面板的节点列表中;
    • 通讯密钥(Xboard 将其存为 server_token 设置项)。整个面板只有这一个密钥,所有节点共用。

    确保至少有一个用户可以使用该节点。只有当用户属于该节点的某个权限组、未被封禁、未过期且还有剩余流量时,Xboard 才会把该用户下发给节点。用户列表为空时,katana 不会绑定任何端口。

  2. 安装 katana。 按照安装操作,然后检查二进制文件:

    终端窗口
    katana --version
    katana 3.0.1
  3. 获取证书。 katana 没有内置 ACME 客户端,唯一的证书模式是 file:你提供一个 PEM 格式的证书和一个 PEM 格式的私钥,katana 在启动监听器时从磁盘读取它们。任何能生成这两个文件的工具都可以。

    终端窗口
    sudo certbot certonly --standalone -d proxy.example.com
    sudo install -d -m 700 /etc/katana/cert
    sudo install -m 644 /etc/letsencrypt/live/proxy.example.com/fullchain.pem /etc/katana/cert/fullchain.pem
    sudo install -m 600 /etc/letsencrypt/live/proxy.example.com/privkey.pem /etc/katana/cert/privkey.pem

    --standalone 在 TCP 80 端口上响应验证请求,所以它运行期间不能有其他程序监听该端口。

    katana 对这两个文件的要求:

    • cert_file 先放服务器证书,再放中间证书(如有)。fullchain.pem 正是这个顺序。
    • key_file 存放与证书配对的 PEM 格式私钥(PKCS#8、RSA 或 EC)。私钥与证书不匹配时,katana 会拒绝。
    • katana 不检查证书中的域名和有效期,但客户端会检查,所以证书必须覆盖客户端用作 TLS 服务器名称的域名。
  4. 编写配置。 将下面的内容保存为 /etc/katana/config.toml,并把占位值替换成你的面板 URL、节点 ID 和密钥:

    /etc/katana/config.toml
    # katana quick start: serve one Xboard (newV2board) VMess node over
    # WebSocket + TLS. The panel decides the port, the transport and the
    # WebSocket path; this file says which panel and node to serve, and where
    # the certificate is.
    [log]
    level = "info"
    [[node]]
    panel_type = "NewV2board"
    [node.api]
    host = "https://panel.example.com"
    node_id = 1
    key = "replace-with-the-panel-key"
    node_type = "V2ray"
    [node.controller]
    listen_ip = "0.0.0.0"
    update_periodic = 60
    [node.controller.cert]
    mode = "file"
    cert_file = "/etc/katana/cert/fullchain.pem"
    key_file = "/etc/katana/cert/privkey.pem"

    文件中每个配置项的含义见下文各配置项的作用。

  5. 检查配置。 --test 会读取文件,并在不访问面板的前提下尽可能构建出节点:

    终端窗口
    katana --test -c /etc/katana/config.toml

    文件有效时,它在 stdout 输出一行,并以状态码 0 退出:

    Configuration OK

    文件无效时,它在 stderr 输出 configuration error: 及原因,并以状态码 1 退出。例如,拼错的配置项会被当作错误,而不会被 katana 忽略:

    configuration error: config parse error: TOML parse error at line 20, column 1
    |
    20 | update_period = 60
    | ^^^^^^^^^^^^^
    unknown field `update_period`, expected one of `listen_ip`, `send_ip`, `update_periodic`, `disable_upload_traffic`, `disable_get_rule`, `disable_sniffing`, `cert`

    Configuration OK 并不代表节点一定能启动。--test 不向面板发送任何请求,对 VMess 节点也既不检查 cert.mode,也不检查证书文件:即使 /etc/katana/cert/fullchain.pem 还不存在,示例配置也能通过。–test 检查哪些内容列出了它确切的检查范围。

  6. 启动 katana。 第一次启动时在前台运行:

    终端窗口
    sudo katana -c /etc/katana/config.toml

    绑定 1024 以下的端口(例如 443)需要 root 权限或 CAP_NET_BIND_SERVICE capability。两者都没有时,监听器会以 Permission denied (os error 13) 失败。节点正常工作后,请改为以服务方式运行 katana,见部署。

  7. 查看日志。 katana 把日志写到 stdout。面板响应成功且监听器绑定完成后,它会为该节点输出一行日志:

    2026-09-24T20:28:49.297288Z INFO katana::manager::node: node 1: listening on 0.0.0.0:443

    node 1 是配置中的 node_id,0.0.0.0:443 是 listen_ip 加上面板下发的端口。对于正常启动的节点,katana 只输出这一行。在默认的 info 级别下,它不会为每个连接输出日志。如果几秒内没有看到这一行,请参阅启动日志。

  8. 连接客户端。 把面板的订阅链接导入 VMess 客户端,或者手动填写以下参数:

    客户端设置 取值
    地址 proxy.example.com
    端口 443
    用户 ID 面板中该用户的 UUID
    alterId 0
    加密方式(数据加密算法) auto、aes-128-gcm 或 chacha20-poly1305
    传输协议 ws,路径 /ws
    TLS 开启,服务器名称 proxy.example.com

    katana 只支持 AEAD VMess,也就是 alterId = 0 所选择的模式。它拒绝 none 和 zero 这两种加密方式。

  9. 确认流量上报。 通过客户端打开几个网页,然后等待一个 update_periodic 周期(此配置中为 60 秒)。面板中该用户的上传和下载流量应当增加。下文的流量上报说明了 katana 发送什么内容、输出哪些日志。

快速上手配置使用了 11 个配置项。katana 在每个表中都会拒绝它不认识的配置项,所以拼写错误会让程序停止,而不是被忽略。

配置项 本页取值 含义
[log].level "info" 日志过滤器,使用 tracing 过滤器语法:"info"、"debug"、"info,katana=debug"。默认值为 "info"。如果设置了环境变量 RUST_LOG,启动时以它为准;之后修改这个配置项会替换当前级别,无需重启。
panel_type "NewV2board" 面板 API。"NewV2board" 及其别名 "V2board" 选择 Xboard 和 V2board 提供的 UniProxy API;"SSpanel" 选择 mod_mu。不区分大小写。其他值会以 unknown panel_type 报错。
[node.api].host "https://panel.example.com" 面板的基础 URL,需包含协议头。katana 会去掉末尾的 /。
[node.api].node_id 1 面板中的节点 ID,也用于在日志中标识该节点。
[node.api].key "replace-with-the-panel-key" 面板的通讯密钥。katana 将其作为查询参数 token 发送。
[node.api].node_type "V2ray" 节点的协议类型:"V2ray"(别名 "vmess" 和 "vless")、"Trojan"、"Shadowsocks" 或 "Hysteria2"(别名 "hysteria" 和 "hy2")。不区分大小写。其他值会以 unknown node_type 报错。katana 将该值转为小写后作为查询参数 node_type 发送;V2ray 节点在 enable_vless = true 时则发送 vless。V2ray 节点提供 VMess 还是 VLESS 由 enable_vless 决定,而不是由这个值决定。
[node.controller].listen_ip "0.0.0.0" 要绑定的地址。默认值为 "0.0.0.0"。
[node.controller].update_periodic 60 两次面板同步之间的秒数。每次同步都会拉取节点配置和用户列表,并上报流量。默认值为 60,0 按 1 处理。
[node.controller.cert].mode "file" 任何启用 TLS 的节点都必须设为小写的 "file"。默认值为 "none";TLS 节点只要取值不是 "file",监听器启动时就会失败。"dns"、"http" 和 "tls"(XrayR 中的 ACME 模式)在所有节点上都会被拒绝,无论是否启用 TLS。对于 Hysteria 2 以外的节点,--test 不检查这个配置项。
[node.controller.cert].cert_file 路径 PEM 格式的证书链。
[node.controller.cert].key_file 路径 PEM 格式的私钥。

示例中省略的一些配置项也有值得了解的默认值。[node.api].timeout 是每个面板请求的超时秒数;为 0 或未设置时取 5。[node.api].enable_vless = true 会让 V2ray 节点提供 VLESS 而不是 VMess。完整的配置项列表见配置文件。

cert_file 和 key_file 请使用绝对路径。katana 会相对于自己的工作目录解析相对路径,而不是相对于配置文件所在目录。

katana --test -c <file> 只执行仅依赖本机的检查。它不绑定任何端口,也不向面板发送请求。

--test 会检查 仅在节点启动时检查
文件存在、是 UTF-8 编码的合法 TOML,且不含未知配置项。 面板能否访问,以及 host、node_id 和 key 是否正确。
至少有一个 [[node]]。 端口、传输层、路径和 TLS 设置。这些都来自面板。
每个节点的 panel_type 和 node_type 都是已知值。 对于 Hysteria 2 以外的所有节点类型:cert.mode,以及 cert_file 和 key_file 是否存在且相互匹配。
[dns] 和每个 [[outbound]] 都能构建成功,包括 DNS 的 ca_file。 listen_ip,以及端口能否绑定。
每个节点的 [node.route] 都能编译:规则语法、出站 tag,以及 geoip 和 geosite 文件。 面板是否为该节点提供了用户。
对于 Hysteria 2 节点:[node.hysteria] 设置、cert.mode,以及证书和私钥文件。 面板要求而 katana 拒绝的功能,例如 REALITY 或 XTLS 流(flow)。

Hysteria 2 的证书检查之所以不同,是因为 Hysteria 2 监听器总是使用 TLS,katana 无需询问面板就知道该节点需要证书。其他节点类型是否启用 TLS 由面板决定,所以 katana 只在启动监听器时才检查 cert.mode 并读取证书文件。

不指明文件名的错误可能会造成误解。如果配置文件本身不存在,--test 只会输出系统错误:

configuration error: No such file or directory (os error 2)

节点没有启动时,它的日志会说明卡在了哪个阶段,katana 也会自动重试(见启动失败后的重试)。启动失败时输出的每一行日志末尾都注明了距下一次尝试的等待时间。下表列出的是第一次失败,其等待时间总是 1 秒。表中省略了 katana::manager::node target 和时间戳。

日志 原因 解决方法
INFO node 1: listening on 0.0.0.0:443 节点已启动。 无需处理。
ERROR node 1: node_info failed: GET /api/v1/server/UniProxy/config; retrying in 1s 面板请求失败:host 错误、面板无法访问,或者面板拒绝了请求(key 错误、node_id 不存在,或者该 ID 对应的是另一种类型的节点)。 检查这三个值,然后按下文所示手动发送请求。
ERROR node 1: node_info failed: parse UniProxy config response; retrying in 1s 面板返回的内容不是节点配置,例如一个 HTML 页面。 检查 host 是否为面板的基础 URL,以及 panel_type 是否与面板匹配。
ERROR node 1: node_info failed: newV2board: server port must be > 0; retrying in 1s 面板中该节点没有设置服务端口。 在面板中设置端口。
ERROR node 1: initial start failed: TLS node requires cert.mode = "file"; retrying in 1s 面板中开启了 TLS,但 cert.mode 未设置、为 "none",或者是小写 "file" 以外的任何值。 设置 mode = "file" 以及两个文件路径。
ERROR node 1: initial start failed: node requests kernel-unsupported feature: ACME cert mode "dns"; retrying in 1s cert.mode 为 "dns"、"http" 或 "tls"。katana 没有 ACME 客户端。 用其他工具获取证书,并设置 mode = "file"。
ERROR node 1: initial start failed: TLS node requires cert.cert_file and cert.key_file; retrying in 1s 已设置 mode = "file",但 cert_file 或 key_file 为空或缺失。 设置两个路径。
ERROR node 1: initial start failed: No such file or directory (os error 2); retrying in 1s cert_file 或 key_file 不存在。错误信息不会指明是哪一个。 检查两个路径。
ERROR node 1: initial start failed: Permission denied (os error 13); retrying in 1s katana 无权绑定该端口,或无权读取私钥文件。 以 root 身份或带 CAP_NET_BIND_SERVICE 运行,并检查私钥文件的权限。
ERROR node 1: initial start failed: Address already in use (os error 98); retrying in 1s 其他程序占用了该端口。 停止该程序,或在面板中更换端口。
ERROR node 1: initial start failed: node requests kernel-unsupported feature: REALITY; retrying in 1s 面板描述了 katana 未实现的功能。 在面板中修改节点。协议列出了 katana 支持的内容。
ERROR node 1: user_list failed: GET /api/v1/server/UniProxy/user; retrying in 1s 用户列表请求失败。katana 需要用户列表才能启动节点,所以在某次尝试拿到用户列表之前,它不会绑定任何端口。 与 node_info failed 一样,检查面板。
没有任何日志 面板返回了空的用户列表,所以 katana 没有绑定任何端口。 至少给一个用户开放该节点。katana 会在第一次返回用户的同步时绑定端口。
ERROR node 1: rebuild failed: No such file or directory (os error 2) 节点启动时没有用户,之后某次同步带来了用户,但监听器启动失败。原因与 initial start failed 相同。 排除原因。katana 每次同步都会重试。
WARN node 1: node_info: GET /api/v1/server/UniProxy/config 或 WARN node 1: user_list: GET /api/v1/server/UniProxy/user 启动之后的某次同步失败。节点继续使用已有的节点配置和用户提供服务。 检查面板。

面板相关的错误日志从不包含 URL,因为 URL 中带有密钥。要查看面板的实际响应,可以自己发送 katana 发出的请求。密钥会留在 shell 历史记录中,事后请清除:

终端窗口
curl -sS 'https://panel.example.com/api/v1/server/UniProxy/config?node_id=1&node_type=v2ray&token=replace-with-the-panel-key'

正常的节点会返回包含 server_port、network、networkSettings 和 tls 的 JSON。katana 会以小写形式发送配置中的 node_type,而 Xboard 把 v2ray 视为 vmess。

启动失败的节点会一直重试,直到启动成功或 katana 停止。每次尝试都会重新请求节点配置和用户列表,然后启动监听器。第一次重试发生在失败 1 秒后,此后每失败一次,等待时间翻倍,最长 60 秒;如果 update_periodic 更短,则最长为 update_periodic 秒。当 update_periodic = 60 时,等待时间依次为 1、2、4、8、16 和 32 秒,之后每次重试都等待 60 秒。在此期间,进程和其他节点照常运行,因此服务管理器会显示 katana 正在运行。

排除原因后,节点会在下一次尝试时启动,无需重启:

  • katana 之外的修复,例如在面板中修正节点、释放端口或放好证书文件,会在下一次重试时生效。
  • 保存对该节点配置文件中 [[node]] 条目的修改,会让 katana 立即重试,而不必等完当前的等待时间。
  • 针对进程本身的修复,例如授予 CAP_NET_BIND_SERVICE 或修改 systemd unit,需要重启 katana,因为正在运行的进程不会感知这些变化。

katana 在中继时按用户计量流量,并在每次同步时(即每 update_periodic 秒)上报。第一次同步发生在节点启动后整整一个周期。对于 newV2board 面板,上报只需一个请求:

POST /api/v1/server/UniProxy/push
{"7":[82,200204]}

每一项把面板用户 ID 映射到以字节为单位的 [上传, 下载]。katana 统计的是解密后中继的有效载荷,因此不包含 TLS、WebSocket 和 VMess 的开销。自上次上报以来没有产生流量的用户不会出现在上报中;如果所有用户都没有流量,katana 不发送请求。

上报成功时不输出日志,失败时输出一条警告:

WARN katana::manager::node: node 1: report traffic: POST UniProxy push

katana 会保留未上报的字节数,并计入下一次上报,所以上报失败只会让数据延迟,不会丢失。katana 因 SIGINT 或 SIGTERM 停止时,会先关闭监听器,再发送最后一次上报。

如果两个周期后面板仍然没有显示流量,并且没有警告,请检查 [node.controller].disable_upload_traffic 是否为 true,以及客户端是否真的经过了这个节点。流量上报详细介绍了流量计数。

在默认的 info 级别下,katana 不会为单个失败的连接输出日志;每个失败连接只在 debug 级别记录。只有当某个节点在一秒内有超过 10 次握手失败时,它才会输出警告。这条警告用节点的 tag 标识节点,tag 由节点类型、listen_ip 和端口组成:

WARN katana::manager::proxy: node V2ray_0.0.0.0_443: 12 inbound handshake failures in the last 1s (possible handshake scan/DoS or misconfigured clients)

要查明某个客户端失败的原因,可以临时设置 [log].level = "info,katana=debug"(katana 无需重启即可应用新的日志级别),或者对照节点逐项检查客户端:

  • WebSocket 路径。 路径必须与面板中的路径完全一致。其他路径 katana 一律返回 HTTP 404。
  • WebSocket host。 如果面板中为节点设置了 Host 头,客户端的 Host 必须与之匹配(忽略大小写和端口)。不匹配时 katana 同样返回 HTTP 404。
  • TLS 服务器名称。 证书必须覆盖客户端发送的名称。
  • 用户。 UUID 必须属于面板当前下发给该节点的用户。在面板中新增的用户会在下一次同步时到达 katana。
  • 时钟。 客户端时钟与服务器相差超过 120 秒时,VMess 认证会失败。

按 Ctrl-C,或发送 SIGTERM。katana 会输出 shutting down,关闭监听器,上报尚未上报的流量,然后以状态码 0 退出。

katana 运行期间会监视配置文件所在目录,并在不重启的情况下应用修改。这也包括 [node.api]:如果修改让节点指向面板中的另一个节点(例如新的 node_id),该节点会重启;其他 [node.api] 修改会立即生效。热重载说明了哪些修改会生效、哪些会断开连接。续期后的证书不会通过这种方式加载:katana 在启动监听器时读取证书文件,所以每次续期后都要重启 katana。