Управление сертификатами с помощью протокола ACME

в 13:45, , рубрики: acme, embedded, IT-стандарты, java, LetsEncrypt

Возникла передо мной такая задача: автоматический выпуск сертификатов для Web приложения. И требования:

  • CA должны доверять все браузеры т.е. самоподписанные сертификаты не подходят;
  • желательно бесплатно;
  • Выпуск надо делать программно с помощью Java Embedded compact1 profile. Это всё по следам Java и без 16Gb памяти?.

Наверное многие уже слышали про бесплатные сертификаты от LetsEncrypt и certbot. А можно ли certbot заменить Java?

Управление сертификатами с помощью протокола ACME - 1

ACME

Многие, конечно, любят LetsEncrypt за бесплатные сертификаты, которые, фактически, позволят перевести весь вэб на https. Но не многие
знают, что для этого они придумали специальный протокол — ACME. И для меня он по значимости чуть ли не выше самих бесплатных сертификатов.

Основные особенности протокола:

  • Описывает взаимодействие клиента и REST сервера;
  • Есть поддержка как платных сертификатов, так и бесплатных;
  • Несколько способов авторизации владения доменом;
  • Внесен на принятие в IETF. Сейчас находится в состоянии draft;
  • Все сообщения передаются в формате JSON Web Token.

Для тех, кому интересны детали и все возможные варианты взаимодействия, можно почитать официальную документацию. Она действительно простая и легко читается в отличии от наших гостов. Здесь же я приведу диаграмму последовательности при выдаче сертификата, которую нужно представлять, если Вы решили интегрироваться.

Управление сертификатами с помощью протокола ACME - 2

Использование

На официальном сайте LetsEncrypt есть множество клиентов работающих по протоколу ACME. Я взял acme4j. Эта библиотека достаточно компактная и работает в compact1 profile!

У неё есть вполне рабочий пример использования, с помощью которого я смог выпустить себе сертификат. Для того, чтобы интегрировать библиотеку достаточно с минимальными изменениями скопировать этот код.

Для продления сертификата необходимо авторизоваться, взять уже готовый CSR и отправить его в CA. После чего скачать новый сертификат.

Единственная проблема, которая у меня возникла — это подкладывание сертификата в nginx. Поясню на примере:

  • приложение стартует в первый раз;
  • nginx стартует. Поскольку приложение стартует в первый раз, то сертификата ещё нет, и nginx слушает на 80 порту;
  • пользователь заходит в приложение, соглашается с правилами использования сертификатов LetsEncrypt и нажимает кнопку "выдать сертификат";
  • сертификат скачивается.

И вот тут проблема: для того чтобы включить 443 порт с новым сертификатом, nginx должен перезачитать конфигурацию. Но чтобы это сделать нужен root. Запускать приложение из под root — плохая идея. Запускать nginx из под пользователя тоже — нельзя будет слушать 80/443 порты.

Я добавил правило для пользователя в sudoers, чтобы можно было делать sudo nginx -s reload. Но это выглядит как костыль. Может кто-нибудь знает как это сделать красивее?

Итого

Получение сертификата в автоматическом режиме оказалось достаточно простой процедурой. А если использовать ACME сервер boulder, то можно даже развернуть такую схему у себя в большой организации! Если у вас есть собственный CA для внутренних сервисов, то ACME должен сильно упростить работу с сертификатами.

Автор: dernasherbrezon

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js