Как настроить AWS Cloudfront для динамического количества доменов для динамического сайта?

Как настроить AWS Cloudfront для динамического количества доменов для динамического сайта?

НАСТРОЙКА
У нас есть система управления веб-сайтами, похожая на webs/wix/etc, которую мы пытаемся использовать с CloudFront. Она имеет следующие домены и поддомены.
- ourdomain: наш основной веб-сайт
- admin.ourdomain: интерфейс администрирования для каждого веб-сайта, доступный через https
- images.ourdomain: контейнер S3
- router.ourdomain: см. ниже
- [customersomething].ourdomain: поддомены для наших бесплатных пользователей
- [customersomething.com]: домены для наших премиум-клиентов

Система работает таким образом, что большинство доменов имеют CNAME-адрес Router.ourdomain (потому что это был самый простой способ для наших клиентов с их различными регистраторами доменов и т. п.), а Router.ourdomain имеет псевдоним A для нашего ELB, а затем PHP на наших EC2 обрабатывает сайты на основе значений HTTP_HOST, в то время как изображения поступают с S3.

НАШ ПЛАН
И теперь мы хотим поместить все это за CloudFront. Большая часть вещей тривиальна. Было легко поместить S3 за CF. Было легко поместить каждый ourdomain/*.(js|css) за CF через поддомен asset.ourdomain. Радостно, что мы можем использовать *.images.ourdomain для сегментации между поддоменами на лету, уменьшая время загрузки на стороне клиента и т. д. и т. п. Мы даже могли бы поместить все *.ourdomain, включая динамические сайты без PHP, за CF, указав "*.ourdomain" в параметрах CF.

ПРОБЛЕМА
Но единственное, чего мы не можем понять, это как поместить все динамически созданные PHP-сайты с пользовательскими доменами за CF. Напоминаем: они CNAME-d в router.ourdomain. Помещение каждого домена в параметры CF не вариант, так как нам нужно иметь возможность обрабатывать десятки тысяч доменных имен, и нам нужно сделать это без ручной настройки для каждого из них.

Поэтому мы подумали, что нам следует поместить router.ourdomain в конфигурацию CF как альтернативное доменное имя, указать router.ourdomain на CF в маршруте 53 и указать CF на наш ELB как источник. Что, как мы обнаружили, является хорошим способом получать это сообщение каждый раз: "ERROR Запрос не может быть удовлетворен. Неправильный запрос. Сгенерировано cloudfront (CloudFront)". На самом делене каждыйвремя, какwww.ourdomain работает как надо (он CNAMEd в router.ourdomain), но каждый другой поддомен выдает ошибку выше (*.ourdomain CNAMEd в router.ourdomain, но это происходит даже для тех поддоменов, которые CNAMEd в router.ourdomain один за другим, за исключением www и, конечно, маршрутизатора). Так что прямо сейчас мы не просто не имеем ни малейшего представления, как решить эту проблему, мы даже не понимаем, почему это работает для www, если не работает для всех остальных, и наоборот.

Буду признателен за любые мысли и идеи, спасибо.

решение1

Напоминаем: это CNAME-d для router.ourdomain

Да, вы об этом упомянули. Вот в чем дело:

Это не имеет значения.

Да, CloudFront ссылается на альтернативные имена хостов как на CNAME. Да, запись DNS CNAME — это типичный способ, которым вы направляете трафик определенного сайта в CloudFront. Но нет, настройка имени хоста как CNAME, указывающего на ваш дистрибутив CloudFront, не имеет значения для работы Cloudfront или HTTP в целом.

Когда браузер хочет подключиться к веб-серверу, он ищет IP-адрес в DNS. Если в пути есть CNAME, эта информация отбрасывается. Все, что волнует браузер, это «к какому IP-адресу мне подключиться?»

Допустим, www.example.org — это CNAME для webfarm.example.com. Браузер ищет www.example.org и в итоге получает IP-адрес для webfarm.example.com.

Получив ответ, браузер устанавливает соединение с веб-сервером и отправляет запрос.

GET / HTTP/1.1
Host: www.example.com

Заголовок Host:в http-запросе, отправленном браузером, содержит имя хоста, как показано в адресной строке. Информация CNAME полностью недоступна и неизвестна ни браузеру, ни веб-серверу.

Так как же CNAME может быть релевантным для анализа запроса и маршрутизации уровня 7? Не может быть. Цель CNAME используется только как путь для поиска IP-адреса для подключения.

Ваш дистрибутив не единственный, использующий эти IP-адреса в Cloudfront. Есть сотни или тысячи других. Все сводится к заголовку Host:.

Список «CNAME» (альтернативные имена хостов) — это набор имен хостов, с которыми CloudFront должен сопоставлять в Host:заголовке входящего сообщения, чтобы определить, следует ли считать запрос принадлежащимтвойраспределение. Это список Host:заголовков, которые браузер может отправить. Пока Host:заголовок не сопоставится с настроенным значением в распределении, распределение, связанное с этим запросом, неизвестно и неопределено.

Что делает Cloudfront, если не может сопоставить входящий Host:заголовок ни с одним распределением?

HTTP/1.1 400 Bad Request

Итак, поведение, которое вы видите, ожидаемо и правильно. Подстановочные знаки работают в конфигурации CloudFront, пока они составляют единственный крайний левый элемент в строке конфигурации альтернативного имени хоста. Но это не имеет никакого отношения к DNS.

Если вы хотите, чтобы ваш дистрибутив использовался другими клиентами, вам не избежать настройки других доменных имен в CloudFront.

Однако вы можете изменять их программно через API, а не вручную:

http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/PutConfig.html

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

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