SSL Nginx: устанавливаем SSL-сертификат на сервер Nginx | LeaderSSL

SSL Nginx: устанавливаем SSL-сертификат на сервер Nginx  | LeaderSSL Сертификаты
Содержание
  1. Почему лучше рассчитывать на sni?
  2. Caveat emptor
  3. Ssl nginx: устанавливаем ssl-сертификат на сервер nginx
  4. Авторизация с помощью сертификата ssl на nginx let’s encrypt
  5. Бесплатные wildcard ssl сертификаты let’s encrypt для поддоменов
  6. Вот и всё
  7. Выбираем шифры
  8. Если нужно добавить поддомен или домен в сертификат
  9. Если нужно получить сертификат для домена без сайта…
  10. Недостатки
  11. Подготовим nginx к получению сертификатов
  12. Подготовка
  13. Подготовка к установке
  14. Получаем сертификаты
  15. Принцип поиска шифров
  16. Проверим полученный сертификат
  17. Продление сертификатов
  18. Продление сертификатов let’s encrypt
  19. Регистрация в let’s encrypt
  20. У вас есть приватный ключ, сам ssl сертификат, а также промежуточный и корневой сертификат
  21. У вас есть приватный ключ, сам ssl сертификат, а также цепочка сертификатов
  22. У вас есть сертификат в другом формате, например pfx
  23. Установка в jessie
  24. Установка сертификата
  25. Итого

Почему лучше рассчитывать на sni?

  1. Это просто. Вам не нужно постоянно держать в голове факты о выданных сертификатах. Для какого домена сертификат был выдан первым. К какому сертификату нужно добавлять еще домены. И так далее… Ни о чем таком со SNI не нужно думать.

  2. Секреты остаются секретами. Если у вас для всех доменов один сертификат, то любой сможет очень легко увидеть весь список, независимо от вашего желания. Если же для каждого сайта свой сертификат, то такой проблемы нет.

Например, так можно посмотреть домены в сертификате Тематических Медиа:

Caveat emptor

Всё знаете про SNI? Читайте сразу про установку.

Ssl nginx: устанавливаем ssl-сертификат на сервер nginx

Установка SSL-сертификата и переход к протоколу HTTPS – отличный способ повысить безопасность соединений между браузером и сервером. SSL-соединение является крайне рекомендованным для всех сайтов, где требуется пользовательская регистрация. Вопреки тому, что говорят многие устаревшие инструкции и руководства, сертификат не добавляет никакой серьезной нагрузки на сервер, и его можно легко и недорого выпустить.

Устанавливаем SSL на Nginx

Первое, что нужно сделать еще до того, как переходить к настройкам Nginx – это заказать SSL-сертификат. Сделать это можно в компании ЛидерТелеком. На выбор предлагаются самые разные сертификаты, среди которых можно особо выделить следующие:

Теперь, когда у вас есть на руках сертификат, вы можете переходить к технической стороне – настройке SSL на Nginx.

Как установить SSL-сертификат на Nginx

Для установки SSL на Nginx нужно будет выполнить следующие шаги:

  1. Вы должны получить архив с сертификатом на свой почтовый адрес, который был указан при заказе SSL-сертификата. Архив обычно хранит в себе корневой, промежуточный сертификат, а также сертификат для домена. Если вы уже имеете файл bundle.crt, вы можете сразу переходить к шагу 4. В противном случае вам нужно будет объединить в один файл три файла сертификатов. Этот процесс подробно описан в пунктах 2 и 3.
  2. У вас должно быть три файла: comodo_root.crt (корневой сертификат), comodo_intermediate.crt (промежуточный сертификат) и vash_domen.crt. Скопируйте их вместе с файлом .key в произвольный каталог на своем сервере, в котором вы хотите их хранить.
  3. Вам нужно будет объединить файл с корневым сертификатом (comodo_root.crt), файл с промежуточным сертификатом (comodo_intermediate.crt) и файл сертификата vash_domen.crt в один crt-файл. Делается это с помощью следующей команды:

cat comodo_root.crt comodo_intermediate.crt vash_domen.crt > bundle.crt

В некоторых случаях Comodo присылают архив, в котором файлы промежуточного сертификата и корневого сертификата уже объединены в один файл. Если так, то вам нужно будет объединить его с файлом сертификата при помощи следующей команды:

