Налаштування та оптимізація SSL для nginx під linux, Айрі

Налаштування та оптимізація SSL для nginx під linux
Оптимізуючи серверне оточення для максимальної продуктивності, обов'язково зіткнешся із завданням підтримки SSL-сертифікатів та оптимізації швидкості SSL-захищеного з'єднання.
Цілком умовно, завдання налаштування підтримки SSL для nginx на Linux-оточенні (у прикладах використовується RedHat/CentOS, але більшість порад платформо-незалежні) можна розбити на кілька складових:
- Оптимізація стека TCP/IP, включаючи розміри TCP вікна.
- Оптимізація TLS-стеку, включаючи OpenSSL.
- Конфігурація nginx з урахуванням налаштувань продуктивності, безпеки та зворотної сумісності.
Оптимізація TCP/IP стека
Ця назва цілком умовна, тому що тут мова піде, в основному, тільки про системні параметри, які критично впливають на продуктивність SSL-з'єднання.
На тему оптимізації TCP/IP було досить багато статей (наприклад, така, що майже не втратила актуальності, налаштування sysctl або дослідження алгоритмів вибору розміру вікна). Базово потрібно максимально оптимізувати процес переговорів розмір TCP пакета (вікна), включити syncookies, збільшити розміри буферів. Можна також зменшити кількість спроб відновлення SYN/SYNACK/keepalive.
Більш-менш безпечний набір для широкого кола серверів виглядає так:
Найбільша зміна, яка стосується сам SSL, — це розмір початкового вікна, з яким сервер починає спілкування з клієнтом, — initcwnd. За замовчуванням (до ядра 2.6.39) цей параметр виставлений в 3 (тобто перший пакет з даними повинен бути не більше 3*1460 байт). Його можна збільшити до 10 (заощадивши один або кілька циклівнадсилання-отримання даних, тобто, як мінімум, 2 часу пінгу до сервера).
Оптимізація TLS-стеку
Як чітко зазначили в дискусії nginx, при великому значенні initcwnd вказана оптимізація може бути зайвою. Починаючи з версії 1.5.9, розмір TSL-буфера можна встановити налаштуванням nginx (що трохи далі за текстом і буде зроблено). Якщо ви використовуєте nginx до версії 1.5.9, то NGX_SSL_BUFSIZE можна виставити в 8096 (спасибі).
Додатково у версії nginx, починаючи з 1.5.7, вирішено проблему маленького буфера для SSL-сертифікатів. Ще одна причина оновитись до останньої стабільної версії. D
За аналогією з TCP Slow Start потрібно буде усунути проблему TLS Slow Start (тобто затримку під час надсилання початкового обсягу даних). Для цієї мети потрібен OpenSSL версії не нижче 1.0.1а (а без вже знайдених уразливостей – 1.0.1i). Версія 1.0.1 також знадобиться для підтримки SPDY. Оптимізація nginx до роботи з TSL.
Все це призводить до прискорення встановлення SSL з'єднання в 2-3 рази.
Як швидкий список для перевірки, чи все оптимізовано, можна використовувати наступний:
- Оновити ядро до останньої версії (Linux: 3.2+).
- Переконатись, що розмір вікна cwnd виставлений у 10.
- Виправити проблему slow-start.
- Переконайтеся, що зміна вікна увімкнена (window scaling).
- Усунути передачу непотрібної інформації.
- Стиснути дані, що передаються.
- Розташувати сервер максимально близько до користувача для зменшення часу пінгу.
- Використовувати вже встановлені з'єднання TCP у всіх можливих випадках.
Оптимізація nginx + OpenSSL
Так, базова річ - це зібрати nginx за допомогою SSL і SPDY. Потрібно буде OpenSSL не нижче 1.0.1, якщо з пакетів не встановлюється - потрібно будезбирати вручну. У якості хінту при конфігурації використовуйте наступний рядок:
Це дозволить встановити OpenSSL поверх поточного системного та використовувати для складання nginx.
При складанні nginx вказуємо модулі:
Якщо ви хочете захистити SSL від атак типу BREACH, можна додатково скористатися модулем nginx-hiding-length (не відключати ж gzip-стиск через це).
Після складання nginx для хоста, для якого ми маємо секретний ключ (SCR, питання про використання еліптичних кривих для його генерації залишається за рамками статті) і публічний ключ (сертифікат), потрібно підготувати приблизно таку конфігурацію (блок server):
Існує багато рекомендацій щодо набору SSL шифрів (з урахуванням Forward Secrecy): від Mozilla, від SSLLabs, від hasGeek та інші. Докладніше можна прочитати у статті про налаштування nginx. Пропонований варіант базується на рекомендаціях від SSLLabs з відключенням RC4 як зовсім безпечного. Зазначені налаштування дозволяють досягти оцінки 95 за тестом Qualsys.
Щоб перевірити, які з цих шифрів підтримуються OpenSSL, можна виконати:
При цьому 3DES шифр не рекомендується підключати з міркувань продуктивності (ще один вектор DDoS-атаки у зв'язку з великою складністю шифру, дослідження швидкості різних шифрів).

- Застосувати дії оптимізації TCP.
- Оновити TLS-бібліотеки до останньої версії, (пере) зібрати сервер з їхньою підтримкою.
- Включити та налаштувати кешування та відновлення SSL-сесій.
- Перевірити налаштування оптимального кешування SSL-сесій.
- Налаштувати шифри forward secrecy для включення TLS False Start.
- Завершувати TLS-сесії максимально близько до користувачів.
- Використовувати динамічні вікна TLS для оптимізаціїзатримок/пропускної спроможності.
- Перевірити, що розмір файлу сертифікатів не перевищує початкового розміру вікна TCP.
- Залишити в ланцюжку сертифікатів лише необхідні.
- Увімкнути скріплення сертифікатів (OCSP stapling).
- Вимкнути TLS-стиск.
- Додати підтримку SNI.
- Додати заголовок HTTP Strict Transport Security.
За кадром залишається питання про динамічне TLS-вікно (невелике при початку з'єднання, що зростає у міру використання і хлопається після простою), безпечне використання TLS-стиснення, стійкість шифрування еліптичними кривими (ECC) та їх використання (дякую) та оптимізацію наборів шифрів для різних пристроїв (про це можна написати ще одну статтю).