Как проверить подлинность сертификата HTTPS-сайта без браузера

Как проверить подлинность сертификата HTTPS-сайта без браузера

Вы открываете сайт — и вдруг замечаете, что браузер ругается на сертификат. Или вы работаете с API, сервером, скриптом — и вам нужно убедиться, что соединение безопасно, но браузер не подключить. Или вы просто проверяете чужой сервер, а не хотите доверять тому, что показывает Chrome или Firefox. Тогда вам нужно уметь проверять SSL-сертификат напрямую — без браузера, без интерфейса, только через команды и данные.

Это не теория. Это то, что я делаю каждый раз, когда настраиваю сервер, проверяю подозрительный домен или разбираюсь с ошибкой в логах CI/CD. И если вы здесь — значит, вам тоже нужно это сделать. Сейчас я покажу, как.

Почему это важно — и зачем браузер не всегда надёжен

Браузер говорит: «Этот сайт не безопасен». Но почему? Он может ошибиться. Сертификат просрочен? Да. Несовпадает домен? Возможно. А может, сертификат выдан легально, но сервер неправильно настроен — и браузер просто не может его проверить из-за цепочки доверия. Или вы работаете с внутренним сервисом, у которого сертификат от локального ЦС — и браузер его не знает.

Когда вы проверяете сертификат без браузера, вы видите всё — как есть. Без фильтров. Без упрощений. Без того, чтобы браузер «решил за вас».

Как получить сертификат — три способа

Всё начинается с извлечения сертификата с сервера. Есть три надёжных способа — все работают через командную строку.

1. OpenSSL — самый точный и универсальный

Это стандарт де-факто. Если вы работаете с серверами — вы уже его знаете. Команда:

openssl s_client -connect example.com:443 -showcerts

Замените example.com на нужный домен. Если порт не 443 — укажите его явно, например: example.com:8443.

После запуска вы увидите кучу текста — это и есть сертификаты, которые сервер отправил. Найдите блок между -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----. Это и есть сертификат. Сохраните его в файл:

openssl s_client -connect example.com:443 -showcerts < /dev/null 2>&1 | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > cert.pem

Теперь у вас есть файл cert.pem — и вы можете его анализировать в любое время.

2. curl — для быстрой проверки

Если вам нужно только увидеть сертификат, а не сохранять его — используйте curl с флагом -v (verbose):

curl -v https://example.com 2>&1 | grep -A 100 "SSL certificate verify result"

Это покажет только конец вывода — где указаны даты, издатель, хост и статус валидации. Но если вы хотите полный сертификат — используйте:

curl --insecure -v https://example.com 2>&1 | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p'

Флаг --insecure нужен, чтобы curl не прервался из-за ошибки сертификата — мы же хотим увидеть его, даже если он плохой.

3. nc (netcat) — если OpenSSL не установлен

Иногда на сервере нет OpenSSL. Тогда можно использовать netcat — он есть почти везде:

echo -n | openssl s_client -connect example.com:443 2>&1

Но это не совсем netcat — это всё тот же OpenSSL. Если его вообще нет — используйте:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n" | nc example.com 443

Это не покажет сертификат — потому что netcat не умеет понимать TLS. Так что этот способ — только для проверки, что порт открыт. Для сертификата нужен OpenSSL. Не тратьте время на обходные пути — устанавливайте OpenSSL, если можете.

Что смотреть в сертификате — 5 ключевых параметров

После того как вы получили сертификат — не читайте его как книгу. Ищите конкретное.

Разберём его по пунктам. Откройте файл cert.pem в текстовом редакторе или выведите в терминале:

openssl x509 -in cert.pem -text -noout

