# LayLink LayLink 是一个基于 PHP Workerman 的策略控制型四层反向访问网关。 它不是 VPN。客户端连接 Client Agent,请求访问某个 TCP 目标;Client Agent 使用 LayLink Frame 协议连接 POP Server;POP Server 负责认证、策略判断、连接公网目标和审计。 ## 当前节点类型 当前 MVP 分成 2 种核心类型: 1. `POP Server` 2. `Client Agent` ## 配置文件关系 `.env` 用来配置当前进程自己的运行参数。 `config/nodes.php` 用来声明 POP Server 认可哪些 Agent 节点,以及 Agent 的本地 allowlist。 `config/policies.php` 用来声明客户端访问策略。POP Server 根据这个文件决定某个用户是否允许访问某个目标,以及是否由 POP Server 直接连接公网目标。 `.env.example` 是示例模板。实际部署时建议复制为 `.env`,再按当前进程类型修改: ```bash cp .env.example .env ``` `.env.example` 中的 `[config]`、`[kcp]`、`[client-agent]`、`[pop-server]` 是阅读分组标题,当前加载器会忽略这些标题,只读取 `KEY=value` 配置行。 Agent 与 POP Server 之间的 LayLink Frame 支持加密: ```env LAYLINK_FRAME_ENCRYPTION=none LAYLINK_FRAME_ENCRYPTION_KEY= ``` 可选值: | 值 | 作用 | | --- | --- | | `none` | 不加密,开发调试默认值。 | | `chacha20` | 使用 libsodium XChaCha20 stream 对 Frame body 加密。 | 启用 `chacha20` 时,POP Server 和 Client Agent 必须配置完全相同的加密方式和密钥: ```env 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` 指令。 * 记录审计日志。 启动入口: ```bash php bin/pop-server.php start ``` POP Server 需要配置这些 `.env`: ```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 返回的目标数据并转发回本地客户端。 启动入口: ```bash php bin/client-agent.php start ``` Client Agent 需要配置这些 `.env`: ```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` 中声明同名节点: ```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 的应用可直接配置: ```text 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 转发路径: ```text 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`: ```php [ '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 用户名密码认证: ```env CLIENT_AGENT_SOCKS5_AUTH_MODE=userpass CLIENT_AGENT_SOCKS5_USERNAME=alice CLIENT_AGENT_SOCKS5_PASSWORD=change-this-password ``` 如果启用 raw-json,客户端连接 raw-json 端口并发送一行 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` 决定。 示例: ```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` 可以这样写: ```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` 控制允许哪些传输协议。例如: ```env POP_ALLOWED_AGENT_TRANSPORTS=tcp,kcp # 也可以写成: POP_ALLOWED_AGENT_TRANSPORTS=["tcp","kcp"] ``` Client Agent 用 `AGENT_TRANSPORT_PROTOCOL` 选择自己实际使用哪种协议。例如: ```env AGENT_TRANSPORT_PROTOCOL=kcp ``` 如果 Agent 选择的协议不在 POP 允许列表中,POP 会在认证阶段返回 `AUTH_FAIL`,原因是 `transport_not_allowed`。 `kcp` 默认使用 FFI 调用 native `ikcp.c`。首次使用前需要构建动态库: ```bash scripts/build-kcp-ffi.sh ``` 然后两端配置: ```env 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: ```bash php bin/pop-server.php start ``` 另一个终端启动 Client Agent: ```bash 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 建议保持一致: ```env 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: ```bash scripts/verify-socks5.sh ``` 默认使用 `127.0.0.1:1080`。如果启用了 SOCKS5 用户名密码: ```bash 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、限流和更完整的审计存储。