Agent 控制协议
状态:Current
最后核对:2026-05-30
协议定义在 common/proto/agent.proto,后端和 Agent 仓库各有一份。
服务
nexus-backend/src/main.rs 注册的生产服务是:
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_IDNEXUS_CONTROL_ENDPOINTNEXUS_CONTROL_PSKNEXUS_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_idpublic_ipv4public_ipv6agent_versionmultiplexmultiplex_portdetected_addresses
Heartbeat
Agent 发送节点 ID、sequence、timestamp、CPU/内存、uptime、peer link metrics,以及运行时 端口 listener/route 表。后端返回 ack 和可选命令:
RELOAD_CONFIGRESTART_PINGORARUN_DIAGNOSTICS
Config Streaming
生产 secure-control 路径使用 ConfigUpdate.runtime_snapshot 携带数据库权威 RuntimeConfigSnapshot。该快照把一个节点的以下运行时目标作为同一代际应用:
PingoraConfigL3TunnelConfigNodeConfig
Agent 会忽略旧快照代际,并用 ConfigApplyReport 回报每次快照应用结果。
完整的代际、重放、回滚和端口冲突设计见 运行时配置热重载。
旧兼容 ConfigUpdate 仍可携带:
PingoraConfig:当前 L4 gateway 配置 envelope。NodeConfig:节点连接设置。L3TunnelConfig:L3 隧道配置。
PingoraConfig 还携带 listener_policies,用于兼容性冲突处理:
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:
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_names 和 health_check_interval_ms,并拒绝 health_check_path。
Transport Profile
Transport profile 分离三层含义:
| 维度 | 枚举 |
|---|---|
| Payload | TCP / UDP / IP |
| Outer | TCP / UDP / QUIC / FAKE_TCP |
| Security | RAW / TLS / REALITY / NOISE |
通用 IP/TUN transport 由 QUIC REALITY 承载时使用 payload=IP、outer=QUIC、security=REALITY。 L4 UDP over FAKE_TCP 使用 payload=UDP、outer=FAKE_TCP、security=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.nxc、agent-state.previous.nxc 或 agent-state.json。
当前运行语义:
- 控制面在配置已应用后断开时,现有 listener 和 tunnel 继续使用进程内状态运行。
- Agent 进程重启后,会发送
config_version = 0的ConfigRequest,等待控制面权威 replay。 - Agent 启动时如果 backend 不可用,不会应用本地 last-known-good 配置。
当前 pin、replay、rekey 和 REALITY 轮换安全模型见安全加固。