如何防止绕过 Kong API gateway 直接访问微服务 API
结论
不要把微服务端口直接暴露到公网。Kong 应当是唯一的公开入口,Payment service 只接受来自 Kong 的网络连接。如果内部网络也不可信,还需要使用 mTLS,确认调用方确实是 Kong。
API key、Basic Auth、HMAC 等机制用于验证外部客户端,适合配置在 Kong 上。防止请求绕过网关,则要依靠网络隔离和服务身份认证,不能只靠这些插件。
建议按以下顺序部署防护措施:
- 只为 Kong 配置公网入口。
- Payment service 使用私有地址,不配置公网负载均衡或端口映射。
- 通过防火墙、安全组或 Kubernetes
NetworkPolicy,只允许 Kong 访问 Payment service。 - 为高风险服务配置 Kong 到上游服务的 mTLS。
- Payment service 无需重复验证客户端 API key,但仍要执行业务授权和数据权限检查。
为什么只在 Kong 中验证 API key 仍然安全
认证逻辑可以集中在网关上,但后端服务必须位于网关保护的信任边界内:
Internet
|
v
[Kong: client authentication]
|
| private network / mTLS
v
[Payment service]
别人知道 Payment service 的地址,不代表能够访问它。需要关注的是网络路径是否可达,以及服务是否会接受该连接。
如果 Payment service 拥有公网 IP,或者任意主机都能访问其端口,攻击者确实可以绕过 Kong。隐藏 IP、使用难以猜测的域名,或者检查自定义 HTTP Header,都无法解决这个问题。
不要把下面这种 Header 当作安全凭据:
X-Request-From: kong
客户端也能构造相同的 Header。只有网络访问控制、TLS 客户端证书或其他不可伪造的服务身份,才能可靠地证明请求来自 Kong。
Kong 的认证配置
下面是一个简化的 Kong declarative configuration。外部请求通过 key-auth 插件验证后,才会转发到 Payment service:
_format_version: "3.0"
services:
- name: payment-service
url: http://payment.default.svc.cluster.local:8080
routes:
- name: payment-route
paths:
- /payments
strip_path: false
plugins:
- name: key-auth
config:
key_names:
- apikey
hide_credentials: true
外部客户端通过 Kong 发起请求:
curl \
-H "apikey: <client-api-key>" \
https://api.example.com/payments
API key 应通过 Kong 支持的管理方式安全创建和保存,不要将真实密钥提交到代码仓库。声明式字段和管理接口可能随 Kong 版本及部署模式变化,具体配置应以当前所用版本的 Kong 文档为准。
在 Kubernetes 中限制后端访问
Payment service 应使用默认的 ClusterIP,不要配置为 LoadBalancer,也不要通过 NodePort 对外开放:
apiVersion: v1
kind: Service
metadata:
name: payment
namespace: payments
spec:
type: ClusterIP
selector:
app: payment
ports:
- name: http
port: 8080
targetPort: 8080
再通过 NetworkPolicy,只允许 Kong namespace 中带有指定标签的 Pod 访问 Payment service:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: payment-ingress-from-kong
namespace: payments
spec:
podSelector:
matchLabels:
app: payment
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kong
podSelector:
matchLabels:
app: kong
ports:
- protocol: TCP
port: 8080
该策略选中 Payment Pod 后,只允许规则中明确声明的入站流量。部署时还要确认以下事项:
- 集群使用的 CNI 插件支持并实际执行
NetworkPolicy。 app: kong等标签与实际部署一致。- 如果监控、健康检查或运维工具需要访问 Payment service,也要为它们显式添加规则。
hostNetwork、节点级代理和某些特殊网络模式可能影响策略效果,需要在实际集群中验证。
即使攻击者知道 payment.payments.svc.cluster.local 或对应的 Cluster IP,只要连接不来自允许访问的 Kong Pod 身份和网络范围,仍会被拒绝。
在云服务器或虚拟机中限制访问
如果 Kong 和服务运行在虚拟机上,可以用私有子网和安全组建立相同的访问边界:
Kong security group:
inbound 443 <- Internet
outbound 8080 -> Payment security group
Payment security group:
inbound 8080 <- Kong security group only
no public IP
优先按照安全组身份授权,不要写死 Kong 的单个 IP。Kong 扩容、故障迁移或地址变化时,基于安全组的规则更容易维护。
如果环境只能使用主机防火墙,Payment service 应绑定到私有网卡地址,并且只允许 Kong 节点访问服务端口。规则在逻辑上应满足:
ALLOW tcp/8080 FROM <Kong private subnet or hosts>
DENY tcp/8080 FROM all other sources
不要让 Payment service 监听公网网卡,也不要通过 Docker ports、云负载均衡或路由器端口转发将其发布到公网。
内部网络不可信时使用 mTLS
限制 Kong 所在网段访问,可以阻止公网请求绕过网关,但未必能防住内网中已经失陷的主机。如果 Payment 是资金类高风险服务,建议在 Kong 和 Payment service 之间启用 mTLS:
- Payment service 持有服务端证书。
- Kong 验证 Payment service 的服务端证书。
- Kong 使用专用客户端证书连接 Payment service。
- Payment service 只信任签发 Kong 客户端证书的内部 CA。
- 没有提供有效客户端证书的连接会在 TLS 握手阶段被拒绝。
两类认证分别承担不同职责:
Client -- API key / HMAC --> Kong -- mTLS --> Payment service
API key 或 HMAC 用于证明「外部客户端是谁」,mTLS 用于证明「调用 Payment service 的是 Kong」。Kong 上游 TLS 和客户端证书的配置方式取决于 Kong 版本、部署模式以及是否使用 Ingress Controller,需要根据实际版本配置,不能用一个自定义 Header 代替。
后端仍然需要保留哪些安全逻辑
把认证集中到 Kong,不代表 Payment service 可以忽略其他安全问题。后端至少还要负责:
- 校验业务输入,不能假设经过网关的数据天然可信。
- 检查用户是否有权访问对应的账户、订单或支付记录。
- 防止越权、重复支付、金额篡改和重放等业务攻击。
- 不盲目信任客户端传入的身份 Header。
- 为敏感操作记录审计日志,并设置超时和幂等机制。
如果 Kong 通过 Header 将认证后的用户信息传给 Payment service,必须先删除客户端可能提交的同名 Header,再写入由 Kong 生成的值。与此同时,Payment service 仍然只能允许 Kong 访问。否则,攻击者可以绕过 Kong,直接伪造这些身份 Header。
运维入口也不要破坏隔离
开发人员或运维系统需要直接调试 Payment service 时,不要为了方便临时把端口暴露到公网。可以使用以下方式:
- VPN 或零信任访问代理;
- 堡垒机;
- Kubernetes
port-forward; - 独立的内部管理网关;
- 有审计能力的短期访问授权。
生产环境中的健康检查接口、指标接口和调试接口也应位于私有网络内,必要时可以使用独立端口,并配置更严格的访问规则。
Kong 负责认证外部客户端,基础设施保证后端只能由 Kong 访问,微服务负责业务授权。把这三层职责分开,既能避免每个服务重复实现 API key 或 HMAC 验证,也能防止外部请求绕过网关直接访问后端。
备注:内容仅供参考。
