На шляху до автоматизації випуску SSL

Досить часто нам доводиться працювати із SSL сертифікатами. Давайте згадаємо процес створення та встановлення сертифіката (загалом для більшості).

  • Знайти провайдера (сайт, на якому ми можемо купити SSL).
  • Згенерувати CSR.
  • Надіслати його провайдеру.
  • Підтвердити володіння доменом.
  • Отримати сертифікат.
  • Перетворити сертифікат на потрібну форму (опціонально). Наприклад, з pem до PKCS #12.
  • Встановити сертифікат на веб-сервер.

Відносно швидко, не складно та зрозуміло. Цей варіант цілком годиться, якщо ми маємо максимум десяток проектів. А якщо їх більше, і у них щонайменше по три оточення? Класичний dev - staging - production. У цьому випадку варто подумати про автоматизацію цього процесу. Пропоную, трохи заглибитись у проблему та знайти рішення, яке надалі мінімізує тимчасові витрати на створення та обслуговування сертифікатів. У статті буде присутній аналіз проблеми та невелике керівництво до повторення.

Заздалегідь зазначу: основна спеціалізація нашої компанії — .net, а відповідно IIS та інші виткові, що виходять. Тому ACME клієнт і всі дії для нього теж будуть описані з точки зору використання windows.

Для кого це актуально і деякі вихідні дані

Компанія К в особі автора. URL (наприклад): company.tld

Проект X - один з наших проектів, займаючись яким я дійшов висновку, що все-таки потрібно рухатися у бік максимальної економії часу при роботі з сертифікатами. Цей проект має чотири оточення: dev, test, staging і production. Dev та test знаходяться на нашій стороні, staging та production на замовнику.

Особливістю проекту є те, що він має велику кількість модулів, які доступні як піддомени.

Тобто маємо наступну картину:

DEV
Тест
Інсценування
Production

projectX.dev.company.tld
projectX.test.company.tld
staging.projectX.tld
projectX.tld

module1.projectX.dev.company.tld
module1.projectX.test.company.tld
module1.staging.projectX.tld
module1.projectX.tld

module2.projectX.dev.company.tld
module2.projectX.test.company.tld
module2.staging.projectX.tld
module2.projectX.tld

...
...
...
...

moduleN.projectX.dev.company.tld
moduleN.projectX.test.company.tld
moduleN.staging.projectX.tld
moduleN.projectX.tld

Для виробництва використовується куплений wildcard сертифікат, тут питань не виникає. Але він покриває лише перший рівень піддомену. Відповідно, якщо є сертифікат для *.projectX.tld – то для staging.projectX.tld він працюватиме, а ось для module1.staging.projectX.tld вже немає. А купувати окремий якось не хочеться.

І це лише на прикладі одного проекту однієї компанії. А проект, звісно, ​​не один.

Загальні для всіх причини вирішити це питання виглядають приблизно так:

  • Відносно недавно Google запропонували зменшити максимальний термін дії SSL сертифікатів. З усіма витікаючими.
  • Полегшити процес випуску та обслуговування SSL для внутрішніх потреб проектів та компанії загалом.
  • Централізоване зберігання записів про сертифікати, яке частково вирішує проблему підтвердження домену за допомогою DNS та подальшого автоматичного оновлення, а також вирішує питання довіри клієнта. Тим не менш, більше довіри викликає CNAME на сервер компанії партнера/виконавця, ніж на сторонній ресурс.
  • Ну, і нарешті, в цьому випадку фраза "краще мати, ніж не мати" підходить відмінно.

Вибір провайдера SSL та підготовчі кроки

З доступних варіантів безкоштовних SSL сертифікатів розглядалися cloudflare і letsencrypt. DNS для цього (і деяких інших проектів) як розташовується на cloudflare, але я не прихильник використання їх сертифікатів. Тому було вирішено використовувати letsencrypt.
Для створення wildcard SSL сертифіката необхідно підтвердити володіння доменом. Ця процедура передбачає створення деякого DNS запису (TXT або CNAME), з подальшою її перевіркою під час випуску сертифіката. У Linux є утиліта Certbotщо дозволяє частково (або повністю для деяких DNS провайдерів) автоматизувати цей процес. Для Windows ж із знайдених та перевірених варіантів ACME клієнтів я зупинився на WinACME.

А запис для домену створено, переходимо до створення сертифіката:

На шляху до автоматизації випуску SSL