Теперь смотрите на:

  • Subject — кто получил сертификат. Должен совпадать с доменом, который вы проверяете. Например: CN=example.com. Если там CN=*.example.com — это wildcard, и он подходит для поддоменов. Если там CN=example.org, а вы проверяете example.com — это не тот сертификат.
  • Issuer — кто выдал сертификат. Доверенные ЦС: Let’s Encrypt, DigiCert, Sectigo, GlobalSign. Если там Issuer: CN=MyInternalCA — это внутренний сертификат. Он может быть легальным, но не доверенным в интернете.
  • Validity — срок действия. Даты Not Before и Not After. Сертификат должен быть действителен сегодня. Если он просрочен — это красный флаг. Если он ещё не начал действовать — тоже проблема.
  • Subject Alternative Names (SAN) — список доменов, для которых сертификат действителен. Часто тут прописаны example.com, www.example.com, api.example.com. Если ваш домен не в списке — сертификат не подходит. Даже если CN совпадает, но SAN его не включает — браузер и клиенты откажутся доверять.
  • Public Key Algorithm — алгоритм ключа. Должен быть RSA (2048+ бит) или ECDSA (256+ бит). Если там RSA 1024 — это устаревший и небезопасный ключ. Его уже не выдают, но старые серверы могут его использовать.

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

Проверка цепочки доверия — где настоящая опасность

Сертификат может быть «правильным», но не доверенным. Почему? Потому что он выдан неизвестным ЦС — или цепочка не завершена.

Браузер знает сотни корневых сертификатов. Команда в терминале — нет. Она не знает, кому доверять. Поэтому нужно проверить цепочку.

Скачайте корневые сертификаты доверенных ЦС. Например, из curl’s CA bundle. Сохраните как ca-bundle.crt.

Теперь проверьте:

openssl verify -CAfile ca-bundle.crt cert.pem

Если вы видите:

cert.pem: OK

— значит, сертификат подписан цепочкой, которую доверяет мир.

Если вы видите:

error 20 at 0 depth lookup: unable to get local issuer certificate

— значит, сертификат не подтверждён. Это может быть:

  • Сертификат от локального ЦС (например, в корпоративной сети);
  • Сертификат выдан неизвестным ЦС (возможно, поддельный);
  • Сервер не отправил промежуточные сертификаты.

Последнее — частая ошибка. Сервер должен отправлять не только свой сертификат, но и все промежуточные. Если он этого не делает — клиент не может построить цепочку. Проверить это можно так:

openssl s_client -connect example.com:443 -showcerts

Если в выводе только один блок -----BEGIN CERTIFICATE----- — это плохо. Должно быть два или три: ваш сертификат + один или два промежуточных.

Если промежуточных нет — сервер неправильно настроен. Это не взлом, но это риск. Некоторые старые клиенты не смогут подключиться. А некоторые — просто откажутся.

Сравнение методов проверки

Вот как выглядят разные способы проверки в реальных сценариях:

Способ Что показывает Когда использовать Плюсы Минусы
openssl s_client Полный сертификат + цепочка + ошибки соединения Полная диагностика Самый детальный, поддерживает все параметры Много вывода, нужно фильтровать
openssl x509 -text Только данные сертификата (без сетевых ошибок) Проверка содержимого после скачивания Чистый вывод, легко анализировать Не проверяет соединение, только файл
curl -v Результат проверки + краткие детали Быстрая проверка в скриптах Просто, быстро, интегрируется в CI Меньше деталей, не показывает полный сертификат без фильтрации
openssl verify Только доверие цепочки Проверка, что сертификат «выглядит легитимно» Чёткий ответ: OK или ошибка Требует CA-бандл, не показывает сроки или SAN

Что выбрать в зависимости от ситуации

Вот как принимать решение:

  1. Вы проверяете сайт перед покупкой или входом в аккаунт — используйте openssl s_client + openssl x509 -text. Проверьте CN, SAN, даты и issuer. Если всё в порядке — можно доверять. Если issuer — неизвестный ЦС — не входите.
  2. Вы настраиваете сервер и хотите убедиться, что клиенты не ругаются — скачайте сертификат, проверьте цепочку через openssl verify с CA-бандлом. Убедитесь, что промежуточные сертификаты включены в конфиг сервера (Nginx/Apache).
  3. Вы пишете скрипт для CI/CD, который проверяет HTTPS — используйте curl -f -s -v + grep на ошибки. Если curl возвращает код 0 — всё ок. Если 60 — сертификат не доверенный.
  4. Вы подозреваете фишинг — скачайте сертификат, сравните его с известным сертификатом настоящего сайта. Если CN — google.com, а issuer — CN=FakeCA — это подделка. Никогда не вводите пароли.
  5. Вы работаете в корпоративной сети с внутренним ЦС — скачайте корневой сертификат от администратора, добавьте его в свой CA-бандл и проверяйте через openssl verify. Это нормально — но только если вы знаете, что ЦС легальный.

