Зшиваємо SSL-сертифікати правильно на bash

Використання SSL-шифрування на сайтах набуває вже майже обов'язковий характер: Google з цього року почав агресивно попереджати про небезпечний з'єднанні з сайтами, ряд платіжних шлюзів вимагають безпечне підключення на сайтах (наприклад, Яндекс.Каса). Установка SSL-сертифіката на сайт вимагає досить складної технічної налаштування веб-сервера nginx, наприклад). Одним з аспектів цієї установки є використання «зшивання» (stapling) SSL-сертифікатів аж до кореневого для прискорення встановлення безпечного з'єднання з браузерів до сайтів.

SSL stapling дозволяє заощадити для нового відвідувача сайту 0,1-1 секунду (за рахунок економії 1-2 запитів за проміжними сертифікатами з урахуванням DNS-запитів, встановлення з'єднання та отримання даних, кожен із запитів може виконуватися до 500 мс у разі 95 перцентиля користувачів). За замовчуванням, SSL stapling виконується для всіх сертифікатів, завантажених в Айрі.

Зазвичай ланцюжок SSL-сертифікатів, яку повинен запросити браузер, виглядає наступним чином:
SSL-сертифікат сайту — Проміжний SSL-сертифікат [- Проміжний SSL-сертифікат 2] — Кореневий сертифікат SSL
Кореневі SSL-сертифікати завантажені в браузер (в цілях запобігання їх підробки при передачі по мережі). Проміжні SSL-сертифікати можуть бути отримані з SSL-сертифікату сайту («батьківський» сертифікат, яким підписано даний сертифікат, внесений у відповідному полі даного сертифіката). Як це коректно зробити, щоб зшити всі сертифікати та прискорити завантаження сайту в браузері?

Openssl
Основним робочим інструментом, буде бібліотека openssl: вона дозволяє реалізувати перетворення сертифікатів і витяг необхідної інформації у текстовому форматі (у сертифікаті інформація закодована або бінарному форматі (DER), або в base64 (PEM)).

Якщо на сервері ви підключаєте SSL-шифрування для сайту, то сама бібліотека, швидше за все, у вас вже встановлена. Перевірити, наприклад, для якого домену (Canonical name) випущений сертифікат (якщо він у форматі PEM, зазвичай у такому форматі сертифікати випускаються і передаються для встановлення на сервер) можна так:
openssl x509 -in ФАЙЛ_СЕРТИФИКАТА -subject -noout
Тут
x509
— вхідний формат сертифіката,
in
— ключ для вхідного файлу,
subject
— вказівку вивести CN сертифіката, а
noout
— заборона на висновок самого сертифіката (у форматі PEM).

Отримуємо «батьківський» сертифікат
Алгоритм «зшивання» сертифікатів досить простий: нам потрібно з сертифіката отримати шлях до «рідної» сертифікату (того сертифікату, яким підписаний даний) і отримати цей «батьківський» сертифікат за извлеченному шляху. Простого набору ключів для
openssl
не вдалося знайти, тому зробимо це за допомогою виводу всієї інформації про сертифікат в тестовому форматі з допомогою ключа
text
:
openssl x509 -in "ФАЙЛ_СЕРТИФИКАТА" text -noout
Після цього нам потрібно лише виділити поле Issuers і отримати з нього URL. Це можна зробити, наприклад, так:
openssl x509 -in "ФАЙЛ_СЕРТИФИКАТА" text -noout | grep Issuers | awk '{sub(/.*http/,"http");print $0}'
Отримавши URL сертифіката, завантажуємо його будь-яким зручним чином. Наприклад, через curl:
curl --user-agent "Mozilla/5.0 (compatible; Airee-Speedup/1.0; +http://airee.ru/robots)" $issuer -o /tmp/stapling.crt 2>/dev/null
Запускаємо рекурсію
Описану вище процедуру можна виконувати в циклі, поки з сертифіката витягується шлях до «рідної». Але є один нюанс. Підписують сертифікати засвідчують центрів зазвичай зберігаються у двійковому форматі, тому нам потрібно буде перевірити формат сертифіката і перетворити його до текстового (щоб коректно включити до фінальної ланцюжок сертифікатів, яка буде записана в форматі PEM).

Для перевірки формату сертифіката скористаємося
verify
від openssl:
openssl verify /tmp/stapling.crt 2>&1 | grep "unable to load")
У разі виникнення помилки читання завантаженого сертифіката нам потрібно буде перетворити його з бінарного формату в base64:
openssl x509 -inform der -in /tmp/stapling.crt -out /tmp/stapling.crt
Після перетворення сертифіката ми можемо спокійною скопіювати його в кінець нашого ланцюжка, визначити шлях до «рідної» сертифікату і продовжити складання ланцюжка (якщо потрібно).

Правильний порядок сертифікатів в ланцюжку
У фіналі повинен вийти файл з ланцюжком сертифікатів наступного змісту:
— BEGIN CERTIFICATE-----
сертифікат сайту у форматі base64
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
проміжний сертифікат у форматі base64
-----END CERTIFICATE-----
[----- BEGIN CERTIFICATE-----
можливо, ще один проміжний сертифікат
-----END CERTIFICATE-----]
-----BEGIN CERTIFICATE-----
кореневий сертифікат у форматі base64
-----END CERTIFICATE-----
Браузерам сам кореневий сертифікат в ланцюжку не потрібно: він у них вже є. Але він потрібний для верифікації ланцюжка самому nginx з включеною налаштуванням
ssl_stapling
.

Підсумок
Для складання ланцюжка сертифікатів з даного потрібні наступні дії:

1. Скопіювати даний сертифікат на початок ланцюжка (cat).
2. Отримати URL «батьківського» сертифіката (openssl + awk / sed).
3. Завантажити «батьківський» сертифікат (curl / wget).
4. Переформатувати «батьківський» сертифікат (openssl).
5. Скопіювати «батьківський» сертифікат в ланцюжок (cat).
6. Повторити кроки 2-5 або завершити.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.