SIRINVIDEO Документация администратора и интегратора На сайт 2026.08

TLS и сертификаты

Включение HTTPS и RTSPS, загрузка своего сертификата, автоматический выпуск по ACME, несколько имён через SNI и разбор типичных ошибок выпуска.

Сервер принимает TLS-соединения сам: отдельный веб-сервер или обратный прокси для HTTPS не нужен. Сертификат можно загрузить свой, получить автоматически по протоколу ACME или оставить самоподписанный — последний создаётся сам и годится только для проверки.

Слушатели TLS#

TLS включается объявлением защищённого слушателя. Без него сертификаты не используются, даже если они настроены.

Параметр Тип и допустимые значения По умолчанию Применение
https номер порта, 0 — выключено 0 рестарт
rtsps номер порта, 0 — выключено 0 рестарт
rtmps номер порта, 0 — выключено 0 рестарт
http 80;      # оставьте открытым: на нём отвечает проверка ACME
https 443;
rtsp 8554;
rtsps 8555;

Все порты применяются только при перезапуске службы (systemctl restart hastreamer), а не при reload. Порты должны различаться между собой, иначе конфигурация отвергается:

invalid config /etc/hastreamer/hastreamer.conf: https and rtsps both use port 8443 — listener ports must be distinct
HTTP-слушатель нужен и после включения HTTPS

Порт http — не только «незащищённая версия» панели. На нём отвечает проверка владения именем при выпуске сертификата ACME, и делает это до любой авторизации. Если вы закрыли http совсем, автоматический выпуск работать не будет.

Три способа получить сертификат#

Способ Когда применять Что настраивается
Самоподписанный стенд, локальная проверка, внутренний контур без доверия к именам ничего: создаётся автоматически
Свой сертификат есть корпоративный УЦ или купленный сертификат, нужен подстановочный (*.example.com) блок certificate с путями к PEM
Автовыпуск ACME публичное имя, доступное из интернета по порту 80 блок certificate с флагом acme

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

Самоподписанный сертификат#

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

https 443;

tls {
  self_signed_names media.example.com localhost;
}
Параметр Тип и допустимые значения По умолчанию Применение
cert путь к PEM-цепочке; абсолютный или относительно хранилища TLS "" горячее
key путь к PEM-ключу "" горячее
ca путь к промежуточным сертификатам (только в блоке certificate) "" горячее
self_signed_names список имён для самоподписанной пары localhost горячее
sync_from путь к внешнему PEM-файлу, из которого копировать пару "" горячее

Блок tls { } задаёт сертификат по умолчанию: он предъявляется, когда клиент не прислал имя (SNI) или когда ни один именованный сертификат под это имя не подошёл.

Файлы самоподписанной пары лежат в хранилище TLS — каталоге tls-state внутри рабочего каталога службы (/var/lib/hastreamer/tls-state/ при установке по умолчанию). Относительные пути в cert и key отсчитываются от него же.

sync_from нужен, когда пару обновляет другая служба на этом же хосте: сервер копирует исходный PEM в собственные файлы cert/key, проверяет их и подменяет «на лету». Указывать cert и key при этом обязательно — они и есть цель копирования:

invalid config …: tls: `sync_from` requires `cert` and `key` (the node-owned snapshot paths the source is copied into)
Самоподписанный сертификат не подходит для браузера

Браузер покажет предупреждение, а публикация из браузера (WHIP) и часть возможностей плеера требуют доверенного соединения. Для рабочей установки используйте ACME или сертификат вашего УЦ.

Свой сертификат#

Положите PEM-файлы и ограничьте права на ключ:

sudo install -d -o root -g root -m 0700 /etc/hastreamer/certs
sudo install -o root -g root -m 0644 fullchain.pem /etc/hastreamer/certs/fullchain.pem
sudo install -o root -g root -m 0600 privkey.pem   /etc/hastreamer/certs/privkey.pem

Объявите именованный сертификат:

https 443;

certificate edge1 {
  hosts media.example.com;
  cert  /etc/hastreamer/certs/fullchain.pem;
  key   /etc/hastreamer/certs/privkey.pem;
  ca    /etc/hastreamer/certs/chain.pem;   # необязательно: промежуточные УЦ
}