Нас цікавить останній висновок, а саме доступні варіанти підтвердження володіння доменом для випуску wildcard сертифіката:

  1. Створення записів DNS вручну (автоматичне оновлення не підтримується)
  2. Створення DNS записів за допомогою acme-dns сервера (докладніше можна почитати тут.
  3. Створення записів DNS за допомогою власного скрипта (аналог плагіна cloudflare для certbot).

На перший погляд, третій пункт цілком підходить, але якщо провайдер DNS не підтримує цей функціонал? А нам потрібний загальний випадок. А загальний випадок - це CNAME записи, вже їх все підтримують. Отже, зупиняємось на пункті 2 і йдемо налаштовувати свій ACME-DNS сервер.

Настроювання ACME-DNS сервера та процес випуску сертифіката

Для прикладу, я створив домен 2nd.pp.ua, і надалі використовуватиму його.

Обов'язковою вимогою Для коректної роботи сервера є створення NS і запису А для його домену. І перший неприємний момент, з яким я зіткнувся - cloudflare (принаймні в режимі безкоштовного використання) не дозволяє одночасно створити NS і A запис для одного і того ж хоста. Не те щоб це було проблемою, але у bind це можна. Саппорт відповів, що їхня панель так робити не дозволяє. Не біда, створимо два записи:

acmens.2nd.pp.ua. IN A 35.237.128.147
acme.2nd.pp.ua. IN NS acmens.2nd.pp.ua.

На даному етапі у нас повинен резолвуватись хост acmens.2nd.pp.ua.

$ ping acmens.2nd.pp.ua
PING acmens.2nd.pp.ua (35.237.128.147) 56(84) bytes of data

А от acme.2nd.pp.ua резолвуватися не буде, оскільки сервер DNS який його обслуговує ще не запущений.

Записи створені, переходимо до налаштування та запуску ACME-DNS сервера. Жити він у мене буде на ubuntu server у Докер контейнері, але запустити його можна скрізь де є golang. Windows теж цілком підійде, але я все ж таки віддаю перевагу Linux сервер.

Створюємо необхідні директорії та файли:

$ mkdir config
$ mkdir data
$ touch config/config.cfg

Скористайтеся vim вашим улюбленим текстовим редактором та вставимо у config.cfg зразок конфігурації.

Для успішної роботи достатньо підправити секції general та api:

[general]
listen = "0.0.0.0:53"
protocol = "both"
domain = "acme.2nd.pp.ua"
nsname = "acmens.2nd.pp.ua" 
nsadmin = "admin.2nd.pp.ua" 
records = 
    "acme.2nd.pp.ua. A 35.237.128.147",
    "acme.2nd.pp.ua. NS acmens.2nd.pp.ua.",                                                                                                                                                                                                  ]
...
[api]
...
tls = "letsencrypt"
…

Також, за бажанням, створимо файл docker-compose в основній директорії сервісу:

version: '3.7'
services:
  acmedns:
    image: joohoi/acme-dns:latest
    ports:
      - "443:443"
      - "53:53"
      - "53:53/udp"
      - "80:80"
    volumes:
      - ./config:/etc/acme-dns:ro
      - ./data:/var/lib/acme-dns

Готово. Можна запускати.

$ docker-compose up -d

На даному етапі повинен почати резолвуватись хост acme.2nd.pp.ua, і з'явитися 404 на https://acme.2nd.pp.ua

$ ping acme.2nd.pp.ua
PING acme.2nd.pp.ua (35.237.128.147) 56(84) bytes of data.

$ curl https://acme.2nd.pp.ua
404 page not found

Якщо цього не з'явилося docker logs -f <container_name> на допомогу, благо, логи цілком читальні.

Можемо приступати до створення сертифікату. Відкриваємо PowerShell від імені адміністратора і запускаємо winacme. Нас цікавлять вибори:

  • M: Create new certificate (full options)
  • 2: Manual input
  • 2: [dns-01] Create verification records with acme-dns (https://github.com/joohoi/acme-dns)
  • На запитання про посилання ACME-DNS сервер вводимо у відповідь URL створеного сервера (https). URL of the acme-dns server: https://acme.2nd.pp.ua

У відвір клієнт видає запис, який треба додати в існуючий DNS сервер (процедура одноразова):

[INFO] Creating new acme-dns registration for domain 1nd.pp.ua

Domain:              1nd.pp.ua
Record:               _acme-challenge.1nd.pp.ua
Type:                   CNAME
Content:              c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.
Note:                   Some DNS control panels add the final dot automatically.
                           Only one is required.

На шляху до автоматизації випуску SSL

Створюємо необхідний запис, і переконуємося, що він створився коректно:

На шляху до автоматизації випуску SSL

$ dig CNAME _acme-challenge.1nd.pp.ua +short
c82a88a5-499f-464f-96e4-be7f606a3b47.acme.2nd.pp.ua.

Підтверджуємо, що ми створили потрібний запис у winacme, і продовжуємо процес створення сертифіката:

На шляху до автоматизації випуску SSL

Як використовувати certbot як клієнт описано тут.

На цьому процес створення сертифіката закінчено, можна встановлювати його на веб-сервер та використовувати. Якщо при створенні сертифіката створити також завдання у планувальнику, то надалі процес оновлення сертифіката відбуватиметься автоматично.

Джерело: habr.com

Додати коментар або відгук