我的目标
我有多个域名(例如 10 个或 20 个),我想重定向任何访客任何地方将这些页面迁移到另一个域上的页面(例如我的 stackoverflow.com 个人资料页面)。
这包括
- 顶级域名使用
http
(例如http://mydomain01.com
) - 顶级域名使用
https
(例如https://mydomain01.com
) - 子域名使用
http
(例如http://www.mydomain01.com
或http://blog.mydomain01.com
) - 子域名使用
https
(例如https://www.mydomain01.com
或https://blog.mydomain01.com
) - 任何路径(例如
http://mydomain01.com/some_path
或https://www.mydomain01.com/another/path.html
)
mydomain02.com
以及我的所有其他域名( 、mydomain03.com
等;每个都有上述用例)的相同内容。
我的研究
- 这篇 AWS 文章解释如何将互联网流量从顶级域重定向到另一个域(我的案例 #1这包括上面列出的)使用AWS S3和AWS Route 53:这对有用
http
,但对无效https
。 - 这篇 AWS 文章解释了如何在多种情况下重定向互联网流量(从表面上看,涵盖了我所这包括上面列出的)使用AWS S3,AWS Route 53和AWS CloudFront
http
:这对和都有效https
。(还讨论了使用应用程序负载均衡器,但我想这超出了这里的范围......) - 这篇 AWS 文章添加了有关设置 CloudFront 分发和如何深入了解日志文件的更多详细信息。
- 这篇 AWS 文章文档重定向规则使用高级条件重定向:不确定我是否需要去那里来实现我的目标,所以还没有真正研究过这一点。
另外,显然还有很多 SO 问题(见有关的在这个问题的右边)和关于这个主题的其他帖子;其中大多数的问题在于它们使用了以前版本的 AWS 控制台 UI 的屏幕截图:大多数内容应该仍然相同,但将这些屏幕截图与当前 UI IMO 相关联会增加另一层混乱。
AWS(及其他)文档的关键要点:
- 我需要在 AWS S3 中创建一个存储桶并在其中配置重定向,
- 我需要在 AWS CloudFront 中创建一个分发;
- 为了在 CloudFront 中使用自定义域,我需要在 AWS ACM 中创建证书,
- 我需要在 AWS Route 53 中创建一个托管区域并在其中配置记录。
我迄今为止的工作
已安装最新的 AWS CLI,region
并output
在 中进行配置~/.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
put-bucket-website
文档 - 没有必要编辑我的 SO 个人资料...
aws s3api put-bucket-website --bucket mydomain01.com --website-configuration \
'{ "RedirectAllRequestsTo": { "HostName": "stackoverflow.com/users/217844/ssc" } }'
- 没有反应
明白了:S3 存储桶名称必须与顶点域名匹配。
使用任何存储桶名称mydomain01.com
(对于我的示例)似乎都会失败,并且没有任何原因提示。AWS 文档并没有真正清楚地说明这一点 - 事实上,我仍然不确定我是否在这里误解了某些东西,但据我所知,官方 AWS 文档实际上在这一点上有些马虎 - 在我看来 - 关键的关键点:例如,#2只是说
- 创建一个具有全局唯一名称的 S3 存储桶。
这可能是任何全局唯一名称。#1以某种方式提到这一点 - 一旦您知道如何阅读这些位......
顺便提一下,第二篇文章继续让我感到困惑
如果您不使用自定义域...
我为什么要不是使用自定义域名?!重点是重定向我的自定义域名,不是吗?!好吧,无论如何……
明白了:不能将协议添加到主机名前面。
AWS 控制台和 AWS CLI 似乎都不会测试http://
是否https://
在主机名UI 字段 / 传入HostName
JSON 字符串。但是,如果在前面添加了一个,则重定向会失败;请参阅测试重定向以下。
明白了: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
--> 似乎有效
- 如果协议错误地添加到主机名前面,则测试重定向;注意损坏的
Location
URL:
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
子域名记录以下)。如果我错了,请纠正我:
- 问:即使我使用 CloudFront,是否也适用“存储桶名称 == 域名”要求?
A:是的。 - 问:我是否需要为顶级域和每个子域分别创建一个存储桶?因此,在我的示例中
mydomain01.com
www.mydomain01.com
blog.mydomain01.com
?
A:是的。
设置 Route 53 托管区域
创建托管区域
- AWS Route 53
create-hosted-zone
文档 caller-reference
必须只是一个唯一的字符串
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
,下一步将需要用到它
为顶级域创建记录
- AWS Route 53
change-resource-record-sets
文档 - 这应该适用于
http
,但不适用于https
- 要传递的 JSON 有点复杂;
change-batch.apex.json
使用以下内容创建一个本地临时文件 - 获取
HostedZoneId
和DNSName
的值Amazon S3 网站终端节点:Bucket 创建于US East (N. Virginia)
,因此使用Z3AQBSTGFYJSTF
{
"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.com
或example.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 字段/ Name
JSON 值。
为顶级域创建记录,继续。
- 使用
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
为子域名创建记录
- 唯一的区别是
Name
JSON 值
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 ACM
request-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 ACM
describe-certificate
文档 - 将响应保存到临时本地文件;提取
ResourceRecord.Name
并ResourceRecord.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 CloudFront
create-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
作为创建此分布的全部目的是从重定向http
到https
- 注意:我不知道(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.net
到https://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
- 为什么 S3 存储桶拒绝访问?
- S3 bucket 根本没有访问策略,这正常吗?通常没有明确允许任何人访问的“公共”bucket 策略?
- 如同每个顶点/子域一个 S3 存储桶,每个顶点/子域是否也需要一次 CloudFront 分发?
- 如果是这样,我想将
*.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 聊天并在聊天中@我。