AWS: Как перенаправить несколько доменов на страницу в другом домене?

AWS: Как перенаправить несколько доменов на страницу в другом домене?

Моя цель

У меня есть несколько доменов (например, 10 или 20) и я хотел бы перенаправитьлюбойпосетителив любом местес этих страниц на одну страницу в другом домене (например, на мою страницу профиля stackoverflow.com).

Это включает

  1. домен apex с использованием http(например http://mydomain01.com)
  2. домен apex с использованием https(например https://mydomain01.com)
  3. поддомены с использованием http(например, http://www.mydomain01.comили http://blog.mydomain01.com)
  4. поддомены с использованием https(например, https://www.mydomain01.comили https://blog.mydomain01.com)
  5. любые пути (например http://mydomain01.com/some_pathили https://www.mydomain01.com/another/path.html)

плюс то же самое для всех моих других доменов ( mydomain02.com, mydomain03.com, и т.д.; каждый с указанными выше вариантами использования).

Мое исследование

  1. Эта статья AWSобъясняет, как перенаправить интернет-трафик с домена apex на другой домен (случай № 1 в моемЭто включаетсписок выше) с использованиемАВС S3иМаршрут 53 AWS: Это работает для http, но не для https.
  2. Эта статья AWSобъясняет, как перенаправить интернет-трафик для ряда случаев (судя по всему, охватывает все случаи в моемЭто включаетсписок выше) с использованиемАВС S3,Маршрут 53 AWSиAWS CloudFront: Это работает как для , так httpи для https. (Также говорится об использовании Application Load Balancer, но я полагаю, что это выходит за рамки данной темы...)
  3. Эта статья AWSдобавлены некоторые дополнительные сведения о настройке дистрибутива CloudFront и о том, как получить доступ к файлам журналов.
  4. Эта статья AWSправила перенаправления документов для использования расширенных условных перенаправлений: Не уверен, нужно ли мне это делать для достижения моей цели, поэтому пока не изучал этот вопрос.

Плюс, очевидно, есть много вопросов SO (см.Связанныйсправа от этого вопроса) и другие сообщения по теме; проблема большинства из них в том, что они используют скриншоты из предыдущих версий пользовательского интерфейса AWS Console: большая часть содержимого должна быть той же, но сопоставление этих скриншотов с текущим пользовательским интерфейсом, на мой взгляд, добавляет еще один уровень путаницы.

Основные выводы из документов AWS (и других):

  1. Мне нужно создать корзину в AWS S3 и настроить в ней перенаправление,
  2. Мне необходимо создать дистрибутив в AWS CloudFront;
  3. Чтобы использовать пользовательский домен в CloudFront, мне нужно создать сертификат в AWS ACM,
  4. Мне необходимо создать размещенную зону в 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

Я опускаю все подсказки оболочки или >символы продолжения строки оболочки для облегчения копирования этого поста в оболочку.

Настройте контейнер 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 должно совпадать с именем домена apex.

Использование любого имени контейнера, но mydomain01.com(в моем примере) похоже, что происходит сбой без указания причины. Документация AWS на самом деле не очень ясно это объясняет - на самом деле, я все еще не уверен, что я что-то здесь неправильно понимаю, но насколько я могу судить, официальная документация AWS на самом деле несколько небрежна в этом - IMO - важном ключевом моменте: Например,#2просто говорит

  1. Создайте контейнер S3 с глобальным уникальным именем.

что могло бы бытьлюбойглобально уникальное имя.#1упоминает об этом в некотором роде - как только вы научитесь читать эти отрывки...

Кстати, статья №2 продолжает сбивать меня с толку

Если вы не используете пользовательский домен...

Зачем мненетиспользовать пользовательский домен ?!? Весь смысл в том, чтобы перенаправить мой пользовательский домен, не так ли ?!? Ну, в любом случае...

Попался:Не следует добавлять протокол к имени хоста.

Ни AWS Console, ни AWS CLI, похоже, не проверяют, был ли введен протокол ( http://или https://) вИмя хостаПоле UI / передается в HostNameстроке JSON. Однако если оно добавлено, перенаправление не выполняется; см.тестовое перенаправлениениже.

Попался:Ошибка пользовательского интерфейса консоли AWS S3.

После настройки перенаправления в пользовательском интерфейсе AWS Console отображается кликабельная ссылка на URL-адрес контейнера ( http://mydomain01.com.s3-website-us-east-1.amazonaws.com) в самом низу контейнера.Характеристикивкладка, вРазмещение статических веб-сайтовраздел.

При нажатии на эту ссылку страница не открывается, по-видимому, потому, что AWS Console искажает URL-адрес и пытается открыть ее http://https//stackoverflow.com/users/217844/ssc/, независимо от протокола.

тестовое перенаправление

  • с использованиемHTTPieв оболочке вместо curlили wgetпотому что это то, что крутые ребята, похоже, используют в наши дни
  • скопируйте ссылку из AWS Console в браузере в оболочку
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?
    А:Да.
  2. В:Нужно ли мне создавать по одному контейнеру для домена apex и каждого поддомена? Итак, в моем примере
    • mydomain01.com
    • www.mydomain01.com
    • blog.mydomain01.com?
      А:Да.

Настройте зону размещения 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"
        ]
    }
}
  • запишите идентификатор размещенной зоны Z123456789EXAMPLE0SKX, он понадобится в следующих шагах

создать запись для домена apex

{
  "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, ), адословное значение изстол, то естьs3-website-us-east-1.amazonaws.com.

Попался:Не следует добавлять протокол к имени хоста.

Подобно приведенному выше примеру, как AWS Console, так и AWS CLI с радостью принимают протокол ( http://или https://), добавленный к значению, введенному вИмя хостаПоле пользовательского интерфейса / передано как DNSName. По крайней мере, это выглядит такоченьнеправильно в консоли, напримерhttp\072\057\057mydomain01.s3-website-us-east-1.amazonaws.com.

Оба недостатка несколько смягчены в AWS Console, где значения можно выбирать из раскрывающегося списка при создании или редактировании записи; при использовании AWS CLI необходимо дважды проверять отправляемые данные.

Тот же самый трюк и смягчение последствий применимы кИмя записиПоле пользовательского интерфейса/ Nameзначение JSON.

создать запись для домена apex, продолжение.

  • использовать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"
    }
}

тестовая запись домена apex

  • тест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, но концепция одинакова для любой ОС.

Попался:Кэш браузера.

При тестировании изменений 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 request-certificateACM
  • сертификат должен работать для вершины и всех поддоменов, поэтому необходимодобавить еще одно имя к этому сертификату/ проход --subject-alternative-names; см.эта статья AWS(верхний синий прямоугольник).
  • добавьте кавычки *.mydomain01.com, чтобы оболочка не интерпретировала*
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; все, что после certificate/— это просто UUID

получить данные сертификата

  • Документы AWS describe-certificateACM
  • сохранить ответ во временный локальный файл; извлечь 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, см. напримерсоздать запись для домена apex; содержание:
{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "_1234567890abcdef1234567890abcdef.mydomain01.com.",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "_1234567890abcdef1234567890abcdef.weirdchars.acm-validations.aws."
          }
        ]
      }
    }
  ]
}
  • Команда оболочки:
