Назад к блогу Webship

Инженерия Webship

TLS-сертификаты в Webship: встроенный ACME CA

Посмотрите, как Webship 1.4.0 выпускает и обновляет частные TLS-сертификаты для каждого сайта с помощью встроенного удостоверяющего центра, как работает доверие клиента и как встроенные идентификации сосуществуют с публичными сертификатами ACME и вручную установленными сертификатами.

# TLS-сертификаты в Webship: встроенный ACME CA

TLS-сертификат выполняет две функции: он помогает шифровать соединение и сообщает клиенту, с какой идентичностью он взаимодействует. Шифрование может быть сильным, в то время как решение о доверии неправильное для аудитории. Именно поэтому автоматизация сертификатов должна начинаться с одного вопроса: кто должен доверять этому сайту?

Webship 1.4.0 делает этот выбор независимо для каждого настроенного сайта. Публичный веб-сайт может использовать браузер-доверенный ACME сертификат, внутренний сервис может использовать встроенный частный центр сертификации Webship, а сайт с существующей PKI может сохранить управляемые оператором файлы сертификатов. Все они могут использовать один процесс Webship без совместного использования одного приватного ключа или одной границы доверия.

Четыре автоматических режима сертификации, выбираемых для каждого сайта

Поле certificate_mode относится к каждой записи [[sites]]. Это не глобальный переключатель.

| Режим | Доверенный источник | Наилучшее соответствие | Путь проверки | | --- | --- | --- | --- | | per_site | Публичные хранилища доверия браузеров и операционных систем | Публичный сайт с одним точным именем хоста | Публичный ACME с TLS-ALPN-01 | | флот | Публичные хранилища доверия браузеров и операционных систем | Большие наборы имен третьего и четвертого уровней под явными зарегистрированными доменами | Публичный ACME с DNS-01 и стабильными сегментами сертификатов | | встроенный | Частный корень Webship, установленный оператором | Внутренние сервисы, управляемые устройства, частные флоты и тестовые среды | Выпуск в процессе; внешние проверки отсутствуют | | общий | Публичные хранилища доверия браузеров и операционных систем | Устаревшие развертывания, которые намеренно используют одну публичную группу multi-SAN | Публичный ACME с TLS-ALPN-01 |

По умолчанию используется per_site. Он заказывает один публичный сертификат для точного имени сайта. Режим Fleet является масштабируемым публичным вариантом для множества глубоких поддоменов. Встроенный режим использует частный внутренний CA Webship. Общий режим по-прежнему доступен для совместимости, но он не является настройкой по умолчанию.

Полный сертификат и ключ в разделе [sites.tls] всегда имеют приоритет над автоматической выдачей для этого сайта.

Что означает «встроенный ACME CA»

Раздел конфигурации называется [acme_ca], но встроенный CA не является публичным или доступным через сеть сервисом ACME. Он не предоставляет конечную точку каталога, не принимает удаленную регистрацию, не вызывает API регистрара и не выполняет проверку контроля с помощью задания доказательства.

Вместо этого Webship хранит весь путь частного выпуска в одном процессе:

  1. Сайт выбирает certificate_mode = "embedded".
  2. Webship загружает или создает приватную корневую идентичность в настроенной директории состояния.
  3. Webship генерирует новый приватный ключ для сайта.
  4. Встроенный корневой сертификат подписывает сертификат для листа именно с этим именем.
  5. Webship проверяет завершённую идентификацию перед её установкой в рабочий TLS-резолвер.
  6. Затем сертификат становится доступным для каждого включенного протокола для этого сайта.

Сетевой вызов в стиле ACME подтвердил бы Webship только самому себе, поэтому встроенный путь намеренно не имеет сетевого протокола. Раздел [acme_ca] — это частное состояние PKI: он определяет, где находится корень, и как долго действуют выданные конечные сертификаты.

Настройте встроенный сертификат для одного сайта

Это минимальная форма для частного сайта:

~~~toml listen = "0.0.0.0:443"

[tls] unknown_sni = "reject"

[автоматический_tls] включено = true cache_dir = "/var/lib/webship/acme"

[acme_ca] state_dir = "/var/lib/webship/acme-ca" срок_действия_листа_в_днях = 90

[[сайты]] домен = "service.internal.example" root = "/srv/service" certificate_mode = "встроенный"

[сайты.протоколы] h1 = правда h2 = правда h3 = правда ~~~

