14.4.4. Сертификаты, подписанные CA (с публичным доверием)¶
Самоподписанные сертификаты работают, когда вы контролируете обе стороны. Если же произвольные клиенты (браузеры, телефоны, стороннее ПО) должны подключаться к камере без указания доверять пользовательскому сертификату, сертификат должен быть подписан публичным центром сертификации (Certificate Authority, CA), которому эти клиенты уже доверяют. TLS-код на камере идентичен случаю с самоподписанным сертификатом – load_cert_chain с сертификатом и ключом в форме DER – меняется лишь способ получения этого сертификата.
Самый важный момент: закрытый ключ вы генерируете сами, и он никогда не покидает вашу машину. CA никогда его не видит. То, что вы отправляете CA, – это запрос на подпись сертификата (CSR) – небольшой файл, содержащий ваш открытый ключ и ваше доменное имя, а то, что вы получаете обратно, – это сертификат (ваш открытый ключ и имя, подписанные CA). Ключ и сертификат – это два отдельных файла, создаваемых двумя отдельными шагами; CA имеет дело только с открытой половиной.
Общий процесс, полностью выполняемый на обычной машине (никогда на камере):
Получите доменное имя. Публичные CA сертифицируют DNS-имя, которое вы контролируете (например,
cam.example.com); они не выдают сертификаты для голого IP-адреса или локального имени вродеmycam.Сгенерируйте ключ и 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; он не содержит секретов.Отправьте CSR и докажите, что вы контролируете домен. Именно здесь различаются два распространённых пути:
Автоматизированный ACME-CA, такой как Let’s Encrypt, управляемый инструментом вроде
certbotилиacme.sh, выполняет шаги 2 и 3 за вас: он генерирует ключ, строит CSR, автоматически отвечает на запрос проверки (HTTP-01: отдаёт токен через порт 80 на домене, или DNS-01: публикует TXT-запись в его DNS) и записывает готовые файлы.Коммерческий CA (приобретённый напрямую или через реселлера доменов/хостинга): вы вставляете текст
domain.csrв веб-форму, затем подтверждаете контроль, ответив на письмо для валидации, опубликовав DNS-запись или разместив файл на веб-сервере этого домена. После валидации вы скачиваете выпущенные файлы.
Соберите выпущенные файлы. Чтобы разобраться в том, что вы получаете, полезно знать, что сертификаты образуют цепочку доверия: сертификат вашего домена подписан промежуточным 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– это тот, который вы сгенерировали сами.Преобразуйте и скопируйте. Преобразуйте закрытый ключ и конечный сертификат в DER и скопируйте их на камеру точно так же, как на странице Самоподписанные сертификаты. Затем камера предъявляет их в качестве своего серверного сертификата, и стандартные клиенты принимают соединение автоматически, поскольку они уже доверяют CA – настройка на стороне клиента не требуется.
Совет
На практике то, что камера предъявляет только конечный сертификат (и никогда промежуточные), проявляется так:
Клиенты, у которых уже закэширован промежуточный сертификат CA – основные браузеры и HTTPS-библиотеки обычно его имеют – сами достраивают цепочку и подключаются нормально.
Клиенты, которые полагаются на то, что сервер предоставит промежуточный сертификат, не пройдут рукопожатие с камерой.
Если успешно подключаться должен каждый возможный клиент, не завершайте публичный TLS непосредственно на камере. Поставьте перед ней шлюз / обратный прокси, который отдаёт полную цепочку внешнему миру, и пусть прокси обращается к камере по описанному выше потоку с самоподписанным сертификатом.