aws route53 change-resource-record-sets --hosted-zone-id Z123456789EXAMPLE0SKX \
    --change-batch "file://$(pwd)/change-batch.cert.json
  • ответ аналогичен тому, что и при создании записей выше
  • ПРИМЕЧАНИЕ: ACM может потребоваться несколько минут для проверки сертификата.

создать дистрибутив CloudFront

  • Документация AWS create-distributionCloudFront
  • опять же, CallerReferenceэто должна быть просто уникальная строка; используйте, например, date '+%Y%m%d-%H%M%S'в оболочке для создания и копирования в файл; см.создать размещенную зону
  • как и прежде, используйте временный локальный файл create-distribution.jsonдля сложных значений; содержимое ниже
  • MinimumProtocolVersion: получить значение изэта статья AWS
  • OriginProtocolPolicy: использование, http-onlyпоскольку источник (контейнер S3) может делать только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
}
  • Команда оболочки:
  • ПРИМЕЧАНИЕ: добавьте, --no-cli-pagerчтобы отключить подкачку и сохранить ответ во временном локальном файле для проверки
aws --no-cli-pager cloudfront create-distribution \
    --distribution-config "file://$(pwd)/create-distribution.json"
 > create-distribution.response.json
  • ответ: большая структура JSON, в основном конфигурация, отправленная с некоторой метаинформацией о дистрибуции

