Полная инструкция по настройке HTTPS с оценкой А+

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

Опубликованный недавно закон о персональных данных так же требует переход на безопасный протокол.

А при ранжировании сайта поисковыми системами использование этого протокола расценивается как положительный фактор, поэтому желательно начать использовать https.

В нашем примере мы рассмотрим настройку https протокола для любой платформы и веб-сервера, но так же расмотрим ньюансы настройки для php-fpm и платформы Bitrix, так как именно бизнес-сектор интернета чаще всего нуждается в этом протоколе.

Что мы имеем

Nginx - веб-сервер, который мы используем для проксирования трафика и распределения нагрузки между нашими виртуальными площадками, будем называть его Nginx Proxy.

Nginx + php-fpm - в своих проектах мы давно отказались от веб-сервера apache и полностью заменили его на связку nginx + php-fpm, так как работает во много раз быстрее и нет никакой путаницы в конфигах, называть этот веб-сервер мы будем Nginx Site.

SSL сертификат с приватным ключем - файл с расширением crt и ключ с расширением key.

Цепочка сертификатов - цепочка доверия, структура, которая позволяет людям проверять валидность сертификата эмитента.

Ключ Диффи — Хеллмана - необходим для работы Forward Secrecy, сгенерируем его позднее на сервере.

Немного времени

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

Все сертификаты разделяются по двум критериям: центру сертификации и опциям заложенным в него. Центр сертификации не играет никакой роли в выборе, важно выбрать протокол с необходимыми опциями, например некоторые сертификаты выпускаются только для юридических лиц, Business сертификаты, они требуют подтверждения учредительной информации.

Другие важных опции: EV - добавляет зеленый значек в строке браузера, не несет никакой дополнительной безопасности, просто заметна для пользователя. WildCard - позволяет использовать сертификат не только для искомого домена и поддомена www, но и для всех субдоменов.

Выбранные опции серьезно сказываются на стоимости сертификата, поэтому лучше взвесить все за и против, и выбрать оптимальный вариант. Для интернет-магазинов мы чаще всего используем Thawte SSLWebServer, банковского и страхового сектора GeoTrust True BusinessID EV, для всех остальных сайтов RapidSSL

Шаг 1. Заказываем сертификат.

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

Шаг 2. Подтверждение.

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

Шаг 3. Получение готового сертификата.

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

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

Так как у нас проксирующий nginx, то устанавливать сертификат нужно именно на него, Nginx Proxy.

Шаг 1. Создаем папку с сертификатами:

cd /etc/nginx/
mkdir ssl
cd ssl
mkdir onlinebd.ru

Шаг 2. Переносим сертификаты и ключ в папку (не оставляем переносы строк после последнего символа):

cd onlinebd.ru
nano onlinebd.crt
# вставляем сертификат и сохраняем Ctrl+X
nano private.key
# вставляем ключ и сохраняем Ctrl+X

Шаг 2.1. Возможно, что ваш приватный ключ зашифрован паролем, пароль можно найти там же, где и скачали этот ключ, у регистратора. Такой ключ необходимо преобразовать:

openssl rsa -in private.key -out private_new.key
# вводим пароль
mv private.key private.nokey
mv private_new.key private.key

Шаг 3. Скачиваем цепочку сертификатов для RapidSSL. Иногда сертификаты цепочки приходят вместе с сертификатом сайта или их можно найти на сайте центра сертификации:

wget https://www.websecurity.symantec.com/content/dam/websitesecurity/support/digicert/rapidssl/ica/RapidSSL_RSA_CA_2018.pem
wget https://www.websecurity.symantec.com/content/dam/websitesecurity/support/digicert/rapidssl/root/DigiCert_Global_Root_CA.pem

Шаг 4. Создаем бандл, bundle.crt, файл который содержит в себе сертификат сайта и сертификаты цепочки. Лучше не добавлять в него Root сертификат, он не имеет никакой цели, увеличивает задержку квитирования и можно получить ошибку на ssllabs: Chain issues: Contains anchor, поэтому добавляем только Intermediate.

# последовательность файлов должна быть именно такой: сертификат сайта -> Intermediate -> Root (если используется)
cat onlinebd.crt RapidSSL_RSA_CA_2018.pem > bundle.crt

