AWS CloudFront如何将用户访问的备用DNS名透传至后端Lambda函数
现有AWS架构链路
当前搭建的请求流转链路如下:
用户访问公网DNS名称 -> CloudFront CloudFront -> API Gateway API Gateway -> Lambda函数
初始问题描述
Lambda函数内部无法识别用户实际访问的DNS名称,从请求头中仅能获取到API Gateway的域名,接收到的Host字段值为API Gateway的默认DNS地址,而非CloudFront绑定的公网域名或用户实际访问的DNS名,Host字段示例如下:
"Host": [ "9b8vc8vvhl.execute-api.us-east-1.amazonaws.com" ],
附:浏览器实际请求传参截图、请求头内容截图
核心诉求:确认是否存在CloudFront可配置项,实现用户输入访问的DNS名全链路透传,供后端Lambda代码读取。
配置后异常说明
按照社区给出的方案尝试配置(附配置操作截图)后,请求返回503 ERROR,错误提示翻译如下:
请求无法被满足,与CloudFront分配关联的Lambda函数无效或缺少所需权限,当前无法连接至应用/网站服务器,可能为流量过高或配置错误导致,可参考CloudFront文档排查问题
错误对应的CloudFront Request ID:n03zM0u93vrvdcwQi-hgyhONbv3b10x3ETq-A4Ru7-fC-RUlskjJxQ==
解决方案
原始域名透传正确配置方法
- 不要直接修改CloudFront转发给API Gateway的默认
Host头。API Gateway会强制校验请求的Host值必须匹配自身分配的执行域名,直接把Host改成用户访问的公网域名,会直接触发API Gateway校验失败,这也是配置后服务异常的核心原因。 - 正确透传方式是通过自定义请求头传递原始域名:在CloudFront的源站请求策略中新增自定义头,比如命名为
X-Forwarded-Host,值设置为捕获用户请求的原始Host值,CloudFront会自动将用户实际访问的DNS名称填充到这个头中,顺着链路传给API Gateway,最终透传到Lambda。 - 具体配置操作:进入对应CloudFront分配的详情页,选中绑定API Gateway的源站进入编辑页,找到源站请求策略配置项:
- 可以直接选用AWS托管的
AllViewerExceptHost策略,该策略会自动转发除Host外的所有用户请求头,同时携带CloudFront侧记录的原始访问信息 - 也可以自定义源站请求策略,在头转发规则中新增映射,将用户原始
Host值绑定到X-Forwarded-Host头转发即可
- 可以直接选用AWS托管的
- Lambda代码侧直接读取请求头中的
X-Forwarded-Host字段,就能拿到用户实际输入访问的公网DNS名称,全程不需要修改默认Host头,不会触发API Gateway的域名校验规则。
503错误排查步骤
按以下优先级排查即可:
- 先检查是否直接修改了转发给源站的
Host头为用户访问域名,如果是,先还原Host头为默认配置(让CloudFront自动将Host设置为API Gateway的源站域名),先恢复基础服务可用性。 - 如果配置过程中使用了Lambda@Edge做请求头修改逻辑,检查Lambda@Edge的执行角色配置:
- 角色信任策略必须同时允许
lambda.amazonaws.com和edgelambda.amazonaws.com两个服务代入执行 - 角色必须绑定基础执行权限,包含CloudWatch日志写入等基础权限,权限缺失就会触发“Lambda无效或缺少所需权限”类报错
- 角色信任策略必须同时允许
- 检查关联到CloudFront的Lambda@Edge版本:CloudFront仅支持关联已发布的固定版本Lambda,不能直接关联
$LATEST版本,关联未发布版本也会触发该类503错误。
内容的提问来源于stack exchange,提问作者Yuriy Gavriluk
相关产品推荐
相关产品推荐

