# Implementing API Gateway Security Controls

> 在API网关层实施安全控制，包括认证强制执行、速率限制、请求验证、IP白名单、TLS终止和威胁防护。 配置API网关（Kong、AWS API Gateway、Azure APIM、Apigee）作为集中式安全执行点， 在流量到达后端服务前对所有API流量进行验证、节流和监控。

- Skill: `killvxk/implementing-api-gateway-security-controls` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/implementing-api-gateway-security-controls`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/implementing-api-gateway-security-controls/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/implementing-api-gateway-security-controls

---

# 实施API网关安全控制

## 适用场景

- 为微服务API部署集中式认证和授权层
- 对所有API端点实施速率限制、节流和配额管理
- 在网关级别根据OpenAPI规范配置请求/响应验证
- 为API流量设置TLS终止、双向TLS和证书管理
- 将WAF规则与API网关集成，阻断注入、XSS和已知攻击模式

**不适用**作为唯一安全层。API网关提供纵深防御，但后端服务也必须验证授权和输入。

## 前置条件

- 已选择并部署API网关平台（Kong、AWS API Gateway、Azure APIM或Apigee）
- 所有后端API的OpenAPI/Swagger规范
- 网关域名的TLS证书
- 已为OAuth2/OIDC配置身份提供商（IdP）（Okta、Auth0、Azure AD）
- 监控和日志基础设施（CloudWatch、Datadog、ELK）
- 后端服务端点已注册并可从网关访问

## 工作流程

### 步骤1：Kong网关安全配置

```yaml
# kong.yml - 带安全插件的声明式Kong配置
_format_version: "3.0"

services:
  - name: user-service
    url: http://user-service:8080
    routes:
      - name: user-api
        paths:
          - /api/v1/users
        methods:
          - GET
          - POST
          - PUT
          - PATCH
          - DELETE
        strip_path: false

plugins:
  # 1. 认证：JWT验证
  - name: jwt
    config:
      uri_param_names:
        - jwt
      header_names:
        - Authorization
      claims_to_verify:
        - exp
      maximum_expiration: 3600  # 令牌最大有效期1小时

  # 2. 速率限制
  - name: rate-limiting
    config:
      minute: 60
      hour: 1000
      policy: redis
      redis_host: redis
      redis_port: 6379
      fault_tolerant: true
      hide_client_headers: false
      limit_by: credential  # 按用户而非按IP

  # 3. 请求大小限制
  - name: request-size-limiting
    config:
      allowed_payload_size: 1  # 最大1MB
      size_unit: megabytes

  # 4. IP限制（管理端点）
  - name: ip-restriction
    service: admin-service
    config:
      allow:
        - 10.0.0.0/8
        - 172.16.0.0/12

  # 5. 机器人检测
  - name: bot-detection
    config:
      deny:
        - "sqlmap"
        - "nikto"
        - "nmap"
        - "masscan"

  # 6. CORS配置
  - name: cors
    config:
      origins:
        - "https://app.example.com"
      methods:
        - GET
        - POST
        - PUT
        - PATCH
        - DELETE
      headers:
        - Authorization
        - Content-Type
      credentials: true
      max_age: 3600

  # 7. 响应转换器 - 移除敏感头部
  - name: response-transformer
    config:
      remove:
        headers:
          - X-Powered-By
          - Server
      add:
        headers:
          - "X-Content-Type-Options: nosniff"
          - "X-Frame-Options: DENY"
          - "Strict-Transport-Security: max-age=31536000; includeSubDomains"
          - "Content-Security-Policy: default-src 'none'"
```

### 步骤2：AWS API Gateway安全配置

```python
import boto3
import json

apigw = boto3.client('apigatewayv2')

# 创建带双向TLS的API
api_response = apigw.create_api(
    Name='secure-api',
    ProtocolType='HTTP',
    DisableExecuteApiEndpoint=True,  # 强制使用自定义域名
)
api_id = api_response['ApiId']

# 配置授权器（带Cognito的JWT）
authorizer = apigw.create_authorizer(
    ApiId=api_id,
    AuthorizerType='JWT',
    IdentitySource='$request.header.Authorization',
    Name='cognito-jwt-authorizer',
    JwtConfiguration={
        'Audience': ['your-app-client-id'],
        'Issuer': 'https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx'
    }
)

# 创建带授权器的路由
apigw.create_route(
    ApiId=api_id,
    RouteKey='GET /api/v1/users',
    AuthorizerId=authorizer['AuthorizerId'],
    AuthorizationType='JWT',
)

