从 S3 存储桶提供的 Django 静态文件出现 ERR_CERT_COMMON_NAME_INVALID 和 SSL_ERROR_BAD_CERT_DOMAIN 错误

Posted

技术标签:

【中文标题】从 S3 存储桶提供的 Django 静态文件出现 ERR_CERT_COMMON_NAME_INVALID 和 SSL_ERROR_BAD_CERT_DOMAIN 错误【英文标题】:ERR_CERT_COMMON_NAME_INVALID and SSL_ERROR_BAD_CERT_DOMAIN errors with Django static files served from S3 bucket 【发布时间】:2019-08-31 08:20:31 【问题描述】:

我遇到了 Django 静态文件的问题。我正在使用 Django 管理员和 Django Rest 框架。我正在尝试使用 S3 存储桶为管理员和 DRF 提供静态文件。我可以成功访问存储桶中任何文件的 URL,它将加载到我的浏览器中,并且文件通过 HTTPS 提供。

我在 CloudFormation 中为 S3 存储桶创建了一个嵌套堆栈:

Description: >
  This template deploys S3 buckets for serving Django static files.

Parameters:
  AppUrl:
    Type: "String"
    Description: "The URL for our app (e.g. mydomain.com)"
    AllowedPattern: "[a-z0-9._-]+"

Resources:
  AssetsBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub $AppUrl-assets

  AssetsBucketPolicy:
    Type: "AWS::S3::BucketPolicy"
    Properties:
      Bucket: !Ref AssetsBucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
        - Sid: PublicReadForGetBucketObjects
          Effect: "Allow"
          Principal: "*"
          Action: "s3:GetObject"
          Resource: !Sub "$AssetsBucket.Arn/static/*"

当我的应用程序启动时,它会运行collectstatic 并将静态文件移到存储桶中。这是我遇到的问题:

当我访问带有查询参数?format=json 的 DRF URL 时。这将返回一个 JSON 响应,其中没有来自可浏览 API 的静态文件,而且我没有看到任何错误。但是,当我访问可浏览的 API 或管理界面时,我似乎发现了三个错误消息之一。在 Chrome 中,我看到了两种类型的行为。 HTTPS 已从 URL 中删除(以红色划掉),但静态资产加载时控制台中显示以下两个错误之一:

Access to font at 'https://mydomain.com-assets.s3.amazonaws.com/static/admin/fonts/Roboto-Bold-webfont.woff' from origin 'https://api.mydomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

GET https://mydomain.com-assets.s3.amazonaws.com/static/rest_framework/css/bootstrap.min.css net::ERR_CERT_COMMON_NAME_INVALID

Firefox 中,不加载静态文件,不剥离 HTTPS,并且我在调试窗口的网络选项卡中看到以下错误:

An error occured: SSL_ERROR_BAD_CERT_DOMAIN

我尝试使用以下 XML 向存储桶添加 CORS 策略:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

但这并没有解决 HTTPS 问题。有什么东西可以帮助我摆脱被划掉的 HTTPS 吗?

我确信证书没有问题,并且该问题与通过 HTTPS 连接请求的 HTTP 无关。我认为这是一个 CORS 问题,所以我不确定为什么添加 CORS 存储桶策略不能解决此问题。

另外,我在我的 Django 应用程序中安装了 django-cors-headers 并使用 CORS_ORIGIN_ALLOW_ALL = True

【问题讨论】:

您没有 CORS 问题。您看到这些 CORS 消息的唯一原因是 SSL 协商失败。如果证书正常,您将不会收到 ERR_CERT_COMMON_NAME_INVALID 和 SSL_ERROR_BAD_CERT_DOMAIN 消息。这些表明https://mydomain.com-assets.s3.amazonaws.com/ 站点的证书无效。在浏览器中打开https://mydomain.com-assets.s3.amazonaws.com/static/rest_framework/css/bootstrap.min.css,你会得到同样的错误。或转到https://www.ssllabs.com/ssltest/analyze.html?d=mydomain.com-assets.s3.amazonaws.com 并查看您返回的有关证书的哪些信息 @sideshowbarker 感谢您的评论。我确信静态文件能够通过 https 提供,但果然我再次检查并没有(他们也将 https 划掉了)。为了解决这个问题,我删除了“。”来自我的存储桶名称,以便它与证书一起有效。 【参考方案1】:

根据 S3 存储桶命名文档,问题似乎与存储桶名称中的点有关。

当您使用带有安全套接字层的虚拟托管式存储桶时 (SSL),SSL 通配符证书仅与不匹配的存储桶匹配 包含句点。要解决此问题,请使用 HTTP 或编写您自己的 证书验证逻辑。我们建议您不要使用 使用虚拟托管式存储桶时,存储桶名称中的句点(“.”)。

将bucket名称中的域名名称slug化(用连字符代替点)使其生效。

文档链接:here

【讨论】:

这个答案拯救了我的一天

以上是关于从 S3 存储桶提供的 Django 静态文件出现 ERR_CERT_COMMON_NAME_INVALID 和 SSL_ERROR_BAD_CERT_DOMAIN 错误的主要内容,如果未能解决你的问题,请参考以下文章

授予对 s3 存储桶的公共访问权限,而不是为 aws 无服务器应用程序提供静态网站

AWS S3存储桶Django 3.0用户配置文件图像上传访问错误

从静态网页上传 csv 文件到 S3 存储桶

将 Amazon S3 存储桶和 Cloudfront 与 SSL Wordpress 站点一起使用不会提供静态文件

用于收集静态的 Django 1.11 + Amazon S3

如何通过节点 expressjs 从 s3 提供静态网站?