Gateway API中的插件和中间件
1)为什么需要插件和中间件
API网关是企业策略的执行点。正确组装的插件链:- 标准化安全性(authN/authZ,WAF,CORS),
- 保护可持续性(利率限制,巡回赛决胜局,回归政策),
- 管理合同(方桉验证、转型),
- 给出可观察性(度量,逻辑,跟踪),
- 降低成本(缓存、重复数据消除、金丝雀规则)。
关键:最小潜伏期和明确的应用顺序。
2)插件类及其在做什么
1.识别/身份验证
JWT/JWKS提供商,OAuth2/OIDC,API密钥和mTLS(客户端证书)。
HMAC签名(webhooks/partners),边缘的DPoP/PoP。
2.授权授权
RBAC/ABAC/OPA/Cedar(PDP)具有本地解决方桉缓存。
BOLA后卫:在标题/上下文中检查"tenant"/"owner"。
3.网络和礼宾保护
WAF(OWASP CRS),反机器人(rate/behavioral),Geo/IP/ASN过滤器,TLS配置文件。
CORS,CSP标题,Fetch-Metadata过滤器,CORP/COOP/COEP。
4.可持续性
比例限制(token bucket/GCRA),配额和竞争力。
巡回赛决胜局,计时赛,自适应衔接,装载共享。
Retry-policy带有per-try timeout和jitter。
5.转换和验证
路径/标头普查,车身恢复,JSON/XML ↔,gRPC ↔ HTTP。
模式验证(OpenAPI/JSON Schema/Protobuf),ID规范化。
6.缓存和性能
响应/帧缓存,ETag/If-None-Match,压缩和brotli。
请求相同键的拼接(coalescing)。
7.可观察性和审计
RED/USE度量标准,决策编写(429/403/5xx),跟踪(W3C Trace-Context/OpenTelemetry),采样(tail/adaptive)。
审核安全标题和策略版本。
8.生命周期和操作
Canary/blue-green, feature-flags, shadow solutions(编写,不应用),版本迁移。
3)应用程序(推荐链)
[Ingress TLS]
→ Early-Deny (ASN/Geo, IP allow/deny)
→ mTLS / Client Cert Auth
→ JWT/OAuth2 AuthN (JWKS cache)
→ OPA/ABAC AuthZ (solution cache)
→ Rate Limit / Concurrency
→ Circuit / Timeout / Retries (пер-try)
→ Schema Validation (request)
→ Transform (headers/path/body) / CORS
→ Caching (lookup)
→ Upstream Proxy (app)
← Caching (store) / Compression
← Response Transform / Schema Validation (response)
← Logging / Tracing / Metrics / Security Headers
原则:以前-更便宜/更胖子(deny,auth,极限),后来是"化妆品"(转化,缓存)。
4)性能和基数
坚持O (1)步骤,无需在热路上进行外部查询。
所有"外部呼叫"插件(PDP/JWKS)都是通过短TTL和asynchronous refresh进行的。
度量的标签/标签是受限基数("tenant","plan","route",但不是"user_id")。
"重"插件(WAF, body-transform)-选择性地按路线打开。
5)配置示例
5.1 Envoy: JWT+RateLimit+OPA+Retries(伪)
yaml static_resources:
listeners:
- name: public_listener filter_chains:
- filters:
- name: envoy. filters. network. http_connection_manager typed_config:
route_config:
name: main virtual_hosts:
- name: api domains: ["api. example. com"]
routes:
- match: { prefix: "/v1/payments" }
route:
cluster: payments timeout: 350ms retry_policy:
retry_on: connect-failure,reset,5xx,gateways num_retries: 1 per_try_timeout: 200ms http_filters:
- name: envoy. filters. http. jwt_authn typed_config:
providers:
oidc:
issuer: https://auth. example. com/
remote_jwks:
http_uri: { uri: https://auth. example. com/.well-known/jwks. json, cluster: jwks, timeout: 2s }
cache_duration: 300s forward: true
- name: envoy. filters. http. ext_authz # OPA/Cedar PDP typed_config:
http_service:
server_uri: { uri: http://opa:8181, cluster: opa, timeout: 50ms }
authorization_request: { allowed_headers: { patterns: [{ exact: "authorization" }, { exact: "x-tenant" }] } }
- name: envoy. filters. http. ratelimit typed_config:
domain: public-api rate_limit_service:
grpc_service: { envoy_grpc: { cluster_name: rl } }
- name: envoy. filters. http. router
5.2 NGINX/OpenResty: HMAC+Lua+Redis(伪)
nginx lua_shared_dict jwks 10m;
lua_shared_dict limits 10m;
server {
listen 443 ssl http2;
Early deny by ASN/Geo if ($bad_asn) { return 403; }
HMAC signature check (webhooks/partners)
set_by_lua_block $sig_ok {
return verify_hmac_signature(ngx. var. http_x_signature, ngx. var. request_time, ngx. var. request_body)
}
if ($sig_ok = 0) { return 401; }
Token bucket in Redis access_by_lua_block {
local key = ngx. var. binary_remote_addr.. ":".. ngx. var. request_uri local allowed, retry_after = ratelimit_allow(key, 50, 100)
if not allowed then ngx. header["Retry-After"] = retry_after return ngx. exit(429)
end
}
proxy_read_timeout 300ms;
proxy_connect_timeout 100ms;
proxy_pass http://app_backend;
}
5.3 Kong:沿途插件
yaml services:
- name: payments url: http://payments:8080 routes:
- service: payments paths: ["/v1/payments"]
plugins:
- name: jwt config: { key_claim_name: kid, secret_is_base64: false, run_on_preflight: false }
- name: opa config: { server_url: "http://opa:8181/v1/data/authz/allow", timeout: 50 }
- name: rate-limiting config: { second: 50, policy: redis, redis_host: redis, fault_tolerant: true }
- name: correlation-id config: { header_name: "traceparent" }
- name: response-transformer config: { add: { headers: ["Strict-Transport-Security:max-age=31536000"] } }
5.4 Apache APISIX: JWT + Limit + Proxy-Mirror (shadow)
yaml routes:
- uri: /v1/wallets/
plugins:
openid-connect:
client_id: wallet discovery: "https://auth. example. com/.well-known/openid-configuration"
scope: "openid"
limit-count:
count: 100 time_window: 60 key_type: "var"
key: "remote_addr"
proxy-mirror: # shadow traffic host: "http://shadow-backend:8080"
upstream_id: 1
5.5 Traefik: Middleware连锁店
yaml http:
middlewares:
hsts-headers:
headers:
stsSeconds: 31536000 stsIncludeSubdomains: true ratelimit:
rateLimit:
average: 50 burst: 100 routers:
api:
rule: "Host(`api. example. com`) && PathPrefix(`/v1`)"
service: app middlewares:
- hsts-headers
- ratelimit
6)多功能性和策略版本
路由密钥: "{tenant, plan, region, route, version}".
插件从mTLS SAN/JWT污名/标头中读取"tenant",→应用限额/配额/规则。
转化策略("policy_version"),引导changelog和金丝雀滚动。
7)测试和滚动
发布之前
合同链测试(如果有的话):auth→deny,auth→allow,rate→429,schema→422。
负载:bursts × 10,长高原,"肮脏"模式(慢开机)。
溷沌:PDP/JWKS/Redis降解-必须是失败的/降解到最低安全。
发行版
"Report-Only"/shadow-mode(我们编写解决方案而无需应用)。
金丝雀流量的1-5%+指标比较(p95/p99,4xx/5xx/429)。
通过SLO/Alert自动回滚。
8)可观察性和指标
度量标准:- `http_requests_total{route,tenant,plan,status}`
- `request_duration_seconds_bucket{route}` (p95/p99)
- `rate_limited_total{policy}`, `retry_total{reason}`, `circuit_state`
- `authn_fail_total{reason}`, `authz_denied_total{action}`
- `schema_validation_fail_total{route}`
- 预告片:按过滤器演唱,"policy_version","tenant","limit_key"属性。
- Logi(采样):deny/429/5xx解决方案,其中包含原因和"trace_id"。
- Dashbords:执行摘要,per-route,per-tenant,"热门"策略。
9)安全和操作
所有秘密(HMAC、JWKS私有、API密钥)-在KMS/Vault,不在config文件中。
敏感路由的deny-by-default策略。
JWKS/PDP缓存短TTL,后端异步更新。
转换方案的迁移-经过;"打破"-通过双写。
限制车身尺寸(DoS)和JSON深度。
10)反模式
每条路线上通用的全包插件集→额外的毫秒和计数。
没有缓存/时间戳的插件的外部依赖性→级联时间戳。
没有过滤器顺序:首先是转换/逻辑,然后是限制-不正确。
指标标签的高基数(raw'user_id'/'ip')。
在转换模式中混合authN/authZ(Lua/Jinja中的隐式解决方案)。
编译秘密/令牌。
一个全局Redis/群集,用于所有限值,不带硬化/备份。
11) iGaming/财务细节
常规/常规:KYC/AML,制裁,负责任付款限制。
支付路线的强硬政策:短时间,一次重复,等效性("Idempotency-Key")。
PSP/KYC SDK(单个域/插件链)的周长分离。
审核不变的决策逻辑(结论,锁定,制裁豁免)。
12)准备就绪支票清单
- 已定义过滤器的顺序:authN → authZ → limits → circuit/timeout → schema → transform → cache。
- Per路线插件集;沉重-仅在需要的地方。
- 具有短TTL和缓存的JWKS/PDP;定时和倒退策略。
- Rate/Quota/Concurrency-密钥设计,存储硬盘。
- RED/USE指标集、OTel跟踪、tail/adaptive sampling。
- 金丝雀+影子模式,通过SLO自动回滚。
- KMS/Vault中的秘密;configs是可转换的,有迁移。
- 身体限制/头条;超大/慢开机自检保护。
- 客户文件:编码401/403/409/422/429/5xx,"Retry-After",标题示例。
13) TL;DR
建立"早期故障→身份验证/授权→限制/可持续性→转换→验证/缓存→遥测"链。仅启用所需的per-route插件,缓存外部解决方桉(JWKS/PDP),设置时间表和返回策略,控制度量的基数。通过影子/金丝雀发布,在KMS/Vault中保持秘密,并测量每个插件对p95/p99的影响。