cat comodo-bundle.crt vash_domen.crt > bundle.crt

  1. Переходим к настройке Nginx. Чтобы сгенерировать конфигурационный файл для веб-сервера, можно воспользоваться сервисом https://mozilla.github.io/server-side-tls/ssl-config-generator/. Самым распространенным вариантом является Intermediate, включающий в себя все методы кодирования, поддерживаемые текущими популярными версиями браузеров.

    Открываем файл виртуального хоста Nginx для сайта, который вы хотите защитить. Если вы хотите, чтобы ваш сайт был доступен и через незащищенное, и через защищенное соединение, вам нужно будет добавить модуль сервера для каждого типа подключения. Сделайте копию существующего модуля для незащищенного соединения и вставьте его под основным кодом. После чего добавьте к нему следующие строки (выделены жирным):

server {

listen 443;

ssl on;

ssl_certificate /etc/ssl/bundle.crt;

ssl_certificate_key /etc/ssl/vash_domen.key;

server_name vashdomen.com;

access_log /var/log/nginx/nginx.vhost.access.log;

error_log /var/log/nginx/nginx.vhost.error.log;

location / {

root /home/www/public_html/vash_domen/public/;

index  index.html;

}

}

Убедитесь в том, что в ssl_certificate указан crt-файл, созданный нами ранее.

Если вы использовали генератор, приведенный выше по ссылке, то в таком случае ваш конфигурационный файл может иметь следующий вид (здесь мы подразумеваем, что вы генерировали dhparam.pem для прямой секретности. Если нет, то делается это командой openssl dhparam -out /etc/pki/nginx/dhparam.pem 4096):

server {

    listen 80;

    server_name name.ru www.name.ru;

    return 301 https://name.ru$request_uri;

}

# Добавляем 301 редирект

server {

     listen 443 ssl http2;

     server_name www.name.ru;

     # здесь обязательно указываем сертификаты

     ssl_certificate /etc/nginx/ssl/name.ru/bundle.crt;

     ssl_certificate_key /etc/nginx/ssl/name.ru/name.key;

     return 301 https://name.ru$request_uri;

}

