Шифрование само по себе ничего не гарантирует: можно идеально зашифровать разговор с мошенником. Поэтому в рукопожатии сервер предъявляет сертификат — документ, в котором сказано: «ключ такой-то принадлежит сайту такому-то», и подпись того, кто это проверил. Замок в адресной строке означает, что браузер проверил этот документ и подпись под ним. Посмотрим, что именно он проверяет — на сертификате этого сайта.
Это восьмая часть цикла «Что происходит, когда открываешь сайт».
Что прислал сервер
$ echo | openssl s_client -connect alekseychikun.ru:443 -servername alekseychikun.ru
Certificate chain
0 s:CN=alekseychikun.ru
i:C=US, O=Let's Encrypt, CN=YR2
a:PKEY: RSA, 4096 (bit); sigalg: sha256WithRSAEncryption
v:NotBefore: Sep 30 17:48:20 2026 GMT; NotAfter: Dec 29 17:48:19 2026 GMT
1 s:C=US, O=Let's Encrypt, CN=YR2
i:C=US, O=ISRG, CN=Root YR
v:NotBefore: Sep 3 00:00:00 2025 GMT; NotAfter: Sep 2 23:59:59 2028 GMT
2 s:C=US, O=ISRG, CN=Root YR
…
Verify return code: 0 (ok)
s: — кому выдан сертификат (subject), i: — кто его подписал (issuer). Сертификат сайта подписан промежуточным центром Let’s Encrypt «YR2», тот — корневым «Root YR». Каждая строка цепочки подписана следующей.
Почему не подписывают сразу корнем
Закрытый ключ корневого центра — самое ценное, что у центра есть: если он утечёт, придётся менять доверие во всех браузерах мира. Поэтому корень хранят отключённым от сети и используют редко — только чтобы подписать промежуточные сертификаты. А сертификаты сайтов каждый день выдают промежуточные. Утечёт промежуточный ключ — его отзовут и выпустят новый, корень останется.
Что проверяет браузер
- Имя. Адрес в строке должен быть в списке имён сертификата. Смотрят не на
CN, а на полеSubject Alternative Name: у этого сайта тамalekseychikun.ruиwww.alekseychikun.ru. Зайдёте на третье имя — будет ошибка, даже если сервер тот же; - Срок. Текущее время между
NotBeforeиNotAfter. Отсюда же классическая ошибка с неправильными часами на компьютере: сертификаты «ещё не действуют» у всех сайтов сразу; - Подписи по цепочке вплоть до корня, которому браузер доверяет. Корни лежат в хранилище операционной системы или браузера — от сервера корень браузер не принимает: иначе любой мог бы прислать «свой корень»;
- Подпись рукопожатия (
CertificateVerifyиз прошлой части): сервер доказывает, что у него есть закрытый ключ от предъявленного сертификата. Без этого сертификат можно было бы просто скопировать — он же публичный; - Не отозван ли и записан ли в публичные журналы прозрачности (Certificate Transparency). Каждый выпущенный сертификат попадает в открытые журналы, и подделку можно обнаружить.
90 дней — это нормально
Сертификат этого сайта выпущен 30 сентября и действует до 29 декабря — ровно 90 дней. Let’s Encrypt выдаёт короткие сертификаты специально: их продлевает автоматика, и утёкший ключ перестаёт работать быстро. У нас продлением занимается сам прокси, за месяц до конца срока. Обратная сторона — если автоматика сломалась, узнаете вы об этом через считаные недели, и лучше раньше: заведите проверку срока по расписанию.
# сколько дней осталось
end=$(echo | openssl s_client -connect example.ru:443 -servername example.ru 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
echo $(( ( $(date -d "$end" +%s) - $(date +%s) ) / 86400 )) дней
Неполная цепочка: браузер работает, скрипты — нет
Частая поломка: сервер присылает только сертификат сайта, без промежуточного. Браузеры это часто прощают — они запоминают промежуточные сертификаты с других сайтов или докачивают их по ссылке из сертификата. А curl, Python, Node и интеграции между серверами — нет, они честно падают с ошибкой проверки. Выглядит как «у нас всё открывается, а у партнёров интеграция не работает».
# сколько сертификатов присылает сервер — должно быть 2 и больше
echo | openssl s_client -connect example.ru:443 -servername example.ru -showcerts 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
Подключать в сервер надо файл fullchain (сертификат и промежуточные), а не голый сертификат. При покупном сертификате промежуточный скачивается по ссылке из поля Authority Information Access самого сертификата.
Почему замок не значит «сайт честный»
Сертификат Let’s Encrypt подтверждает одно: тот, кто его получил, управляет этим доменом. Не то, что за доменом стоит настоящая компания, и не то, что сайт не мошеннический. Фишинговый сайт на похожем имени получит такой же замок за пару минут. Замок — про то, что разговор с этим именем никто не подслушивает и не подменяет. А имя проверяйте глазами.
Сайт открывается в браузере, а интеграции падают на сертификате?
Пришлите адрес — проверю цепочку, сроки и имена и подскажу, какой файл подключить.
// загружаю комментарии…