В этой статье мы расскажем, как включить HTTP/2 для сайта в NGINX, размещенного на VPS от Infobox и какие преимущества это даст вашему сайту. Поддержка HTTP/2 была добавлена в релиз NGINX 1.9.5.



Зачем нужен HTTP/2


HTTP/2 – новая версия протокола HTTP, стандартизированная в начале 2015 года. Использование HTTP/1.1 из-за некоторых особенностей вносит негативный эффект на производительность веб-приложений.

В частности HTTP/1.0 позволяет выполнять только один запрос одновременно в TCP–соединении. В HTTP/1.1 были добавлены конвейерные запросы, но они только частично помогают параллельному исполнению запросов и по-прежнему приводят к блокировкам. Клиенты HTTP/1.0 и HTTP/1.1, которым необходимо делать много запросов сейчас используют множество соединений к серверу.

Кроме этого, поля заголовка HTTP многословны и часто повторяются, производя ненужный сетевой трафик. Также время тратится на заторы TCP. Это может привести к повышенным задержкам при множестве запросов сделанных с помощью новых TCP–соединений.

HTTP/2 решает эти проблемы, определяя оптимизированную семантику протокола HTTP. В частности это позволяет выполнять чередование запросов и ответов через то же подключение и предоставляет эффективное кодирование полей HTTP-заголовка. Также HTTP/2 позволяет приоритизировать запросы, позволяя более важным запросам выполняться быстрее.

В результате протокол становится более дружественным к сети, требуя установки меньшего количества TCP–соединений в сравнении с HTTP/1.x, что приводит к более эффективному использованию сети. Также HTTP/2 дает возможность эффективнее обрабатывать сообщения с помощью бинарного формата.

HTTP/2 тесно связан с SSL. Несмотря на то, что спецификация не требует обязательного использования SSL, все веб-браузеры выпущенные на текущий момент будут работать с HTTP/2 только если веб-сайт использует SSL.


Разворачиваем сервер с последней версией NGINX


Если у вас еще нет VPS от Infobox, заказать сервер можно тут. В статье описана настройка HTTP2 для сервера с CentOS 7. После заказа и создания сервера подключитесь к нему по SSH.

Устанавливаем последнюю версию NGINX на новый VPS с CentOS 7
Для установки последней версии NGINX добавим официальный репозиторий. Для этого в файл /etc/yum.repos.d/nginx.repo добавьте следующее содержимое:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

Остановите Apache и запретите его автозапуск:
systemctl stop httpd && systemctl disable httpd

Обновите ОС командой:
yum -y update

После этого перезагрузите ОС.
reboot

Установите nginx и firewalld командой:
yum install -y nginx firewalld

Теперь запустите nginx и добавьте в автозагрузку:
systemctl start nginx && systemctl enable nginx

Аналогично запустите firewalld:
systemctl start firewalld && systemctl enable firewalld

Последнее, что осталось сделать — открыть порты 80, 443 и 22.
firewall-cmd --zone=public --add-port=80/tcp --add-port=443/tcp --add-port=22/tcp  --permanent

firewall-cmd --reload

Теперь зайдите в браузере по ip–адресу вашей VPS. Вы увидите приветственную страницу NGINX.




Генерируем сертификат


Для работы HTTP/2 на текущий момент должна быть включенa поддержка соединения по HTTPS в NGINX.
Обычно этот процесс состоит из четырех шагов:
  • генерация приватного ключа (key)
  • создания запроса на подпись (CSR) и отправка запроса в сертифицирующий центр (CA)
  • установка сертификата от сертифицирующего центра
  • настройка конфигурации NGINX

Такой процесс обеспечивает доверие браузеров пользователей к сайту.

Создайте папку, в которой будут храниться ключи шифрования и перейдите в нее:
mkdir /etc/nginx/ssl && cd /etc/nginx/ssl

Для понимания способов генерации ключа необходимо знать следующие понятия:
Алгоритм генерации ключа. OpenSSL поддерживает RSA, DSA и ECDSA ключи, но не все типы подходят для практического использования во всех сценариях. Например, для веб-серверов нужно использовать RSA, потому что DSA ключи ограничены 1024 битами (IE не поддерживает ничего сложнее) и ECDSA ключи еще не поддерживаются широко сертифицирующими центрами. Если бы мы генерировали ключ для SSH – подошли бы RSA и DSA, так как ECDSA еще может не поддерживаться частью клиентов.
Размер ключа. Размер ключа по-умолчанию может быть небезопасен. Например ключ по-умолчанию для RSA – только 512 бит и его использование совершенно небезопасно. Сегодня рекомендуется использовать минимум 2048 бит для RSA, 2048 бит для DSA и 256 бит для ECDSA. Мы будем использовать RSA и 4086 бит.