server {

    # добавляем протокол http2

    listen 443 ssl http2;

    server_name name.ru;

    access_log off;

    #access_log /var/log/nginx/name.ru.access.log;

    error_log /var/log/nginx/name.ru.error.log;

  ssl on;

    # Включаем OCSP-stapling. Что это такое и зачем нужно, вы можете найти у нас в FAQ.

    ssl_stapling on;

    ssl_stapling_verify on;

    # наши сертификаты

    ssl_certificate /etc/nginx/ssl/name.ru/bundle.crt;

    ssl_certificate_key /etc/nginx/ssl/name.ru/name_private.key;

    ssl_dhparam /etc/nginx/ssl/name.ru/dhparam.pem;

    # настраиваем сессию

    ssl_session_tickets off;

    ssl_session_timeout 1d;

    ssl_session_cache shared:SSL:50m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

    ssl_ciphers ‘ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS’;

    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security max-age=31536000;

    # проксирование данных

    location / {

        # параметры проксирования

        proxy_send_timeout 600;

        proxy_read_timeout 600;

        proxy_buffer_size   128k;

        proxy_buffers   4 256k;

        proxy_busy_buffers_size   256k;

        proxy_set_header Host      $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header HTTPS YES;

        # IP-адрес целевой площадки для проксирования

        proxy_pass http://192.168.1.108;

    }

Также вам нужно будет добавить в конфиг следующее (здесь все зависит от используемой CMS):

location ~ .php$ {
fastcgi_pass unix:/var/run/php-fpm/www.sock;
fastcgi_split_path_info ^(. .php)(/. )$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_param HTTPS on;
fastcgi_param HTTP_HTTPS on;
fastcgi_param REQUEST_SCHEME https;
fastcgi_param SERVER_PORT 443;
}

  1. Сделайте рестарт Nginx. Просто выполните следующую команду:

sudo /etc/init.d/nginx restart

Готово! Вы установили SSL-сертификат на Nginx. Если у вас остались какие-либо вопросы, связанные с установкой SSL-сертификата, вы всегда можете обратиться к нам по представленным на сайте контактам.

Авторизация с помощью сертификата ssl на nginx let’s encrypt

Добрый день, вечер или ночь, все зависит от времени суток в который вам довелось прочитать мою статью.

В связи с ростом количества корпоративных клиентов, было принято решение дать доступ к учетной системе внешним пользователям. Для самостоятельного оформления заказов и отслеживания их состояний. Реализация была создан web интерфейс с необходимым функционалом и доступом. Тут же стал вопрос безопасности, кроме стандартных пользователь-пароль было решено еще усилить безопасность, для этого применили OpenVPN, но появились клиенты, для которых нельзя применять OpenVPN (политики безопасности, нежелания и.д.), тут на глаза попались статьи про доступ по ssl сертификату.

SSL Nginx: устанавливаем SSL-сертификат на сервер Nginx  | LeaderSSL

Исходные данные:

Сервер с учетной программой web интерфейс находятся в DMZ;
WEB-server на nginx, на него проброшены порты http(80) и https(443);
На web-server настроен proxy_pass на сервер с учетной программой, доступ только по порту 8080 и только с IP web-server, большего доступа с серверу нет(обычная безопасность);
На сайт для доступа установлен сертификат от Let’s Encrypt.

Переходим к самому процессу создания сертификата пользователя:

Для сертификатов будем использовать каталог “/etc/ssl/crm.example.ru”

Создаём структуру каталогов:

# mkdir /etc/ssl/crm.example.ru
# cd /etc/ssl/crm.example.ru
# mkdir db
# mkdir db/certs
# mkdir db/newcerts
# touch db/index.txt
# echo "01" > db/serial
# chmod 700 ./

Создаем конфигурационный файл для подписи сертификатов.

/etc/ssl/crm.example.ru/ca.conf”

[ ca ]
default_ca             		= CA_CITENAME          	# Секция по умолчанию для подписи сертификатов

[ CA_CITENAME ]
droot                  		= /etc/ssl/crm.example.ru # Корневой каталог хранилища
dir                    		= $droot/db            	# Каталог базы хранилища
certs                  		= $dir/certs           	# Каталог сертификатов
new_certs_dir          		= $dir/newcerts        	# Каталог для новых сертификатов (pem)

database               		= $dir/index.txt       	# Файл базы сертификатов
serial                 		= $dir/serial          	# Файл серийного номера

# Файл доверенного сертификата
certificate            		= $droot/ca.crt
# Закрытый ключ доверенного сертификата
private_key            		= $droot/ca.key

default_days           		= 365                  	# Срок действия нового сертификата (дни)
default_crl_days       		= 7                    	# Срок действия списка отозванных сертификатов
default_md             		= md5                  	# Использовать алгоритм MD5

policy                 		= policy_citename      	# Политика секции

[ policy_citename ]
countryName            		= optional             	# Необязательный параметр
stateOrProvinceName    		= optional             	# .......................
localityName           		= optional             	# .......................
organizationName       		= optional             	# .......................
organizationalUnitName 		= optional             	# .......................
commonName             		= supplied             	# обязательный параметр
emailAddress           		= supplied             	# .....................

[ req_distinguished_name ]
countryName                     = Название страны (2-буквенный код)
countryName_default             = RU
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = Название области (полное название)
stateOrProvinceName_default     = Tyumen region

localityName                    = Название местности (например, город)
localityName_default            = Tyumen

0.organizationName              = Название организации
0.organizationName_default      = EXAMPLE

organizationalUnitName          = Название организационной единицы (например, отдел)

commonName                      = Ваше имя
commonName_max                  = 64

emailAddress                    = Email адрес
emailAddress_max                = 64

Создаем самоподписанный сертификат и новый ключ сервера без пароля:

# openssl req -new -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 365 
-subj "/C=RU/ST=Tyumen region/L=Tyumen/O=EXAMPLE/OU=CRM/CN=crm.example.ru/emailAddress=crm@example.ru" 
-out ca.crt

Либо, если хотите всё вводить вручную.

# openssl req -new -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 365 -out ca.crt

Просмотреть данные закрытого ключа и сертификата вы можете с помощью команд:

# openssl rsa -noout -text -in ca.key              (для ключа)
# openssl x509 -noout -text -in ca.crt             (для сертификата)

Создание клиентского закрытого ключа и запроса на сертификат (CSR):

# openssl req -new -newkey rsa:2048 -nodes -keyout client01.key 
-subj "/C=RU/ST=Tyumen region/L=Tyumen/O=EXAMPLE/OU=CRM/CN=User example1/emailAddress=user@example1.ru" 
-out client01.csr

Либо, если хотите всё вводить вручную.

#openssl req -new -newkey rsa:2048 -nodes -keyout client01.key -out client01.csr

Заместо User example1 можно указать почту клиента, а за место EXAMPLE компанию клиента, это поможет отслеживать сертификаты.

В результате выполнения команды появятся два файла client01.key и client01.csr. Просмотреть данные закрытого ключа и запроса на сертификат (CSR) вы можете с помощью команд:

# openssl rsa -noout -text -in client01.key             (для ключа)
# openssl req -noout -text -in client01.csr             (для запроса)

Подпись запроса на сертификат (CSR) с помощью доверенного сертификата (CA). При подписи запроса используются параметры заданные в файле ca.config

# openssl ca -config ca.config -in client01.csr -out client01.crt -batch

Подготовка данных для передачи клиенту. Для передачи полученных в результате предыдущих операций файлов клиенту, обычно используется файл в формате PKCS#12. В этот файл упаковывается и защищается паролем вся информация необходимая клиенту для инсталляции сертификата в броузер.

# openssl pkcs12 -export -in client01.crt -inkey client01.key 
-certfile ca.crt -out client01.p12 -passout pass:123ewqasdcxz

Выставляем права доступа на ключи.

# chmod 600 /etc/ssl/crm.example.ru/client*.crt
# chmod 600 /etc/ssl/crm.example.ru/client*.key

Переместим все созданные файлы в каталог db/certs на хранение.

# mv ./client01.* db/certs/

В nginx надо установить:

            ssl_client_certificate      /etc/ssl/crm.example.ru/ca.crt;
            ssl_verify_client           on;
            ssl_verify_depth            1;

Для того чтобы клиент смог подключиться по сертификату ему необходимо отправить файл client01.p12 и ca.crt, а так же сообщить пароль для установки сертификата. ca.crt необходим, так как мы не используем его для сертификации сервера, для этомо используеться Let’s Encrypt.

Процесс выдачи сертификатов можно автоматизировать, написать просто скрипт не составит труда. У нас таких клиентов не много, около 15, так что вбить всё руками не составило проблем.

Мой рабочий пример:

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

SSL Nginx: устанавливаем SSL-сертификат на сервер Nginx  | LeaderSSL

Сам сертификат:

SSL Nginx: устанавливаем SSL-сертификат на сервер Nginx  | LeaderSSL

Работоспособность Let’s Encrypt:

SSL Nginx: устанавливаем SSL-сертификат на сервер Nginx  | LeaderSSL

В подготовке материала помогли статьи:

«Авторизация клиентов в nginx посредством SSL сертификатов»
«Авторизация по SSL сертификатам»
«Авторизация с помощью клиентских SSL сертификатов. (ssl crypt mod_ssl apache)»
«Великий и могучий Google»

P.S. Проверка проводилась на Google Chrome.

Бесплатные wildcard ssl сертификаты let’s encrypt для поддоменов

Чтобы выпустить wildcard сертификат Let’s Encrypt для всех поддоменов, используется другая команда. Кроме того, в DNS настройках вашего домена нужно создать специальную txt-запись. Чтобы выпустить wildcard сертификат для поддоменов, в директории /opt/letsencrypt/ запустите команду:

Вот и всё

Если вам близки по духу tee и sed, то есть гораздо более короткая инструкция по настройке связки Let’s Encrypt и nginx, при условии корректно настроенного hostname. Только копируй команды и вставляй.

Выбираем шифры

Теперь у нас есть всё, чтобы составить список шифров для nginx, которые не будет требовать дополнения при выходе новых версий OpenSSL, теряя старые шифры и приобретая новые без какого-либо участия с нашей стороны. Мы учём необходимость поддержки старых браузеров и требования к скорости.

Начнём с получения уже используемого нам списка шифров, но не будем исключать шифры для сертификатов c EC на случай если мы когда-нибудь захотим использовать такой вид сертификатов.

$ openssl ciphers -v 'EECDH AES256' | column -t
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1

На деле нам нужнен не столько конкретно AES, а сколько не нужны слабые шифры 3DES и RC4. Последний исключим полностью и навсегда.

$ openssl ciphers -v 'EECDH:-3DES:!NULL:!RC4' | column -t
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1

Отдадим приоритет более быстрым шифрам, понизив его для AES-256. Совсем удалять AES-256 не будем на случай если кому-то очень будет нужен именно AES-256. (Добавочные биты у него — воображаемые.)

$ openssl ciphers -v 'EECDH: AES256:-3DES:!NULL:!RC4' | column -t
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1

Такая строка шифров не исключит ChaCha20/Poly1305 в следующей версии OpenSSL.

$ openssl version; openssl ciphers -v 'EECDH: AES256:-3DES:!NULL:!RC4' | column -t | head -n 6
OpenSSL 1.1.0e  16 Feb 2021
ECDHE-ECDSA-CHACHA20-POLY1305   TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=CHACHA20/POLY1305(256)  Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305     TLSv1.2  Kx=ECDH  Au=RSA    Enc=CHACHA20/POLY1305(256)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256   TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)             Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256     TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)             Mac=AEAD
ECDHE-ECDSA-AES128-CCM8         TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESCCM8(128)            Mac=AEAD
ECDHE-ECDSA-AES128-CCM          TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESCCM(128)             Mac=AEAD

