| bin | ||
| config | ||
| native/kcp | ||
| scripts | ||
| src | ||
| vendor | ||
| .env.example | ||
| .gitignore | ||
| composer.json | ||
| composer.lock | ||
| contract.md | ||
| problems.md | ||
| readme.md | ||
LayLink
LayLink 是一个基于 PHP Workerman 的策略控制型四层反向访问网关。
它不是 VPN。客户端连接 Client Agent,请求访问某个 TCP 目标;Client Agent 使用 LayLink Frame 协议连接 POP Server;POP Server 负责认证、策略判断、连接公网目标和审计。
当前节点类型
当前 MVP 分成 2 种核心类型:
POP ServerClient Agent
配置文件关系
.env 用来配置当前进程自己的运行参数。
config/nodes.php 用来声明 POP Server 认可哪些 Agent 节点,以及 Agent 的本地 allowlist。
config/policies.php 用来声明客户端访问策略。POP Server 根据这个文件决定某个用户是否允许访问某个目标,以及是否由 POP Server 直接连接公网目标。
.env.example 是示例模板。实际部署时建议复制为 .env,再按当前进程类型修改:
cp .env.example .env
.env.example 中的 [config]、[kcp]、[client-agent]、[pop-server] 是阅读分组标题,当前加载器会忽略这些标题,只读取 KEY=value 配置行。
Agent 与 POP Server 之间的 LayLink Frame 支持加密:
LAYLINK_FRAME_ENCRYPTION=none
LAYLINK_FRAME_ENCRYPTION_KEY=
可选值:
| 值 | 作用 |
|---|---|
none |
不加密,开发调试默认值。 |
chacha20 |
使用 libsodium XChaCha20 stream 对 Frame body 加密。 |
启用 chacha20 时,POP Server 和 Client Agent 必须配置完全相同的加密方式和密钥:
LAYLINK_FRAME_ENCRYPTION=chacha20
LAYLINK_FRAME_ENCRYPTION_KEY=change-this-long-random-secret
密钥支持普通口令,也支持 hex: 或 base64: 前缀的 32 字节原始密钥。
POP Server
POP Server 是控制面和转发入口。
它负责:
- 监听 Agent 长连接。
- 校验 Agent 的
NODE_ID和NODE_TOKEN。 - 校验客户端访问请求。
- 根据
config/policies.php选择路由。 - 向 Agent 下发
OPEN指令。 - 记录审计日志。
启动入口:
php bin/pop-server.php start
POP Server 需要配置这些 .env:
APP_ENV=dev
POP_AGENT_LISTEN=0.0.0.0:9001
POP_ALLOWED_AGENT_TRANSPORTS=tcp,kcp
POP_AGENT_TCP_WORKERS=1
POP_AGENT_KCP_WORKERS=1
AUDIT_LOG=runtime/audit.log
LOG_LEVEL=debug
配置说明:
| 变量 | 作用 | 常见值 |
|---|---|---|
APP_ENV |
当前运行环境。开发时使用 dev,生产可使用 prod。 |
dev、test、prod |
LAYLINK_FRAME_ENCRYPTION |
Agent 与 POP Server 之间 Frame 加密方式,两端必须一致。 | none、chacha20 |
LAYLINK_FRAME_ENCRYPTION_KEY |
Frame 加密密钥,启用 chacha20 时必填。 |
普通口令、hex:...、base64:... |
POP_AGENT_LISTEN |
POP Server 给 Client Agent 连接的监听地址。Agent 的 POP_SERVER_ADDRESS 应指向这里。 |
0.0.0.0:9001、127.0.0.1:9001 |
POP_ALLOWED_AGENT_TRANSPORTS |
POP Server 允许 Agent 使用的底层传输协议。支持逗号数组,也支持 JSON 数组。Agent 认证时会上报自己的选择,不在列表内会被拒绝。 | tcp、tcp,kcp、["tcp","kcp"] |
POP_AGENT_TCP_WORKERS |
POP TCP Agent listener 的 worker 数。TCP 模式可按 CPU 和并发提高。 | 1、2、4、8 |
POP_AGENT_KCP_WORKERS |
POP KCP/UDP Agent listener 的 worker 数。当前必须保持 1。 |
1 |
AUDIT_LOG |
审计日志路径。MVP 使用 JSON Lines 追加写入。 | runtime/audit.log |
LOG_LEVEL |
日志级别预留配置。当前 MVP 主要为后续日志工厂使用。 | debug、info、warning、error |
POP Server 通常不需要配置 NODE_ID、NODE_TYPE、NODE_TOKEN、POP_SERVER_ADDRESS。这些是 Agent 进程使用的。
Client Agent
Client Agent 部署在客户端侧,作为本机或局域网入口。
它负责:
- 主动出站连接 POP Server。
- 使用
NODE_ID、NODE_TYPE、NODE_TOKEN向 POP Server 认证。 - 维持心跳。
- 接收本地客户端连接。
- 将客户端请求和数据封装为 LayLink Frame。
- 通过选定的底层传输协议把 Frame 发送给 POP Server。
- 接收 POP Server 返回的目标数据并转发回本地客户端。
启动入口:
php bin/client-agent.php start
Client Agent 需要配置这些 .env:
APP_ENV=dev
NODE_ID=client-01
NODE_TYPE=client
NODE_TOKEN=CHANGE_ME
AGENT_TRANSPORT_PROTOCOL=tcp
CLIENT_AGENT_POP_CONNECTIONS=1
CLIENT_AGENT_AUTH_TOKEN=dev-token
CLIENT_AGENT_USER_ID=admin
CLIENT_AGENT_SOCKS5_ENABLED=true
CLIENT_AGENT_SOCKS5_LISTEN_IP=127.0.0.1
CLIENT_AGENT_SOCKS5_LISTEN_PORT=1080
CLIENT_AGENT_SOCKS5_UDP_LISTEN_IP=127.0.0.1
CLIENT_AGENT_SOCKS5_UDP_LISTEN_PORT=1081
CLIENT_AGENT_SOCKS5_UDP_ADVERTISE_IP=127.0.0.1
CLIENT_AGENT_SOCKS5_AUTH_MODE=no-auth
CLIENT_AGENT_SOCKS5_USERNAME=
CLIENT_AGENT_SOCKS5_PASSWORD=
CLIENT_AGENT_HTTP_PROXY_ENABLED=false
CLIENT_AGENT_HTTP_PROXY_LISTEN_IP=127.0.0.1
CLIENT_AGENT_HTTP_PROXY_LISTEN_PORT=8080
CLIENT_AGENT_RAW_JSON_ENABLED=false
CLIENT_AGENT_RAW_JSON_LISTEN_IP=127.0.0.1
CLIENT_AGENT_RAW_JSON_LISTEN_PORT=9000
POP_SERVER_ADDRESS=tcp://10.1.0.2:9001
LOG_LEVEL=debug
配置说明:
| 变量 | 作用 | 常见值 |
|---|---|---|
APP_ENV |
当前运行环境。 | dev、test、prod |
NODE_ID |
当前 Client Agent 的节点 ID。必须存在于 config/nodes.php。 |
client-01 |
NODE_TYPE |
当前节点类型。Client Agent 必须配置为 client。 |
client |
NODE_TOKEN |
当前节点认证密钥。必须和 config/nodes.php 中同一 NODE_ID 的 token 一致。 |
强随机字符串,开发时可临时用 CHANGE_ME |
AGENT_TRANSPORT_PROTOCOL |
当前 Agent 到 POP Server 使用的底层传输协议。必须被 POP Server 的 POP_ALLOWED_AGENT_TRANSPORTS 允许。 |
tcp、udp、kcp |
CLIENT_AGENT_POP_CONNECTIONS |
Client Agent 到 POP Server 的并行长连接数量。新 TCP 会话会在已认证连接间轮询分配,适合多并发请求或多线程测速。 | 1、2、4 |
CLIENT_AGENT_AUTH_TOKEN |
SOCKS5/HTTP 代理入口生成 OPEN 帧时使用的客户端认证 token。 |
dev-token,生产应替换 |
CLIENT_AGENT_USER_ID |
SOCKS5/HTTP 代理入口生成 OPEN 帧时使用的默认用户 ID。 |
admin、normal-user |
CLIENT_AGENT_SOCKS5_ENABLED |
是否启用 SOCKS5 本地入口。 | true、false |
CLIENT_AGENT_SOCKS5_LISTEN_IP |
SOCKS5 本地入口监听 IP,默认只允许本机访问。 | 127.0.0.1、0.0.0.0 |
CLIENT_AGENT_SOCKS5_LISTEN_PORT |
SOCKS5 本地入口监听端口。 | 1080 |
CLIENT_AGENT_SOCKS5_UDP_LISTEN_IP |
SOCKS5 UDP ASSOCIATE 本地 UDP relay 监听 IP。 | 127.0.0.1、0.0.0.0 |
CLIENT_AGENT_SOCKS5_UDP_LISTEN_PORT |
SOCKS5 UDP ASSOCIATE 本地 UDP relay 监听端口。 | 1081 |
CLIENT_AGENT_SOCKS5_UDP_ADVERTISE_IP |
UDP ASSOCIATE 回复给应用的 UDP relay IP。 | 127.0.0.1、Client Agent 局域网 IP |
CLIENT_AGENT_SOCKS5_AUTH_MODE |
SOCKS5 认证模式。no-auth 使用无认证,userpass 使用 RFC1929 用户名/密码认证。 |
no-auth、userpass |
CLIENT_AGENT_SOCKS5_USERNAME |
SOCKS5 用户名,仅 userpass 模式使用。 |
自定义用户名 |
CLIENT_AGENT_SOCKS5_PASSWORD |
SOCKS5 密码,仅 userpass 模式使用。 |
强随机密码 |
CLIENT_AGENT_HTTP_PROXY_ENABLED |
是否启用 HTTP 代理本地入口,支持 CONNECT 和普通 HTTP 绝对 URL 请求。 |
true、false |
CLIENT_AGENT_HTTP_PROXY_LISTEN_IP |
HTTP 代理本地入口监听 IP,默认只允许本机访问。 | 127.0.0.1、0.0.0.0 |
CLIENT_AGENT_HTTP_PROXY_LISTEN_PORT |
HTTP 代理本地入口监听端口。 | 8080、7890 |
CLIENT_AGENT_RAW_JSON_ENABLED |
是否启用 raw-json 调试入口。 | true、false |
CLIENT_AGENT_RAW_JSON_LISTEN_IP |
raw-json 调试入口监听 IP。 | 127.0.0.1 |
CLIENT_AGENT_RAW_JSON_LISTEN_PORT |
raw-json 调试入口监听端口。 | 9000 |
POP_SERVER_ADDRESS |
POP Server 的 Agent 监听地址。必须带 tcp://。 |
tcp://10.1.0.2:9001、tcp://127.0.0.1:9001 |
LOG_LEVEL |
日志级别预留配置。 | debug、info、warning、error |
Client Agent 的节点身份不是只写在 .env 中,POP Server 侧还必须在 config/nodes.php 中声明同名节点:
'client-01' => [
'node_type' => 'client',
'token' => 'CHANGE_ME',
'allowed_cidrs' => [
'192.168.0.0/16',
'10.10.0.0/16',
],
'allowed_ports' => [22, 80, 443, '8080-10080', 3306, 5432],
'enabled' => true,
],
当前 allowed_cidrs 和 allowed_ports 仍保留给后续 Agent 侧直连目标能力;新的最小路径会优先让 POP Server 直连公网目标。
当前 MVP 提供三种本地入口:
| 入口 | 默认状态 | 默认监听 | 适用场景 |
|---|---|---|---|
| SOCKS5 | 开启 | 127.0.0.1:1080 |
只能配置 SOCKS5 代理的应用。 |
| HTTP 代理 | 关闭 | 127.0.0.1:8080 |
支持 HTTP proxy 或 HTTP CONNECT 的应用。 |
| raw-json | 关闭 | 127.0.0.1:9000 |
开发调试,手工发送一行 JSON。 |
只能用 SOCKS5 的应用可直接配置:
SOCKS5 Host: 127.0.0.1
SOCKS5 Port: 1080
SOCKS5 当前支持:
| 能力 | 状态 |
|---|---|
| 方法协商 | 支持 |
无认证 0x00 |
支持 |
用户名/密码 0x02,RFC1929 |
支持 |
| IPv4 地址 | 支持 |
| 域名地址 | 支持 |
| IPv6 地址 | 支持 |
CONNECT |
支持 |
BIND |
按协议返回 command not supported |
UDP ASSOCIATE |
支持,经 LayLink UDP_DATA Frame 转发到 POP Server |
SOCKS5 UDP 转发路径:
App UDP
-> Client Agent UDP relay
-> UDP_DATA Frame over Agent transport
-> POP Server
-> Public UDP target
UDP 访问仍然由 POP Server 的 config/policies.php 控制。默认示例允许 53、123、443:
[
'policy_id' => 'public-udp-egress',
'users' => ['normal-user', 'admin', 'devops'],
'target_hosts' => ['*'],
'target_ports' => [53, 123, 443],
'protocol' => 'udp',
'route_type' => 'direct',
'enabled' => true,
],
启用 SOCKS5 用户名密码认证:
CLIENT_AGENT_SOCKS5_AUTH_MODE=userpass
CLIENT_AGENT_SOCKS5_USERNAME=alice
CLIENT_AGENT_SOCKS5_PASSWORD=change-this-password
如果启用 raw-json,客户端连接 raw-json 端口并发送一行 JSON:
{"auth_token":"dev-token","user_id":"admin","target_host":"example.com","target_port":443,"protocol":"tcp"}
字段说明:
| 字段 | 作用 | 常见值 |
|---|---|---|
auth_token |
客户端认证 token。当前 MVP 固定为 dev-token。 |
dev-token |
user_id |
用户身份。POP Server 会用它匹配 config/policies.php。 |
admin、devops、normal-user |
target_host |
目标主机。 | 192.168.10.20、example.com |
target_port |
目标端口。 | 22、80、443、8080、5432 |
protocol |
目标协议。当前只支持 TCP。 | tcp |
route_hint |
预留字段。新的最小路径由 POP Server 直连公网目标,通常不需要填写。 | null |
策略如何配置
客户端访问是否允许,由 config/policies.php 决定。
示例:
[
'policy_id' => 'public-web-egress',
'users' => ['normal-user', 'admin', 'devops'],
'target_hosts' => ['*'],
'target_ports' => [80, 443, '8080-10080'],
'protocol' => 'tcp',
'route_type' => 'direct',
'enabled' => true,
],
这条策略表示:
normal-user、admin和devops可以访问任意主机的80、443,以及8080到10080端口。- Client Agent 只负责把请求封装成 Frame 发到 POP Server。
- POP Server 校验策略后直接连接公网目标。
target_ports 和 allowed_ports 都支持两种写法:
- 单端口:
80 - 端口范围:
'8080-10080'
路由类型:
route_type |
作用 |
|---|---|
direct |
POP Server 直接连接目标,适合公共互联网出口。 |
reject |
拒绝访问。默认行为就是拒绝。 |
本地开发示例
一个最小本地开发 .env 可以这样写:
APP_ENV=dev
POP_AGENT_LISTEN=127.0.0.1:9001
POP_ALLOWED_AGENT_TRANSPORTS=tcp,kcp
NODE_ID=client-01
NODE_TYPE=client
NODE_TOKEN=CHANGE_ME
AGENT_TRANSPORT_PROTOCOL=tcp
CLIENT_AGENT_AUTH_TOKEN=dev-token
CLIENT_AGENT_USER_ID=admin
CLIENT_AGENT_SOCKS5_ENABLED=true
CLIENT_AGENT_SOCKS5_LISTEN_IP=127.0.0.1
CLIENT_AGENT_SOCKS5_LISTEN_PORT=1080
CLIENT_AGENT_SOCKS5_UDP_LISTEN_IP=127.0.0.1
CLIENT_AGENT_SOCKS5_UDP_LISTEN_PORT=1081
CLIENT_AGENT_SOCKS5_UDP_ADVERTISE_IP=127.0.0.1
CLIENT_AGENT_SOCKS5_AUTH_MODE=no-auth
CLIENT_AGENT_SOCKS5_USERNAME=
CLIENT_AGENT_SOCKS5_PASSWORD=
CLIENT_AGENT_HTTP_PROXY_ENABLED=false
CLIENT_AGENT_HTTP_PROXY_LISTEN_IP=127.0.0.1
CLIENT_AGENT_HTTP_PROXY_LISTEN_PORT=8080
CLIENT_AGENT_RAW_JSON_ENABLED=false
CLIENT_AGENT_RAW_JSON_LISTEN_IP=127.0.0.1
CLIENT_AGENT_RAW_JSON_LISTEN_PORT=9000
POP_SERVER_ADDRESS=tcp://127.0.0.1:9001
AUDIT_LOG=runtime/audit.log
LOG_LEVEL=debug
Agent 到 POP 的传输协议
Agent 到 POP Server 的业务数据始终使用 LayLink 自定义 Frame 协议封装。AGENT_TRANSPORT_PROTOCOL 只决定这些 Frame 运行在哪种底层传输上。
当前规划的传输类型:
| 值 | 含义 | 当前状态 |
|---|---|---|
tcp |
Frame over TCP,最容易部署和调试。 | 已实现 |
udp |
Frame over UDP,需要额外处理可靠性、顺序和丢包。 | 已预留,未实现 |
kcp |
Frame over KCP/UDP,默认通过 FFI 调用 native ikcp.c。 |
已实现,需构建动态库 |
POP Server 用 POP_ALLOWED_AGENT_TRANSPORTS 控制允许哪些传输协议。例如:
POP_ALLOWED_AGENT_TRANSPORTS=tcp,kcp
# 也可以写成:
POP_ALLOWED_AGENT_TRANSPORTS=["tcp","kcp"]
Client Agent 用 AGENT_TRANSPORT_PROTOCOL 选择自己实际使用哪种协议。例如:
AGENT_TRANSPORT_PROTOCOL=kcp
如果 Agent 选择的协议不在 POP 允许列表中,POP 会在认证阶段返回 AUTH_FAIL,原因是 transport_not_allowed。
kcp 默认使用 FFI 调用 native ikcp.c。首次使用前需要构建动态库:
scripts/build-kcp-ffi.sh
然后两端配置:
LAYLINK_KCP_BACKEND=ffi
LAYLINK_KCP_FFI_LIB=native/kcp/liblaylink_kcp.so
使用 kcp 时,POP Server 会在 POP_AGENT_LISTEN 的同一 host:port 上监听 UDP,Client Agent 的 POP_SERVER_ADDRESS 仍填写同一地址即可。服务器防火墙需要放行同端口 UDP。
如果运行环境暂时不能启用 FFI,可以配置 LAYLINK_KCP_BACKEND=php 使用调试回退实现;该实现不适合作为生产高吞吐路径。
KCP 可调参数:
| 变量 | 作用 | 建议 |
|---|---|---|
LAYLINK_KCP_NODELAY |
KCP nodelay 开关。 | 默认 1 |
LAYLINK_KCP_INTERVAL_MS |
KCP update 间隔,越小越低延迟但发包/CPU 更高。 | 10、20、30 |
LAYLINK_KCP_FAST_RESEND |
快速重传阈值。 | 2,拥堵时试 3、4 |
LAYLINK_KCP_NO_CONGESTION_CONTROL |
是否关闭 KCP 拥塞控制。 | 公网建议 0,内网压测可试 1 |
LAYLINK_KCP_SEND_WINDOW |
KCP 发送窗口。 | 128、256、512 |
LAYLINK_KCP_RECV_WINDOW |
KCP 接收窗口。 | 256、512、1024 |
LAYLINK_KCP_MTU_BYTES |
KCP MTU。 | 公网建议 1200,内网可试 1350 |
LAYLINK_KCP_TICK_MS |
PHP transport tick 间隔。 | 通常等于 LAYLINK_KCP_INTERVAL_MS |
LAYLINK_KCP_UDP_SEND_QUEUE_BYTES |
UDP 发送遇到 EAGAIN 时的本地排队上限。 | 16777216、33554432 |
LAYLINK_KCP_UDP_FLUSH_PACKETS |
每次 tick 最多刷出的 UDP packet 数。 | 拥堵时 64/128,吞吐压测 256/512 |
LAYLINK_KCP_OUTPUT_DRAIN_PACKETS |
每次从 native KCP 输出队列搬到 UDP 发送队列的最大 packet 数。 | 延迟敏感用 64/128,吞吐压测用 256/512 |
如果出现 stream_socket_sendto(): Resource temporarily unavailable,说明 UDP socket 发送缓冲暂时满了。LayLink 会把 KCP packet 放入本地发送队列并在后续 tick 重试;同时建议把 LAYLINK_KCP_NO_CONGESTION_CONTROL 保持为 0,必要时降低 LAYLINK_KCP_SEND_WINDOW、LAYLINK_KCP_UDP_FLUSH_PACKETS 或调大 LAYLINK_KCP_INTERVAL_MS。
KCP/UDP 目前不要把 POP_AGENT_KCP_WORKERS 调大。KCP 会话状态存在单个 worker 进程里,UDP 多 worker 会让同一个会话的数据包分散到不同进程,导致找不到会话、重传增加甚至断流。要横向扩展 KCP,当前推荐启动多个 POP 端口或多个 POP 实例,由 Client Agent 配置多 POP/多进程策略;后续可以做 SO_REUSEPORT 五元组哈希、外部 session 表或每 conv 固定 worker 分发。
单 worker 并不等于一个大下载会同步阻塞其他请求:目标连接、UDP socket 和本地客户端都是非阻塞 I/O。但大文件会带来大量 KCP 分片和加密/解密/FFI 调用,可能短时间占用事件循环 CPU。延迟敏感场景可降低 LAYLINK_DATA_CHUNK_BYTES、LAYLINK_KCP_OUTPUT_DRAIN_PACKETS 和 LAYLINK_KCP_UDP_FLUSH_PACKETS,让一个大流量会话每次 tick 少占一点时间,换取更好的多会话公平性。
如果 Agent 配置为 udp,进程会启动失败并明确提示该传输尚未实现。
启动 POP Server:
php bin/pop-server.php start
另一个终端启动 Client Agent:
php bin/client-agent.php start
然后把应用的代理设置为 SOCKS5 127.0.0.1:1080。Client Agent 会解析 SOCKS5 CONNECT,封装成 OPEN 帧发给 POP Server;POP Server 校验通过后直连公网目标,随后通过 DATA 帧转发原始 TCP 数据。
TCP 大流量 DATA 帧使用二进制帧编码;AUTH、OPEN、CLOSE、ERROR 等控制帧仍使用 JSON 编码。启用 chacha20 时,二进制和 JSON Frame body 都会被加密。
吞吐相关参数由两端共用,POP Server 和 Client Agent 建议保持一致:
LAYLINK_DATA_CHUNK_BYTES=1048576
LAYLINK_MAX_SEND_BUFFER_BYTES=67108864
LAYLINK_BACKPRESSURE_HIGH_WATERMARK_BYTES=33554432
LAYLINK_DATA_CHUNK_BYTES 越大,每 MB 需要处理的 Frame 越少,单连接下载通常越快;如果多会话公平性变差,可以降到 262144 或 524288。LAYLINK_BACKPRESSURE_HIGH_WATERMARK_BYTES 必须小于 LAYLINK_MAX_SEND_BUFFER_BYTES。
大文件下载时,LayLink 会使用 Workerman 的 pauseRecv() / resumeRecv() 做背压:当下游发送缓冲区过高时暂停上游读取,缓冲排空后继续读取。这可以避免单个慢连接无限堆积内存或因为发送缓冲区满而断联。
当 POP 收到目标站关闭连接时,Client Agent 会先等待本地客户端发送缓冲区排空,再关闭本地 socket,避免大文件尾部数据还在缓冲区里时被提前截断。TCP DATA 默认按 1 MiB 分片发送,以减少帧开销;可通过 LAYLINK_DATA_CHUNK_BYTES 调整。
Client Agent 默认使用 1 条 Agent-to-POP TCP 长连接。可通过 CLIENT_AGENT_POP_CONNECTIONS 增加并行长连接数,新 TCP 会话会在已认证 POP 连接之间轮询分配,并在会话生命周期内固定使用同一条连接。它主要改善多并发请求、多线程下载或测速场景;单个 TCP 下载是否变快取决于客户端和目标站是否本身使用多连接。背压可以保护进程不堵死,但单条会话仍受单 TCP 流限制;KCP、per-session window 和更细粒度 TCP 调优仍是后续性能优化方向。
验证 SOCKS5 HTTPS 联通性和出口 IP:
scripts/verify-socks5.sh
默认使用 127.0.0.1:1080。如果启用了 SOCKS5 用户名密码:
SOCKS5_USER=alice SOCKS5_PASSWORD=change-this-password scripts/verify-socks5.sh
部署检查清单
部署前至少确认:
NODE_TOKEN已替换为强随机密钥。config/nodes.php中的token和 Agent.env中的NODE_TOKEN一致。NODE_TYPE和config/nodes.php中的node_type一致。- Agent 的
allowed_cidrs和allowed_ports足够窄。 config/policies.php不存在过宽的target_hosts和target_ports。- 生产环境不要继续使用固定的
dev-token客户端认证。 - 生产环境应补充 TLS、JWT 或 mTLS、限流和更完整的审计存储。