Для генерации приватного ключа и запроса на подписание сертификата выполните команду:
openssl req -out /etc/nginx/ssl/domain.csr -new -newkey rsa:4086 -nodes -keyout /etc/nginx/ssl/domain.key

В процессе обязательно укажите FQDN (Common name) – имя домена и email в домене, например webmaster@domain.tld. Не устанавливайте пароль на ключ.

После генерации вы увидите в папке /etc/nginx/ssl два файла с расширениями key (приватный ключ) и csr (запрос на подписание сертификата). Если вы хотите использовать доверенный сертификат — закажите его у центра сертификации (можно например заказать в тут). Для формирования сертификата потребуется содержимое csr, которое можно посмотреть так:
cat /etc/nginx/ssl/domain.csr

После заказа и формирования сертификата сохраните его содержимое в файле /etc/nginx/ssl/domain.crt. После самого содержимого сертификата в этот же файл с новой строки добавьте содержимое Intermediate сертификата, если он будет предоставлен вам сертифицирующим центром и сохраните файл.

Если вы разворачиваете тестовое окружение — можно бесплатно сгенерировать самоподписанный сертификат так:
openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/nginx/ssl/domain.key -out /etc/nginx/ssl/domain.crt




Также необходимо сгенерировать DH параметры для того, чтобы в случае кражи приватного ключа нельзя было расшифровать последние сообщения.
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096


Включаем доступ только по HTTPS в NGINX и активируем HTTP2


Отредактируйте файл конфигурации NGINX /etc/nginx/conf.d/default.conf.
В нем удалите секцию server и добавьте:
server {
        listen 80;
        server_name domain.tld  www.domain.tld;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name domain.tld  www.domain.tld;
        ssl on;
        ssl_certificate /etc/nginx/ssl/domain.crt;
        ssl_certificate_key /etc/nginx/ssl/domain.key;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
        ssl_prefer_server_ciphers On;
        ssl_protocols 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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
        add_header Strict-Transport-Security max-age=15768000;
        ssl_stapling on;

        location / {
            root /usr/share/nginx/html;
	}
    }
}

, где domain.tld замените на имя вашего сайта, для которого включаете HTTP2.



После изменений протестируйте конфигурацию nginx на отсутствие ошибок командой:
nginx -t




Теперь перезапустите NGINX:
systemctl restart nginx

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



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

Чтобы проверить, что сайт работает по HTTP2, установите HTTP2 indicator для Firefox или Chrome.

Теперь при заходе на сайт, поддерживающий HTTP2 или SPDY вы увидите синюю молнию.



Действительно, сайт работает по HTTP2.

Пробная версия VPS от Infobox бесплатно


Вы можете настроить все, описанное в статье, на пробной версии VPS.
Для этого пришлите ваше имя и номер телефона на trial@infobox.ru, в ответ получите данные для доступа к панели управления. Вы можете тестировать VPS в течение 10 дней.

Успешной работы!