Для некоторых устаревших клиентов вернём AES без эфемерных ключей.

$ openssl ciphers -v 'EECDH: AES256:-3DES:RSA AES:!NULL:!RC4' | column -t
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1
AES256-GCM-SHA384              TLSv1.2  Kx=RSA   Au=RSA    Enc=AESGCM(256)  Mac=AEAD
AES256-SHA256                  TLSv1.2  Kx=RSA   Au=RSA    Enc=AES(256)     Mac=SHA256
AES256-SHA                     SSLv3    Kx=RSA   Au=RSA    Enc=AES(256)     Mac=SHA1
AES128-GCM-SHA256              TLSv1.2  Kx=RSA   Au=RSA    Enc=AESGCM(128)  Mac=AEAD
AES128-SHA256                  TLSv1.2  Kx=RSA   Au=RSA    Enc=AES(128)     Mac=SHA256
AES128-SHA                     SSLv3    Kx=RSA   Au=RSA    Enc=AES(128)     Mac=SHA1

Наконец, вернём 3DES без эфемерных ключей чисто для IE8/XP. Помочь IE6/XP никак нельзя — он по умолчанию не поддерживает TLS.

$ openssl ciphers -v 'EECDH: AES256:-3DES:RSA AES:RSA 3DES:!NULL:!RC4' | column -t
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1
AES256-GCM-SHA384              TLSv1.2  Kx=RSA   Au=RSA    Enc=AESGCM(256)  Mac=AEAD
AES256-SHA256                  TLSv1.2  Kx=RSA   Au=RSA    Enc=AES(256)     Mac=SHA256
AES256-SHA                     SSLv3    Kx=RSA   Au=RSA    Enc=AES(256)     Mac=SHA1
AES128-GCM-SHA256              TLSv1.2  Kx=RSA   Au=RSA    Enc=AESGCM(128)  Mac=AEAD
AES128-SHA256                  TLSv1.2  Kx=RSA   Au=RSA    Enc=AES(128)     Mac=SHA256
AES128-SHA                     SSLv3    Kx=RSA   Au=RSA    Enc=AES(128)     Mac=SHA1
DES-CBC3-SHA                   SSLv3    Kx=RSA   Au=RSA    Enc=3DES(168)    Mac=SHA1