Применение — горячее, разрыва соединений нет:

sudo hastreamer --validate /etc/hastreamer/hastreamer.conf
sudo systemctl reload hastreamer

Тот же результат даёт панель (Configuration → Certificates → Add or replace a certificate, режим Upload PEM) или API:

curl -sS -X POST "https://media.example.com/api/v1/certs/edge1" \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"hosts":["media.example.com"],
       "cert":"-----BEGIN CERTIFICATE-----\n…\n-----END CERTIFICATE-----\n",
       "key":"-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----\n"}'

Пара «сертификат — ключ» проверяется до сохранения: несовпадающая пара отвергается и ничего не перезаписывает. Сохранённые файлы получают права 0600 и подхватываются без перезапуска.

Автоматический выпуск (ACME)#

Сервер умеет сам заказывать и продлевать сертификаты по ACME с проверкой HTTP-01.

Настройка#

http 80;          # обязательно: на этом слушателе отвечает проверка
https 443;

acme_contact ops@example.com;

certificate media.example.com {
  hosts media.example.com;
  acme;
}
Параметр Тип и допустимые значения По умолчанию Применение
acme_directory URL каталога удостоверяющего центра https://acme-v02.api.letsencrypt.org/directory рестарт
acme_contact адрес электронной почты для уведомлений УЦ "" рестарт
acme (в блоке certificate) флаг: acme;, acme on;, acme off; off горячее

Обратите внимание на разное применение: сам блок certificate — «горячий» (добавляется без перезапуска), а параметры учётной записи acme_directory и acme_contact — «рестартные». Настраивайте их до первого выпуска.

Что должно совпасть, иначе выпуска не будет#

  1. Объявлен хотя бы один защищённый слушатель (https, rtsps или rtmps). Без него задача выпуска вообще не запускается.
  2. Имена конкретные, без подстановок. HTTP-01 не выпускает *.example.com.
  3. Удостоверяющий центр должен достучаться до http://media.example.com/.well-known/acme-challenge/<токен> по порту 80. Сервер отвечает на этот путь на своём http-слушателе открытым текстом, до авторизации и маршрутизации. Если http не равен 80, пробросьте внешний 80-й порт на него.
  4. Разрешены исходящие HTTPS-соединения к адресу из acme_directory.
  5. Имя в DNS указывает на этот сервер.
Ошибка в этих условиях не мешает старту — сертификат просто не появляется

Конфигурация с acme проходит проверку, даже если ни одного защищённого слушателя нет: сервер запустится и будет молча работать без сертификата. Смотрите журнал — сообщения об ошибках выпуска начинаются с acme[<имя>]:.

Как это работает#

  • Внутренняя задача выпуска сканирует конфигурацию раз в 60 секунд и начинает со сна — чтобы слушатели успели подняться до первой проверки со стороны УЦ.
  • Конфигурация читается живой: добавленный через панель или API сертификат подхватывается за один цикл, без перезапуска.
  • Продление начинается за 30 суток до окончания срока, так что у неудачного продления есть недели на повторы.
  • При неудаче — нарастающая пауза: 15 минут после первой ошибки, удвоение на каждой следующей, верхний предел 6 часов. Это защита от лимитов УЦ.
  • Выпущенная пара подставляется в SNI-хранилище на лету: без перезапуска и без обрыва зрителей. Если пересборка не удалась, продолжает работать прежний сертификат.
  • Файлы: tls-state/certs/<имя>/acme.cert.pem, acme.key.pem и acme.meta.json рядом. Ключ учётной записи ACME сохраняется в tls-state/acme/account.key.pem при первом выпуске, поэтому учётная запись переживает перезапуски.

Успешный выпуск виден в журнале:

acme: issued/renewed cert(s) hot-swapped into the SNI store
Отлаживайте на тестовом каталоге УЦ

Пока вы проверяете доступность порта 80 и записи DNS, укажите тестовый каталог: acme_directory https://acme-staging-v02.api.letsencrypt.org/directory;. Он выдаёт недоверенные сертификаты, зато с мягкими лимитами. Затем верните рабочий каталог и перезапустите службу — параметр «рестартный».