Комментарии (35)


  1. grossws
    10.10.2015 21:19
    +15

    Торт, торт! Уже целые статьи пишут про дописывание 6 букв " http2" в конфиг. 6 букв, Карл!


    1. infobox
      10.10.2015 21:38
      +1

      Если бы все внимательно следили за обновлениями документации и возможностей NGINX и использовали новые возможности — мир был бы прекраснее, да.


      1. grossws
        10.10.2015 22:29
        +1

        Посмотрел, действительно, пока на хабре статьи, упоминающие http/2 в nginx'е были в небольшом количестве: про то, что он появится в виде экспериментального модуля для 1.9.0+ и в статье про nginscript.


    1. porutchik
      11.10.2015 20:07

      Пробел – не буква, а символ, Карл! :)


  1. ibKpoxa
    10.10.2015 23:05
    +5

    интересно, почему хабр не работает через https…


    1. nikitasius
      11.10.2015 01:43
      +1

      Видимо, чтобы неназываемые могли блокировать по страницам, а не весь домен.


      1. skobkin
        11.10.2015 05:10

        Можно работать одновременно по http и https.


        1. igordata
          11.10.2015 15:16

          Нет, если закрывают https, то закрывают доступ к всему сайту. Получается, можно одновременно по http работать, a по https не работать =)

          На Хабре кроме пароля никакой секурной сверхсекретной фигни не передаётся. Какой в этом смысл?


          1. ZoomLS
            11.10.2015 17:48

            Всякое может быть в личных сообщениях, да и вообще, лучше шифровать, чем не шифровать.


          1. skobkin
            11.10.2015 19:08

            Личные сообщения, личный кабинет и отчисления авторам (!), кабинеты партнерок компаний, etc.


            1. el777
              11.10.2015 21:01

              Вынести ЛК на отдельный домен и ip — и достаточно.


      1. navion
        11.10.2015 17:35

        Тут что-то ещё — модераторы работают очень оперативно и от провайдеров без DPI это не спасёт. Тем более, что на балансировщике сертификат стоит и используется в TM ID.


  1. baldr
    10.10.2015 23:58
    +6

    В сравнительно небольшой статье 8 ссылок на свои сайт и контакты. Мы поняли, спасибо. Скромнее надо быть.


    1. infobox
      11.10.2015 00:14
      +4

      Количество ссылок уменьшено. Спасибо за отзыв.


  1. navion
    11.10.2015 17:13
    +1

    Про сертификаты ерунда написана, ключи длиннее 2048 бит тоже имеют проблемы с совместимости и теоретически будут уязвимы только после 2030 года, нет dhparam и cipherlist.
    Дали бы хоть ссылку на статью с обсуждением.


    1. navion
      11.10.2015 17:16

      А ECDSA выдаёт Comodo и Symantec, но пока это не афишируют. У последних есть занятная презентация по теме:
      Symantec’s View of the Current State of ECDSA on the Web


    1. infobox
      11.10.2015 19:50

      В файл конфигурации добавлены настройки согласно рекомендациям Mozilla, позволяющие достичь A+ в SSLTest. Спасибо.


  1. porutchik
    11.10.2015 20:17
    +2

    А почему infobox.ru не работает по HTTP/2?


    1. infobox
      11.10.2015 20:25

      Всему свое время. Поддержке HTTP/2 в NGINX всего несколько недель. Любые изменения тщательно тестируются, особенно когда дело касается большой и сложной инфраструктуры.


      1. el777
        11.10.2015 21:02

        А где тестовый сайт, чтобы посмотреть как это работает у вас?


        1. infobox
          11.10.2015 21:35

          Например можно посмотреть у пользователя на le-vert.ru. Единственное — пользователь использует автомасштабирование и обычно частота CPU – 100-300 мгц для экономии.


      1. porutchik
        12.10.2015 09:53

        Вебсайт – это «большая и сложная архитектура»?
        Я правильно понял, что в статье вы рекомендуете пользователям включать сырой HTTP/2, а сами его не включаете?


        1. infobox
          12.10.2015 10:12

          В этой статье мы рассказываем о том, как включить новую возможность NGINX — HTTP/2 и какие преимущества это даст. Поддержка HTTP/2 — часть релиза NGINX (это не альфа или бета) и поддерживается разработчиками. Таким образом поддержка HTTP/2 является стабильной и готовой к использованию. Более того, некоторые наши пользователи уже используют HTTP/2. Тем не менее, при использовании любой технологии ее нужно тестировать со своим ресурсом, это нормальная практика. Если вы считаете, что поддержка HTTP/2 в NGINX сырая — вы всегда можете отправить баг-репорты разработчикам trac.nginx.org/nginx если действительно вам известно о какой-то проблеме с продуктом.


        1. ibKpoxa
          12.10.2015 12:05

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


          1. infobox
            12.10.2015 12:09

            это правда. Ссылки на внешние ресурсы или абсолютные ссылки должны быть выявлены при тестировании. То же относится и ко включению просто HTTPS на сайте, поэтому это не специфично для HTTP/2.


  1. blind_oracle
    11.10.2015 20:33
    +2

    А ещё ключ длиной 4096 увеличивает время RSA-подписи почти в 7 раз, а RSA-проверки в 4 раза — относительно 2048 бит.
    Что отрицательно сказывается на нагрузке на сервер и количестве новых подключений в секунду.


    1. Komzpa
      11.10.2015 21:57

      А сколько это в настоящих числах? А то вот случается, что 0*7=0.


      1. blind_oracle
        12.10.2015 00:13
        +1

        Там, к сожалению, совсем не ноль.

        Вот, к пример, однопоточное тестирование на Xeon X5650:

        # openssl speed rsa
        ...
                          sign    verify    sign/s verify/s
        rsa  512 bits 0.000101s 0.000007s   9899.7 140006.3
        rsa 1024 bits 0.000345s 0.000021s   2896.4  48730.2
        rsa 2048 bits 0.002274s 0.000072s    439.8  13939.4
        rsa 4096 bits 0.016812s 0.000272s     59.5   3670.4
        

        Т.е. этот совсем не слабый процессор одним ядром может всего-лишь ~60 RSA-sign транзакций в секунду.
        И это притом что больше ничем он заниматься не будет, а в реальной жизни это далеко не так.

        Также эти 4096 бит ложаться бременем на клиентские устройства — те же телефоны будут в несколько раз сильнее напрягаться при установке TLS соединения. Это, конечно, почти незаметно, но тем не менее.

        В общем, я пришёл к выводу что пока что 4096 смысла городить нет. А когда появится — там и ECDSA станет распространён достаточно, в результате чего в 4096 необходимость вообще отпадёт.

        Facebook вон не зря у себя использует сертификат SHA1 + ECDSA, при их нагрузках это выливается в экономию дофигалиарда зелёных денег на серверах и электричестве.


  1. deep_orange
    11.10.2015 21:13

    Насколько я понимаю, то http2-траффик будет проксироваться на http1 сервер. А как быть, если я хочу шифрованное соединение, но для клиентов, что не поддерживают http2 проксировать на http1 сервер. А для других — на http2. Это реально? И ещё, как быть с websockets? У nginx есть насчёт этого страничка. Но будет ли она работать по такой схеме? Будет ли она работать просто по http2?


    1. infobox
      11.10.2015 21:24

      NGINX решает проблему с клиентами, еще не поддерживающими HTTP/2 с помощью Next Protocol Negotiation (NPM) расширения TLS.


    1. ibKpoxa
      12.10.2015 12:20

      При установлении https соединения клиент и сервер пытаются друг другу сказать, что они поддерживают http2, если хоть один из двух не поддерживает этот протолок, то автоматом используется https, работу по которому сейчас поддерживают, наверное, все.


      1. deep_orange
        13.10.2015 21:20

        Да я имею ввиду, что нет возможности прокинуть HTTP/2 трафик, через Nginx. Т.е. на проксируемый сервер он будет приходить всегда HTTP/1.x. И это печально. По сути ngx_http_v2_module — это некая адаптация SPDY-модуля. Да, я согласен, что на текущий момент — это именно, то что нужно. Но Вы только взгляните как устроен HTTP/2. А сейчас получается, что всё что из него можно выжать — это пакованный заголовок(?), и экономию на хэндшайках. Может это не совсем так, но факт остаётся фактом. Как управлять приоритетами, как вытолкнуть в кэш, что использовать: 1000-картинок или огромный спрайт? Вот о чём я. В общем, я читаю документацию к H2O в данный момент.


        1. ibKpoxa
          14.10.2015 11:18

          Пуши и приоритеты у nginx в планах на следующие версии, а в целом http2 и так даёт достаточно преимуществ, окупающихся при запросе более чем 3-4 файлов, что уже и этого хвататет, например если у вас статики и картинок на сайта с 50 штук на страничке, и отдаёте вы их через nginx без проксирования, то обращение к бэкэнду в виду апача или fastcgi и не требуется те плюшки, что есть в http2, ведь http2 не имеет практически никаких плюсов в сетях с низкой rtt.


          1. VBart
            15.10.2015 13:31

            … приоритеты у nginx в планах на следующие версии
            Поддержка HTTP/2 с приоритизацией на основе весов и зависимостей. @ nginx.org/ru


        1. VBart
          15.10.2015 13:35
          +1

          Приоритезацией управляет клиент, а не сервер. Браузеру куда виднее, какого ресурса ему сейчас не хватает в первую очередь, и такую информацию он сообщает в nginx, а тот в свою очередь приоритизирует отдачу.

          К слову сказать, приоритизация в http/2 нужна исключительно для решения проблемы самого протокола, который использует только одно соединение. Если у вас всего одна труба, то требуется тщательно выбирать в каком порядке в нее наливать. Да, http/2 — это протокол для экономии на хэндшейках и не более.

          Ну и кстати, тестировали, h2o стабильно показывает худшие результаты по времени отрисовки и загрузки сайта, чем nginx c http/2 или spdy.