Если нужно добавить поддомен или домен в сертификат

Если вы вдруг забыли указать поддомен www, или вам нужно добавить другой домен или поддомен в сертификат (которых может быть до 100 в одном сертификате), то это легко сделать после получения сертификата. Просто запустите команду еще раз, добавив требуемое имя:

Если нужно получить сертификат для домена без сайта…

Типичный пример — сертификат для выделенных под SMTP или IMAP серверов, на которых вообще нет каких-то сайтов. Либо используйте универсальный переадресатор что выше, либо…

Недостатки

Но есть одна проблема. Если результаты теста прокрутить до раздела Handshake Simulation, то мы увидим что на наш сайт не попадут пользователи IE любых версий младше 11, Java до SE 8, Android до версии 4.3 и даже некоторые версии Safari. Про софт, собранный с OpenSSL версии младше 0.9.8, даже и не говорю.

Есть и ещё одна проблема: производительность. Наш ключ на 4096 бит непосредственно влияет на скорость установки соединения, при этом не слишком усиливает защиту. Шифры на 256 бит тоже не помогают ускорить соединеие, что касается мобильных устройств с маломощными процессорами и прочих клиентов без AES-NI (аппаратного ускорения).

В случае RSA легко убедиться в негативном влиянии на скорость, используя встроенный в OpenSSL тест.

