Служба на Java не может проверить сертификат собеседника
Среда исполнения Java проверяет сертификаты по своему хранилищу доверия, а не по системному. Из-за этого служба может отвергать сертификат, который другие программы на той же машине принимают без замечаний.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Нужного центра нет в хранилище Java
Хранилище среды исполнения отдельное. Добавление центра в системное хранилище на него не влияет.
-
Нет прав на файл хранилища
Служба работает от своего пользователя. Без права чтения хранилища проверка невозможна.
-
Хранилище не обновлено после обновления среды исполнения
Обновление среды может заменить хранилище, потеряв добавленные вручную сертификаты.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Хранилище доверия среды исполнения и число записей.
keytool -list -cacerts -storepass changeit 2>/dev/null | head -5Пользователь службы и заданные параметры запуска.
systemctl show myapp.service -p User -p EnvironmentСообщения о проверке сертификата.
journalctl -u myapp.service -n 20 --no-pager | grep -iE "PKIX|SunCert|trust"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Хранилище среды исполнения отдельное. Добавление центра в системное хранилище на него не влияет.
- Как проверить
-
Посмотрите, есть ли центр в хранилище Java.
keytool -list -cacerts -storepass changeit 2>/dev/null | grep -ci "ваш-центр" ls -l /etc/ssl/certs/java/cacerts 2>/dev/null
- Как исправить
- Добавьте сертификат центра в хранилище среды исполнения либо укажите службе своё хранилище параметрами запуска. В дистрибутивах хранилище Java часто связано с системным средством управления сертификатами.
- Почему происходит
- Служба работает от своего пользователя. Без права чтения хранилища проверка невозможна.
- Как проверить
-
Посмотрите права файла и пользователя службы.
ls -l /etc/ssl/certs/java/cacerts 2>/dev/null systemctl show myapp.service -p User
- Как исправить
- Дайте пользователю службы право чтения хранилища. Право записи ему не нужно.
- Почему происходит
- Обновление среды может заменить хранилище, потеряв добавленные вручную сертификаты.
- Как проверить
-
Посмотрите дату файла и записи в нём.
ls -l --time-style=full-iso /etc/ssl/certs/java/cacerts 2>/dev/null keytool -list -cacerts -storepass changeit 2>/dev/null | head -3
- Как исправить
- Добавляйте сертификаты штатным средством дистрибутива, а не правкой хранилища напрямую: тогда они восстановятся после обновления.
Пример вывода
Центра нет в хранилище среды исполнения. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[12600]: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
myapp[12600]: at sun.security.ssl.Alert.createSSLException(Alert.java:131)
systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Связанные ошибки
- Java-служба не запускается: не найдена среда исполнения Служба на JVM падает с кодом 203 или 127: путь к java неверен или среда исполнения не установлена.
- nginx: ошибки сертификата при запуске (SSL_CTX_use_PrivateKey) nginx не запускается из-за сертификата: не совпадает ключ, неполная цепочка, файл повреждён, нет прав на чтение ключа.
- Сервер сборки не запускается: версия Java не подходит Служба падает сразу после запуска: установлена не та версия среды исполнения или выбрана не та из нескольких.
- Брокер сообщений не открывает слушатель: права и пути Служба падает при открытии слушателя: занятый порт, нет прав на сертификаты или каталог постоянного хранения.
- Обратный прокси не получает сертификаты: файл хранения недоступен Автоматический выпуск сертификатов не проходит: права на файл хранения слишком широкие или файл недоступен.
- Почтовый сервер доступа не запускается: не читается сертификат Служба падает при чтении сертификата: права на закрытый ключ, неверный порядок цепочки или путь к ней.
- Служба не читает закрытый ключ TLS Права на закрытый ключ: как дать доступ службе, не открывая ключ всем. Группы и каталоги сертификатов.
- AppArmor: apparmor="DENIED" в журнале ядра Профиль AppArmor запретил операцию: как прочитать запись, найти профиль и поправить его правильно.
Источники
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено обращением к узлу с сертификатом внутреннего центра из службы на Java. -
systemd.exec(5)
Environment= для передачи параметров среде исполнения.