Файлы не подаются по HTTP/2 на VPS с Windows Server 2019

Вопрос или проблема

Мой веб-сайт, который я размещаю на своем VPS (не CloudFlare) и обслуживаю файлы (например, изображения, js и т.д.), не использует http/2, он обрабатывает запросы с помощью http/1.

Что я пробовал:

  1. Я использовал IIS Crypto, настроил его так и отключил tls1.0 и tls1.1:
    image

  2. Отключил поддержку tls1.0 и tls1.1 в настройках Internet Explorer: https://markcz.wordpress.com/2014/10/26/full-http2-support-in-windows-10/

  3. Принудил https через web.config:

    <!-- Перенаправить HTTP на HTTPS на www -->
    <rule name="Force HTTPS on www" stopProcessing="true">
      <match url=".*" />
      <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
        <add input="{HTTP_HOST}" pattern="^www\.example\.com$" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:0}" redirectType="Permanent" />
    </rule>
    
  4. Предоставил группе IIS_IUSRS разрешения на чтение в корневом каталоге

  5. Включил анонимную аутентификацию для моего веб-сайта

  6. У меня есть https привязки для моего веб-сайта: отключил “Отключить HTTP/2”, включил “Требовать указание имени сервера”, привязан к порту 443, IP-адрес установлен на “Все не назначенные”