Попался:Развертывание дистрибутивов CloudFront занимает некоторое время.

вРаспределенияобзор, естьПоследнее изменениеполе, которое говоритРазвертываниенекоторое время после каждого изменения; в зависимости от ширины экрана и окна браузера это поле может быть скрыто, поэтому пользовательский интерфейс может выглядеть так, будто дистрибутив запущен и работает, хотя на самом деле это не так.

тестовое распределение

  • получить 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
        }
      }
    }
  ]
}
  • команда оболочки
aws route53 change-resource-record-sets \
    --hosted-zone-id Z123456789EXAMPLE0SKX \
    --change-batch "file://$(pwd)/change-batch.apex.update.json"
  • ответ аналогичен тому, что и при создании записей выше

тестовая запись домена apex

  • тест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 нет никаких ограничений доступа вообще - так как же может бытьдоступ запрещен?!?

дважды проверьте разрешения на контейнер

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 вообще нет политики доступа? Обычно у «публичных» бакетов нет политики, которая явно разрешает доступ кому угодно?
  3. Похожий наодин контейнер S3 на вершину/поддомен, мне также нужен один дистрибутив CloudFront на каждый домен/поддомен?
  4. Если так, то, полагаю, добавление *.mydomain01.comальтернативного домена к сертификату (и дистрибуции) на самом деле не имеет никакого смысла, не так ли?!? Мне также понадобится один сертификат на дистрибуцию, выделенный для одного домена, верно?

решение1

В целом вы на правильном пути. Только один комментарий: Route53 можно пропустить, если ваш домен уже использует какой-то другой поставщик услуг DNS.

В: Применяется ли требование «имя контейнера == имя домена», даже если я использую CloudFront?

Нет, если вы используете CloudFront. CNAME настраивается отдельно в CloudFront.

В: Нужно ли мне создавать по одному сегменту для главного домена и каждого поддомена?

Нет, вам не нужно отдельное хранилище на домен/поддомен.

Почему контейнер S3 отказывает в доступе?

Вам следует использовать свой s3-website-us-east-1.amazonaws.comдомен в качестве источника CF.

Нормально ли, что у бакета S3 вообще нет политики доступа? Обычно у «публичных» бакетов нет политики, которая явно разрешает доступ кому угодно?

Если вы используете контейнер только для перенаправления трафика, то никакой политики доступа быть не должно.

Аналогично одному контейнеру S3 на вершину/поддомен, мне также нужен один дистрибутив CloudFront на вершину/поддомен?

Да, вам нужен один дистрибутив CloudFront на домен/поддомен, поскольку к одному дистрибутиву можно прикрепить не более одного сертификата ACM.

Если так, то, полагаю, добавление *.mydomain01.comальтернативного домена к сертификату (и дистрибуции) на самом деле не имеет никакого смысла, не так ли?!? Мне также понадобится один сертификат на дистрибуцию, выделенный для одного домена, верно?

Добавление подстановочного домена имеет смысл, поскольку дистрибутив CF должен также обрабатывать трафик поддоменов.

Если у вас есть дополнительные вопросы, присоединяйтесь к нам.Чат AWSи @me в чате.

Связанный контент