Частые ошибки — и как их избежать

Вот что ломает людям проверку сертификатов:

  • Считают, что «нет ошибки в браузере» = сертификат хороший. Браузер может не показывать ошибку, если сертификат выдан от устаревшего ЦС, который ещё в доверенном списке — но уже не безопасен. Проверяйте даты и ключи.
  • Игнорируют SAN. Сертификат выдан на example.com, а вы заходите на www.example.com. Браузер иногда это прощает — но клиенты и скрипты — нет. Проверяйте SAN.
  • Проверяют сертификат на локальном хосте без указания порта. openssl s_client -connect localhost — это не сработает. Нужно localhost:443.
  • Пользуются сертификатами без промежуточных. Сервер отправляет только свой сертификат. Клиенты не могут проверить цепочку — и отказываются. Это не взлом — это плохая настройка.
  • Думают, что «срок действия не истёк» — значит всё ок. Сертификат может быть выдан на 5 лет, но ключ — 1024 бит. Это устаревший и небезопасный формат. Проверяйте алгоритм ключа.
  • Используют сертификаты от Let’s Encrypt без проверки цепочки. Let’s Encrypt — доверенный, но если вы скачали сертификат с сайта, который не ваш — он может быть перехвачен. Проверяйте не только issuer, но и CN/SAN.

Как лучше делать — рекомендации от практика

Вот что я делаю всегда:

  • Сохраняю сертификаты в файлы. Никогда не полагаюсь на вывод в терминале. Сохраняю в cert.pem — и проверяю его несколько раз.
  • Использую CA-бандл от curl. Он обновляется ежемесячно, содержит все доверенные корневые сертификаты. Скачиваю его раз в месяц и проверяю все серверы с ним.
  • Проверяю не только даты, но и ключ. Если RSA — 2048 бит и выше. Если ECDSA — 256 бит и выше. Ниже — отклоняю.
  • Проверяю SAN даже если CN совпадает. Потому что CN устарел. Современные клиенты смотрят только на SAN.
  • Пишу скрипты для автоматической проверки. Например, проверяю все домены в списке раз в неделю. Если сертификат истекает через 14 дней — приходит уведомление.
  • Не доверяю «незнакомым» issuer. Даже если сертификат «правильный». Если issuer — CN=MyCompanyCA — я не знаю, откуда он взялся. Проверяю у администратора.

Итог: что делать прямо сейчас

Если вы читаете это — значит, вам нужно проверить сертификат HTTPS-сайта без браузера. Вот что делать:

  1. Установите OpenSSL, если его нет. Это стандарт — без него вы не сможете проверить ничего надёжно.
  2. Выполните: openssl s_client -connect ваш-домен:443 -showcerts < /dev/null 2>&1 | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > cert.pem
  3. Скачайте ca-bundle.crt и сохраните его рядом.
  4. Проверьте: openssl x509 -in cert.pem -text -noout — и убедитесь, что CN, SAN, даты и ключ в порядке.
  5. Проверьте цепочку: openssl verify -CAfile ca-bundle.crt cert.pem. Если не OK — сертификат не доверенный.
  6. Если вы видите «OK» — сертификат подлинный. Если нет — не доверяйте.

Это не теория. Это то, что я делаю каждый день. Никаких браузеров. Только команды. Только данные. Только уверенность.

Информация в этой статье носит ознакомительный характер. Проверка SSL-сертификатов не заменяет комплексную оценку безопасности сайта. При работе с конфиденциальными данными всегда консультируйтесь с ИБ-специалистом.

Оцените статью
PEFile — Безопасность и технологии простым языком