Домашние сервисы обычно открываются по HTTP, и это первым замечает любой член семьи: браузер ругается на незащищённое соединение, пароли летят по сети открытым текстом, а приложения отказываются сохранять данные. Сертификаты решают эту проблему, но у домашней инфраструктуры нет публичного адреса и часто нет домена. Разберём три подхода: Let’s Encrypt с DNS-челленджем, автоматический ACME через acme.sh и собственный внутренний центр сертификации.

Какой способ кому подходит

  • HTTP-01 требует доступ к порту 80 извне и прописанную запись в DNS; за домашним NAT или CGNAT он не сработает.
  • DNS-01 проверяет TXT-запись у DNS-провайдера: открытые порты не нужны, а результат — wildcard-сертификат сразу на все поддомены.
  • Внутренний CA работает полностью локально для имён вида nas.home.arpa и адресов 192.168.x.x, но доверие придётся распространить на каждое устройство.

Let’s Encrypt через DNS-челлендж

Если домен обслуживается провайдером с API, certbot получит сертификат без единого открытого порта. Плагин ставится отдельно, а ключ доступа хранится в файле с жёсткими правами:

sudo apt install certbot python3-certbot-dns-cloudflare
printf 'dns_cloudflare_api_token = ТОКЕН\n' | sudo tee /etc/letsencrypt/cloudflare.ini
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
sudo certbot certonly --dns-cloudflare -d example.ru -d '*.example.ru'

Готовый сертификат ляжет в каталог /etc/letsencrypt/live/example.ru/: полная цепочка — файл fullchain.pem, ключ — privkey.pem. Обслуживание заданий проверяется штатным таймером, который создаёт пакет certbot:

sudo certbot renew --dry-run
systemctl list-timers | grep certbot
sudo systemctl enable --now certbot.timer

В драй-ране видно, какой плагин используется для обновления и не упирается ли он в лимиты: Let’s Encrypt ограничивает количество выпусков на один домен в неделю, поэтому хаотичные пересоздания сертификата упираются в лимит и разрушают доверие к автоматике.

acme.sh как альтернатива

acme.sh — самодостаточный скрипт на shell без зависимости от Python, удобен там, где не хочется тянуть пакеты. Он ставится под пользователем, хранит учётные данные в своём каталоге и регистрирует задание в планировщике. Для nginx предусмотрен хук, перечитающий конфиг после продления:

curl https://get.acme.sh | sh -s email=admin@example.ru
acme.sh --issue --dns dns_cf -d example.ru
acme.sh --install-cert -d example.ru --key-file /etc/ssl/private/site.key --fullchain-file /etc/ssl/certs/site.crt --reloadcmd "systemctl reload nginx"

Перед выпуском экспортируйте переменную с токеном DNS-провайдера, иначе плагин не сможет создать TXT-запись. Следите за тем, где лежат ключи: каталог по умолчанию создаётся с правами 700, и его не стоит переносить на общедоступный диск. Полезные команды для обслуживания:

acme.sh --list
acme.sh --upgrade
crontab -l | grep acme.sh

Первая команда показывает все выпущенные сертификаты и даты следующего продления, вторая обновляет сам скрипт вместе с плагинами DNS-провайдеров. Проверяйте её раз в несколько месяцев: API провайдеров меняется, и устаревший плагин — самая частая причина тихого отказа автоматического продления.

Публикация сертификата в веб-сервере

Полученный сертификат привязывается к виртуальному хосту. В nginx указываются оба файла, и обязательно полная цепочка, иначе клиенты не получат промежуточный сертификат:

server {
    listen 443 ssl;
    http2 on;
    server_name nas.example.ru;
    ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
}

Блок на 80-м порту оставьте для редиректа и для будущих проверок HTTP-01. После каждой выдачи или продления перечитывайте конфигурацию deploy-хуком: ошибки в ней не всплывают сами, клиенты просто продолжают получать старый сертификат.

Внутренний центр сертификации

Когда публичного домена нет вовсе, честнее поднять собственный CA. Компактный вариант на openssl устроит для одного-двух серверов: корневой сертификат живёт десять лет, серверные выпускаются на год и подписываются им же.

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout ca.key -out ca.crt -subj "/CN=Home Lab CA"
openssl req -new -newkey rsa:2048 -nodes -keyout nas.key -out nas.csr -subj "/CN=nas.home.arpa"
openssl x509 -req -in nas.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -out nas.crt -extfile san.cnf

Файл san.cnf задаёт обязательные альтернативные имена: subjectAltName = DNS:nas.home.arpa, IP:192.168.1.10. Без поля SAN браузер отклонит сертификат даже с правильным именем хоста — это самая частая ошибка ручного выпуска. Для инфраструктуры побольше рассмотрите step-ca: он поднимает ACME-сервер внутри сети и выдаёт сертификаты автоматически, без публичных сервисов.

Сами сертификаты раздаются по сети: скопируйте nas.crt и nas.key на целевую машину, а ca.crt — всем клиентам. Отзыв для личного CA почти не нужен: проще перевыпустить серверный сертификат с новым сроком, чем поддерживать список отозванных и обновлять его на каждом устройстве.

Доверие на клиентах

Корневой сертификат нужно установить в доверенные: на Debian и Ubuntu это делается системно, после чего curl и большинство утилит перестают ругаться.

sudo cp ca.crt /usr/local/share/ca-certificates/home-ca.crt
sudo update-ca-certificates
echo | openssl s_client -connect nas.home.arpa:443 -servername nas.home.arpa | openssl x509 -noout -subject -issuer -dates

Firefox и Thunderbird хранят доверие отдельно от системного хранилища: импортируйте ca.crt в раздел сертификатов либо разворачивайте его через организационную политику. На Android добавление корневого сертификата — отдельное действие в настройках безопасности, и без него приложение с внутренним адресом снова покажет ошибку.

Проверять удобно в таком порядке: сначала клиент, потом цепочка, потом сроки. Команда curl с флагом -v покажет, какой сертификат сервер реально отправил и совпал ли он с ожидаемым субъектом:

curl -vk https://nas.home.arpa 2>&1 | grep -E 'subject|issuer|expire'
grep -c 'Home Lab CA' /etc/ssl/certs/ca-certificates.crt

Типичные ошибки и контроль сроков

  1. В конфиге веб-сервера указан cert.pem вместо fullchain.pem — клиенты не получают промежуточный сертификат и сообщают об ошибке цепочки.
  2. Права на privkey.pem шире 600 — сервер отказывается стартовать, а причина видна только в журнале.
  3. Сертификат просрочился: проверяйте дату openssl-командой и подключите срок к мониторингу.
  4. Пакет ca-certificates устарел — обновите его, иначе новые корневые сертификаты не подхватятся.

Итог

Для домашних сервисов удобна связка: wildcard-сертификат Let’s Encrypt через DNS-челлендж для публичных имён и собственный CA для внутренних адресов. Важнее не выбрать инструмент, а выстроить жизненный цикл: автоматическое продление, доверие на всех клиентах и контроль сроков. С настроенным циклом HTTPS перестаёт быть разовой задачей и становится фоновой частью инфраструктуры.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте