diff --git a/config/env.example b/config/env.example index 8cddffc7f7721572608ece2593a6705e7e73b8fe..278bf3dcf2d93b5eef3354c95dab168d223bdaff 100644 --- a/config/env.example +++ b/config/env.example @@ -173,6 +173,10 @@ MSG_ETL=ip://127.0.0.1:7779 # footstone 服务端口(宿主机映射端口,容器内实际监听端口由 trpc_go.yaml.template 决定) # 默认使用非标准端口以避免与宿主机已有服务(20000/7778/20001)冲突 +# 安全(issue #IK49NP):FOOTSTONE_TRPC_PORT 对应的 17778 端口仅绑定 127.0.0.1, +# 不对外暴露;tRPC filter 链被 AllowTrpc 放过,外部网络若可达 17778 即可绕过 +# tm-userpassword/tm-permission 鉴权调用任意 RPC。管理面所有外部访问请走 HTTP 网关 +# (FOOTSTONE_HTTP_PORT=21000),由网关统一鉴权后再转发到内部 tRPC。 FOOTSTONE_HTTP_PORT=21000 FOOTSTONE_TRPC_PORT=17778 FOOTSTONE_WS_PORT=21001 diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index 37a0aafcb971e57f76125dde53c98e4d5066e7f0..5ec5a53f740530acec463e47d5156b68ae7e3c82 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -257,6 +257,12 @@ cd manager/backend/services/sysdiagnose/bin > 通过 Docker 内部网络访问。本地二进制运行没有这层映射,`trpc_go.yaml` 直接 > 按 `.env` 中的值监听,即上表数值。 +> **安全(issue #IK49NP)**:footstone tRPC `17778` 的 filter 链被 `AllowTrpc` +> 放过,外部网络若可达即可绕过 `tm-userpassword`/`tm-permission` 鉴权调用任意 +> RPC。`docker-compose.yml` 已将其宿主机映射改为 `127.0.0.1:17778:17778`, +> **仅本机可达,不对外暴露**;外部管理请求请走 HTTP 网关(`21000`)。本地二进制 +> 运行若监听到非回环地址,请通过 `trpc_go.yaml` 显式绑定 `127.0.0.1`。 + ### 步骤 6:启动前端开发服务器 ```bash diff --git a/docs/reference/env-variables.md b/docs/reference/env-variables.md index 4f30ac5fdfe7c9785161af26335adcd7cb536688..ade832613316fd2b280ef7cf72d87a164663a1a1 100644 --- a/docs/reference/env-variables.md +++ b/docs/reference/env-variables.md @@ -64,8 +64,8 @@ | 变量 | 默认 | 消费者 | 说明 | |------|------|--------|------| -| `FOOTSTONE_HTTP_PORT` | `21000` | docker-compose | footstone HTTP 网关映射 | -| `FOOTSTONE_TRPC_PORT` | `17778` | docker-compose | footstone tRPC | +| `FOOTSTONE_HTTP_PORT` | `21000` | docker-compose | footstone HTTP 网关映射(外部管理面入口,由 `tm-userpassword`/`tm-permission` 鉴权) | +| `FOOTSTONE_TRPC_PORT` | `17778` | docker-compose | footstone tRPC(**仅绑定 `127.0.0.1`,不对外暴露**,issue #IK49NP) | | `FOOTSTONE_WS_PORT` | `21001` | docker-compose | footstone WebSocket | | `SYSDIAGNOSE_HTTP_PORT` | `21006` | docker-compose | sysdiagnose HTTP 网关 | | `FRONTEND_PORT` | `13070` | docker-compose | 前端 nginx | diff --git a/manager/backend/pkg/plugin/permission/plugin.go b/manager/backend/pkg/plugin/permission/plugin.go index 5ed49b75091124279fe064063278539a0fae35f6..daf3f297109c342919700237f7cba83ef9bfe113 100644 --- a/manager/backend/pkg/plugin/permission/plugin.go +++ b/manager/backend/pkg/plugin/permission/plugin.go @@ -305,6 +305,13 @@ func (c *Config) PullAllowPath() error { } // AllowTrpc @Description: 放过trpc请求 +// +// 安全说明(issue #IK49NP):纯 tRPC 协议请求(无 HTTP head)会绕过 +// tm-userpassword / tm-permission 过滤器。这是当前内部服务间调用的设计前提 +// (如 sysdiagnose -> footstone,无用户 JWT)。因此 tRPC 端口(17778)必须 +// 仅在受信网络内可达,不得对外暴露——见 docker-compose.yml 中 127.0.0.1 绑定。 +// 后续若要对 tRPC 也做鉴权,需引入服务间身份机制(mTLS / 服务账号 token), +// 并改造 verifyToken 与 GetPath 以支持从 tRPC metadata 取 token 与 RPC 名。 func AllowTrpc(ctx context.Context) bool { var head *trpcHttp.Header if head = trpcHttp.Head(ctx); head == nil { diff --git a/manager/deployments/compose/README.md b/manager/deployments/compose/README.md index 4f66e7f11e421eb004dd7e1e2d225bbf1fda8eeb..61dc7329ae1705730a5e5cf991aa80c284e115dc 100644 --- a/manager/deployments/compose/README.md +++ b/manager/deployments/compose/README.md @@ -33,12 +33,19 @@ bash scripts/deploy.sh | ClickHouse HTTP | 8123 | **18123** | `CLICKHOUSE_HTTP_PORT` | | ClickHouse TCP | 9000 | **19000** | `CLICKHOUSE_TCP_PORT` | | footstone HTTP | — | **21000** | `FOOTSTONE_HTTP_PORT` | -| footstone tRPC | — | **17778** | `FOOTSTONE_TRPC_PORT` | +| footstone tRPC | — | **17778**(仅 `127.0.0.1`,不对外) | `FOOTSTONE_TRPC_PORT` | | sysdiagnose HTTP | — | **21006** | `SYSDIAGNOSE_HTTP_PORT` | | 前端 | 80 | **13070** | `FRONTEND_PORT` | > 如仍有冲突,修改 `config/.env` 对应的 `*_PORT` 变量即可,容器内端口无需改动。 +> **安全(issue #IK49NP)**:`FOOTSTONE_TRPC_PORT=17778` 的 filter 链被 `AllowTrpc` +> 放过(纯 tRPC 请求无 HTTP head 即返回 true),`docker-compose.yml` 已将宿主机 +> 映射改为 `127.0.0.1:17778:17778`,**仅本机可达,不对外暴露**。容器间内部调用 +> 仍走 Docker 网络 `ip://footstone:17778`,不受影响。管理面所有外部访问请走 +> footstone HTTP 网关(`FOOTSTONE_HTTP_PORT=21000`),由 `tm-userpassword` / +> `tm-permission` 鉴权后再转发到内部 tRPC。 + ## 全量部署常用命令 ```bash diff --git a/manager/deployments/compose/docker-compose.yml b/manager/deployments/compose/docker-compose.yml index 12de09523e8838e674dc03b873bb81d3e3a4ec81..91c62e02202e637ee2184a7642ef668058fc7d74 100644 --- a/manager/deployments/compose/docker-compose.yml +++ b/manager/deployments/compose/docker-compose.yml @@ -65,7 +65,11 @@ services: ports: # 宿主机端口由 .env 控制;容器内部端口固定,与 nginx.docker.conf 保持一致 - "${FOOTSTONE_HTTP_PORT:-21000}:20000" - - "${FOOTSTONE_TRPC_PORT:-17778}:17778" + # 安全(issue #IK49NP):tRPC 端口 17778 的 filter 链被 AllowTrpc 放过, + # 直接暴露到宿主机/外部网络会绕过所有鉴权。这里仅绑定到 127.0.0.1, + # 供本机调试;容器间内部调用走 docker 网络 ip://footstone:17778,不受影响。 + # 如需跨机访问 tRPC,请通过带鉴权的前置网关代理,切勿直接对外暴露。 + - "127.0.0.1:${FOOTSTONE_TRPC_PORT:-17778}:17778" volumes: - ${LOG_DIR:-./logs}/footstone:/app/logs # 存活探针走独立 no-protocol 端口,避免被业务 tRPC/HTTP 路由解析。