Корневая идентификация создается лениво, когда встроенный сайт впервые нуждается в ней. Webship сохраняет корневой ключ с ограничительными разрешениями в state_dir. Срок действия корневого сертификата составляет десять лет; срок действия листа контролируется параметром leaf_validity_days.

Рассматривайте оба места хранения как состояние производства:

  • Кэш ACME хранит автоматически управляемые идентификаторы сайтов.
  • Каталог состояния встроенного УЦ содержит приватный корневой идентификатор.
  • У учетной записи сервиса нужен доступ, но пользователи приложения не нуждаются.
  • Резервные копии должны сохранять конфиденциальность и права доступа к файлам.
  • Для производства, разработки и тестирования следует использовать отдельные корневые каталоги и отдельные директории.

Удаление корневого каталога не «сбрасывает TLS». Это создаёт новый корневой сертификат доверия. Клиенты, которые доверяют старому корню, будут отклонять сертификаты, выданные заменой, пока их хранилища доверия не будут обновлены.

Частный траст является намеренным

Сертификаты от встроенного УЦ не доверяются автоматически публичными браузерами или операционными системами. Они становятся доверенными только после того, как оператор установит экспортированный корневой сертификат Webship в хранилище доверия клиента.

Это делает встроенный режим хорошим вариантом для:

  • ноутбуки и телефоны, управляемые компанией, зарегистрированные через управление устройствами;
  • внутренний трафик между сервисами с явным пакетом CA;
  • частные устройства и контролируемые периферийные парки;
  • среды разработки и тестирования, которые должны использовать реальное поведение TLS;
  • отключенные сети, которые не могут полагаться на общедоступный центр сертификации.

Это не правильный режим для обычного публичного веб-сайта, посетители которого используют немодерируемые браузеры. Используйте публичную выдачу per_site для точного публичного имени, выдачу для флота для больших наборов публичных поддоменов, shared только для преднамеренной устаревшей многосетевой SAN-развертки или ручные файлы от уже доверенной PKI.

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

Публичные и приватные сертификаты могут сосуществовать

Webship 1.4.0 может смешивать стратегии сертификатов на одном слушателе:

~~~toml listen = "0.0.0.0:443"

[tls] unknown_sni = "reject"

[автоматический_tls] включено = true directory_url = "https://acme-v02.api.letsencrypt.org/directory" cache_dir = "/var/lib/webship/acme" contacts = ["mailto:ops@example.com"] принять_условия_обслуживания = true

[acme_ca] state_dir = "/var/lib/webship/acme-ca" leaf_validity_days = 90

[[сайты]] домен = "www.example.com" root = "/srv/public" certificate_mode = "по_сайту"

[[сайты]] домен = "control.internal.example" root = "/srv/control" certificate_mode = "встроенный"

[[сайты]] домен = "payments.example.com" root = "/srv/payments"

[сайты.tls] cert = "/etc/webship/payments-fullchain.pem" key = "/etc/webship/payments-private-key.pem" ~~~

Здесь www.example.com получает свой собственный публичный ACME-сертификат. control.internal.example получает приватный сертификат от встроенного УЦ. payments.example.com остается под внешней PKI оператора, так как его явные файлы имеют приоритет.

Публичный каталог ACME игнорируется встроенными сайтами. Встроенный корень никогда не подписывает публичный сайт. Ручной сайт никогда не вовлекается автоматически в какой-либо рабочий процесс.

Один резольвер сертификатов для H1, H2, H3 и WebTransport

Выбор сертификата происходит во время TLS-рукопожатия, до появления HTTP-запроса. Webship использует имя сервера из ClientHello для выбора идентичности сайта, а затем согласует протокол приложения.

  • HTTP/1.1 и HTTP/2 используют TLS поверх TCP.
  • HTTP/3 и WebTransport используют TLS внутри QUIC поверх UDP.
  • Одна действительная идентификация сайта может обслуживать каждый включённый протокол.
  • HTTP/3 также требует доступности UDP; H1 и H2 используют путь TCP.
  • Alt-Svc может рекламировать H3 с сохранением резервного варианта TCP.

TCP, TLS и QUIC используют одну и ту же модель идентичности, учитывающую сайт. Точные имена имеют приоритет, побеждает самый длинный допустимый универсальный сертификат там, где настроены универсальные сертификаты, а неизвестный указанный SNI может быть отклонен вместо получения несвязанного сертификата по умолчанию.

Используйте unknown_sni = "reject" на слушателе с несколькими сайтами, когда неподтвержденное имя хоста должно приводить к отказу. Протестируйте распознаваемые имена, неподтвержденные имена и ожидаемое поведение без SNI перед развертыванием в производственной среде.