Шаг 5. Генерируем dhparam.pem, позволяет реализовать прямую секретность, Forward Secrecy, если третья сторона узнает какой-либо сеансовый ключ, тогда возможно будет получить доступ лишь к данным, защищенным этим ключом.

openssl dhparam -out /etc/pki/nginx/dhparam.pem 4096

Настройка nginx

Есть замечательный сайт от Mozilla https://mozilla.github.io/server-side-tls/ssl-config-generator/, на котором генерируется конфиг для любого веб-сервера и набора браузеров. Для набора браузеров рекомендую использовать вариант Intermediate, он содержит все используемые на текущий момент браузеры, точнее поддерживаемые методы шифрования, для Modern варианта еще время не пришло.

У меня получился вот такой конфиг, немного измененный:

# Добавляем 301 редирект, если у нас запросят сайт по HTTP протоколу
server {
    listen 80;
    server_name onlinebd.ru www.onlinebd.ru;
    return 301 https://onlinebd.ru$request_uri;
}

# Добавляем 301 редирект, если у нас запросят сайт по www субдомену и протоколу HTTPS
server {
     listen 443 ssl http2;
     server_name www.onlinebd.ru;

     # сертификаты в этом редиректе обязательны, остальные параметры можно не указывать
     ssl_certificate /etc/nginx/ssl/onlinebd.ru/bundle.crt;
     ssl_certificate_key /etc/nginx/ssl/onlinebd.ru/onlinebd.key;
     return 301 https://onlinebd.ru$request_uri;
}

server {
    # добавляем еще протокол http2, бывший spdy, ускоряет открытие страниц
    # но может привести к проблемам с медийным контентом: ERR_SPDY_PROTOCOL_ERROR
    listen 443 ssl http2;
    server_name onlinebd.ru;

    access_log off;
    #access_log /var/log/nginx/onlinebd.ru.access.log;
    error_log /var/log/nginx/onlinebd.ru.error.log;

    # SSL конфигурация
    ssl on;

    # ssl_stapling позволяем серверу прикреплять OCSP-ответы, уменьшая время загрузки страниц
    ssl_stapling on;
    ssl_stapling_verify on;

    # наши сертификаты
    ssl_certificate /etc/nginx/ssl/onlinebd.ru/bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/onlinebd.ru/onlinebd_private.key;
    ssl_dhparam /etc/nginx/ssl/onlinebd.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;

        # лучше указать передачу заголовков, они так же есть в fastcgi_params, который подключается в nginx.conf
        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;
    }
}

Ньюансы работы c проксированием

В конфиге Nginx Site, веб-сервера сайта, нам необходимо указать, что сайт работает по протоколу https.

Для сайта на Grav:

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;

        # параметры https
        fastcgi_param HTTPS on;
        fastcgi_param HTTP_HTTPS on;
        fastcgi_param REQUEST_SCHEME https;
        fastcgi_param SERVER_PORT 443;
}

Так же для сайта на Grav необходимо указать опцию в конфиге system.yaml:

force_ssl: true

Для сайта на Битрикс:

location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        try_files $uri @bitrix;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param REMOTE_ADDR $http_x_real_ip;

        # параметры https
        fastcgi_param HTTPS on;
        fastcgi_param HTTP_HTTPS on;
}

Для всех сайтов никак не удалось добиться изменение глобальной переменной $_SERVER['HTTPS'], параметр fastcgi_param HTTPS on; меняет только переменную $_SERVER['HTTP_HTTPS']. Для решения этой проблемы есть несколько вариантов:

Вариант 1. Если на сервере Nginx Site работает только один сайт, можно поменять переменную env[HTTPS] = 'on' в конфиге php.fpm, он находится в файле /etc/php-fpm.d/www.conf

Вариант 2. (для Битрикс) Работает для любого количества сайтов и при многосайтовости, где не все сайты на http. Добавляем в dbconn.php строчки:

if ($_SERVER['HTTP_HTTPS'] == 'YES') {
    $_SERVER['HTTPS'] = 'YES';
}

Проверить получившийся результат можно на сайте: https://www.ssllabs.com/ssltest/

Успехов и безопасности вам!