openssl speed rsa2048 rsa4096

На маломощном Celeron 1007U разница очевидна.

               sign      verify      sign/s verify/s
rsa 2048 bits  0.002381s 0.000071s    420.0  14051.0
rsa 4096 bits  0.016790s 0.000260s     59.6   3852.8

Подпись на стороне сервера делается в семь раз медленнее. Проверка подписи на клиенте — в 3.6 раза медленнее. На другом железе тенденция остаётся та же. Этот проигрыш в скорости — плата за усиление стойкости шифра на какие-то 16%.

Аналогичным образом проверим скорость рекомендуемых шифров на OpenSSL 1.1.0e.

for cipher in aes-128-gcm aes-256-gcm chacha20-poly1305
do openssl speed -decrypt -evp $cipher 2>/dev/null | grep ^$cipher
done | column -t

На Celeron 1007U шифр ChaCha20/Poly1305 будет в два раза быстрее AES-128, а последний на треть быстрее AES-256. На Core i7 с AES-NI картина другая: ChaCha20/Poly1305 будет медленнее AES-128 на треть, а AES-256 лишь немного медленнее AES-128. При шифровании картина примерно та же.

Обмен ключами с используемой по умолчанию кривой prime256v1 (она же secp256r1 или NIST P-256) будет существенно быстрее, чем с усиленной кривой secp384r1 (NIST P-384).

$ openssl speed ecdsap256 ecdsap384 ecdhp256 ecdhp384
                              sign    verify    sign/s verify/s
 256 bit ecdsa (nistp256)   0.0001s   0.0003s   7923.8   3214.4
 384 bit ecdsa (nistp384)   0.0006s   0.0023s   1756.6    430.1
                              op      op/s
 256 bit ecdh (nistp256)   0.0002s   4893.5
 384 bit ecdh (nistp384)   0.0019s    525.9

Работа с P-384 требует в 7-9 раз больше времени в зависимости от операции.

Если сравнить ECDSA и RSA, то видно что в случае ECDSA вычислительная нагрузка ложится больше на клиента, чем на сервер.

Если вы захотите повторить тесты у себя, то перед тестами стоит поднять приоритет текущего процесса.

sudo renice -1 $$

Очевидно одно: к выбору шифров и параметров нужно подходить более взвешено.

Подготовим nginx к получению сертификатов

В общем случае для получения сертификата необходимо во всех блоках server добавить следующий блок до других блоков location:

location /.well-known {
    root /var/www/html;
}

Понятно, что вписывать для каждого сайта такой блок явно — это моветон, потому создадим файл /etc/nginx/acme с содержанием блока выше.

# cat /etc/nginx/acme 
location /.well-known {
    root /var/www/html;
}

Затем для каждого домена и поддомена, для которых нужно получить сертификаты, в блоке server перед всеми блоками location укажем:

include acme;

Хосты-редиректоры (например, с голого домена на www) можно пропустить. ACME сервер обязан учитывать стандартную переадресацию. Подробней об этом ниже.

Перезагрузим nginx и проверим что наш тестовый файл виден:

Подготовка

Работать будем с Debian 8.7. Если у вас другой дистрибутив, то версии должны быть такие же или более новые.

# lsb_release -d
Description:    Debian GNU/Linux 8.7 (jessie)

# openssl version
OpenSSL 1.0.1t  3 May 2021

# nginx -V
nginx version: nginx/1.6.2

Настроим nginx для получения сертификатов от Let’s Encrypt по инструкции, но только до получения сертификата для нашего домена.

Подготовка к установке

Наилучший вариант т.к. потребуется только указать эти данные в конфигурации nginx и перезапустить его.

Получаем сертификаты

У Let’s Encrypt есть лимиты на количество обращений за сертификатами, потому сначала попробуем получить необходимый сертификат в режиме для тестов:

Принцип поиска шифров

Перечисление шифров списком — не лучшая идея потому что уже скоро можно будет штатно, без перекомпиляции и сторонних источников, использовать ChaCha20/Poly1305 в nginx. С явным заданием шифров сервер не будет использовать любые новые виды шифрования без перенастройки. Это не то, о чем вы хотите думать каждый день.

