Контейнерное приложение Springboot - загрузка встроенного хранилища ключей (.jks / .p12) из ​​JAR - PullRequest
0 голосов
/ 21 февраля 2020

Справочная информация: у меня есть приложение springboot, которое упаковано в контейнер с помощью docker и работает в кластере kubernetes. Он выполняет вызовы API и использует SSLContext, который требует загрузки хранилища доверенных сертификатов .jks, например:

SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(ResourceUtils.getFile(keyStoreFilePath),
                        keyStorePassword.toCharArray(), new TrustSelfSignedStrategy()).build();

Обратите внимание, что String keyStoreFilePath в настоящее время внедряется как переменная окружения / свойства во время выпуска, и указывает в расположение, например /etc/ssl/keystore.jks на хост-компьютере, на котором выполняется контейнер. Недостатком является то, что мне приходится прибегать к монтированию этого как постоянного тома в kubernetes, чтобы мое контейнерное приложение получило к нему доступ.

Вместо этого я решил встроить его в путь к классам приложения, чтобы нашей операционной команде не приходилось настраивать его на всех хост-машинах. Но когда я это сделаю, указав значение keyStoreFilePath, например, так: classpath:security/keystore.jks, оно прекрасно работает, когда я запускаю проект в Eclipse / STS. Но происходит сбой с ошибкой, приведенной ниже внутри контейнера:

class path resource [security/cacerts] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/security/cacerts","stackTrace":"org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217)

Опять же, интересно то, что точно такая же вещь работает в Eclipse, но не работает внутри контейнера. Есть указатели?

Обновление: проверено, что файл keystore.jks имеет размер <1 МБ. </p>

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Сообщение об ошибке показывает file:/<some-path-in-the-container>/App.jar!/keystore.jks - папка «security» отсутствует, в то время как значение, переданное для keyStoreFilePath, равно classpath:security/keystore.jks?

Маловероятно, что файл JKS больше 1 МБ, что ограничение в Kubernetes для ConfigMap-s и Secrets, поэтому можно создать Secret с файлом JKS и подключить том из Secret - не нужно использовать постоянный том или hostPath громкость.

HTH

0 голосов
/ 21 февраля 2020

Я смог понять это. Так как keystore.jks встроен в jar-файл и должен быть загружен из пути к классам (classpath:security/keystore.jks), мы не можем прочитать его как файл. Вместо этого нам нужно будет прочитать его как входной поток - true для всех ресурсов в файле jar (classpath). Итак, я должен сделать что-то вроде этого, чтобы заставить его работать:

KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(truststoreResource.getInputStream(), keyStorePassword.toCharArray());
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore, new TrustSelfSignedStrategy()).build();

Этот ответ был полезен.

...