# 配置节流
apigw.create_stage(
    ApiId=api_id,
    StageName='prod',
    DefaultRouteSettings={
        'ThrottlingBurstLimit': 100,
        'ThrottlingRateLimit': 50.0,  # 每秒50个请求
    },
    AccessLogSettings={
        'DestinationArn': 'arn:aws:logs:us-east-1:123456789:log-group:api-access-logs',
        'Format': json.dumps({
            'requestId': '$context.requestId',
            'ip': '$context.identity.sourceIp',
            'caller': '$context.identity.caller',
            'user': '$context.identity.user',
            'requestTime': '$context.requestTime',
            'httpMethod': '$context.httpMethod',
            'resourcePath': '$context.resourcePath',
            'status': '$context.status',
            'protocol': '$context.protocol',
            'responseLength': '$context.responseLength'
        })
    }
)

# WAF关联
waf = boto3.client('wafv2')
web_acl = waf.create_web_acl(
    Name='api-security-acl',
    Scope='REGIONAL',
    DefaultAction={'Allow': {}},
    Rules=[
        {
            'Name': 'AWS-AWSManagedRulesSQLiRuleSet',
            'Priority': 1,
            'Statement': {
                'ManagedRuleGroupStatement': {
                    'VendorName': 'AWS',
                    'Name': 'AWSManagedRulesSQLiRuleSet'
                }
            },
            'OverrideAction': {'None': {}},
            'VisibilityConfig': {
                'SampledRequestsEnabled': True,
                'CloudWatchMetricsEnabled': True,
                'MetricName': 'SQLiRuleSet'
            }
        },
        {
            'Name': 'RateLimit',
            'Priority': 2,
            'Statement': {
                'RateBasedStatement': {
                    'Limit': 2000,
                    'AggregateKeyType': 'IP'
                }
            },
            'Action': {'Block': {}},
            'VisibilityConfig': {
                'SampledRequestsEnabled': True,
                'CloudWatchMetricsEnabled': True,
                'MetricName': 'RateLimitRule'
            }
        },
    ],
    VisibilityConfig={
        'SampledRequestsEnabled': True,
        'CloudWatchMetricsEnabled': True,
        'MetricName': 'ApiSecurityACL'
    }
)
```

### 步骤3：使用OpenAPI Schema进行请求验证

```yaml
# Kong OAS验证插件配置
plugins:
  - name: oas-validation
    config:
      api_spec: |
        openapi: "3.0.3"
        info:
          title: Secure API
          version: "1.0"
        paths:
          /api/v1/users:
            post:
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      type: object
                      required: [name, email]
                      properties:
                        name:
                          type: string
                          maxLength: 100
                          pattern: "^[a-zA-Z ]+$"
                        email:
                          type: string
                          format: email
                          maxLength: 255
                      additionalProperties: false  # 阻止批量赋值
              responses:
                '201':
                  description: User created
      validate_request_body: true
      validate_request_header_params: true
      validate_request_query_params: true
      validate_request_uri_params: true
      verbose_response: false  # 错误信息中不暴露Schema详情
```

### 步骤4：双向TLS配置

```bash
# 为mTLS生成CA和客户端证书
# 1. 创建CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -out ca.crt -days 365 \
    -subj "/CN=API Gateway CA/O=Example Corp"

# 2. 创建客户端证书
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
    -subj "/CN=api-client/O=Example Corp"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
    -CAcreateserial -out client.crt -days 365

# Kong mTLS配置
# 将CA证书上传到Kong
curl -X POST http://kong-admin:8001/ca_certificates \
    -F "cert=@ca.crt"

# 启用mTLS插件
curl -X POST http://kong-admin:8001/services/user-service/plugins \
    --data "name=mtls-auth" \
    --data "config.ca_certificates[]=$(cat ca_cert_id)" \
    --data "config.revocation_check_mode=SKIP" \
    --data "config.authenticated_group_by=CN"
```

### 步骤5：日志和监控配置

```python
# 用于API安全事件的CloudWatch监控
import boto3

cloudwatch = boto3.client('cloudwatch')
logs = boto3.client('logs')

# 为安全事件创建指标过滤器
security_filters = [
    {
        'name': 'UnauthorizedAccess',
        'pattern': '{ $.status = 401 || $.status = 403 }',
        'metric': 'UnauthorizedAccessCount'
    },
    {
        'name': 'RateLimitHits',
        'pattern': '{ $.status = 429 }',
        'metric': 'RateLimitHitCount'
    },
    {
        'name': 'ServerErrors',
        'pattern': '{ $.status >= 500 }',
        'metric': 'ServerErrorCount'
    },
    {
        'name': 'LargeResponses',
        'pattern': '{ $.responseLength > 1000000 }',
        'metric': 'LargeResponseCount'
    },
]

for sf in security_filters:
    logs.put_metric_filter(
        logGroupName='api-access-logs',
        filterName=sf['name'],
        filterPattern=sf['pattern'],
        metricTransformations=[{
            'metricName': sf['metric'],
            'metricNamespace': 'APISecurityMetrics',
            'metricValue': '1',
            'defaultValue': 0
        }]
    )