Будет лучше выбирать шифры по ключевым словам или тегам, каждое из которых соответствуют какой-то группе шифров. Ключевые слова в разных версиях OpenSSL отличаются, но мы всегда можем их проверить.

Например, тег EECDH соответствует всем шифрам с обменом одноразовыми (эфемерными) ключами по алгориму DH с эллиптическими кривыми.

$ openssl ciphers -v 'EECDH' | column -t
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA384
ECDHE-ECDSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(256)     Mac=SHA1
ECDHE-ECDSA-AES256-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(256)     Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(128)  Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256        TLSv1.2  Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA256
ECDHE-ECDSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA           SSLv3    Kx=ECDH  Au=RSA    Enc=AES(128)     Mac=SHA1
ECDHE-ECDSA-AES128-SHA         SSLv3    Kx=ECDH  Au=ECDSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-RC4-SHA              SSLv3    Kx=ECDH  Au=RSA    Enc=RC4(128)     Mac=SHA1
ECDHE-ECDSA-RC4-SHA            SSLv3    Kx=ECDH  Au=ECDSA  Enc=RC4(128)     Mac=SHA1
ECDHE-RSA-DES-CBC3-SHA         SSLv3    Kx=ECDH  Au=RSA    Enc=3DES(168)    Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA       SSLv3    Kx=ECDH  Au=ECDSA  Enc=3DES(168)    Mac=SHA1
ECDHE-RSA-NULL-SHA             SSLv3    Kx=ECDH  Au=RSA    Enc=None         Mac=SHA1
ECDHE-ECDSA-NULL-SHA           SSLv3    Kx=ECDH  Au=ECDSA  Enc=None         Mac=SHA1

Шифры показываются в списке согласно приоритету: клиент выберет первый подходщящий шифр, просматривая список в указанном порядке.

Если бы у нас была самая последняя версия OpenSSL, то для получения того же списка мы бы использовали понятный тег ECDHE, дающий тот же самый список и соответствующий префиксу шифров. В текущей версии такого тега нет, потому используем какой есть.

В полученном списке бросаются в глаза шифры без, собственно, шифрования, которые идут с отметкой Enc=None. Исключим такие шифры, дающие только аутентификацию. Заодно исключим шифры без аутентификации.

openssl ciphers -v 'EECDH:!aNULL:!eNULL'

Для полного и безвозратного исключения теги групп aNULL и eNULL c неподходящими шифрами упомянуты с отрицанием. В списке не останется шифров с Au=None или с Enc=None.

Теги можно сочетать, получая пересечения множеств шифров. Получим шифры, сочетающие ECDHE, AES-256 и GCM.

$ openssl ciphers -v 'EECDH AES256 AESGCM' | column -t
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2  Kx=ECDH  Au=RSA    Enc=AESGCM(256)  Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=ECDSA  Enc=AESGCM(256)  Mac=AEAD

Группы шифров можно переместить ниже по приоритету, указав с плюсом в начале. Понизим приоритет у шифров с AES-256, не удаляя их.

$ openssl ciphers -v 'EECDH aRSA AES: AES256' | column -t
ECDHE-RSA-AES128-GCM-SHA256  TLSv1.2  Kx=ECDH  Au=RSA  Enc=AESGCM(128)  Mac=AEAD
ECDHE-RSA-AES128-SHA256      TLSv1.2  Kx=ECDH  Au=RSA  Enc=AES(128)     Mac=SHA256
ECDHE-RSA-AES128-SHA         SSLv3    Kx=ECDH  Au=RSA  Enc=AES(128)     Mac=SHA1
ECDHE-RSA-AES256-GCM-SHA384  TLSv1.2  Kx=ECDH  Au=RSA  Enc=AESGCM(256)  Mac=AEAD
ECDHE-RSA-AES256-SHA384      TLSv1.2  Kx=ECDH  Au=RSA  Enc=AES(256)     Mac=SHA384
ECDHE-RSA-AES256-SHA         SSLv3    Kx=ECDH  Au=RSA  Enc=AES(256)     Mac=SHA1

Можно временно убрать какую-то группу шифров, чтобы потом добавить её в другом виде. Исключим из всех ECDHE шифров шифры с 3DES, а затем вернём их обратно, но только в сочетании с обменом ключами RSA. Такие слабые шифры должны оказаться в самом конце списка.

