如何阻止直接请求内部微服务?基于.NET Core+Ocelot网关场景
阻止内部微服务被直接访问的可行方案
针对你用C#/.NET Core、Docker、Ocelot搭建的微服务项目,要阻止用户直接访问内部服务(比如http://localhost:5002/api/comment),可以从以下几个层面入手:
1. 调整Docker端口映射策略
当前你的commenting.api通过ports: "5002:80"把容器80端口绑定到了主机的所有网卡上,这是外部能直接访问的核心原因。可以做两种调整:
- 完全隐藏内部服务端口:直接删除
ports配置项。这样内部服务仅能在Docker内部网络中被网关(同网络下)通过服务名(commenting.api)访问,主机外部和主机本身都无法直接通过端口访问。 - 仅允许主机本地调试访问:如果需要在开发阶段主机本地调试内部服务,可将端口绑定到回环地址:
这样只有主机本地能通过ports: - "127.0.0.1:5002:80"localhost:5002访问,外部用户无法触及。
2. 用Docker内部网络做隔离
创建一个专属的Docker桥接网络,让网关和所有内部服务都加入这个网络,内部服务不暴露端口到主机网络。示例docker-compose配置:
version: '3.8' networks: microservices-net: driver: bridge services: ocelot.gateway: container_name: ocelot.gateway ports: - "80:80" networks: - microservices-net # 其他配置... commenting.api: container_name: commenting.api environment: - ASPNETCORE_ENVIRONMENT=Development - ConnectionString=Server=mydb;Port=5432;Database=commentDb;UId=admin;Password=somepass; - CustomSerilog__ElasticUri=http://elasticsearch:9200 - EventBus__EventBusConnection=rabbitmq networks: - microservices-net # 移除ports配置,或仅绑定回环
此时内部服务之间通过服务名(如commenting.api)通信,外部完全无法直接访问内部服务容器。
3. 内部服务添加访问校验逻辑
在每个内部.NET Core服务中添加中间件,仅接受来自Ocelot网关的请求:
方案A:验证专属请求头
网关转发请求时添加一个自定义头(比如X-Gateway-Auth),内部服务验证该头的有效性:
- 首先在Ocelot的路由配置中添加请求头:
"Routes": [ { "DownstreamPathTemplate": "/api/comment/{everything}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "commenting.api", "Port": 80 } ], "UpstreamPathTemplate": "/comment/{everything}", "UpstreamHttpMethod": ["Get", "Post"], "AddHeadersToRequest": { "X-Gateway-Auth": "your-secret-gateway-key" } } ] - 然后在内部服务的
Program.cs(.NET 6+)中添加中间件:app.Use(async (context, next) => { var gatewayAuthHeader = context.Request.Headers["X-Gateway-Auth"].FirstOrDefault(); if (string.IsNullOrEmpty(gatewayAuthHeader) || gatewayAuthHeader != "your-secret-gateway-key") { context.Response.StatusCode = StatusCodes.Status403Forbidden; await context.Response.WriteAsync("Direct access not allowed"); return; } await next(); });
方案B:IP白名单校验
如果网关和内部服务在同一Docker网络,可限制内部服务仅接受网关容器的IP访问。不过Docker容器IP可能动态变化,更可靠的是通过服务名解析,但IP白名单适合固定网络环境。
4. 云环境适配(未来迁移时)
当迁移到云环境时,可以:
- 用云服务商的VPC网络隔离内部服务,仅允许网关所在的子网访问内部服务端口。
- 借助云负载均衡器,仅对外暴露网关的80端口,内部服务端口不对外开放。
- 部分云服务(如AWS ECS、Azure AKS)支持服务网格(如Istio、Linkerd),可通过服务网格实现更细粒度的访问控制。
内容的提问来源于stack exchange,提问作者Kaveh Naseri
相关产品推荐
相关产品推荐

