AWS:如何将多个域重定向到另一个域上的页面?

AWS:如何将多个域重定向到另一个域上的页面?

我的目标

我有多个域名(例如 10 个或 20 个),我想重定向任何访客任何地方将这些页面迁移到另一个域上的页面(例如我的 stackoverflow.com 个人资料页面)。

这包括

  1. 顶级域名使用http(例如http://mydomain01.com
  2. 顶级域名使用https(例如https://mydomain01.com
  3. 子域名使用http(例如http://www.mydomain01.comhttp://blog.mydomain01.com
  4. 子域名使用https(例如https://www.mydomain01.comhttps://blog.mydomain01.com
  5. 任何路径(例如http://mydomain01.com/some_pathhttps://www.mydomain01.com/another/path.html

mydomain02.com以及我的所有其他域名( 、mydomain03.com等;每个都有上述用例)的相同内容。

我的研究

  1. 这篇 AWS 文章解释如何将互联网流量从顶级域重定向到另一个域(我的案例 #1这包括上面列出的)使用AWS S3AWS Route 53:这对有用http,但对无效https
  2. 这篇 AWS 文章解释了如何在多种情况下重定向互联网流量(从表面上看,涵盖了我所这包括上面列出的)使用AWS S3AWS Route 53AWS CloudFronthttp:这对和都有效https。(还讨论了使用应用程序负载均衡器,但我想这超出了这里的范围......)
  3. 这篇 AWS 文章添加了有关设置 CloudFront 分发和如何深入了解日志文件的更多详细信息。
  4. 这篇 AWS 文章文档重定向规则使用高级条件重定向:不确定我是否需要去那里来实现我的目标,所以还没有真正研究过这一点。

另外,显然还有很多 SO 问题(见有关的在这个问题的右边)和关于这个主题的其他帖子;其中大多数的问题在于它们使用了以前版本的 AWS 控制台 UI 的屏幕截图:大多数内容应该仍然相同,但将这些屏幕截图与当前 UI IMO 相关联会增加另一层混乱。

AWS(及其他)文档的关键要点:

  1. 我需要在 AWS S3 中创建一个存储桶并在其中配置重定向,
  2. 我需要在 AWS CloudFront 中创建一个分发;
  3. 为了在 CloudFront 中使用自定义域,我需要在 AWS ACM 中创建证书,
  4. 我需要在 AWS Route 53 中创建一个托管区域并在其中配置记录。

我迄今为止的工作

已安装最新的 AWS CLI,regionoutput在 中进行配置~/.aws/config,并在 中设置凭证~/.aws/credentials(每个 AWS 账户各一个);AWS_*环境变量export编辑。

我正在使用 AWS 区域US East (N. Virginia) (us-east-1)来处理所有事情,以防止由于 AWS 资源在某个区域不可用而导致的任何其他问题。

$ aws --version
aws-cli/2.2.23 Python/3.9.6 Darwin/19.6.0 source/x86_64 prompt/off

我省略了任何 shell 提示符或>shell 行继续符,以便更容易地从这篇文章复制到 shell 中。

设置 S3 存储桶

警告:这将创建一个没有任何访问限制的“全部公开”存储桶。在这种情况下,这应该无关紧要,因为没有要保护的存储桶内容,但这种公开存储桶通常是一种不好的做法。此外,我使用公开存储桶是为了防止访问限制导致的任何其他问题:首先,让它运转起来;其次,确保其安全

创建存储桶

aws s3api create-bucket --bucket mydomain01.com
  • 回复:
{
    "Location": "/mydomain01.com"
}

设置重定向

aws s3api put-bucket-website --bucket mydomain01.com --website-configuration \
    '{ "RedirectAllRequestsTo": { "HostName": "stackoverflow.com/users/217844/ssc" } }'
  • 没有反应

明白了:S3 存储桶名称必须与顶点域名匹配。

使用任何存储桶名称mydomain01.com(对于我的示例)似乎都会失败,并且没有任何原因提示。AWS 文档并没有真正清楚地说明这一点 - 事实上,我仍然不确定我是否在这里误解了某些东西,但据我所知,官方 AWS 文档实际上在这一点上有些马虎 - 在我看来 - 关键的关键点:例如,#2只是说

  1. 创建一个具有全局唯一名称的 S3 存储桶。

这可能是任何全局唯一名称。#1以某种方式提到这一点 - 一旦您知道如何阅读这些位......

顺便提一下,第二篇文章继续让我感到困惑

如果您不使用自定义域...

我为什么要不是使用自定义域名?!重点是重定向我的自定义域名,不是吗?!好吧,无论如何……

明白了:不能将协议添加到主机名前面。

AWS 控制台和 AWS CLI 似乎都不会测试http://是否https://主机名UI 字段 / 传入HostNameJSON 字符串。但是,如果在前面添加了一个,则重定向会失败;请参阅测试重定向以下。

明白了:AWS S3 控制台 UI 错误。

设置重定向后,AWS 控制台会在 UI 中显示指向存储桶 URL 的可点击链接 ( http://mydomain01.com.s3-website-us-east-1.amazonaws.com),该链接位于存储桶的最底部特性选项卡中静态网站托管部分。

单击该链接无法打开页面,似乎是因为 AWS 控制台弄乱了 URL 并尝试打开http://https//stackoverflow.com/users/217844/ssc/,无论使用什么协议。

测试重定向

  • 使用HTTPie在壳里,而curl不是wget因为现在的酷孩子们似乎都用这个
  • 将浏览器中 AWS 控制台中的链接复制到 shell
http http://mydomain01.com.s3-website-us-east-1.amazonaws.com/
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Date: Mon, 02 Aug 2021 12:39:09 GMT
Location: http://stackoverflow.com/users/217844/ssc/
Server: AmazonS3
x-amz-id-2: rakAqUMnRraGvo/WkSa6AnbuhWn/9YZX/CAlI/OJQKYoWp/OdQIbyhsvHSwNved3suwMdgglqpE=
x-amz-request-id: C5BBG833Q9TQ9J6X

--> 似乎有效

  • 如果协议错误地添加到主机名前面,则测试重定向;注意损坏的LocationURL:
http http://mydomain01.com.s3-website-us-east-1.amazonaws.com/
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Date: Mon, 02 Aug 2021 12:52:10 GMT
Location: http://https://stackoverflow.com/users/217844/ssc/
Server: AmazonS3
x-amz-id-2: Ee2/ob0faTpRdp6mGITdmClozXNmF1Q2oTbPioms8O91VA8n5VA3MoHhveeFz7v2VS65YKFKlDA=
x-amz-request-id: ZJP653R50YD5HSRS

我的问题 #1

注意:当我开始写这篇文章时,我有这些问题;我思考我自己能够回答这些问题,因为(见测试www子域名记录以下)。如果我错了,请纠正我:

  1. 问:即使我使用 CloudFront,是否也适用“存储桶名称 == 域名”要求?
    A:是的。
  2. 问:我是否需要为顶级域和每个子域分别创建一个存储桶?因此,在我的示例中
    • mydomain01.com
    • www.mydomain01.com
    • blog.mydomain01.com
      A:是的。

设置 Route 53 托管区域

创建托管区域

aws route53 create-hosted-zone --caller-reference "$(date '+%Y%m%d-%H%M%S')" --name mydomain01.com
  • 回复
{
    "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z123456789EXAMPLE0SKX",
    "HostedZone": {
        "Id": "/hostedzone/Z123456789EXAMPLE0SKX",
        "Name": "mydomain01.com.",
        "CallerReference": "20210802-150736",
        "Config": {
            "PrivateZone": false
        },
        "ResourceRecordSetCount": 2
    },
    "ChangeInfo": {
        "Id": "/change/C1234567890SKXEXAMPLE",
        "Status": "PENDING",
        "SubmittedAt": "2021-08-02T13:07:37.860000+00:00"
    },
    "DelegationSet": {
        "NameServers": [
            "ns-1234.awsdns-12.com",
            "ns-5678.awsdns-34.co.uk",
            "ns-1234.awsdns-56.net",
            "ns-5678.awsdns-78.org"
        ]
    }
}
  • 记下托管区域 ID Z123456789EXAMPLE0SKX,下一步将需要用到它

为顶级域创建记录

{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "mydomain01.com.",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z3AQBSTGFYJSTF",
          "DNSName": "s3-website-us-east-1.amazonaws.com",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}

明白了:必须逐字s3-website-us-east-1.amazonaws.com使用DNSName

AWS 文档在各种地方讨论了example.comexample.com.s3-website-us-east-1.amazonaws.com等。在这种情况下,这不是一些可以用自己的值替换的示例(例如mydomain01.com.s3-website-us-east-1.amazonaws.com),而是逐字值来自桌子, IEs3-website-us-east-1.amazonaws.com

明白了:不能将协议添加到主机名前面。

与上面的陷阱类似,AWS 控制台和 AWS CLI 都乐意接受在输入的值前面添加协议(http://或)https://主机名UI 字段 / 传递为DNSName。至少,这看起来非常控制台中出现错误,例如http\072\057\057mydomain01.s3-website-us-east-1.amazonaws.com.

在 AWS 控制台中,这两个陷阱都得到了一定程度的缓解,在创建或编辑记录时可以从下拉框中选择值;当使用 AWS CLI 时,您必须仔细检查发送的内容。

同样的陷阱和缓解措施也适用于记录名称UI 字段/ NameJSON 值。

为顶级域创建记录,继续。

  • 使用jq为了快速测试,临时文件包含有效的 json
jq . < change-batch.apex.json 1> /dev/null
  • 无输出 --> 有效的 JSON
aws route53 change-resource-record-sets --hosted-zone-id Z123456789EXAMPLE0SKX \
    --change-batch "file://$(pwd)/change-batch.apex.json"
  • 回复
{
    "ChangeInfo": {
        "Id": "/change/C1234567890EXAMPLESKX",
        "Status": "PENDING",
        "SubmittedAt": "2021-08-02T14:20:09.370000+00:00"
    }
}

测试顶点域名记录

  • 测试http
http http://mydomain01.com
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Date: Mon, 02 Aug 2021 15:06:08 GMT
Location: http://stackoverflow.com/users/217844/ssc/
Server: AmazonS3
x-amz-id-2: EfDtCxif2iV4eInskirSBAOjQS7o9arzJCeZjscF6mW7cwwmm9Nxb7QJT50x2kjdslX2fOxA+lk=
x-amz-request-id: WM7K9TDEF75A6P1V

--> 看起来不错

  • http使用路径测试
http http://mydomain01.com/some/path
 ... similar output as above ...
  • 测试https
http https://mydomain01.com

http: error: ConnectionError: HTTPSConnectionPool(host='mydomain01.com', port=443):
  Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x101a48100>:
    Failed to establish a new connection: [Errno 60] Operation timed out')) while doing a GET request to URL: https://mydomain01.com/
  • (为方便阅读,响应已换行)

--> 超时(60 秒后?)- 正如预期:使用 S3 存储桶进行重定向不起作用https(参见上文)

明白了:DNS 更改传播延迟。

AWS 和 Google非常在传播 DNS 设置更改方面速度很快(以秒或分钟为单位),但可能涉及其他“较慢”的名称服务器。按照所述绕过它们这里以消除这种混乱。这种方法仅适用于 macOS,但对于任何操作系统来说,概念都是相同的。

明白了:浏览器缓存。

当在浏览器中而不是 shell 中测试 DNS 更改时,浏览器可能会从其缓存中获取结果。我大部分工作都是使用 Chrome 完成的,但使用 Firefox(或 Safari)进行测试,因此我可以在每次测试之前清除整个缓存以消除这个潜在问题 - 而无需退出 Google、AWS 等。

www为子域名创建记录

  • 唯一的区别是NameJSON 值
sed -e 's|mydomain01.com.|www.mydomain01.com.|g' change-batch.apex.json > change-batch.www.json
aws route53 change-resource-record-sets --hosted-zone-id Z123456789EXAMPLE0SKX \
    --change-batch "file://$(pwd)/change-batch.www.json
  • 响应与上述类似

测试www子域名记录

  • 测试http
http http://www.mydomain01.com
HTTP/1.1 404 Not Found
Content-Length: 363
Content-Type: text/html; charset=utf-8
Date: Mon, 02 Aug 2021 15:28:05 GMT
Server: AmazonS3
x-amz-id-2: MGLcynq1iEGKh+pT6N6iRpCuQSN243q/5zm2Y7rXTnM7iW9nvDokF6s20xEUBr7QiEtBPEzZmII=
x-amz-request-id: TK83G35EMYFR8SKX

<html>
<head><title>404 Not Found</title></head>
<body>
<h1>404 Not Found</h1>
<ul>
<li>Code: NoSuchBucket</li>
<li>Message: The specified bucket does not exist</li>
<li>BucketName: www.mydomain01.com</li>
<li>RequestId: TK83G35EMYFR8SKX</li>
<li>HostId: MGLcynq1iEGKh+pT6N6iRpCuQSN243q/5zm2Y7rXTnM7iW9nvDokF6s20xEUBr7QiEtBPEzZmII=</li>
</ul>
<hr/>
</body>
</html>
  • 我认为这回答了我的问题 #1以上:我需要每个顶点/子域一个 S3 存储桶来转发。

设置 CloudFront 分配

  • 注意:AWS 控制台可以非常轻松地申请证书并使用 DNS 进行验证。

创建证书

  • AWS ACMrequest-certificate文档
  • 该证书应该适用于顶级域名和所有子域名,因此需要为该证书添加另一个名称/ 通过--subject-alternative-names; 参见这篇 AWS 文章(上方蓝色框)。
  • 添加引号,*.mydomain01.com这样 shell 就不会解释*
aws acm request-certificate --domain-name mydomain01.com --validation-method DNS \
    --subject-alternative-names '*.mydomain01.com'
  • 回复:
{
    "CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/12345678-90ab-cdef-1234-1234567890ab"
}
  • 123456789012是我的 AWS 账户 ID;后面的所有内容certificate/都只是一个 UUID

获取证书详细信息

  • AWS ACMdescribe-certificate文档
  • 将响应保存到临时本地文件;提取ResourceRecord.NameResourceRecord.Value使用jq
  • 需要 AWS Route 53 记录来证明我拥有mydomain01.com
  • 或者,使用--query参数aws acm describe-certificate
aws acm describe-certificate \
    --certificate-arn "arn:aws:acm:us-east-1:123456789012:certificate/12345678-90ab-cdef-1234-1234567890ab" \
 > describe-certificate.json
jq -r '.Certificate.DomainValidationOptions[0].ResourceRecord.Name' describe-certificate.json
_1234567890abcdef1234567890abcdef.mydomain01.com.

jq -r '.Certificate.DomainValidationOptions[0].ResourceRecord.Value' describe-certificate.json 
_1234567890abcdef1234567890abcdef.weirdchars.acm-validations.aws.

创建 Route 53 记录以进行证书验证

  • 将由 AWS ACM 自动检查,一旦找到此记录,就会验证证书
  • 与以前一样,使用临时本地文件change-batch.cert.json,例如为顶级域创建记录; 内容:
{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "_1234567890abcdef1234567890abcdef.mydomain01.com.",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "_1234567890abcdef1234567890abcdef.weirdchars.acm-validations.aws."
          }
        ]
      }
    }
  ]
}
  • shell 命令:
aws route53 change-resource-record-sets --hosted-zone-id Z123456789EXAMPLE0SKX \
    --change-batch "file://$(pwd)/change-batch.cert.json
  • 响应类似于上面创建记录时
  • 注意:ACM 可能需要几分钟来验证证书。

创建 CloudFront 分发

  • AWS CloudFrontcreate-distribution文档
  • 再次强调,CallerReference必须只是一个唯一的字符串;例如date '+%Y%m%d-%H%M%S'在 shell 中使用来创建并复制到文件中;参见创建托管区域
  • create-distribution.json和以前一样,对复数使用临时本地文件;内容如下
  • MinimumProtocolVersion:获取价值这篇 AWS 文章
  • OriginProtocolPolicy:使用,http-only因为源(S3 bucket)只能执行http
  • ViewerProtocolPolicy: 使用redirect-to-https作为创建此分布的全部目的是从重定向httphttps
  • 注意:我不知道(AWS 文档也没有说明)哪些字段是强制性要求的;如果发送的数据有缺失或错误,AWS CLI 命令会显示清晰详细的消息。
{
    "CallerReference": "20210802-191725",
    "Aliases": {
        "Quantity": 2,
        "Items": ["mydomain01.com", "*.mydomain01.com"]
    },
    "Origins": {
        "Quantity": 1,
        "Items": [
            {
                "Id": "mydomain01.com.s3.us-east-1.amazonaws.com_20210802-191725",
                "DomainName": "mydomain01.com.s3.us-east-1.amazonaws.com",
                "CustomOriginConfig": {
                    "HTTPPort": 80,
                    "HTTPSPort": 443,
                    "OriginProtocolPolicy": "http-only"
                }
            }
        ]
    },
    "OriginGroups": {
        "Quantity": 0
    },
    "DefaultCacheBehavior": {
        "TargetOriginId": "mydomain01.com.s3.us-east-1.amazonaws.com_20210802-191725",
        "ForwardedValues": {
            "QueryString": false,
            "Cookies": {
                "Forward": "none"
            },
            "Headers": {
                "Quantity": 0
            },
            "QueryStringCacheKeys": {
                "Quantity": 0
            }
        },
        "TrustedSigners": {
            "Enabled": false,
            "Quantity": 0
        },
        "ViewerProtocolPolicy": "redirect-to-https",
        "MinTTL": 0,
        "AllowedMethods": {
            "Quantity": 2,
            "Items": [
                "HEAD",
                "GET"
            ],
            "CachedMethods": {
                "Quantity": 2,
                "Items": [
                    "HEAD",
                    "GET"
                ]
            }
        },
        "SmoothStreaming": false,
        "DefaultTTL": 86400,
        "MaxTTL": 31536000,
        "Compress": false,
        "LambdaFunctionAssociations": {
            "Quantity": 0
        },
        "FieldLevelEncryptionId": ""
    },
    "CacheBehaviors": {
        "Quantity": 0
    },
    "CustomErrorResponses": {
        "Quantity": 0
    },
    "Comment": "",
    "Logging": {
        "Enabled": false,
        "IncludeCookies": false,
        "Bucket": "",
        "Prefix": ""
    },
    "PriceClass": "PriceClass_All",
    "Enabled": true,
    "ViewerCertificate": {
        "ACMCertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/12345678-90ab-cdef-1234-1234567890ab",
        "MinimumProtocolVersion": "TLSv1.2_2021",
        "SSLSupportMethod": "sni-only"
    },
    "Restrictions": {
        "GeoRestriction": {
            "RestrictionType": "none",
            "Quantity": 0
        }
    },
    "WebACLId": "",
    "HttpVersion": "http2",
    "IsIPV6Enabled": true
}
  • shell 命令:
  • 注意:添加--no-cli-pager禁用分页并将响应存储在临时本地文件中以供检查
aws --no-cli-pager cloudfront create-distribution \
    --distribution-config "file://$(pwd)/create-distribution.json"
 > create-distribution.response.json
  • 响应:一个大型 JSON 结构,主要是发送的配置和一些分发元信息

明白了:CloudFront 分发需要一点时间来部署。

在里面分布概述,有一个上一次更改字段部署每次更改后都会持续一段时间;根据屏幕和浏览器窗口的宽度,此字段可能会被隐藏,因此 UI 可能看起来像分发已启动并正在运行,但事实上并非如此。

测试分布

  • DomainName从响应中获取
jq -r '.Distribution.DomainName' create-distribution.response.json
abcdefghij1234.cloudfront.net
  • 测试http
http http://abcdefghij1234.cloudfront.net
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 183
Content-Type: text/html
Date: Mon, 02 Aug 2021 20:14:27 GMT
Location: https://abcdefghij1234.cloudfront.net/
Server: CloudFront
Via: 1.1 8640a37b586353bc916562c577770223.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ooT0Y1QvDE7_yoRmb0p0Un2Db6O713rBvudtmz1xer7YwEU0GE8smw==
X-Amz-Cf-Pop: HAM50-C2
X-Cache: Redirect from cloudfront

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>CloudFront</center>
</body>
</html>

因此,分布从 重定向http://abcdefghij1234.cloudfront.nethttps://abcdefghij1234.cloudfront.net- 正如它应该的那样;这就是它被创建的原因。

  • 测试https
HTTP/1.1 403 Forbidden
Connection: keep-alive
Content-Type: application/xml
Date: Mon, 02 Aug 2021 20:14:35 GMT
Server: AmazonS3
Transfer-Encoding: chunked
Via: 1.1 c3e656776c8a9f0e1ea24405ab1dcc85.cloudfront.net (CloudFront)
X-Amz-Cf-Id: or4SC8urWEv_8c3jDURv5IINwFU1TDVLSQ3_X7tya7Ncz8ujyz0-IQ==
X-Amz-Cf-Pop: HAM50-C2
X-Cache: Error from cloudfront
x-amz-bucket-region: us-east-1

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>EAST1CM5WJR8QM3S</RequestId>
  <HostId>zF2dJm2vsuSM633NHuzcA5VqrCrNkfYGu31FRmKKIkebuI5+6l5DlVnr4kk9be262hcqktoiROw=</HostId>
</Error>
  • (为便于阅读,采用 xml 格式)

看起来不太好。不知道这是否是意料之中的事?!?

更新 AWS Route 53 记录

  • 从使用 S3 存储桶更改为使用 CloudFront 分发
  • change-batch.apex.updatejson和前面一样,通过sed先前的文件创建一个临时的本地文件change-batch.apex.json
  • 使用UPSERT而不是CREATE:该记录已经存在,必须更新。
  • HostedZoneId:将旧值Z3AQBSTGFYJSTF(对于 S3)替换为Z2FDTNDATAQYW2,取自change-resource-record-sets文档
  • DNSName:引自change-resource-record-sets文档

指定您创建分配时 CloudFront 分配的域名。

您的 CloudFront 分配必须包含与资源记录集名称匹配的备用域名。例如,如果资源记录集的名称是 acme.example.com,则您的 CloudFront 分配必须包含 acme.example.com 作为备用域名之一。

--> 替换s3-website-us-east-1.amazonaws.com(针对 S3)abcdefghij1234.cloudfront.net

sed -e 's|CREATE|UPSERT|g' \
    -e 's|Z3AQBSTGFYJSTF|Z2FDTNDATAQYW2|g' \
    -e 's|s3-website-us-east-1.amazonaws.com|abcdefghij1234.cloudfront.net|g' \
    change-batch.apex.json > change-batch.apex.update.json
  • 文件内容:
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "mydomain01.com.",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "abcdefghij1234.cloudfront.net",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}
  • shell 命令
aws route53 change-resource-record-sets \
    --hosted-zone-id Z123456789EXAMPLE0SKX \
    --change-batch "file://$(pwd)/change-batch.apex.update.json"
  • 响应类似于上面创建记录时

测试顶点域名记录

  • 测试http
http http://mydomain01.com
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 183
Content-Type: text/html
Date: Mon, 02 Aug 2021 19:08:27 GMT
Location: https://mydomain01.com/
Server: CloudFront
Via: 1.1 2408979685aa1bdb752824d292e63bf7.cloudfront.net (CloudFront)
X-Amz-Cf-Id: Ww60Ol_0fdR8SsgcHeRYUd_de1rVejX6w_wuK80aR21e3IHstB-irA==
X-Amz-Cf-Pop: HAM50-C2
X-Cache: Redirect from cloudfront

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>CloudFront</center>
</body>
</html>
  • 响应现在来自 CloudFront,不再来自 S3,因此更新的 DNS 记录似乎有效 :-)
  • http使用路径测试
http http://mydomain01.com/some/path
 ... similar output as above ...

--> 看起来不错

  • 测试https
http https://mydomain01.com
HTTP/1.1 403 Forbidden
Connection: keep-alive
Content-Type: application/xml
Date: Mon, 02 Aug 2021 18:53:51 GMT
Server: AmazonS3
Transfer-Encoding: chunked
Via: 1.1 ea89c67081222c8c680e7a37ad75f4f0.cloudfront.net (CloudFront)
X-Amz-Cf-Id: 5prv5_g5zXOX3aRBp2Gq64JJPuwC2o5dHIp9RCAHm6Ls8hK6EFghXw==
X-Amz-Cf-Pop: HAM50-C2
X-Cache: Error from cloudfront
x-amz-bucket-region: us-east-1

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>Access Denied</Message>
  <RequestId>T78ASF3FA9QGV4T5</RequestId>
  <HostId>xaEgwEtbeesL4XfxMdxVoPAt9Lpb1ZDM9Fs5W4htBbcWNbV9sMUTjVAPIuWwAQ3Xh1yRhh4b4Ts=</HostId>
</Error>
  • (与以前一样,为便于阅读,采用 xml 格式)

注意:此回复来自AmazonS3,而不是CloudFront前一个回复。S3 bucket 没有任何访问限制 - 那么怎么可能存在拒绝访问?!?

仔细检查存储桶权限

aws s3api get-bucket-policy --bucket mydomain01.com

An error occurred (NoSuchBucketPolicy) when calling the GetBucketPolicy operation: The bucket policy does not exist

匹配空的存储桶策略AWS S3 控制台中的字段 - 但是根本没有存储桶策略真的可以吗?!?

现在回头看看测试分布上面,我看到直接访问的响应abcdefghij1234.cloudfront.net也来自 S3,而不是来自 CloudFront,所以问题似乎很清楚:

我的问题 #2

  1. 为什么 S3 存储桶拒绝访问?
  2. S3 bucket 根本没有访问策略,这正常吗?通常没有明确允许任何人访问的“公共”bucket 策略?
  3. 如同每个顶点/子域一个 S3 存储桶,每个顶点/子域是否也需要一次 CloudFront 分发?
  4. 如果是这样,我想将*.mydomain01.com备用域添加到证书(和分发)中实际上没有任何意义,不是吗?!我还需要每个分发一个证书,专用于一个域,对吗?

答案1

总体来说,您走的路是对的。只有一条评论:如果您的域已经使用了其他 DNS 服务提供商,则可以省略 Route53。

问:即使我使用 CloudFront,是否也适用“存储桶名称 == 域名”要求?

如果您使用 CloudFront,则不需要。CNAME 在 CloudFront 中单独配置。

问:我是否需要为顶级域和每个子域分别创建一个存储桶?

不,您不需要每个域/子域一个存储桶。

为什么 S3 存储桶拒绝访问?

您应该使用您的s3-website-us-east-1.amazonaws.com域名作为 CF 原点。

S3 bucket 根本没有访问策略,这正常吗?通常没有明确允许任何人访问的“公共”bucket 策略?

如果您仅使用存储桶来重定向流量,则没有访问策略应该没问题。

与每个顶点/子域一个 S3 存储桶类似,每个顶点/子域是否也需要一个 CloudFront 分发?

是的,每个域/子域需要一个 CloudFront 分发,因为一个分发最多可以附加一个 ACM 证书。

如果是这样,我想将*.mydomain01.com备用域添加到证书(和分发)中实际上没有任何意义,不是吗?!我还需要每个分发一个证书,专用于一个域,对吗?

添加通配符域确实有意义,因为 CF 分发也需要处理子域流量。

如果您还有其他问题,请加入AWS 聊天并在聊天中@我。

相关内容