ТЕСТ 1

  1. Пробовал h21:

    h2i www.example.com
    Подключение к www.example.com:443
    Подключено к 123.123.123.123:443
    Согласованный протокол “h2”
    Отправка: []
    h2i> ←[5D←[K[FrameHeader SETTINGS len=18]
    h2i> ←[5D←[K [MAX_CONCURRENT_STREAMS = 100]
    h2i> ←[5D←[K [UNKNOWN_SETTING_16 = 2]
    h2i> ←[5D←[K [INITIAL_WINDOW_SIZE = 1048576]
    h2i> ←[5D←[K[FrameHeader WINDOW_UPDATE len=4]
    h2i> ←[5D←[K Window-Increment = 983041
    h2i> ←[5D←[K[FrameHeader SETTINGS flags=ACK len=0]
    h2i>

  2. IIS Application Request Routing не установлен на моем сервере

  3. Я проверил настройки SSL/TLS и совместимость сертификата с HTTP/2 через SSL Labs. Это показывает “TLS 1.2 > h2”, “TLS 1.2” для современных браузеров. Только старые браузеры показывают “TLS 1.2 > http/1.1”

  4. Я не использую никакие CDN или обратные прокси

  5. Мой applicationhost.config выглядит так:

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
    <staticTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
        <add mimeType="application/atom+xml" enabled="true" />
        <add mimeType="application/xaml+xml" enabled="true" />
        <add mimeType="image/svg+xml" enabled="true" />
    </staticTypes>
    <dynamicTypes>
        <add mimeType="text/*" enabled="true" />
        <add mimeType="message/*" enabled="true" />
        <add mimeType="application/x-javascript" enabled="true" />
        <add mimeType="application/javascript" enabled="true" />
    </dynamicTypes>
</httpCompression>
  1. мой web.config выглядит так:
<staticContent>
  <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" /> <!-- 365 дней -->     
</staticContent>
  1. мой www.example.com и example.com корректно привязаны в IIS
  2. “Get-ItemProperty -Path “HKLM:\System\CurrentControlSet\Services\HTTP\Parameters” -Name Http2Enabled” указывает на то, что Http2Enabled установлен на 1
  3. Я пробовал curl к одному из файлов с проблемой: `-I –http2 https://www.example.com/js/_myfuncs.min.js?v=1
HTTP/1.1 200 OK
Cache-Control: max-age=31536000
Content-Length: 44124
Content-Type: application/javascript
Last-Modified: Tue, 24 Sep 2024 18:29:47 GMT
Accept-Ranges: bytes
ETag: "5ec25bcafedb1:0"
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Strict-Transport-Security: max-age=63072000; includeSubDomains
Date: Sun, 29 Sep 2024 19:52:10 GMT

ТЕСТ 2

Я запустил curl -vso /dev/null --http2 https://www.example.com/js/_myfuncs.min.js?v=1

Это вывод:

* Хост www.example.com:443 был разрешен.
* IPv6: (нет)
* IPv4: 123.123.123.123
*   Пытаюсь 123.123.123.123:443...
* ALPN: curl предлагает h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [315 байт данных]
*  CAfile: C:\ProgramData\curl\bin\curl-ca-bundle.crt
*  CApath: нет
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [94 байта данных]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3282 байт данных]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [493 байта данных]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 байта данных]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [102 байта данных]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 байт данных]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 байт данных]
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 байт данных]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 байт данных]
* SSL соединение с использованием TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 / [пусто] / UNDEF
* ALPN: сервер принял h2
* Сертификат сервера:
*  subject: CN=example.com
*  дата начала: Sep 25 15:40:55 2024 GMT
*  дата окончания: Dec 24 15:40:54 2024 GMT
*  subjectAltName: хост "www.example.com" совпадает с сертификатом "www.example.com"
*  issuer: C=US; O=Let's Encrypt; CN=R10
*  SSL сертификат проверен успешно.
*   Уровень сертификата 0: Тип публичного ключа ? (3072/128 бит/сек), подписан с использованием sha256WithRSAEncryption
*   Уровень сертификата 1: Тип публичного ключа ? (2048/112 бит/сек), подписан с использованием sha256WithRSAEncryption
*   Уровень сертификата 2: Тип публичного ключа ? (4096/128 бит/сек), подписан с использованием sha256WithRSAEncryption
* Подключено к www.example.com (123.123.123.123) порт 443
* с использованием HTTP/2
* [HTTP/2] [1] ОТКРЫТ поток для https://www.example.com/js/_myfuncs.min.js?v=1
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: www.example.com]
* [HTTP/2] [1] [:path: /js/_myfuncs.min.js?v=1]
* [HTTP/2] [1] [user-agent: curl/8.10.1]
* [HTTP/2] [1] [accept: */*]
> GET /js/_myfuncs.min.js?v=1 HTTP/2
> Host: www.example.com
> User-Agent: curl/8.10.1
> Accept: */*
>
* Запрос полностью отправлен
* HTTP/2 поток 1 не был закрыт корректно: HTTP_1_1_REQUIRED (ошибка 13)
* Понижение до HTTP/1.1
* Пустой ответ от сервера
* Соединение #0 с хостом www.example.com осталось нетронутым
* Выполняю еще один запрос к этому URL: 'https://www.example.com/js/_myfuncs.min.js?v=1'
* Имя хоста www.example.com найдено в DNS-кашировании
*   Пытаюсь 123.123.123.123:443...
* Повторное использование SSL идентификатора сессии
* ALPN: curl предлагает http/1.1
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [255 байт данных]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [100 байт данных]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3282 байт данных]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [493 байта данных]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 байта данных]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [102 байт данных]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 байт данных]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 байт данных]
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 байт данных]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 байт данных]
* SSL соединение с использованием TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 / [пусто] / UNDEF
* ALPN: сервер принял http/1.1
* Сертификат сервера:
*  subject: CN=example.com
*  дата начала: Sep 25 15:40:55 2024 GMT
*  дата окончания: Dec 24 15:40:54 2024 GMT
*  subjectAltName: хост "www.example.com" совпадает с сертификатом "www.example.com"
*  issuer: C=US; O=Let's Encrypt; CN=R10
*  SSL сертификат проверен успешно.
*   Уровень сертификата 0: Тип публичного ключа ? (3072/128 бит/сек), подписан с использованием sha256WithRSAEncryption
*   Уровень сертификата 1: Тип публичного ключа ? (2048/112 бит/сек), подписан с использованием sha256WithRSAEncryption
*   Уровень сертификата 2: Тип публичного ключа ? (4096/128 бит/сек), подписан с использованием sha256WithRSAEncryption
* Подключено к www.example.com (123.123.123.123) порт 443
* с использованием HTTP/1.x
> GET /js/_myfuncs.min.js?v=1 HTTP/1.1
> Host: www.example.com
> User-Agent: curl/8.10.1
> Accept: */*
>
* Запрос полностью отправлен
* TLSv1.2 (IN), TLS handshake, Hello request (0):
{ [4 байта данных]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [255 байт данных]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [109 байт данных]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3282 байта данных]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [493 байта данных]
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
{ [30 байт данных]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 байта данных]
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
} [7 байт данных]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [102 байт данных]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 байт данных]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 байт данных]
* Запрос полностью отправлен
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
{ [1 байт данных]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 байт данных]
* старый SSL идентификатор сессии устарел, удаление
< HTTP/1.1 200 OK
< Cache-Control: max-age=31536000
< Content-Type: application/javascript
< Last-Modified: Sat, 16 Nov 2024 17:27:21 GMT
< Accept-Ranges: bytes
< ETag: "d3f655cb4c38db1:0"
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Content-Type
< Strict-Transport-Security: max-age=63072000; includeSubDomains
< Date: Fri, 29 Nov 2024 17:44:22 GMT
< Content-Length: 44307
<
{ [15999 байт данных]
* Ошибка записи вывода в назначение, передано 15999 возвращенных 4294967295
* Закрываю соединение
* TLSv1.2 (OUT), TLS alert, close notify (256):
} [2 байта данных]

Когда я запускаю curl -sI --http2-prior-knowledge -w '%{http_version}\n' -o /dev/null https://www.example.com в командной строке на моем VPS, он возвращает “1.1”, так что это исключает наличие промежуточного узла.

Если вы хотите увидеть это вживую, зайдите на этот пример сайта здесь.

Ответ или решение

Проблема с тем, что файлы не обслуживаются через HTTP/2 на вашем VPS с Windows Server 2019, охватывает несколько аспектов настройки сервера и протоколов безопасности. Давайте рассмотрим возможные причины и пути их устранения.

Фоновые сведения

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

Возможные причины и пути решения

  1. Поддержка протоколов TLS:

    • Вы упомянули, что отключили поддержку TLS 1.0 и 1.1, что является необходимым шагом, так как HTTP/2 требует как минимум TLS 1.2. Убедитесь, что ваши сертификаты правильно настроены и поддерживают TLS 1.2 или более новые версии.
  2. Настройки IIS:

    • Необходимо проверить, что ваш IIS не отключен для обработки HTTP/2. В вашем случае вы упомянули, что галочка "Disable HTTP/2" не активна. Это правильно. Убедитесь также, что вы используете последнюю версию IIS и все обновления Windows установлены.
  3. Настройки ALPN (Application-Layer Protocol Negotiation):

    • Убедитесь, что ваш сервер правильно настроен для поддержки ALPN. Это ключевая часть процесса согласования протокола, которая позволяет клиентам и серверам определять, какие протоколы будут использоваться.
  4. Проверка конфигурации на уровне приложения:

    • Проверьте файл applicationhost.config и web.config. Убедитесь, что настройки httpCompression включают все необходимые типы MIME. Возможно, вам нужно добавить дополнительные типы, которые ваша веб-страница использует для обслуживания статичных файлов.
  5. Тестирование и диагностика:

    • Используйте такие инструменты, как curl и SSL Labs, чтобы протестировать конечную точку вашего сервера. Вы уже провели некоторые из этих тестов. Особенное внимание уделите тому, какие версии HTTP принимает сервер. Если сервер Продолжает отвечать HTTP/1.1 для определенных запросов, это указывает на возможные проблемы.
  6. Проблемы с прокси и middleware:

    • Хотя вы упомянули, что не используете CDNs или обратные прокси, стоит проверить, нет ли других компонентов, находящихся между клиентом и сервером, которые могли бы вызвать проблему.
  7. Системные настройки и разрешения:

    • Обязательно проверьте настройки Windows Server. Убедитесь, что у IIS достаточно разрешений для работы с HTTP/2. Логи событий Windows могут дать дополнительное представление о том, почему запросы не обрабатываются через HTTP/2.

Практические рекомендации

  • Обновите все компоненты: Убедитесь, что у вас установлены все обновления Windows и IIS.
  • Логи IIS: Ознакомьтесь с логами IIS, чтобы найти возможные аномалии или ошибки, связанные с обработкой запросов.
  • Отладка: Воспользуйтесь инструментами отладки, чтобы проанализировать, на каком этапе происходит откат к HTTP/1.1.
  • Тестирование различных клиентов: Иногда разные клиенты могут вести себя по-разному. Попробуйте протестировать с помощью разных браузеров и инструментов (например, Postman).

Заключение

Проблема с тем, что файлы не обслуживаются через HTTP/2, может быть результатом множества факторов. Постоянная проверка конфигураций, анализ логов и тестирование помогут вам более точно определить источник проблемы. Следуйте рекомендованным шагам, и это должно способствовать успешному переходу на HTTP/2 для вашего сайта на Windows Server 2019.

Оцените материал
Добавить комментарий

Капча загружается...