# 为异常401/403峰值创建告警
cloudwatch.put_metric_alarm(
    AlarmName='API-UnauthorizedAccessSpike',
    MetricName='UnauthorizedAccessCount',
    Namespace='APISecurityMetrics',
    Statistic='Sum',
    Period=300,  # 5分钟
    EvaluationPeriods=1,
    Threshold=100,
    ComparisonOperator='GreaterThanThreshold',
    AlarmActions=['arn:aws:sns:us-east-1:123456789:security-alerts'],
    AlarmDescription='5分钟内超过100次未授权访问尝试'
)
```

## 核心概念

| 术语 | 定义 |
|------|------------|
| **API网关（API Gateway）** | 所有API流量的集中入口点，在路由到后端服务前强制执行认证、授权、速率限制和请求验证 |
| **速率限制（Rate Limiting）** | 控制客户端在时间窗口内的API请求数量，防止滥用并确保资源公平分配 |
| **请求验证（Request Validation）** | 在转发到后端服务前，验证传入的API请求是否符合预期的Schema（数据类型、必填字段、值范围） |
| **双向TLS（Mutual TLS，mTLS）** | 客户端和服务器双方均出示证书的双向TLS认证，为API间通信提供强身份验证 |
| **WAF集成（WAF Integration）** | 在API网关层应用Web应用防火墙规则，阻断常见攻击模式（SQL注入、XSS、路径遍历） |
| **OAuth2/OIDC** | 基于令牌的认证协议，网关在允许访问前针对身份提供商验证JWT令牌 |

## 工具和系统

- **Kong Gateway**：开源API网关，具有丰富的安全、速率限制和认证插件生态系统
- **AWS API Gateway**：托管API网关服务，内置节流、WAF集成和Lambda授权器
- **Azure API Management**：企业级API网关，具有基于策略的安全、开发者门户和Azure AD集成
- **Apigee（Google Cloud）**：API管理平台，具有威胁防护、配额管理和API分析
- **Envoy Proxy**：高性能代理，在服务网格架构中用作API网关，具有广泛的过滤链

## 常见场景

### 场景：使用Kong Gateway保护微服务API

**背景**：公司正在将单体API迁移到微服务架构，每个微服务都有自己的REST API。安全团队需要在不修改每个服务的情况下实施集中式认证、速率限制和请求验证。

**方法**：
1. 将Kong Gateway部署为单一入口点，将流量路由到8个后端微服务
2. 配置JWT验证插件，验证公司Keycloak身份提供商的令牌
3. 应用速率限制：普通用户每分钟60个请求，高级用户每分钟300个请求，通过JWT Claims识别
4. 启用OAS验证插件，拒绝不符合OpenAPI规范的请求（阻断批量赋值和注入攻击）
5. 为网关后的服务间通信配置mTLS
6. 配置响应转换器删除Server和X-Powered-By头，并添加安全头
7. 集成AWS WAF实现SQL注入和XSS防护规则
8. 将访问日志配置到CloudWatch，并设置安全指标过滤器和告警

**注意事项**：
- 仅依赖网关进行授权，而后端服务也需要验证权限
- 未按认证用户配置速率限制（仅按IP允许攻击者通过IP轮换绕过）
- 使用详细错误响应，暴露内部服务架构信息
- 部署后未使用安全工具测试网关配置
- 网关和后端服务之间缺少双向TLS，允许直接访问后端

## 输出格式

```
## API网关安全配置报告

**网关**: Kong 3.5（Kubernetes部署）
**后端服务**: 8个微服务
**日期**: 2024-12-15

### 已实施安全控制

| 控制措施 | 插件/功能 | 配置 |
|---------|---------------|---------------|
| 认证 | JWT插件 | Cognito IdP，最大TTL 1小时 |
| 速率限制 | 速率限制插件 | 60 req/min（用户），Redis后端 |
| 请求验证 | OAS验证 | 严格模式，不允许额外属性 |
| TLS | Kong TLS | 仅TLS 1.3，启用HSTS |
| mTLS | mTLS认证插件 | 管理API需要客户端证书 |
| WAF | AWS WAF | SQL注入、XSS、基于速率的规则 |
| 响应头 | 响应转换器 | 删除Server头，添加安全头 |
| 日志 | HTTP日志插件 | CloudWatch，安全指标过滤器 |

### 验证结果

- JWT验证：过期/无效令牌正确拒绝（测试了50个载荷）
- 速率限制：在60 req/min强制执行，返回带Retry-After头的429
- 请求验证：格式错误的请求被拒绝并返回400（测试了30个无效载荷）
- mTLS：无客户端证书的请求被拒绝并返回401
- WAF：SQL注入载荷被阻断（测试了Top 100 SQL注入模式）
```

