14.4.4. Сертификаты, подписанные CA (с публичным доверием)

Самоподписанные сертификаты работают, когда вы контролируете обе стороны. Если же произвольные клиенты (браузеры, телефоны, стороннее ПО) должны подключаться к камере без указания доверять пользовательскому сертификату, сертификат должен быть подписан публичным центром сертификации (Certificate Authority, CA), которому эти клиенты уже доверяют. TLS-код на камере идентичен случаю с самоподписанным сертификатом – load_cert_chain с сертификатом и ключом в форме DER – меняется лишь способ получения этого сертификата.

Самый важный момент: закрытый ключ вы генерируете сами, и он никогда не покидает вашу машину. CA никогда его не видит. То, что вы отправляете CA, – это запрос на подпись сертификата (CSR) – небольшой файл, содержащий ваш открытый ключ и ваше доменное имя, а то, что вы получаете обратно, – это сертификат (ваш открытый ключ и имя, подписанные CA). Ключ и сертификат – это два отдельных файла, создаваемых двумя отдельными шагами; CA имеет дело только с открытой половиной.

Общий процесс, полностью выполняемый на обычной машине (никогда на камере):

  1. Получите доменное имя. Публичные CA сертифицируют DNS-имя, которое вы контролируете (например, cam.example.com); они не выдают сертификаты для голого IP-адреса или локального имени вроде mycam.

  2. Сгенерируйте ключ и CSR. Одна команда OpenSSL создаёт закрытый ключ и соответствующий ему CSR. Используйте тот же тип ключа, что и для самоподписанного сертификата (см. Концепции: доверие, ключи и формат файлов); рекомендуется ECDSA P-256.

    ECDSA P-256 – рекомендуется:

    openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
        -nodes -keyout domain.key -out domain.csr \
        -subj "/CN=cam.example.com" \
        -addext "subjectAltName=DNS:cam.example.com"
    

    ECDSA P-384 – надёжнее, но больше/медленнее:

    openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 \
        -nodes -keyout domain.key -out domain.csr \
        -subj "/CN=cam.example.com" \
        -addext "subjectAltName=DNS:cam.example.com"
    

    RSA-2048 – максимальная совместимость:

    openssl req -new -newkey rsa:2048 \
        -nodes -keyout domain.key -out domain.csr \
        -subj "/CN=cam.example.com" \
        -addext "subjectAltName=DNS:cam.example.com"
    

    Храните domain.key в секрете – это файл ключа, который вы в итоге поместите на камеру. domain.csr – это файл, который вы передаёте CA; он не содержит секретов.

  3. Отправьте CSR и докажите, что вы контролируете домен. Именно здесь различаются два распространённых пути:

    • Автоматизированный ACME-CA, такой как Let’s Encrypt, управляемый инструментом вроде certbot или acme.sh, выполняет шаги 2 и 3 за вас: он генерирует ключ, строит CSR, автоматически отвечает на запрос проверки (HTTP-01: отдаёт токен через порт 80 на домене, или DNS-01: публикует TXT-запись в его DNS) и записывает готовые файлы.

    • Коммерческий CA (приобретённый напрямую или через реселлера доменов/хостинга): вы вставляете текст domain.csr в веб-форму, затем подтверждаете контроль, ответив на письмо для валидации, опубликовав DNS-запись или разместив файл на веб-сервере этого домена. После валидации вы скачиваете выпущенные файлы.

  4. Соберите выпущенные файлы. Чтобы разобраться в том, что вы получаете, полезно знать, что сертификаты образуют цепочку доверия: сертификат вашего домена подписан промежуточным CA, который, в свою очередь, подписан корневым CA. Каждое звено ручается за то, что ниже него. В итоге вы получаете:

    • Ваш закрытый ключ (из шага 2). CA никогда его не имел; он остаётся на вашей машине и является ключом, который вы в итоге поместите на камеру.

    • Конечный сертификат – также называемый сертификатом конечной сущности (end-entity) или серверным сертификатом. Это сертификат для вашего конкретного домена (cam.example.com): он содержит ваш открытый ключ и ваше имя и подписан промежуточным CA. Это тот сертификат, который камера предъявляет, чтобы идентифицировать себя.

    • Один или несколько промежуточных сертификатов CA («цепочка» или «пакет CA»). CA не подписывает ваш конечный сертификат своим корневым напрямую – ключ корневого хранится в офлайне и тщательно защищён – поэтому он подписывает его промежуточным, который сам подписан корневым. Промежуточный сертификат – это звено, соединяющее ваш конечный сертификат с корневым.

    Корневой сертификат – это якорь доверия: самоподписанный сертификат, принадлежащий CA и находящийся на вершине цепочки. Его вам не выдают и вы его никогда не разворачиваете, потому что он уже есть у каждого клиента – операционные системы, браузеры, телефоны и среды выполнения языков поставляются со встроенным «хранилищем доверия» корневых сертификатов. Клиент доверяет вашему конечному сертификату, проходя по цепочке: он уже доверяет корневому, корневой ручается за промежуточный, а промежуточный ручается за ваш конечный. (Именно эту работу выполняет ваш единственный server.der / cafile в случае с самоподписанным сертификатом – там вы являетесь своим собственным корневым CA.)

    Файл fullchain – это просто конечный сертификат и промежуточный(е), объединённые в один файл, конечным сертификатом вперёд, намеренно без корневого (отправлять корневой бессмысленно – клиент доверяет только тем корневым сертификатам, которые у него уже есть). Обычный сервер предъявляет всю эту цепочку fullchain, чтобы любой клиент мог пройти по ней. Камера так не может: она загружает и предъявляет один сертификат – конечный – и не может также отправить промежуточный(е) сертификат(ы), которые вам дал CA.

    Имена файлов, которые вы на самом деле увидите: ACME-инструмент вроде certbot записывает privkey.pem (ваш ключ), cert.pem (только конечный сертификат), chain.pem (только промежуточный(е)) и fullchain.pem (конечный + промежуточный(е)). Коммерческий CA обычно даёт вам .crt для конечного сертификата и .ca-bundle для промежуточного(ых), а .key – это тот, который вы сгенерировали сами.

  5. Преобразуйте и скопируйте. Преобразуйте закрытый ключ и конечный сертификат в DER и скопируйте их на камеру точно так же, как на странице Самоподписанные сертификаты. Затем камера предъявляет их в качестве своего серверного сертификата, и стандартные клиенты принимают соединение автоматически, поскольку они уже доверяют CA – настройка на стороне клиента не требуется.

Совет

На практике то, что камера предъявляет только конечный сертификат (и никогда промежуточные), проявляется так:

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

  • Клиенты, которые полагаются на то, что сервер предоставит промежуточный сертификат, не пройдут рукопожатие с камерой.

Если успешно подключаться должен каждый возможный клиент, не завершайте публичный TLS непосредственно на камере. Поставьте перед ней шлюз / обратный прокси, который отдаёт полную цепочку внешнему миру, и пусть прокси обращается к камере по описанному выше потоку с самоподписанным сертификатом.