certificate verify failed в журнале службы
Сообщения о неудачной проверке сертификата означают, что служба не доверяет собеседнику. Причины делятся на четыре: срок истёк, цепочка неполная, имя не совпадает, или в системе нет нужных корневых сертификатов.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Срок сертификата истёк
Автообновление не сработало, и никто этого не заметил. Самая частая причина внезапных отказов «работавшего» соединения.
-
Неполная цепочка сертификатов
Сервер отдаёт только свой сертификат без промежуточных. Браузеры иногда достраивают цепочку сами, а библиотеки в службах — нет.
-
Имя в сертификате не совпадает с адресом
Обращение по IP или по другому имени: сертификат выдан на конкретные имена.
-
В системе нет доверенных корневых сертификатов
В минимальных образах и контейнерах пакет корневых сертификатов часто отсутствует. Тогда не доверяется ничего.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Полная картина: цепочка, имена, срок, результат проверки.
echo | openssl s_client -connect узел:443 -servername узел 2>&1 | head -25Точная формулировка от библиотеки службы.
journalctl -u myapp.service -n 30 --no-pager | grep -iE "certificate|x509|tls"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Автообновление не сработало, и никто этого не заметил. Самая частая причина внезапных отказов «работавшего» соединения.
- Как проверить
-
Посмотрите срок сертификата на той стороне.
echo | openssl s_client -connect узел:443 -servername узел 2>/dev/null | openssl x509 -noout -subject -enddate
- Как исправить
- Обновите сертификат и проверьте, почему обновление не прошло: у certbot для этого есть проверочный прогон.
- Почему происходит
- Сервер отдаёт только свой сертификат без промежуточных. Браузеры иногда достраивают цепочку сами, а библиотеки в службах — нет.
- Как проверить
-
Посмотрите, сколько сертификатов отдаёт сервер.
echo | openssl s_client -connect узел:443 -servername узел 2>/dev/null | grep -c "BEGIN CERTIFICATE"
- Как исправить
- Настройте сервер отдавать полную цепочку. Для Let’s Encrypt это файл fullchain, а не cert.
- Почему происходит
- Обращение по IP или по другому имени: сертификат выдан на конкретные имена.
- Как проверить
-
Посмотрите имена в сертификате.
echo | openssl s_client -connect узел:443 -servername узел 2>/dev/null | openssl x509 -noout -ext subjectAltName
- Как исправить
- Обращайтесь по имени из сертификата или выпустите сертификат на нужное имя.
- Почему происходит
- В минимальных образах и контейнерах пакет корневых сертификатов часто отсутствует. Тогда не доверяется ничего.
- Как проверить
-
Проверьте наличие хранилища.
ls -l /etc/ssl/certs/ca-certificates.crt 2>/dev/null || ls -l /etc/pki/tls/certs/ca-bundle.crt 2>/dev/null
- Как исправить
-
Установите пакет корневых сертификатов и обновите хранилище.
sudo apt-get install -y ca-certificates && sudo update-ca-certificates
Пример вывода
Служба не доверяет собеседнику: нет корневых сертификатов. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[4400]: error: Get "https://api.example.org/v1": x509: certificate signed by unknown authority
myapp[4400]: fatal: cannot initialise client
systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Связанные ошибки
- nginx: ошибки сертификата при запуске (SSL_CTX_use_PrivateKey) nginx не запускается из-за сертификата: не совпадает ключ, неполная цепочка, файл повреждён, нет прав на чтение ключа.
- certbot: проверка владения доменом не проходит Обновление сертификата не удаётся: занят порт 80, недоступен каталог проверки, перехвачен редиректом.
- Connection refused в журнале службы Соединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- nginx: SSL_do_handshake() failed и ошибки TLS Ошибки рукопожатия TLS в журнале nginx: несовпадение версий протокола, отсутствие поддерживаемых наборов шифров, обращение по http к https-порту.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Automount: каталог монтируется не вовремя или отваливается Автомонтирование через .automount: как работает TimeoutIdleSec, почему ресурс отваливается и когда лучше обычный .mount.
- Broken pipe в журнале службы Запись в закрытый канал или соединение: клиент отключился, обработчик завершился, конвейер разорван.
- Cannot assign requested address при привязке Ошибка 99 при привязке: адрес не принадлежит машине или ещё не поднят. Разбор с network-online.target и ip_nonlocal_bind.
Где встречается чаще всего
Источники
- Документация OpenSSL: s_client
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено в контейнере без пакета корневых сертификатов.