亚马逊AWS官方博客

Amazon CloudFront 用户域名部署及典型故障排查

Amazon CloudFront 用户域名部署及典型故障排查

Amazon CloudFront是亚马逊云科技的CDN(内容分发网络)服务,在全球拥有超过300个边缘站点并通过亚马逊云科技骨干网与亚马逊云科技区域(Region)互联。借助此全球边缘网络,CloudFront可将您的Web内容以低延迟和高可用性分发至世界各地。除了CDN加速效果外,在安全性上,CloudFront支持用户自定义域名,并关联该域名的SSL证书,使用HTTPS方式进行内容分发。

本文将为您介绍CloudFront用户自定义域名创建及SSL/TLS证书关联和生命周期管理,即通过Amazon Certificate Manager(ACM)进行自动的证书申请/证书更新/证书吊销。此外,不少用户在配置了CloudFront HTTPS源站后,会产生HTTP 502(源站证书验证失败)的报错,本文将为您解释该问题产生的原因和修复的方法。

Amazon CloudFront的HTTPS支持

CloudFront支持端到端的加密通讯,包括查看器(客户端)与CloudFront边缘站点之间使用HTTPS,以及CloudFront边缘站点与您的源站之间使用HTTPS。

从CloudFront边缘站点到源站间的HTTPS

源设置中,在使用ALB/EC2/自定义源作为源站时,将配置从CloudFront边缘站点回源时的协议。

如果希望使用HTTPS回源,可以选择:

  • 仅HTTPS
  • 匹配查看器(当且仅当查看器协议策略为HTTPS only或HTTP重定向至HTTPS时)

最低源SSL协议保持默认设置即可。

从查看器到CloudFront边缘站点的HTTPS

在行为设置中,将配置从查看器(客户端)到CloudFront边缘站点的协议策略。

如果希望使用HTTPS访问分配,则可以选择:

  • HTTPS only 或
  • 重定向HTTP至HTTPS

CloudFront分配在创建完成后会提供一个形如d123abcxxx.cloudfront.net的分配地址用于访问加速,此时会使用CloudFront提供的默认SSL证书。通常用户会希望使用自己的域名来进行访问,在分配设置中,可以通过添加备用域名(CNAME)并关联SSL证书来实现。

为Amazon CloudFront分配设置备用域名(CNAME)并关联SSL证书

在分配设置中填写好备用域名后,为了验证域名,以及实现查看器(客户端)到CloudFront分配的HTTPS连接,需要为备用域名关联SSL证书。CloudFront结合亚马逊云科技 Certificate Manager(ACM)提供了以下3种方法用于申请或上传证书。

*提示:即使查看器(客户端)到CloudFront边缘站点使用HTTP,如果您自定义域名,CloudFront也会要求您关联SSL/TLS证书,以确保自定义域名的合法性和唯一性(SSL/TLS证书的申请过程包含了对您的域名的验证)。

在ACM中申请免费公有证书

亚马逊云科技 Certificate Manager(ACM)服务能够简化创建、存储和续订公有 SSL/TLS X.509 证书和密钥的复杂操作,提供免费的公有SSL证书,且证书受大多数浏览器、操作系统和移动设备的信任,并可以与Elastic Load Balancing,Amazon CloudFront, Amazon API Gateway等亚马逊云科技服务集成。如果您的域名尚未拥有公有证书,可以从ACM中免费申请。

在CloudFront分配设置中填写好分配的备用域名后,点击下方的请求证书按钮将自动跳转至ACM服务控制台,或者您也可以在亚马逊云科技管理控制台中搜索ACM服务进入。请注意为了使申请的证书能够与CloudFront分配关联,务必确认右上角的区域为美国东部弗吉尼亚北部(us-east-1)区域。

第一步:添加域名

在添加域名时,可以使用通配符来匹配多个子域名,这样对于同一个顶级下的多个二级域名能够共用同一个ACM公有证书,而不必多次申请。在这个例子中,我将使用*.example.com来保护www.example.com

需要注意的是,*.example.com无法保护三级域名如test.login.example.com或一级域名example.com。如果需要保护其他域名,可以点击“为此证书添加另一个名称”继续添加其他域名。

现在我们选择默认的DNS验证方法,点击请求。