Вращайте встроенные идентичности без периода простоя

Webship предоставляет состояние сертификата и контролируемые изменения через свой аутентифицированный MCP-сервер, привязанный к локальной петле:

  • webship.tls.get_status сообщает о активном резольвере сертификатов и состоянии его обновления.
  • webship.tls.reissue_certificate немедленно перевыпускает автоматически управляемый сайт только когда этот сайт использует встроенный режим.
  • webship.tls.reload перезагружает состояние сертификата через обычный защищённый TLS-путь.
  • webship.acme_ca.status сообщает, выбрана ли частная CA, ее каталог состояния, срок жизни листа, количество выданных сертификатов, количество отзывов и недавний пример домена.
  • webship.sites.apply добавляет или удаляет сайты в соответствии с закрепленной версией конфигурации.

Для встроенного повторного выпуска Webship создает и проверяет замену перед тем, как включить её в эксплуатацию. Текущая действительная идентичность продолжает обслуживать, пока новая идентичность не будет готова. Снятая с эксплуатации идентичность регистрируется только после установки замены.

Операция немедленного переиздания намеренно отклоняет публичные сертификаты per_site. Публичное обновление должно оставаться внутри публичного жизненного цикла ACME, а не путаться с частной процедурой подписи в процессе. Участие в режиме общего использования также заморожено при перезапуске, поскольку изменение группы с несколькими SAN восстанавливает границу идентичности.

MCP — это привилегированная управляющая поверхность. Держите её в режиме петли, требуйте TLS и сильный токен носителя, используйте аутентифицированный туннель для удалённого администрирования и проводите аудит каждой модификации.

Границы неудачи, которые имеют значение

Система защищённых сертификатов должна выходить из строя в правильном направлении.

  • Недавно настроенный встроенный сайт не получает идентификатор другого сайта, пока выпуск ожидается.
  • Неправильная замена не устанавливается поверх действующего сертификата.
  • Явные ручные файлы предотвращают автоматическое присвоение собственности на этот сайт.
  • Неизвестный именованный SNI может быть отклонён до маршрутизации HTTP.
  • Встроенный УЦ остается приватным и не имеет удаленной точки регистрации.
  • Публичные и встроенные идентификаторы используют отдельные пути кэширования внутри состояния автоматического TLS.

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

Контрольный список производства

Перед включением встроенного режима:

  1. Определите каждую клиентскую группу, которая должна доверять сайту.
  2. Создайте контролируемый процесс для экспорта и установки корневого сертификата.
  3. Используйте отдельное корневое состояние для производства, разработки и тестирования.
  4. Сохраняйте и защищайте каталог состояния встроенного CA и кэш автоматического TLS.
  5. Запускайте Webship с использованием выделенной служебной учетной записи, имеющей доступ только к необходимым ключевым материалам.
  6. Выберите certificate_mode на каждом сайте, чья граница доверия должна быть явной.
  7. Установите и протестируйте политику для неизвестного SNI.
  8. Преднамеренно включите H1, H2 и H3 и проверьте как TCP, так и UDP пути.
  9. Практиковать повторный выпуск, перезапуск, резервное копирование, восстановление и проверку доверия клиента вне производственной среды.
  10. Перед развертыванием запустите webship --check-config, затем проверьте эмитента, имена, действительность, цепочку и согласованные протоколы на реальном клиенте.

Выбирайте сначала доверие, затем автоматизацию

Встроенный УЦ устраняет зависимость от внешнего сервиса сертификатов для частной инфраструктуры. Он не делает частный корневой сертификат глобально доверенным и не снимает с оператора ответственность за PKI.

Webship автоматизирует генерацию ключей, подпись, проверку, установку, ротацию и выбор сертификатов по всему протоколу. Оператор по-прежнему сохраняет контроль над корневым ключом, регистрацией клиентов, разделением окружений, резервным копированием, восстановлением и решением использовать публичный или частный путь доверия.

Это разделение является особенностью. Самостоятельный сервер может автоматизировать приватный TLS без притворства публичным центром сертификации — и при этом публичные сайты все равно могут использовать доверенную браузером выдачу для отдельных сайтов или для всего пула в том же процессе.

Прочтите версионированную документацию Webship 1.4.0 перед развертыванием. RFC 5280 определяет профили сертификатов и проверку, RFC 6066 определяет сигнализацию имени сервера TLS, RFC 8446 определяет TLS 1.3, RFC 8555 определяет публичный ACME, а RFC 9525 определяет проверку идентичности сервиса.