Skip to content

Agent 控制协议

状态:Current

最后核对:2026-05-30

协议定义在 common/proto/agent.proto,后端和 Agent 仓库各有一份。

服务

nexus-backend/src/main.rs 注册的生产服务是:

protobuf
service SecureAgentService {
  rpc OpenSession(OpenSessionRequest) returns (OpenSessionResponse);
  rpc Control(stream SecureFrame) returns (stream SecureFrame);
}

AgentService RPC 仍留在 protobuf 中用于兼容和测试,但不是当前后端入口注册的生产服务。

Secure Session

Agent 使用 h2c gRPC 连接后端,然后打开 Nexus secure control session。环境变量:

  • NEXUS_AGENT_ID
  • NEXUS_CONTROL_ENDPOINT
  • NEXUS_CONTROL_PSK
  • NEXUS_CONTROL_REKEY_INTERVAL_SECS(可选;默认 6 小时)

OpenSession 使用每节点 PSK verifier 和临时密钥交换认证节点。后端保存 verifier 和 fingerprint,不保存明文 PSK。会话建立后,控制消息放在 AEAD 保护的 SecureFrame 中。

Agent 会在配置的 rekey interval 后主动重连 secure control session。即使 stream 长时间健康,也会周期性重新派生 session key。

Agent Hello

首个加密 payload 包含:

  • node_id
  • public_ipv4
  • public_ipv6
  • agent_version
  • multiplex
  • multiplex_port
  • detected_addresses

Heartbeat

Agent 发送节点 ID、sequence、timestamp、CPU/内存、uptime、peer link metrics,以及运行时 端口 listener/route 表。后端返回 ack 和可选命令:

  • RELOAD_CONFIG
  • RESTART_PINGORA
  • RUN_DIAGNOSTICS

Config Streaming

生产 secure-control 路径使用 ConfigUpdate.runtime_snapshot 携带数据库权威 RuntimeConfigSnapshot。该快照把一个节点的以下运行时目标作为同一代际应用:

  • PingoraConfig
  • L3TunnelConfig
  • NodeConfig

Agent 会忽略旧快照代际,并用 ConfigApplyReport 回报每次快照应用结果。

完整的代际、重放、回滚和端口冲突设计见 运行时配置热重载

旧兼容 ConfigUpdate 仍可携带:

  • PingoraConfig:当前 L4 gateway 配置 envelope。
  • NodeConfig:节点连接设置。
  • L3TunnelConfig:L3 隧道配置。

PingoraConfig 还携带 listener_policies,用于兼容性冲突处理:

protobuf
message ListenerPolicy {
  string transport = 1;      // "tcp" 或 "udp";QUIC 使用 UDP namespace
  string listen_addr = 2;
  int32 listen_port = 3;
  repeated string priority_order = 4; // reality,tls,noise,raw
}

Agent 只在无法合并到同端口 route table 的兼容场景使用这些策略。TCP REALITY/TLS/SSLPREREAD 加一个 RAW fallback 可以共用一个 TCP SNI-family listener;UDP Noise、一个 UDP RAW fallback 和嵌入式 QUIC REALITY route 在早期包信号明确时可以共用一个 UDP socket。

运行时 listener heartbeat protobuf:

protobuf
message HeartbeatRequest {
  string node_id = 1;
  uint64 sequence = 2;
  google.protobuf.Timestamp timestamp = 3;
  double cpu_usage = 4;
  double memory_usage = 5;
  uint64 uptime_seconds = 6;
  repeated LinkMetric link_metrics = 7;
  repeated RuntimeListener runtime_listeners = 8;
}

message RuntimeListener {
  string transport = 1;
  string listen_addr = 2;
  int32 listen_port = 3;
  string state = 4;
  repeated RuntimeRoute routes = 5;
  uint64 bytes_in = 6;
  uint64 bytes_out = 7;
  uint64 active_sessions = 8;
  uint64 total_sessions = 9;
  uint64 error_sessions = 10;
}

message RuntimeRoute {
  string service = 1;
  string payload = 2;
  string outer = 3;
  string security = 4;
  string match_kind = 5;
  string match_value = 6;
  string next_hop = 7;
}

UpstreamCluster 这个 protobuf 结构比控制台里的 L4 upstream CRUD 更宽。 控制协议里仍保留 health_check 子消息用于运行时兼容;控制台 REST API 已改为直接暴露 server_nameshealth_check_interval_ms,并拒绝 health_check_path

Transport Profile

Transport profile 分离三层含义:

维度枚举
PayloadTCP / UDP / IP
OuterTCP / UDP / QUIC / FAKE_TCP
SecurityRAW / TLS / REALITY / NOISE

通用 IP/TUN transport 由 QUIC REALITY 承载时使用 payload=IPouter=QUICsecurity=REALITY。 L4 UDP over FAKE_TCP 使用 payload=UDPouter=FAKE_TCPsecurity=RAW

封包格式见 FAKE_TCP 封包格式,数据面行为见 FAKE_TCP 数据面模式

规则安全字段

TcpProxyRule 当前支持:

  • RAW/TLS/REALITY mode。
  • inbound REALITY private key 和 metadata。
  • outbound/upstream REALITY。
  • outbound/upstream QUIC REALITY。
  • upstream TLS SPKI SHA-256 pins:upstream_tls_spki_pins_sha256
  • transport profile。

启用 upstream TLS 时,Agent 要求至少一个 SPKI pin,并对叶子证书 SubjectPublicKeyInfo DER 计算 SHA-256 进行比对。普通业务 upstream TLS 不使用 no-verify。

配置 Replay 和重启行为

Agent 不再持久化本地 L4/L3 配置 cache 文件,也不再读写 agent-state.nxcagent-state.previous.nxcagent-state.json

当前运行语义:

  • 控制面在配置已应用后断开时,现有 listener 和 tunnel 继续使用进程内状态运行。
  • Agent 进程重启后,会发送 config_version = 0ConfigRequest,等待控制面权威 replay。
  • Agent 启动时如果 backend 不可用,不会应用本地 last-known-good 配置。

当前 pin、replay、rekey 和 REALITY 轮换安全模型见安全加固

NexusNet documentation