* DNS验证方法是用域名记录修改的方式,帮助证书颁发机构确认证书申请人能够在example.com下增加颁发机构指定的DNS记录内容。从而证明证书申请人对example.com域名的拥有权。

第二步:对域名进行DNS验证

在ACM控制台,可以看到刚刚申请的证书处在“等待验证”状态。进入该证书的详情,复制CNAME名称和CNAME值,并在您的DNS服务中创建一条CNAME记录。如果您使用的是Amazon Route53托管域名,则可以点击“在Route 53中创建记录”一键完成记录创建。

在Route53中创建的CNAME记录如下图所示。

第三步:将证书在CloudFront分配中关联

确认在DNS服务中创建正确的CNAME记录后,刷新ACM控制台即可发现证书已成功颁发。

回到CloudFront分配设置,点击自定义SSL证书右侧的刷新按钮,在下拉菜单中将显示刚刚在ACM中申请的公有证书。

在安全策略上,建议使用推荐的策略以实现最广泛的浏览器兼容性。

在ACM中上传已有的第三方SSL证书

如果您的域名已经在第三方证书颁发机构(CA)申请过SSL证书,亦可以上传至ACM中来和CloudFront分配关联。在上传证书时,同样需要确认ACM服务在美国东部弗吉尼亚北部(us-east-1)区域。

对于可导入至ACM的SSL/TLS证书具有以下要求,详见

https://docs.aws.amazon.com/zh_cn/acm/latest/userguide/import-certificate-prerequisites.html

进入ACM导入证书页面,在步骤1输入证书详细信息,有三个部分需要填写,分别是证书正文 certificate body、证书私钥 private key、证书链 certificate chain。而大多数从第三方购买的SSL证书,通常只包含两个文件如xxx.pem和xxx.key,导入ACM时请参考以下方式填写:

  • 打开xxx.key文件,复制完整内容至证书私钥处,以 —–BEGIN PRIVATE KEY—– 开头并以 —–END PRIVATE KEY—– 结尾。
  • 打开xxx.pem文件,文件中包含两段以—–BEGIN CERTIFICATE—– 开头并以 —–END CERTIFICATE—–结尾的内容。分别复制第一段至证书正文,第二段至证书链处。

在步骤3审核并导入,可以看到刚刚导入的证书的详情,证书关联的域、过期时间、加密算法会正确显示。

将第三方SSL证书导入至ACM后,您同样可以在CloudFront分配设置的自定义SSL证书下拉框中看到刚刚上传的证书。

在IAM中上传已有的公有证书

如果您使用的是亚马逊云科技中国区,由于CloudFront关联自定义SSL证书时仅支持从IAM中选择,可以通过以下方式将第三方SSL证书上传至IAM。

在CloudFront分配设置页面,点击上载证书至IAM。

证书的内容按以下形式填写:

  • 私有密钥:复制xxx.key的完整内容,以 —–BEGIN PRIVATE KEY—– 开头并以 —–END PRIVATE KEY—– 结尾。
  • 证书正文:复制xxx.pem的第一段,以“—–BEGIN CERTIFICATE—– 开头并以 —–END CERTIFICATE—–“结尾。
  • 证书链:复制xxx.pem的第二段,以“—–BEGIN CERTIFICATE—– 开头并以 —–END CERTIFICATE—–“结尾。

最后,在DNS服务中,为您设置的备用域名创建一条CNAME记录,指向CloudFront分配地址,即可实现通过备用域名访问。如果您使用的是Route 53中,可以使用别名记录将流量路由至CloudFront分配。

修复使用ALB作为源站时的HTTP 502错误

至此,我们已基本完成端到端的CloudFront HTTPS配置。如果您使用网络负载均衡器ALB作为源站,访问备用域名发生HTTP 502报错时,可参考以下原理和方法进行正确配置。

业务拓扑

请求流:客户端—HTTPS—login.test.example.com (CloudFront Distribution: d123abc.cloudfront.net) —HTTPS回源— Origin (ALB: LOGINTEST-abc-12345.us-east-1.elb.amazon亚马逊云科技.com) —HTTP— EC2。按照此请求流,客户端看到HTTP 502报错。