Несколько имён и SNI#

Каждое имя описывается своим блоком certificate. Сервер выбирает сертификат по имени, которое клиент прислал в TLS-рукопожатии (SNI); если совпадения нет — предъявляется пара из блока tls { }.

http 80;
https 443;

acme_contact ops@example.com;

# Публичное имя — выпускается автоматически.
certificate public {
  hosts media.example.com;
  acme;
}

# Внутреннее имя и весь домен филиалов — сертификат корпоративного УЦ.
certificate internal {
  hosts media.internal.example.com *.branch.example.com;
  cert  /etc/hastreamer/certs/internal-fullchain.pem;
  key   /etc/hastreamer/certs/internal-privkey.pem;
}

# Что предъявлять, если имя не подошло или клиент его не прислал.
tls {
  cert /etc/hastreamer/certs/internal-fullchain.pem;
  key  /etc/hastreamer/certs/internal-privkey.pem;
}

Правила именования узлов в hosts:

  • перечисляйте имена через пробел, в одной строке;
  • подстановка допускается только вида *.suffixодна метка (*.branch.example.com подходит, *.*.example.com — нет);
  • подстановочные имена возможны только с загруженным сертификатом: автовыпуск их не поддерживает;
  • имена блоков должны быть уникальны.

Проверка#

Сервер предъявляет ожидаемый сертификат
openssl s_client -connect media.example.com:443 -servername media.example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates
subject=CN = media.example.com
issuer=C = US, O = Example CA, CN = Example CA R3
notBefore=Aug 19 09:14:00 2026 GMT
notAfter=Nov 17 09:13:59 2026 GMT

Список всех известных серверу сертификатов, включая срок и состояние автовыпуска:

curl -sS "https://media.example.com/api/v1/certs" -H "Authorization: Bearer $TOKEN"

Данные читаются из сохранённых файлов, а не из конфигурации, поэтому показывают то, что сервер действительно предъявит. То же видно в панели: Configuration → Certificates, где у записи с автовыпуском есть значок ACME и состояние — сколько суток осталось, идёт ли выпуск, была ли ошибка продления.

Типичные ошибки#

Ошибки конфигурации (проверяются hastreamer --validate, приведены дословно):

Сообщение Причина
certificate "edge1": needs at least one `hosts` entry (else it is never selected) в блоке нет ни одного имени — такой сертификат никогда не будет выбран
certificate "edge1": `cert` and `key` paths are required (or set `acme` to auto-issue) не указаны пути к PEM и не включён автовыпуск
certificate "edge1": `acme` and explicit `cert`/`key` are mutually exclusive нельзя одновременно загрузить пару и заказать выпуск
certificate "edge1": ACME/HTTP-01 cannot issue the wildcard "*.example.com" — give a concrete hostname подстановочное имя с флагом acme
duplicate certificate name "edge1" два блока с одинаковым именем
https and rtsps both use port 8443 — listener ports must be distinct два слушателя на одном порту

Ошибки выпуска (конфигурация верна, сертификат не появляется):

Симптом Причина Что делать
Сертификата нет, и в журнале нет ни одной строки об ACME — ни об ошибке (acme[имя]: …), ни об успехе не объявлен защищённый слушатель — задача выпуска не запущена добавьте https <порт>; и перезапустите службу
acme[имя]: … с ошибкой проверки УЦ не смог получить http://<имя>/.well-known/acme-challenge/<токен> на порту 80 откройте порт 80 снаружи и пробросьте его на http-слушатель; проверьте запись DNS
Ошибка соединения с каталогом УЦ закрыт исходящий HTTPS разрешите исходящие соединения к адресу из acme_directory
Повторные попытки идут редко сработала нарастающая пауза (до 6 часов) исправьте причину и перезапустите службу, чтобы не ждать окончания паузы
Браузер показывает старый сертификат клиент держит установленное соединение подмена действует на новых рукопожатиях; переоткройте соединение
Сертификат есть, но не предъявляется имя в hosts не совпадает с тем, что запрашивает клиент сверьте SNI: openssl s_client -servername …

Что дальше#