对于具有以下AWS架构的解决方案:
Client A --> API Gateway A --> Server A
|
|--> Lambda Authorizer (custom and shared)
|
Client B --> API Gateway B --> Server B
|
S3 Bucket
(trustore)
为了使用API网关公开的API:
- 两个客户端ip都需要加入白名单
- 两个客户端都需要有有效的凭据/令牌
- 客户端B需要mTLS(使用API网关B)
使用的AWS API网关类型是HTTP API (v2) -主要是因为REST API具有成本效益。
创建的自定义Lambda授权器由两个API网关共享,并基于它们的:
授权客户端。- ip - CIDR块验证
- 凭据/令牌-认证
两个API网关(A和B)的安全配置为:
securitySchemes:
oauth:
in: header
name: IpAuthorizer
type: apiKey
x-amazon-apigateway-authtype: oauth2
x-amazon-apigateway-authorizer:
type: request
authorizerPayloadFormatVersion: 1.0
identitySource: "$request.header.Authorization,$context.identity.sourceIp"
authorizerUri: !Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaAuthorizerArn}/invocations"
但是Lambda Authorizer Events的内容不同且不一致:
- 客户端A -从API网关A:
{
"version": "1.0",
"type": "REQUEST",
"identitySource": "<Token_ClientA>, <IP_ClientA>",
"headers": {
"x-forwarded-for": "<IP_ClientA>",
...
},
"requestContext": {
"identity": {
"sourceIp": " <IP_ClientA>",
...
},
...
},
...
}
问题1:为什么$.identitySource
和$.requestContext.identity.sourceIp
中的$context.identity.sourceIp
部分前面有一个额外的空白(' ')?
- For Client B - from API Gateway B:
{
"version": "1.0",
"type": "REQUEST",
"identitySource": "<Token_ClientB>,10.1.9.160:35840",
"headers": {
"x-forwarded-for": "<IP_ClientB>",
...
},
"requestContext": {
"identity": {
"sourceIp": "10.1.9.160:35840",
...
},
...
},
...
}
问题2:为什么客户端IP ($context.identity.sourceIp
)在$.identitySource
和$.requestContext.identity.sourceIp
中都不存在?
问题3:什么是10.1.9.160:35840
(非常数),它从何而来?
Lambda Authorizer Events内容中唯一的一致性似乎是X-Forwarded-For
报头的存在,包含直接TCP API网关连接的源IP地址。
但是即使X-Forwarded-For
报头的使用也不是真正一致的,因为如果我们将两个客户端放在相同的反向代理后面,启用X-Forwarded-*
设置,我们在Lambda Authorizer Events内容中有不同的报头内容:
- 客户端A -从API网关A:
{
...
"headers": {
"x-forwarded-for": "<IP_ClientA>, <IP_ReverseProxy>",
...
},
...
}
- For Client B - from API Gateway B:
{
...
"headers": {
"x-forwarded-for": "<IP_ReverseProxy>",
...
},
...
}
问题4:为什么X-Forwarded-For
头没有正确通过API网关B?
在与AWS Support进行一些交互后:
问题1的答案:(简单API网关)
我们可以确认在HTTP API中存在一个差异,其中$. requestcontext .identity。sourceIp带有一个额外的空格,它适用于所有ip。我们已经意识到这个问题,我们正在努力修复它。
-修复已经应用,这个问题不再重现。
问题2、3、4的答案:(API Gateway with mTLS)
后端团队已经确定了IP地址的多个差异,他们正在努力修复这个问题。API Gateway服务团队一直在处理这个问题,他们已经实现了部署修复的管道。然而,目前还没有确切的预计时间来解决这个问题。
未解
结论:
- 无法使用
$.identitySource
或$.requestContext.identity.sourceIp
验证客户端IP ($context.identity.sourceIp
) - 如果在反向代理后面,则无法验证真实客户端IP
- 只能验证
X-Forwarded-For
报头中最近/最后/唯一的IP