Получение wildcard сертификата let's encrypt для работы по https

Про получение сертификата let's encrypt с использованием certbot уже написано уже множество статей, и обычно это не вызывает особых проблем. Но чаще всего речь идёт только о получении обычных сертификатов — когда он получается только для одного конкретного домена, например mysite.ru. Если же мы создадим поддомен, например billing.mysite.ru, то для него нужно будет получать отдельный сертификат. В обычном случае это тоже не вызывает проблем ведь let's encrypt позволяет сделать несколько сертификатов (у let's encrypt есть определённые лимиты, но в обычно ситуации превысить их достаточно сложно).

Но иногда нужно получить сертификат wildcard — он будет работать для любых поддоменов вашего домена. Это полезно, когда вам нужно сделать возможность пользователям добавлять свои поддомены. Let's encrypt позволяет создавать такие сертификаты, но увы, метод подтверждения прав на домен путём создания файлов .well-known, как это обычно делается при получении обычных сертификатов, здесь не работает. Права на домен нужно получать через DNS.

Сложности подтверждения прав через DNS

Для того, чтобы подтвердить права на домен, нужно создать DNS-запись для домена типа TXT и в ней указать код подтверждения. Вроде как в этом нет ничего сложного, поскольку в любом DNS-хостинге в панели управления можно создать такую запись.

Но проблема в том, что нам недостаточно просто один раз получить сертификат — нужно, чтобы он автоматически обновлялся. Конечно, можно обновлять его и вручную. Но опыт показывает, что это неизбежно приведёт к тому, что продлить его в какой-то момент забудут и пользователи останутся без доступа к сайту. Поэтому важно настроить именно автоматическое продление.

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

Рассмотрим для примера работу с Сloudflare. Вообще компания Сloudflare предоставляет услуги по предоставлению CDN, но в качестве сопутствующей услуги у них есть бесплатный DNS-хостинг.

Делегируем наш домен на Cloudflare

Допустим у вас есть домен mysite.ru, где уже работает какой-то сайт. Он работает на каком-то другом DNS-хостинге, а нам нужно перенести его на cloudflare для того, чтобы была возможность получить возможность внесения изменений в DNS через certbot.

1. Регистрируемся на cloudflare.com

2. Заходим в раздел Websites

3. Жмём "Add a site"

4. Указываем наш домен mysite.ru (без www или http://, просто домен)

5. Выбираем тарифный план Free

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

7. Ставим proxy status = off (потому что CDN нам не нужен, нас интересует только DNS).

Этап, связанный с «improve security» и «Optimize performance» можно пропустить на этом этапе.

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

А именно:

1. Зайти в панель управления регистратора, где зарегистрирован домен, найти домен mysite.ru.

2. Удалить те DNS-серверы, которые там есть.

3. Добавить вместо них coen.ns.cloudflare.com и holly.ns.cloudflare.com.

4. Сохранить изменения.

После этого можно вернуться в панель cloudflare, нажать «Done, check nameservers». Нас предупреждают, что полное обновление может занять до 24 часов. Стоит дождаться полного переноса домена на cloudflare прежде, чем продолжать далее — обновляйте страницу, пока не увидите сообщение «Great news! Cloudflare is now protecting your site».

Обеспечиваем доступ к DNS для certbot

1. Заходим в раздел «User API Tokens», «User API Tokens».

2. Жмём «Create Token», выбираем тип «Edit zone DNS».

3. В разделе «Zone Resources» в пункте «Zone Resources» выбираем наш домен.

Остальные параметры можно оставить как есть.

Затем жмём «Continue to summary» и «Create Token».

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

Настройка certbot на сервере

Приступаем к настройке сервера. Устанавливаем certbot и плагин для доступа к cloudflare:

sudo snap install certbot certbot-dns-cloudflare

Создаём файл /root/.secrets/certbot/cloudflare.ini следующего содержания:

dns_cloudflare_api_token = VBGnM5sadfsadfsadfsadfYo1ZNSVzZdraaMu-69

Где VBGnM5sadfsadfsadfsadfYo1ZNSVzZdraaMu-69 — ваш скопированный токен.

После этого можно запускать certbot:

sudo certbot certonly --agree-tos -d mysite.ru -d *.mysite.ru --dns-cloudflare --dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini --dns-cloudflare-propagation-seconds 60

Если всё прошло как надо, то получаем сообщение вида:

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/mysite.ru/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/mysite.ru/privkey.pem
This certificate expires on 2024-01-30.
These files will be updated when the certificate renews.

Далее нужно настроить использование этого сертификата в веб-сервере, но это уже тема для отдельной статьи.

Автоматическое обновление серификата

Для того, чтобы не получить внезапно неработающий сайт после 30 января, нужно настроить автоматическое обновление. Поскольку доступ к DNS у нас уже работает, то настроить автоматическое обновление не будет сложно. Достаточно настроить автоматический запуск certbot в режиме обновления. Для этого можно использовать cron. Вводим в консоли команду:

sudo crontab -e

Добавляем строку:

0 * * * * certbot renew

Не забываем сохранить файл перед выходом.

После этого обновление certbot будет запускаться каждый час в 00 минут. Не слишком ли часто? Нет, потому что certbot сам проверит дату истечения сертификатов. Если время обновления ещё не пришло, то ничего обновлять не будет.