Зачем нужен 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]
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)
ibKpoxa
10.10.2015 23:05+5интересно, почему хабр не работает через https…
nikitasius
11.10.2015 01:43+1Видимо, чтобы неназываемые могли блокировать по страницам, а не весь домен.
skobkin
11.10.2015 05:10Можно работать одновременно по http и https.
igordata
11.10.2015 15:16Нет, если закрывают https, то закрывают доступ к всему сайту. Получается, можно одновременно по http работать, a по https не работать =)
На Хабре кроме пароля никакой секурной сверхсекретной фигни не передаётся. Какой в этом смысл?ZoomLS
11.10.2015 17:48Всякое может быть в личных сообщениях, да и вообще, лучше шифровать, чем не шифровать.
navion
11.10.2015 17:35Тут что-то ещё — модераторы работают очень оперативно и от провайдеров без DPI это не спасёт. Тем более, что на балансировщике сертификат стоит и используется в TM ID.
navion
11.10.2015 17:13+1Про сертификаты ерунда написана, ключи длиннее 2048 бит тоже имеют проблемы с совместимости и теоретически будут уязвимы только после 2030 года, нет dhparam и cipherlist.
Дали бы хоть ссылку на статью с обсуждением.navion
11.10.2015 17:16А ECDSA выдаёт Comodo и Symantec, но пока это не афишируют. У последних есть занятная презентация по теме:
Symantec’s View of the Current State of ECDSA on the Web
porutchik
11.10.2015 20:17+2А почему infobox.ru не работает по HTTP/2?
infobox
11.10.2015 20:25Всему свое время. Поддержке HTTP/2 в NGINX всего несколько недель. Любые изменения тщательно тестируются, особенно когда дело касается большой и сложной инфраструктуры.
el777
11.10.2015 21:02А где тестовый сайт, чтобы посмотреть как это работает у вас?
infobox
11.10.2015 21:35Например можно посмотреть у пользователя на le-vert.ru. Единственное — пользователь использует автомасштабирование и обычно частота CPU – 100-300 мгц для экономии.
porutchik
12.10.2015 09:53Вебсайт – это «большая и сложная архитектура»?
Я правильно понял, что в статье вы рекомендуете пользователям включать сырой HTTP/2, а сами его не включаете?infobox
12.10.2015 10:12В этой статье мы рассказываем о том, как включить новую возможность NGINX — HTTP/2 и какие преимущества это даст. Поддержка HTTP/2 — часть релиза NGINX (это не альфа или бета) и поддерживается разработчиками. Таким образом поддержка HTTP/2 является стабильной и готовой к использованию. Более того, некоторые наши пользователи уже используют HTTP/2. Тем не менее, при использовании любой технологии ее нужно тестировать со своим ресурсом, это нормальная практика. Если вы считаете, что поддержка HTTP/2 в NGINX сырая — вы всегда можете отправить баг-репорты разработчикам trac.nginx.org/nginx если действительно вам известно о какой-то проблеме с продуктом.
ibKpoxa
12.10.2015 12:05Если на сайте подключаются ресурсы, например изображения, с других сайтов, то все они должны подключаться через HTTPS, иначе будет значок, что шифруется не все, таким образом переход на https/http2 это не просто добавление его поддержки на сервере, это несколько сложнее.
infobox
12.10.2015 12:09это правда. Ссылки на внешние ресурсы или абсолютные ссылки должны быть выявлены при тестировании. То же относится и ко включению просто HTTPS на сайте, поэтому это не специфично для HTTP/2.
blind_oracle
11.10.2015 20:33+2А ещё ключ длиной 4096 увеличивает время RSA-подписи почти в 7 раз, а RSA-проверки в 4 раза — относительно 2048 бит.
Что отрицательно сказывается на нагрузке на сервер и количестве новых подключений в секунду.Komzpa
11.10.2015 21:57А сколько это в настоящих числах? А то вот случается, что 0*7=0.
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, при их нагрузках это выливается в экономию дофигалиарда зелёных денег на серверах и электричестве.
deep_orange
11.10.2015 21:13Насколько я понимаю, то http2-траффик будет проксироваться на http1 сервер. А как быть, если я хочу шифрованное соединение, но для клиентов, что не поддерживают http2 проксировать на http1 сервер. А для других — на http2. Это реально? И ещё, как быть с websockets? У nginx есть насчёт этого страничка. Но будет ли она работать по такой схеме? Будет ли она работать просто по http2?
infobox
11.10.2015 21:24NGINX решает проблему с клиентами, еще не поддерживающими HTTP/2 с помощью Next Protocol Negotiation (NPM) расширения TLS.
ibKpoxa
12.10.2015 12:20При установлении https соединения клиент и сервер пытаются друг другу сказать, что они поддерживают http2, если хоть один из двух не поддерживает этот протолок, то автоматом используется https, работу по которому сейчас поддерживают, наверное, все.
deep_orange
13.10.2015 21:20Да я имею ввиду, что нет возможности прокинуть HTTP/2 трафик, через Nginx. Т.е. на проксируемый сервер он будет приходить всегда HTTP/1.x. И это печально. По сути ngx_http_v2_module — это некая адаптация SPDY-модуля. Да, я согласен, что на текущий момент — это именно, то что нужно. Но Вы только взгляните как устроен HTTP/2. А сейчас получается, что всё что из него можно выжать — это пакованный заголовок(?), и экономию на хэндшайках. Может это не совсем так, но факт остаётся фактом. Как управлять приоритетами, как вытолкнуть в кэш, что использовать: 1000-картинок или огромный спрайт? Вот о чём я. В общем, я читаю документацию к H2O в данный момент.
ibKpoxa
14.10.2015 11:18Пуши и приоритеты у nginx в планах на следующие версии, а в целом http2 и так даёт достаточно преимуществ, окупающихся при запросе более чем 3-4 файлов, что уже и этого хвататет, например если у вас статики и картинок на сайта с 50 штук на страничке, и отдаёте вы их через nginx без проксирования, то обращение к бэкэнду в виду апача или fastcgi и не требуется те плюшки, что есть в http2, ведь http2 не имеет практически никаких плюсов в сетях с низкой rtt.
VBart
15.10.2015 13:31… приоритеты у nginx в планах на следующие версии
Поддержка HTTP/2 с приоритизацией на основе весов и зависимостей. @ nginx.org/ru
VBart
15.10.2015 13:35+1Приоритезацией управляет клиент, а не сервер. Браузеру куда виднее, какого ресурса ему сейчас не хватает в первую очередь, и такую информацию он сообщает в nginx, а тот в свою очередь приоритизирует отдачу.
К слову сказать, приоритизация в http/2 нужна исключительно для решения проблемы самого протокола, который использует только одно соединение. Если у вас всего одна труба, то требуется тщательно выбирать в каком порядке в нее наливать. Да, http/2 — это протокол для экономии на хэндшейках и не более.
Ну и кстати, тестировали, h2o стабильно показывает худшие результаты по времени отрисовки и загрузки сайта, чем nginx c http/2 или spdy.
grossws
Торт, торт! Уже целые статьи пишут про дописывание 6 букв " http2" в конфиг. 6 букв, Карл!
infobox
Если бы все внимательно следили за обновлениями документации и возможностей NGINX и использовали новые возможности — мир был бы прекраснее, да.
grossws
Посмотрел, действительно, пока на хабре статьи, упоминающие http/2 в nginx'е были в небольшом количестве: про то, что он появится в виде экспериментального модуля для 1.9.0+ и в статье про nginscript.
porutchik
Пробел – не буква, а символ, Карл! :)