ssc*_*ssc 6 amazon-s3 redirect amazon-cloudfront amazon-web-services amazon-route53
我有多个域(例如 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等;每个域都有上述用例)。
httphttpshttphttps另外,显然有很多 SO 问题(请参阅与此问题右侧相关的内容)以及有关该主题的其他帖子;其中大多数的问题是它们使用以前版本的 AWS 控制台 UI 的屏幕截图:大多数内容应该仍然相同,但在我看来,将这些屏幕截图与当前 UI 相关联又增加了一层混乱。
已安装最新的 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
Run Code Online (Sandbox Code Playgroud)
我省略了任何 shell 提示或>shell 行继续字符,以便更轻松地从本文复制到 shell 中。
警告:这将创建一个“所有公共”存储桶,没有任何访问限制。在这种情况下,这应该不重要,因为没有要保护的存储桶内容,但这种公共存储桶通常是一种不好的做法。另外,我使用公共存储桶来防止访问限制引起的任何其他问题:首先,让它工作;第二,确保安全。
$ aws --version
aws-cli/2.2.23 Python/3.9.6 Darwin/19.6.0 source/x86_64 prompt/off
Run Code Online (Sandbox Code Playgroud)
aws s3api create-bucket --bucket mydomain01.com
Run Code Online (Sandbox Code Playgroud)
put-bucket-website文档{
"Location": "/mydomain01.com"
}
Run Code Online (Sandbox Code Playgroud)
使用任何存储桶名称,但mydomain01.com(对于我的示例)似乎会失败,并且没有任何原因指示。AWS 文档并没有真正明确这一点 - 事实上,我仍然不确定我是否严重误解了这里的某些内容,但据我所知,官方 AWS 文档实际上在这一点上有些草率 - IMO - 至关重要的关键点:例如,#2只是说
- 创建具有全局唯一名称的 S3 存储桶。
这可以是任何全球唯一的名称。#1在某种程度上提到了这一点 - 一旦你知道如何阅读这些位......
顺便说一句,第 2 篇文章仍然让我感到困惑
如果您不使用自定义域...
为什么我不使用自定义域?!?重点是重定向我的自定义域,不是吗?!?好吧,无论如何……
AWS 控制台和 AWS CLI 似乎都不会测试是否在主机名UI 字段中输入了协议(http://或) /是否在JSON 字符串中传递了协议。但是,如果在前面添加一个,则重定向会失败;请参阅下面的测试重定向。https://HostName
设置重定向后,AWS 控制台会在其 UI 中显示指向存储桶 URL ( ) 的可点击链接,该链接位于http://mydomain01.com.s3-website-us-east-1.amazonaws.com存储桶属性选项卡最底部的静态网站托管部分。
单击该链接无法打开该页面,似乎是因为 AWS 控制台弄乱了 URL 并尝试打开http://https//stackoverflow.com/users/217844/ssc/,无论协议如何。
HTTPie在 shell 中使用而不是curlorwget因为这就是现在很酷的孩子们使用的aws s3api put-bucket-website --bucket mydomain01.com --website-configuration \
'{ "RedirectAllRequestsTo": { "HostName": "stackoverflow.com/users/217844/ssc" } }'
Run Code Online (Sandbox Code Playgroud)
--> 似乎有效
Location网址: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
Run Code Online (Sandbox Code Playgroud)
注意:当我开始写这篇文章时,我有这些问题;我想我能够自己回答这些问题(请参阅下面的测试www子域记录)。如果我错了,请有人纠正我:
mydomain01.comwww.mydomain01.comblog.mydomain01.com?create-hosted-zone文档caller-reference必须是一个唯一的字符串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
Run Code Online (Sandbox Code Playgroud)
aws route53 create-hosted-zone --caller-reference "$(date '+%Y%m%d-%H%M%S')" --name mydomain01.com
Run Code Online (Sandbox Code Playgroud)
Z123456789EXAMPLE0SKX后续步骤中需要的托管区域 IDchange-resource-record-sets文档http,但不适用于httpschange-batch.apex.json使用以下内容创建本地临时文件HostedZoneId以及DNSName从Amazon S3 网站终端节点获取值:存储桶是在 中创建的,因此请使用US East (N. Virginia)Z3AQBSTGFYJSTF{
"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"
]
}
}
Run Code Online (Sandbox Code Playgroud)
s3-website-us-east-1.amazonaws.comDNSNameAWS 文档在各种地方谈论example.comor等。在这种情况下,这不是用自己的值(例如)example.com.s3-website-us-east-1.amazonaws.com替换的示例,而是表中的逐字值,即。mydomain01.com.s3-website-us-east-1.amazonaws.coms3-website-us-east-1.amazonaws.com
与上面的问题类似,AWS 控制台和 AWS CLI 都乐意接受在主机名UI 字段中输入的值前面添加的协议 (http://或) / 作为 传递。至少,这在控制台中看起来非常错误,例如https://DNSNamehttp\072\057\057mydomain01.s3-website-us-east-1.amazonaws.com.
这两个问题在 AWS 控制台中都得到了一定程度的缓解,在创建或编辑记录时可以从下拉框中选择值;使用 AWS CLI 时,您必须仔细检查发送的内容。
相同的问题和缓解措施适用于记录名称UI 字段/ NameJSON 值。
jq快速测试临时文件包含有效的 jsonjq . < change-batch.apex.json 1> /dev/null
Run Code Online (Sandbox Code Playgroud)
{
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "mydomain01.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z3AQBSTGFYJSTF",
"DNSName": "s3-website-us-east-1.amazonaws.com",
"EvaluateTargetHealth": false
}
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
jq . < change-batch.apex.json 1> /dev/null
Run Code Online (Sandbox Code Playgroud)
httpaws route53 change-resource-record-sets --hosted-zone-id Z123456789EXAMPLE0SKX \
--change-batch "file://$(pwd)/change-batch.apex.json"
Run Code Online (Sandbox Code Playgroud)
--> 看起来不错
http用路径测试{
"ChangeInfo": {
"Id": "/change/C1234567890EXAMPLESKX",
"Status": "PENDING",
"SubmittedAt": "2021-08-02T14:20:09.370000+00:00"
}
}
Run Code Online (Sandbox Code Playgroud)
httpshttp 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
Run Code Online (Sandbox Code Playgroud)
--> 超时(60 秒后?) - 正如预期:使用 S3 存储桶进行重定向不起作用https(见上文)
AWS 和 Google在传播 DNS 设置更改方面非常快(如以秒或分钟为单位),但可能还涉及其他“较慢”的名称服务器。按照此处所述绕过它们,以消除混乱的根源。该方法仅适用于 macOS,但该概念对于任何操作系统都是相同的。
当不在 shell 中而是在浏览器中测试 DNS 更改时,浏览器可能会从其缓存中获取结果。我的大部分工作都使用 Chrome 完成,但使用 Firefox(或 Safari)进行测试,因此我可以在每次测试之前清除整个缓存,以消除潜在的问题 - 无需退出 Google、AWS 等。
www为子域创建记录NameJSON 值http http://mydomain01.com/some/path
... similar output as above ...
Run Code Online (Sandbox Code Playgroud)
www子域记录httphttp 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/
Run Code Online (Sandbox Code Playgroud)
request-certificate文档--subject-alternative-names;请参阅这篇 AWS 文章(上方的蓝色框)。*.mydomain01.com这样 shell 就不会解释*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
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
123456789012是我的 AWS 账户 ID;之后的所有内容都certificate/只是一个 UUIDdescribe-certificate文档ResourceRecord.Name并ResourceRecord.Value使用jqmydomain01.com--query参数aws acm describe-certificateaws acm request-certificate --domain-name mydomain01.com --validation-method DNS \
--subject-alternative-names '*.mydomain01.com'
Run Code Online (Sandbox Code Playgroud)
{
"CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/12345678-90ab-cdef-1234-1234567890ab"
}
Run Code Online (Sandbox Code Playgroud)
change-batch.cert.json,请参阅例如为 apex 域创建记录;内容:aws acm describe-certificate \
--certificate-arn "arn:aws:acm:us-east-1:123456789012:certificate/12345678-90ab-cdef-1234-1234567890ab" \
> describe-certificate.json
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
create-distribution文档CallerReference必须是一个唯一的字符串;在 shell 中使用例如date '+%Y%m%d-%H%M%S'创建并复制到文件中;请参阅创建托管区域create-distribution.json;以下内容MinimumProtocolVersion:从这篇 AWS 文章中获取价值OriginProtocolPolicy:使用是http-only因为源(S3 存储桶)只能做httpViewerProtocolPolicy:redirect-to-https创建此发行版的全部目的是从重定向http到https{
"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,
总的来说,你走在正确的轨道上。仅一条评论:如果您的域已使用其他 DNS 服务提供商,则可以省略 Route53。
问:即使我使用 CloudFront,“存储桶名称 == 域名”要求也适用吗?
不,如果您使用 CloudFront。CNAME 在 CloudFront 中单独配置。
问:我是否需要为顶级域和每个子域各创建一个存储桶?
不,您不需要每个域/子域一个存储桶。
为什么 S3 存储桶拒绝访问?
您应该使用您的s3-website-us-east-1.amazonaws.com域名作为 CF 源。
S3 存储桶根本没有访问策略正常吗?通常没有明确允许任何人访问的“公共”存储桶策略吗?
如果您仅使用存储桶来重定向流量,则没有访问策略应该没问题。
与每个顶点/子域一个 S3 存储桶类似,我是否还需要每个顶点/子域一个 CloudFront 分配?
是的,每个域/子域需要一个 CloudFront 分配,因为一个分配最多可以附加一个 ACM 证书。
如果是这样,我想将
*.mydomain01.com备用域添加到证书(和分发)中并没有任何意义,不是吗?!?我还需要每个发行版一张专用于一个域的证书,对吗?
添加通配符域确实有意义,因为 CF 发行版也需要处理子域流量。
如果您还有任何其他问题,请加入AWS 聊天并在聊天中@我。
| 归档时间: |
|
| 查看次数: |
3729 次 |
| 最近记录: |