Привет.
Развитие Интернета не стоит на месте – и на смену старому и проверенному HTTP 1.1 приходят новые протоколы, призванные значительно ускорить работу с веб-сервисами. Всё это не далёкое будущее, а уже реальность – поэтому нужно уметь их использовать, настраивать, знать преимущества и недостатки.
Про это и поговорим.
Настройка и защита протокола HTTP/2 в Windows Server 2016
- Краткая история вопроса – как расширяли и дорабатывали HTTP
- SPDY
- HTTP 2.0 или HTTP/2
- Включаем и настраиваем HTTP/2 на IIS 10
- ALPN и NPN
- Настраиваем безопасность работы HTTP/2 на IIS 10
Краткая история вопроса – как расширяли и дорабатывали HTTP
Дабы не углубляться в непрактичную некрофилию – думаю, что про HTTP 0.9 и HTTP 1.0/1.1 вы и сами найдёте, где прочитать – начнём с того, что в современном Интернете стандартный протокол для общения – HTTP 1.1 – не менялся уже около 17 лет, со времён своего устаканивания в RFC 2616. И всё это время нарастали проблемы из-за рудиментов и недостаточного функционала.
Активная борьба началась с 2009 года.
SPDY
В 2009 году фирма Google, устав ждать чуда (привет сказке о “великом опенсорсном коммьюнити из миллионов сверхуспешных экспертов, которые легко дописывают и дорабатывают всё то, что реально нужно”), выделяет деньги и разрабатывает свой вариант улучшения HTTP 1.1, назвав его SPDY. Протокол разрабатывается до первой версии к 2012 году, официально выходит, и начинает дорабатываться. Доживает с версии SPDY/1 до SPDY/4, после чего становится понятно, что разработка своего отдельного протокола – к тому же, хоть и лучше, чем существующий HTTP 1.1, но не сильно (по сути основная фишка – мультиплексирование сессий да новые заголовки; в лабораторных условиях страницы грузились до 55% быстрее, т.е. в реальных выигрыш, в общем-то, есть, но не настолько, чтобы городить свой личный протокол) – теряет смысл на фоне завершающих штрихов у HTTP 2.0.
Google продолжает участвовать в работе над HTTP/2, но в части разработки SPDY фактически останавливает процесс. Впрочем, у Google есть разрабатываемый QUIC (который Quick UDP Internet Connections), который, в силу отсутствия необходимости для начала работы поставить TCP-сессию, точно будет обгонять HTTP 2.0 в разы – правда опять же, нужно это будет только в специфичных ситуациях. SPDY остаётся в виде поддержки в современных браузерах (IE 11, например, поддерживает SPDY/3), но всё идёт к постепенному удалению – например, в nginx 1.10 его поддержку уже deprecate в пользу http2.
HTTP 2.0 или HTTP/2
HTTP 2.0 вбирает в себя практически все наработки SPDY, плюс множество сторонних доработок. Правда, некоторыми HTTP 2.0 критикуется за “поспешность создания”, которая не позволила добавить в новый стандарт основного протокола Интернета все теоретически возможные функции, но все равно результат получается очень хороший. Основных преимуществ HTTP 2.0 или HTTP/2 будет три:
Первый пункт – это одно постоянное соединение, внутри которого можно отправлять-принимать много запросов. Это сразу решает задачу “мы-то можем сколь угодно быстро работать, но под нами TCP, который долго разгоняется в плане размера окна, поэтому ставить одиночные сессии ради мелких задач по скачиванию картинок размером с килобайт – накладно”.
Второе – сжатие заголовков (HPACK). Заголовки у HTTP 1.1 рыхлые и приятные для чтения глазом – поэтому можно, например, тестировать HTTP-сервер через подключение telnet’ом, вводя нужные команды. Это преимущество даёт предсказуемый минус – заголовки занимают много места, поэтому с данным пунктом в HTTP 2.0 борьба пошла сразу с двух сторон – и заголовки стали компактнее и в бинарном виде, и сжатие добавилось – которое даёт заметную экономию в ситуации “много однотипных запросов отправляем, где заголовок большой, а данных немного”.
Третье – “Server push”, когда сервер может “предположить”, что клиенту понадобится после первого запроса (например, клиент запросил текст страницы – значит можно ему скидывать параллельно js и css-файлы, которые используются) и самостоятельно отдавать их клиенту в рамках той же сессии, повышая скорость работы и убирая лишний round-trip. Подобная штука была в HTTP 1.1, называлась “inlining”, но её минус был в том, что эти ресурсы отдавались “одним потоком”, и не были самостоятельными ответами на HTTP-запрос, поэтому их нельзя было кэшировать как самостоятельные объекты – в HTTP 2.0 же результаты server push’а являются полноценными ответами сервера “как будто клиент сам запрашивал”, поэтому нормально кэшируются.
Множество других мелких доработок и удаление рудиментов старых вариантов HTTP также улучшают общую картинку стандарта – впрочем, про эти детали вы можете почитать в RFC 7540, а для нас важнее, что надо включать поддержку этого стандарта уже сейчас. Причина проста – все современные браузеры уже его поддерживают (даже IE 11), и поддержка HTTP 2.0 появляется в IIS 10, встроенном в новый Windows Server 2016.
Приступим.
Включаем и настраиваем HTTP/2 на IIS 10
Первым делом надо заметить, что не все IIS 10 одинаково полезны. IIS 10 Express нам, увы, не подойдёт – нам будет нужен только “полновесный” IIS 10, который есть на Windows Server 2016. Поддержка HTTP/2 будет в нём изначально – надо только её настроить.
Для демонстрации я создал тестовый сайт для настройки HTTP/2, назвал его https://http2test.atraining.ru (после убрал и настроил HTTP2 на www.atraining.ru, поэтому всё далее написанное применимо к www.atraining.ru), сгенерил ему сертификат (т.к. работать мы будем поверх TLS), и поставил саму роль IIS на Windows Server 2016 TP5. Эта часть задачи тривиальна и к HTTP/2 не относится, покажу лишь картинки про итоговую конфигурацию.
Вот такой у нас сервер:
(кликните для увеличения до 1013 px на 520 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Binding’и выглядят так:
(кликните для увеличения до 645 px на 423 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Как видно, всё абсолютно тривиально и не требует какого-то специального включения – более того, в конфигурации веб-сервера IIS 10 никаких явных настроек HTTP/2 найти не удалось. Впрочем, их удалось найти у нового драйвера http.sys
, и будут они следующими:
(кликните для увеличения до 1099 px на 477 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Доступны три настройки, свежепоявившиеся именно в IIS 10 – это http2tcp
и http2tls
, соответственно включающие/выключающие поддержку работы HTTP/2 поверх обычного TCP (этот вариант есть в стандарте, но всё по факту идёт к тому, что все будут поддерживать только вариант поверх TLS) либо поверх TLS-сессии, и duo
.
Настройка duo
включает обработку специального заголовка HTTP 1.1, называемого Upgrade
. Смысл отправки этого заголовка клиентом – “я хочу улучшить текущее соединение”, и запрос на улучшение может выражаться в “у меня plaintext, хочу TLS”, либо “хочу протокол новой версии”.
Первый вариант, хоть теоретически и возможен, по сути не используется (т.е. если вы хотите защищённое подключение, вы сразу подключаетесь по HTTPS, а не используете схему “начнём по HTTP, а потом попросим включить TLS”) в HTTP. Зато используется в LDAP, SMTP и FTP – там ситуация “подключились как обычно и позже запросили защиту, типа STARTTLS” бывает.
Второй вариант – как раз наш; он будет работать несложно, клиент будет инициировать подключение по HTTP 1.1 и посылать Upgrade: h2c
. Если сервер может переключиться на HTTP 2.0, то он будет уведомлять об этом кодом 101 Switching Protocol
.
Мы включим работу поверх TLS и поддержку Upgrade
– поддержку же HTTP 2.0 поверх TCP мы отключим, так как практического использования этой возможности нет, а лишний неиспользуемый сервис – дополнительные потенциальные проблемы.
(кликните для увеличения до 980 px на 627 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Проверим через сервис KeyCDN – и видим, что всё ОК:
(кликните для увеличения до 1116 px на 477 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Мы поддерживаем HTTP/2 и даже с расширением ALPN. Что это за расширение?
ALPN и NPN
ALPN – это Application-Layer Protocol Negotiation, а NPN – Next Protocol Negotiation. Суть этих двух технологий схожа, а NPN вообще можно считать “предварительной” версией ALPN – так вот, нужны они для согласования “нам надо работать по безопасному соединению” (в этом плане они схожи с HSTS).
Если сервер поддерживает NPN, то он может, например, после установки HTTP 1.1-сессии – обычной, нормальной – сообщить клиенту “а я кстати поддерживаю SPDY, и вот на этом порту, и защищённый, поверх TLS”. ALPN (разработан инженерами Microsoft и Cisco в 2013 году) развивает эту идею, работая только поверх TLS, и на данный момент замещает собой NPN.
Так что надпись “Поддерживает ALPN” говорит о том, что наш сервер умеет подсказывать клиенту “переключайся на новый безопасный и более быстрый вариант” всеми доступными способами – и это хорошо.
Но что же с безопасностью? Ведь мы уже в курсе, что просто включить TLS мало, надо ещё и настроить.
Настраиваем безопасность работы HTTP/2 на IIS 10
Воспользуемся стандартным тестом от SSLLabs на качество защиты TLS, и посмотрим на результат (тестирование, напомню, идёт на “нулевом” Windows Server 2016 TP5 со всеми обновлениями на май 2016го):
(кликните для увеличения до 1015 px на 479 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Немножко грустно, но это всё ж дефолтные настройки, так что не переживаем.
Выключаем старые версии TLS, т.к. сейчас TLS 1.2 поддерживается уже всеми:
(кликните для увеличения до 977 px на 575 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Тест нам также намекал, что надо выключить RC4 (удобная команда clean
вычищает из ciphersuite’ов ненужные по заданной буквокомбинации):
(кликните для увеличения до 977 px на 712 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
ATcmd реализует такие штуки через прямое обращение к CryptoAPI, поэтому нам даже перезагружаться не надо будет.
Прогоняем тест ещё раз:
(кликните для увеличения до 1000 px на 469 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Лучше, но не особо – например, внезапно, IIS 10, который вроде как по умолчанию работает только с TLS, стал соглашаться на SSL 3.0 для ряда устаревших систем:
(кликните для увеличения до 951 px на 625 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
ОК, явно выключим сейчас SSL 3.0 (аналогично TLS, команды будут no ssl20
и no ssl30
, плюс уберём ciphersuites с вариантами DES, чтобы совсем закрыть возможность упасть даже на “любимый” IIS’ом TLS_RSA_WITH_3DES_EDE_CBC_SHA
, ну и до кучи уберём “короткий” 128ми битовый AES (команды будут clean DES
, clean _128_
). Замечу, что убирать весь 128битовый AES нельзя, потому что в стандарте HTTP/2 явно указано, что среди поддерживаемых сервером должен быть TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
.
Кстати, обратите внимание, в тесте показывается работа ALPN/NPN – при согласовании TLS 1.2 указывается значок “>”, после которого пишется, на какой протокол пошло согласование – h2
будет обозначать HTTP/2.
Вот результат следующего прогона теста:
(кликните для увеличения до 1003 px на 424 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Лучше, но появилась новая проблема – наш IIS 10 начал согласовывать “blacklisted ciphersuites”.
(кликните для увеличения до 895 px на 223 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Список этих ciphersuites есть в приложении A к RFC 7540, и, подчеркну, он необязательный – т.е. там стоит слово MAY, что значит “при согласовании кого-то из этого списка сервер МОЖЕТ сообщить INADEQUATE_SECURITY
“, но в реальности нам надо избегать согласования ciphersuites из этого списка в целях лучшей совместимости с различной реализацией HTTP/2 over TLS у клиентов.
Поэтому выкидываем TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
и TLS_RSA_WITH_AES_256_CBC_SHA
(скриншоты не делаю, потому что идентичная операция) и смотрим на результат. Он остаётся таким же, т.е. мы получаем A – наш единственный минус, что у нас есть шифрование с секретным ключом короче 256 бит (и если мы его выключим, мы выпадем из стандарта HTTP/2), а также есть обмен DH (а не только ECDH). Вопрос полного отключения DH обсуждаем в каждой конкретной ситуации, т.к. он повлечёт за собой несовместимость со множеством устаревших устройств и ОС (например в нашей ситуации удаление TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
приведёт к неработоспособности IE 11 на Windows 7, Windows 8, Windows 8.1 и на Windows Phone всех версий (исключая разве что 10ю) – если сие некритично, то, конечно, вы можете сократить список поддерживаемых ciphersuites ещё сильнее.
Впрочем, такой хардкор уже нуждается в серьёзном обосновании целесообразности – поэтому мы лишь включаем HTTP Strict Transport Security – ведь мы только поверх TLS и работаем, и прогоняем тест ещё раз.
(кликните для увеличения до 995 px на 467 px)Ruslan V. Karmanovrk@atraining.ruУчебный центр Advanced Traininginfo@atraining.ruhttps://www.atraining.ru/
Наш финальный балл – A+, и на этом операцию можно считать завершённой. В итоге HTTP/2 работает, поддерживает все последние расширения (ALPN), совместим не только с самыми последними ОС и браузерами, но и с чуть-чуть старыми, выполнены все требования стандарта HTTP/2 по части наличия необходимых ciphersuites и отсутствия blacklisted, и у нас максимальный балл по тесту SSLLabs.
Финал
Как видно, в Windows Server 2016 появляется полноценная поддержка основного интернет-протокола нового поколения – HTTP/2 – и реализация функциональна и настраиваема.
Так что используйте – можно сделать работу клиентов с веб-сервисами ощутимо более быстрой и безопасной уже сейчас. Ну или точнее, когда выйдет Windows Server 2016 RTM. Если хотите глубже изучить тему тюнинга TLS в Windows Server – про это есть отдельная статья.
Удач!