$ openssl ciphers -v 'EECDH:-3DES:RSA 3DES' | tail -1 | column -t
DES-CBC3-SHA  SSLv3  Kx=RSA  Au=RSA  Enc=3DES(168)  Mac=SHA1

Проверим полученный сертификат

Убедимся что полученный сертификат — именно тот, что нам нужен:

Продление сертификатов

Сертификаты выдаются на три месяца. Не на полгода, не на год, а лишь на три месяца. Естественно это вызывает вопросы. Нужно ли проходить всю эту процедуру через три месяца? Нужно ли это делать всегда до искончания веков? Может стоит всё-таки вложиться в платный сертификат чтобы забыть об этом всем и не воспоминать пару лет?

Но нет, не спешите искать платежные средства! Как и было обещано в начале статьи, с обновлением сертификатов проблем нет.

Продление сертификатов let’s encrypt

Сертификаты Let’s Encrypt выдаются на 90 дней, рекомендуется продлевать эти сертификаты каждые 60 дней.

Чтобы перевыпустить устаревший SSL сертификат Let’s Encrypt, используется команда:

Регистрация в let’s encrypt

Регистрацию нужно сделать только один раз:

У вас есть приватный ключ, сам ssl сертификат, а также промежуточный и корневой сертификат

Данный вариант отличается от первого только тем, что нужно объединить все сертификаты (SSL сертификат, промежуточный и корневой) в одну цепочку.

Будем считать, что SSL сертификат имеет имя site_ru.crt, корневой сертификат CAroot.crt, промежуточный сертификат CAintermediate.crt

В таком случае объединение файлов можно выполнить так:

Перейдем в директорию, где расположены данные файлы (например /root/site_certs/)

[root@server ~]# cd /root/site_certs/

Объединим файлы

[root@server certs]# cat CAroot.crt CAintermediate.crt >> site_ru.crt

Далее выполните действия по установке сертификата: Установка SSL сертификата на nginx

У вас есть приватный ключ, сам ssl сертификат, а также цепочка сертификатов

Данный вариант отличается от первого только тем, что нужно добавить цепочку сертификатов в сам SSL сертификат.

Будем считать, что SSL сертификат имеет имя site_ru.crt, а цепочка сертификатов CA.crt

В таком случае объединение файлов можно выполнить так:

Перейдем в директорию, где расположены данные файлы (например /root/site_certs/)

[root@server ~]# cd /root/site_certs/

Объединим файлы

[root@server certs]# cat CA.crt >> site_ru.crt

Далее выполните действия по установке сертификата: Установка SSL сертификата на nginx

У вас есть сертификат в другом формате, например pfx

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

Будем считать, что SSL сертификат имеет имя cert.pfx

В таком случае получить необходимые файлы можно выполнить так:

Перейдем в директорию, где расположен данный файл (например /root/site_certs/)

[root@server ~]# cd /root/site_certs/

Получим цепочку сертификатов

[root@server certs]# openssl pkcs12 -in cert.pfx -clcerts -nokeys -out public.crt

Получим приватный ключ

[root@server certs]# openssl pkcs12 -in cert.pfx -nocerts -nodes -out private.key

Далее выполните действия по установке сертификата

Установка в jessie

Если у вас еще в ходу актуальный на конец 2021 года Debian stable “jessie”, то всё лишь немного сложнее.

Установка сертификата

Будем считать, что приватный ключ имеет имя private.key, а цепочка сертификатов CAbundle.crt

Создадим директорию ssl в nginx:

[root@server ~]# mkdir /etc/nginx/ssl

Далее скопируйте файл приватного ключа и цепочку сертификатов в директорию /etc/nginx/ssl/

[root@server ~]# mv private.key CAbundle.crt /etc/nginx/ssl

После этого откройте файл конфигурации виртуального хоста nginx в редакторе и измените значения строк ssl_certificate и ssl_certificate_key

Например (вариант при использовании LetsEncrypt:

Было:

Итого

С шифрами закончили. Для поддержки старых клиентов нам нужно вернуть младшие версии TLS и, для скорости, использовать обычную кривую и сертификат на 2048 бит.

Про сертификаты:  Памятка для удостоверяющих центров и других участников PKI / Блог компании Альфа-Банк / Хабр
Оцените статью
Мой сертификат
Добавить комментарий