故障分析

  1. CloudFront分配E1234DEFGH上配置的证书为ACM颁发的*.test.example.com通配符证书。
  2. 源站ALB上安装为ACM颁发*.test.example.com证书。
  3. 通过login.test.example.com的请求里,客户终端使用的是login.test.example.com作为HTTPS Host请求头来访问login.test.example.com。
  4. 客户终端侧的Host请求头 login.test.example.com,在默认CloudFront Cache Request Policy里,会在回源时由CloudFront Distribution point改写为源站Host: LOGINTEST-abc-12345.us-east-1.elb.amazonaws.com(注意CloudFront回源时的Host请求头默认都会由客户终端侧的Host请求头改写为和回源uri一致。)
  5. 由于Host请求头LOGINTEST-abc-12345.us-east-1.elb.amazonaws.com与ALB证书*.test.example.com没有匹配,因此CloudFront distribution point在获取源站内容时,SSL匹配报错导致HTTPS无法完成。

最终发生502报错。

修复方案

方案1:在CloudFront行为设置中转发Host请求头

  1. 在源站ALB上安装与客户终端侧提交的Host请求头login.test.example.com匹配的*.test.example.com的证书。
  2. 在CloudFront Behavior里的Origin request policy里选择“AllViewer” policy,强制CloudFront distribution point在获取源站内容时,保留客户终端侧的Host请求头.

此时从CloudFront边缘站点回源,Host请求头将使用login.test.example.com,可以匹配ALB上的证书*.test.example.com,SSL匹配要求得以满足,HTTPS回源过程顺利完成,502报错消失。

CloudFront行为配置截图如下:

方案2:替换源站地址为ALB的CNAME地址

  1. 在源站ALB上安装通配符证书*.test.example.com的证书
  2. 在DNS服务中,创建一条CNAME记录,该记录的主机名能被*.test.example.com证书保护,如origin.test.example.com,指向ALB的DNS地址(LOGINTEST-abc-12345.us-east-1.elb.amazonaws.com)
  3. 将CloudFront的源站地址改为ALB的CNAME地址(origin.test.example.com)

此方案不需要修改CloudFront分配的request policy,因为此时从CloudFront边缘站点回源,Host请求头将由CloudFront改写为源站地址origin.test.example.com(而非ALB默认的DNS地址),该Host可以匹配ALB上的证书*.test.example.com,SSL匹配要求得以满足,HTTPS回源过程顺利完成,502报错消失。

方案小结

在调试HTTPS回源的CloudFront案例中,502错误经常会是证书相关的回源错误。

原因:CloudFront回源时,默认不会保持每一个view的HTTP请求头。尤其是Host请求头会被改动成为源站对应的域名。本例中Request Policy选择了托管策略AllViewer来转发所有的HTTP header、Query string、Cookie,当然您也可以创建自己的策略来选择在从CloudFront边缘站点回源时需要转发的参数。

引申:访问CloudFront分配默认地址时出现403报错

在我们按照方案1或方案2后进行修复后,现在直接用HTTPS访问CloudFront分配默认地址(如d123abc.cloudfront.net)报错代码403,具体现象如下:

原因:请求回源时的Host请求头为d123abc.cloudfront.net,而源站只接收Host为*.test.example.com的请求头,因此源站不予服务。

总结

本文介绍了CloudFront HTTPS的基本设置,以及在使用备用域名时如何关联域名并申请或上传SSL证书的详细步骤。同时,介绍了在使用ALB作为源站时,由于证书配置错误导致的回源失败,如何修复该HTTP 502报错场景的原理和方案。这个过程同样可以供在EC2或其他自定义源站上安装第三方SSL证书时遇到502报错作为排错参考。

参考文档

[1] 将 HTTPS 与 CloudFront 结合使用

[2] 使用备用域名和 HTTPS

[3] 控制源请求

[4] SSL/TLS证书申请及使用方法

[5] HTTP 502 状态代码 (Bad Gateway)

本篇作者

王北辰

亚马逊云科技解决方案架构师,负责基于亚马逊云科技的云计算方案架构咨询和设计,致力于亚马逊云科技云服务在创新增长客户群体中的推广,具有丰富的解决客户实际问题的经验。

崔俊杰

亚马逊云科技解决方案架构师,负责亚马逊云科技边缘云安全相关的服务产品。为亚马逊云用户提供DDoS防御/网站前端安全防御/域名安全相关的产品咨询。对Cloudfront, Shield, WAF, Route53,Global Accelerator等边缘云安全相关产品有深入了解。在计算机安全,数据中心和网络领域有多年的工作经验。