Files
LinkPort/docs/network-proxies.md
曾志威 9da95beb42
continuous-integration/drone Build is failing
feat: refine management UI, connection diagnostics and local startup
Migrate the workspace to React and Ant Design, improve account forms and responsive layouts, support outbound diagnostics and SSH fingerprint confirmation, and persist the management startup port. Preserve database migrations, remove S3 settings storage, and improve gateway audit handling.
2026-10-13 19:43:23 +08:00

10 KiB
Raw Permalink Blame History

网络代理管理

SSH 指纹自动展示与确认保存(2026-10-07)

用户无需知道或手填指纹。首次保存 SSH 代理时,页面自动探测主机公钥并显示服务器地址与完整 SHA256 指纹;点击“确认指纹并保存”提交确认及配置,继续启用严格主机身份校验。已保存的指纹变化时同时显示新旧指纹,按钮为“确认新指纹并保存”。探测不发送用户名/密码,确认前不创建或更新代理。

地址/端口变化或探测过期需要重新探测确认;修改用户名/密码不会无故清除当前探测结果。已保存的严格校验主机身份不变时,普通编辑不要求重复确认。新代理从 SOCKS5 默认端口切换到 SSH 时使用 22;自定义端口保留。指纹不再提供普通手填输入,仍可查看已保存值。后端原有会话、端点、指纹、有效期和保存基线绑定继续生效,不自动跳过验证。

代理表单交互(2026-10-07)

新建/编辑代理及测试结果使用工作区页面,替代弹框;测试成功/失败颜色和范围说明保留。认证方式使用下拉,SOCKS5 可选无需认证/用户名密码,SSH 仅支持用户名密码;无需认证时隐藏凭据输入。Kubeconfig 资产按名称选择,不再手输 ID。缺失认证凭据会在保存按钮附近显示中文校验错误,服务端失败也保留在当前页面;编辑已保存密码时仍允许留空保留。无协议/API/数据库变更。

各类型代理测试(2026-10-06)

测试结果使用独立弹窗:蓝色“测试中”、绿色“测试成功”、红色“测试失败”,同时显示状态图标与文字,支持当前浅深主题。成功保留测试范围及详细结果,失败显示错误原因;重新测试清除旧结果,只有明确 valid/authenticated 成功标志才显示绿色。影响范围弹窗不再与测试结果混用。

所有代理均可调用 POST /api/v1/outbounds/:id/test。按用户进一步要求,增加 SOCKS5 与 Kubernetes 测试,替代此前仅提示前往关联目标测试的行为。

类型 操作 测试范围
SOCKS5 SOCKS5 握手测试 连接代理,执行 SOCKS5 方法协商及配置的用户名/密码认证,随后断开;不发送 CONNECT 请求
SSH SSH 连接测试 SSH 握手、主机身份检查及认证
Kubernetes Kubernetes 权限测试 使用保存的 Kubeconfig/凭据资产访问集群 API,通过 SelfSubjectAccessReview 检查所配置资源的读取、必要的 Pod 列表及端口转发权限
sing-box 校验配置 调用 sing-box 检查配置;不代表实际出站连通

SOCKS5 测试最长 10 秒,Kubernetes 请求最长 8 秒,客户端取消时终止请求。Kubernetes 拒绝权限或无法确认权限均返回 422,不误报成功;不返回任意上游响应或凭据。新测试只接受空对象参数,不修改保存配置。Kubernetes 权限检查不验证资源存在、Pod 就绪或实际端口转发;完整目标连接仍从目标服务测试。成功结果带 scope 和中文测试范围说明。

验证使用本机 SOCKS5 TCP fixture、Kubernetes HTTPS fixture 和临时配置库,覆盖握手/认证、取消、权限允许/拒绝、API 不可用及凭据不泄露;没有真实上游代理验收。最终构建、浏览器和全量 Go 结果见 测试记录。

当前格式限制(2026-10-06)

目标不再把内联 SOCKS5/SSH 配置自动转为共享代理。创建或修改时应先保存代理,再提交 outboundId;旧内联修改返回 400,现有共享配置保持原样。数据库与配置包版本门槛见 SQLite 存储。

内联 Kubernetes 和旧 TCP 模式删除受到自动审批阻挡,相关路径暂留;旧数据库按最新要求保留启动迁移,旧外部配置包仍不直接导入。

目的与入口

「代理管理 → 新建代理」用于管理网络连通方式。页面顶部直接选择 Kubeconfig、SSH、SOCKS5 或 sing-box,随后填写名称、环境及该类型的连接配置。不再显示文件资产/连接资产分类,也不提供通用文件管理列表。新建和编辑仍使用工作区独立页面。

Kubeconfig 与 SSH、SOCKS5 一样是独立保存、可被多个服务引用的代理。Kubeconfig 文件的上传是配置代理凭据的一步:在代理内选择或「上传 Kubeconfig」,再确定 Context、命名空间与固定资源。SSH 私钥、证书等也仍在需要它们的表单中选择或上传。已有文件通过资源搜索、引用跳转及配置历史继续维护,不删除文件或丢弃凭据。

React 代理编辑字段(2026-10-06)

当前 React「代理管理 → 代理配置」的新建和编辑弹窗按代理类型显示连接字段:SOCKS5 只显示代理主机、端口、用户名、密码和认证方式;SSH 在这些字段之外显示主机指纹及探测/确认操作;Kubernetes 只显示 Kubeconfig 资产 ID、命名空间、资源和 Context;sing-box 通过高级 JSON 的 singBoxOutbound 参数配置,不显示其他类型的连接字段。名称、环境、项目、备注仍为共享信息。

