Сегодня перевел свой блог на HTTPS. Зачем? Не знаю, но почему бы и нет?) Наверное это больше связано с популязацией https в интернете в целом. Поправил конфиг SSL, получив A+ в ssllabs. Добавил Strict Transport Security. Обновил nginx до последней версии 1.9.5, подключив HTTP/2. В целом неплохо так получилось.
Под катом подробнее об этом.
Как правильно настроить HTTPS?
В этом нам поможет сервис SSLLabs. Проверяем свой сайт и, глядя в мануал NGINX, исправляем выявленные недочеты до тех пор пока не исправим их все. Так например, у меня был разрешен SSLv3, который имеет уязвимости, и пара других недочетов. Получаем:
В итоге у меня получился вот такой вот конфиг nginx-а:
ssl on; ssl_certificate "[...].crt"; ssl_certificate_key "[...].key"; ssl_dhparam "[...]/dh2048.pem"; ssl_session_timeout 1h; ssl_session_cache shared:SSL:16m; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate "[...].trusted.crt"; resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!EXP:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_prefer_server_ciphers on;
Кстати сказать плохо настроенный SSL, не даст работать протоколу HTTP/2. Так например, при использовании небезопасного шифра/протокола, не говоря уже о невалидном сертификате, Chrome откажется открывать сайт, выдавая ошибку ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY
. Поэтому если вы планируете подключить HTTP2, обязательно обратите внимание на разрешенные протоколы и шифры (ssl_protocols
и ssl_ciphers
). Приведенная конфигурация выше — эталон, который следует брать за основу.
Хорошо бы сгенерировать ключ dhparam с 2048-битным ключом (ssl_dhparam
), т.к. по дефолту используется 1024-битный ключ, а на данный момент это уже ненадежно. Кое-где рекомендуют 4096 бит, но я не советую этого делать, т.к. это фактически замедляет работу сервера.
Также рекомендую включить поддержку OSCP ответов:
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate "[...].trusted.crt"; resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s;
это позволяет существенно ускорить время установления SSL соединения с сервером, а, следовательно, и время загрузки вашего сайта.
И обязательно включаем ssl_prefer_server_ciphers on
— тем самым указываем, что серверные шифры были более приоритетны, чем клиентские, тем самым исключаем возможность BEAST-атаки.
Ну и включаем кеш сессий:
ssl_session_timeout 1h; ssl_session_cache shared:SSL:16m;
Выполнение этих рекомендаций даст A+ оценку, чего мы собственно и добивались :)
Как включить HSTS
Кстати сказать неплохо включать HTTP Strict Transport Security
для тех сайтов которые работают только по HTTPS. Добавляем в конфиг nginx:
add_header Strict-Transport-Security "max-age=31536000;";
Этот заголовок говорит о том что данный браузер работает только по HTTPS, и необходимо пресекать все попытки открытия его по HTTP, если проще — то всегда открывать его по HTTPS. Но википедия конечно скажет лучше меня:
механизм, активирующий форсированное защищённое соединение через протокол HTTPS. Данная политика безопасности позволяет сразу же устанавливать безопасное соединение, вместо использования HTTP-протокола. Механизм использует особый заголовок Strict-Transport-Security для принудительного использования браузером протокола HTTPS даже в случае перехода по ссылкам с явным указанием протокола HTTP (http://).
Как обновить nginx до 1.9.5 в Debian
В принципе тут проблем никаких быть не должно. Заходим на сайт nginx и выполняем пошагово их инструкцию:
Для Debian/Ubuntu, для проверки подлинности подписи репозитория nginx, и чтобы избавиться от предупреждений об отсутствующем PGP-ключе во время установки пакета nginx, необходимо добавить ключ, которым были подписаны пакеты и репозиторий nginx, в связку ключей программы apt. Загрузите этот ключ с нашего веб-сайта и добавьте его в связку ключей программы apt, выполнив команду:
sudo apt-key add nginx_signing.key
Для Debian замените codename на кодовое имя дистрибутива, и добавьте в конец файла /etc/apt/sources.list следующее:
deb http://nginx.org/packages/mainline/debian/ codename nginx
deb-src http://nginx.org/packages/mainline/debian/ codename nginxДля Ubuntu замените codename на кодовое имя дистрибутива, и добавьте в конец файла /etc/apt/sources.list следующее:
deb http://nginx.org/packages/mainline/ubuntu/ codename nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ codename nginxДля Debian/Ubuntu затем выполните команды:
apt-get update
apt-get install nginx
В процессе обновления у вас может возникнуть конфликт со старой версией nginx, например такая ошибка:
trying to overwrite '/etc/logrotate.d/nginx', which is also in package nginx-common
или
trying to overwrite '/usr/sbin/nginx', which is also in package nginx-full
тогда вам следует удалить эти пакеты, и после таки установить nginx:
apt-get update apt-get remove nginx-full nginx-common nginx apt-get install nginx
Как включить HTTP/2 в nginx?
Нормальная реализация HTTP2 появилась в версии nginx 1.9.5. Собственно поэтому и понадобилось обновиться до этой версии. Ну а подключить поддержку этого протокола еще легче. Правим конфиг nginx, добавляем http2
в listen
:
... listen 433 ssl http2; ...
Тут я наверное уже больше ничего не добавлю)
Как определить поддерживает ли сайт HTTP/2?
Открываем Chrome Developer Tools, переходим в раздел Network. Включаем в таблице ресурсов отображение столбца Protocol
:
Жмем F5, и видим протокол по которому был загружен тот или иной ресурс:
где H2 — это HTTP/2
Итог
После всех этих действий мы будем так сказать «на гребне волны» в сфере развития HTTPS. Ну и маленьким приятным бонусом я сэкономил немножко оперативной памяти:
Немного, где то 50Мб, могу предположить что это из за обновления на nginx 1.9.5, но все таки это лучше чем если бы памяти начало потребляться больше чем было.
Ну и кстати что же дало мне включение HTTP/2? Без HTTP/2 полная загрузка главной страницы сайта со всеми элементами происходила за 1.2 сек, сейчас же всего за 0.8 сек, то есть можно сказать что скорость загрузки выросла на ~30%!
Спасибо за внимание :)
Кстати в SslLab можно получить оценку еще выше, если отключить TLSv1 TLSv1.1, оставив только TLSv1.2
Да, только из-за этого некоторые старые браузеры не будут работать с вашим сайтом. Поэтому я бы не стал все таки этого делать
Скопировал конфигурацию, подключил свои сертификаты, NGNIX 1.9.9. H2 так и не поднялся…
На самом деле вам достаточно указать http2 в параметре listen, чтобы HTTP/2 заработал. Приведите конфигурацию полностью, пожалуйста. Может я смогу вам помочь.
В чём смысл HTTP/2, если общепринят HTTP 1.1? Мы только лишаемся совместимости со старыми браузерами
Нет, вы что) HTTP/2 если можно так сказать обратно совместим со всеми браузерами. Работает по принципу — если сервер и клиент поддерживают HTTP/2 то только тогда они начинают использовать этот протокол. Если кто то не поддерживает, используется HTTP/1.1
А смысл огромен, гляньте например вот этот тест
Добрый день, Дмитрий.
Подскажите, пожалуйста, где взять сертификат для директивы ssl_trusted_certificate?
Его выдает Let’s Encrypt?
Спасибо.
Вячеслав, здравствуйте!
Да, его выдает Let’s Encrypt. Гляньте внимательнее Поставил сертификат Let’sEncrypt а именно вот:
Впрочем даже если бы он не выдавался, то его можно было бы вполне составить вручную из цепочки сертификатов которой подписан ваш сертификат.
лично у меня при использовании http/2 сайт стал грузиться медленнее где то на 200ms. Давно пользуюсь nginx proxy и http/1.1 распараллеливая загрузку. Попробую воткнуть в конфиг resolver может побыстрее http/2 станет
На сколько влияет http/2 на скорость сайта ?
Есть ли какой то плюс при ранжирование сайта
http/2 увеличивает скорость загрузки. Говорят что скорость загрузки — один из факторов влияющих на ранжирование => влияет.
Обратите внимание, что ваш сайт в последней версии chrome (55) работает по http/1.
Причина описана в статье:
https://victor.4devs.io/ru/architecture/nginx-http2-does-not-work.html
или в буржунете:
https://www.nginx.com/blog/supporting-http2-google-chrome-users
Авторы этих статей предлагают как решение скомпилить nginx с нужной версией openssl, но я нашел решение проще для centos 7. Есть репозиторий, где nginx уже собран и слинкован с openssl 1.0.2.
https://brouken.com/brouken-centos-7-repo/
Достаточно добавить репозиторий и обновить из него nginx.
Спасибо!
Да, я знаю уже об этой проблеме несколько месяцев, но все никак не дойдут руки у меня ее решить( У меня дебиан, и вроде как это решается только сборкой nginx из исходников с нужной версией openssl.
Сделал все подобные настройки для SSL, а оценка просто A, без +.
Убрал с бэкенда apache, остался один nginx, теперь A+ показывает.
Добавил себе на сайте https://triptorg.ru/ http/2. Сервис «HTTP/2 Тест — онлайн сервис» показывает, что
сайт поддерживает http/2. Но вот firebug в firefox в заголовках пишет Версия: HTTP/1.1
В чем может быть проблема? Версия Nginx 1.11.6, в конфиге все указал: listen 443 ssl http2;
https://intsystem.org/security/pereexal-na-https-vklyuchil-http2/#comment-26608
как возможный вариант проблемы
Firefo может из кеша тянет.
Здравствуйте. Спасибо за статью. У меня возник вопрос, ответ на который я не смог найти в инете. https замедляет работу сайта, так как должен зашифровать весь трафик. Слышал, что запросов увеличивается вдвое. При этом http/2 увеличивает скорость загрузки. Но без ssl http/2 не работает. То есть палка на 2 концах: один замедляет, другой увеличивает. Установил на сайте сертификат бесплатный через админку бегета. Включился h2, но сайт на h2 загружается в 1.5-2 дольше, исходя из тестов. Вот как так?
Исправьте, пожалуйста:
…
listen 433 ssl http2;
…
Порт 443, думаю, очепятка? :)