Let's Encrypt работает без www, но не с www

Надеюсь, кто-нибудь сможет дать совет — я буду вам очень благодарен. Поясню ситуацию.

Я не раз настраивал Discourse на своём домене hostballs[.]com. Каждый раз при посещении www[.]hostballs[.]com происходил корректный перенаправление на hostballs[.]com, поскольку сертификат LetsEncrypt покрывал оба варианта — с www и без. Это, насколько я знаю, стандартное поведение Discourse при использовании его реализации LetsEncrypt.

В настоящее время моя новая установка Discourse настраивает SSL только для версии без www (так как именно этот адрес указан как URL), но не покрывает www. Из-за этого пользователи, переходящие на www[.]hostballs[.]com, не получают перенаправления, а видят ошибку SSL. Учитывая, что стандартное поведение, насколько мне известно, отличается от этого, а установка Discourse слишком строго контролируется, чтобы я просто захотел запустить certbot и всё настроить вручную (разве это не сделает регулярные обновления забавными?), я не уверен, какой путь выбрать.

Пытаясь решить проблему, я закомментировал шаблоны ssl и LE, а также адрес электронной почты для LE в файле app.yml. Затем я удалил директории letsencrypt и ssl из /shared/standalone. Пересобрал сайт без SSL, после чего снова включил эти опции в app.yml и пересобрал его, чтобы сгенерировать новые сертификаты и конфигурации SSL. Хотя это сработало, проблема с www так и не была решена.

Столкнулся ли кто-нибудь ещё с подобной ситуацией и нашёл ли решение?

Конечно! Это немного дополнительная работа, но всё достаточно просто и является очень распространённым сценарием. См.:

А затем:

Если приведенные выше советы кажутся вам слишком сложными, вы также можете настроить простую DNS-перенаправку. Большинство регистраторов предоставляют эту услугу.

Discourse не может быть опубликован по нескольким URL-адресам: корневая запись (без www) и «A»-запись для www — это разные адреса. Как только вы назначите FQDN для своего сайта, любые дополнительные адреса необходимо обрабатывать с помощью перенаправления.

Если ни один из предложенных вариантов вам не подходит, вы можете использовать www.example.com и перенаправлять на сайт с www с помощью http://forcewww.com/.

Спасибо, друзья. Позвольте мне изложить некоторые детали, которые могут помочь кому-то в будущем.

Всё началось с того, что один пользователь сообщил, что посещение www не работает и выдаёт ошибку сертификата. При прямом переходе по ссылке https, которую он предоставил в теме отчёта, я столкнулся с той же проблемой. Раньше при использовании www я не сталкивался с этим, а перенаправлялся на корневой домен без проблем. Это привело меня к выводу, что моя установка после недавней миграции каким-то образом повреждена и не ведёт себя в соответствии с характеристиками по умолчанию новой установки Discourse.

Поэтому я установил свежую копию Discourse на новом домене, чтобы проверить, работает ли www по умолчанию при использовании корневого домена. Я перешёл на домен, затем отредактировал URL в адресной строке и добавил «www.» в начало. Перенаправление на корневой домен прошло без проблем, как я и ожидал. Затем я решил попробовать ещё одну вещь: вручную ввёл «https://» перед ним. После этого возникла та же ошибка сертификата.

Таким образом, то, что могло заставить меня предположить, что настройка сертификата для www является поведением по умолчанию в реализации Let’s Encrypt в Discourse, на самом деле могло быть тем, что мой браузер по умолчанию использовал порт 80, скрывая часть http/https URL при изменении адреса в строке.

По крайней мере, это моя лучшая оценка ситуации на данный момент.

Да, любой запрос к IP-адресу вашего сервера на порту 80 будет перенаправлен на фактический FQDN по HTTPS, www не является исключением.

Самый простой способ для тех, кто использует свой корневой домен и хочет, чтобы www был подписан Let’s Encrypt для корректного перенаправления по HTTPS, без излишнего усложнения и использования другого веб-сервера для управления перенаправлением:

Замените это:

issue_cert() {
LE_WORKING_DIR=“${LETSENCRYPT_DIR}” $$ENV_LETSENCRYPT_DIR/acme.sh --issue $2 -d $$ENV_DISCOURSE_HOSTNAME --keylength $1 -w /var/www/discourse/public
}

На это:

issue_cert() {
LE_WORKING_DIR=“${LETSENCRYPT_DIR}” $$ENV_LETSENCRYPT_DIR/acme.sh --issue $2 -d $$ENV_DISCOURSE_HOSTNAME -d www.$$ENV_DISCOURSE_HOSTNAME --keylength $1 -w /var/www/discourse/public
}

В файле:
/var/discourse/templates/web.letsencrypt.ssl.template.yml

Затем, конечно:

./var/discourse/launcher rebuild app

Это не решение: изменения будут утрачены при обновлении шаблонов, и по одной этой причине такой подход не рекомендуется.

Если вы хотите модифицировать файлы внутри контейнера, используйте хуки в вашем файле app.yml.

Да, я не вижу способа реализовать это так, чтобы это не могло сломаться при обновлениях. Это просто участь тех, кто выделил отдельные домены для сообществ и не любит лишние поддомены.

Разве что не запустить другой веб-сервер где-то ещё, конечно.

Если вы используете поиск, уже существуют руководства по изменению регистрации сертификатов.

Правильно, я уже вижу одну попытку, которая была прервана из-за изменения файла, что нарушило способ, которым они настраивали его изменение в app.yml:

Независимо от того, редактируем ли мы файл напрямую или позволяем app.yml изменить его после, обновление может изменить этот файл и нарушить ваш способ его редактирования в любом случае.

Моя мысль в том, что любое изменение этого шаблона снова сломает его. За последние несколько лет метод PUPS/hooks ломался только из-за одного изменения — добавления поддержки ECC.