原因是原 React 编辑器无条件渲染所有类型字段,导致 SOCKS5 下出现 Kubernetes 和 SSH 配置。独立 OutboundFields 组件现在按类型选择字段。切换类型只改变可见字段,保留当前草稿,切回时可继续编辑;高级 JSON 输入成为有效对象时同步字段值及类型,未输入完成的 JSON 保留原文。已有秘密留空保留、后端类型校验和引用保护继续生效。HTTP API、存储格式不变,无数据迁移。

实际验证:前端 TypeScript/Vite 生产构建和 Go 1.27.1 新嵌入程序 bin/dev-build/outbound-fields/linkport.exe 成功,web/dist/.gitkeep 保留。使用 LINKPORT_E2E_BINARY、18751/18752 端口及临时 SQLite 运行 outbound-fields、react-migration、ui-domain,15/15 通过(20.8 秒),覆盖四种类型字段隔离、下拉/JSON 类型切换、草稿保留、SOCKS5 真实管理 API 保存与编辑空密码保留。没有连接真实 SOCKS5、SSH 或 Kubernetes 服务器,也未部署或修改真实数据。完整套件使用隔离 18753/18754 端口、max-failures=1、15 秒超时:旧 account-editor 依赖 Vue .target-card 而失败,147 项未运行,日志见 bin/dev-build/outbound-fields/playwright-suite.log。前端构建仍有 Node 22.10.0 版本和大 chunk 提示;本轮未修改 Go 逻辑,未重复 Go 测试/vet。

关联服务

使用方 关联方式 目的地址与端口
目标服务 连接方式中先选类型,再选择已保存代理;直连单独选择 目标保存服务地址、端口及业务账号。Kubeconfig 固定资源不要求普通主机地址;TLS 校验仍使用目标域名
普通协议网关 每个网关账号关联目标账号,并沿用该目标选择的代理 沿用目标服务配置,不增加另一份覆盖代理
TCP 纯端口转发网关 直接选择代理类型和已保存代理,无需目标服务 SSH/SOCKS5/sing-box 填目的地址及端口;Kubeconfig 使用代理固定资源,只填资源端口

代理拥有网络认证信息,目标账号仍属于目标,客户端账号仍属于网关。类型按钮只决定候选代理范围;仅选择类型未选择有效代理时阻止保存。已引用代理失效时显示不可用,不能静默退回直连。代理选择器按类型列出全部范围的配置,维持已有跨项目/环境引用行为。

Kubernetes Pod/Deployment/StatefulSet 使用容器 TCP 端口,Service 使用 Service 端口,运行时解析 targetPort。固定资源不会自动识别数据库主节点,也不提供数据库多节点发现。权限预检只表示授权检查结果;实际网络、资源状态及业务认证需要连接测试。

API 与保护

代理继续使用 /api/v1/outbounds,目标通过 outboundId 引用。TCP 纯端口转发增加以下引用形式:

{
  "type": "tcp",
  "tcpForward": {
    "mode": "proxy",
    "outboundId": "saved-proxy-id",
    "host": "destination.internal",
    "port": 8080
  }
}

Kubeconfig 代理的 host 应为空或省略,资源信息由代理提供;不能同时提交独立的 kubeConfigAssetId/context/namespace/resource。网关只持久化引用及端口,不复制代理密码、Kubeconfig 正文或 sing-box JSON。保存、列表、单条读取、连接测试和导入都解析引用并校验兼容性;管理响应不返回秘密正文。

引用保护覆盖 Kubeconfig → 代理 → 目标/网关:有引用时禁止删除,关联网关运行时阻止修改共享代理及文件。修改代理类型会重新校验引用网关,不能使旧 SOCKS5 网关使用其他类型。SSH 主机指纹确认与会话绑定、凭据加密、配置历史脱敏、完整加密备份保持。

兼容与验证

2026-10-06 按最新要求保留数据库迁移:启动将旧目标内联代理转为共享引用,将旧 TCP 空 mode/SOCKS5 转为 proxy,并将 TCP 内联 K8s 转为共享 Kubernetes 代理;重复重开不会重复生成代理。前端独立 Kubernetes/TCP 兼容入口的删除仍被自动审批拦截,暂时保留。旧执行程序不识别新增 tcpForward.mode="proxy",回退前应使用适配旧版本的备份并核对配置。本次仅在临时库验证,没有迁移真实数据。

新增 model/store/API 测试覆盖四种代理引用、持久化重开、备份导入、脱敏、间接引用及运行保护;本地 SOCKS5 fixture 验证字节转发。前端逻辑覆盖类型切换、未选/丢失引用、K8s 无 host 和旧配置兼容。实际命令、全量结果及生产构建/浏览器限制见 测试记录。没有将 fixture 结果当作真实 Kubernetes、SSH 或 sing-box 服务器验收。

代理编辑缺项提示(2026-10-07)

代理保存前显示名称、主机、端口、认证凭据或 Kubernetes 资产/资源的具体问题,并标红、定位输入。名称为空时保存按钮不再静默禁用;SSH 指纹仍自动获取后等待用户确认,不要求手填。SOCKS5 用户名/密码按 255 个 UTF-8 字节限制,编辑时已保存密码留空保留;高级 JSON 格式错误定位到编辑框。探测和保存请求失败在当前页显示原因,保留草稿。

本次没有变更代理 API、数据格式或数据库迁移。31 项当前前端专项通过,包含 SOCKS5 保存后编辑保留密码、Kubernetes 缺项和 SSH 指纹确认;使用 HTTP fixtures 及隔离管理 API,不代表真实上游服务器连通性验证。详见 testing.md 的 2026-10-07 记录。