Управление клиентскими сертификатами в Heroku

от автора

Допустим, наше Java приложение размещено на платформе "Heroku", и ему требуется подключиться к HTTP серверу, требующему предоставление Клиентского Сертификата.

В этой статье мы рассмотрим вопросы безопасного размещения клиентских хранилищ ключей в облаке, используя переменные окружения.

  • Хранение паролей и других секретных данных в переменных окружения является распространённой практикой для приложений, размещённых в облаке.

Обычно приватные ключи содержались в защищённых паролем файлах — контейнерах ключей, таких как .p12 или jks на файловой системе.

Но проблема становится очевидна, как только становится необходимо разместить подобное приложение в облаке:

  • Даже защищённые паролем приватные ключи не допустимо размещать в репозитории вместе с исходным кодом

  • Тоже самое касается образов Docker и любых других подобных артефактов, доступных нескольким лицам

  • К счастью, это легко исправить в приложениях на Java!

Рассмотрим предполагаемый процесс с точки зрения теории безопасности:

  1. Офицер безопасности (о.б.) экспортирует приватный ключ как строку в кодировке Base64
  2. О.б. заходит в консоль управления облака (в нашем случае в Heroku Dashboard)
  3. О.б. импортирует строку в кодировке Base64 в переменную окружения
  4. Как часть автоматического процесса размещения приложения, эта же переменная окружения конвертируется в двоичные данные и записывается в физический файл
  5. Путь к этому файлу передаётся приложению на этапе запуска

  • Теперь, только круг лиц, имеющих доступ к консоли управления облака, получают доступ к приватному ключу.

Применим этот подход на практике:

  • Язык: Java
  • Платформа: Heroku
  • Система сборки: Gradle
  • Формат хранилища ключей: PKCS12

Экспорт файла .p12

Воспользуйтесь инструкцией, использующей средства, встроенные в Вашу операционную систему:

Импорт в Heroku

  • Зайдите в Heroku
  • Перейдите в секцию Settings Вашего приложения
  • Нажмите "Reveal the config vars"
  • Добавьте следующие переменные окружения:
    • keyStoreFileName — любое незанятое имя файла, например "private_key.p12"
    • keyStoreBase64 — вставьте сюда значение строки закодированной в формате Base64, экспортированной в предыдущем шаге "Экспорт файла .p12"
    • keyStorePassword — пароль, ранее использовавшийся с файлом .p12
    • keyStoreType — в нашем случае pkcs12
    • trustStoreTypejks

Запись файла .p12 используя Gradle

Добавьте нижеприведённое задание в Ваш файл guild.gradle и назначьте его исполнение перед задачей stage:

task initKeyStore() {     doLast {         println("Creating keystore file from environment variables.")         String keyStoreFileName = System.getenv("keyStoreFileName")         if (keyStoreFileName != null) {             String keyStoreBase64 = System.getenv("keyStoreBase64")             new File(keyStoreFileName).withOutputStream {                 it.write(Base64.decoder.decode(keyStoreBase64))             }         }     } } stage.dependsOn(initKeyStore)

Передача реквизитов через "procfile" Heroku

В "procfile" в Heroku не поддерживаются многострочные команды.

Поэтому, мы рекомендуем создать отдельный shell скриптrunApp.sh.

runApp.sh:

java \  -Dserver.port=$PORT \ ...  -Djavax.net.ssl.keyStoreType=$keyStoreType \  -Djavax.net.ssl.trustStoreType=$trustStoreType \  -Djavax.net.ssl.keyStore=$keyStoreFileName \  -Djavax.net.ssl.keyStorePassword=$keyStorePassword \  $JAVA_OPTS \ ...

Не забудьте дать права на выполнение используя git и протолкнуть (push) подтверждение (commit):

git update-index --chmod=+x runApp.sh git commit -m 'Добавление прав на выполнение runApp.sh' git push origin master

Ограничения

В общей сложности Heroku позволяет хранить максимально 32 килобайта информации в переменных окружения.

Это накладывает некоторые ограничения, и вопрос их преодоления в настоящий момент прорабатывается в нашей организации.

Заключение

  • Теперь каждый раз, когда вы размещаете своё приложение в Heroku, Gradle автоматически создаёт хранилище ключей в виде файла P12 на основе переменной окружения.
  • Затем, используя procfile, платформа Heroku передаёт детали этого файла Вашему приложению.
  • Приватный ключ становится доступным приложению, и может быть использован для Клиентской аутентификации как обычный файл .p12 в Java
  • Никаких изменений исторической кодовой базы приложения не требуется для поддержки этого подхода.

Спасибо за внимание!

ссылка на оригинал статьи https://habr.com/ru/post/491870/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *