Реализации веб-сервера HTTP.sys в ASP.NET Core

Авторы: Том Дикстра (Tom Dykstra) и Крис Росс (Chris Ross)

HTTP.sys — это веб-сервер для ASP.NET Core, который запускается только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Важно!

HTTP.sys не подходит для использования с IIS или IIS Express из-за несовместимости с модулем ASP.NET Core.

HTTP.sys поддерживает следующие функции:

  • Проверка подлинности Windows.
  • Совместное использование портов
  • Использование HTTPS с SNI
  • Использование HTTP/2 через TLS (Windows 10 и более поздние версии)
  • Прямая передача файлов
  • кэширование ответов;
  • Использование WebSockets (Windows 8 и более поздние версии)

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии.
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys удобно использовать с развертываниями в таких случаях:

  • когда нужно подключить сервер к Интернету напрямую без использования служб IIS;

    HTTP.sys communicates directly with the Internet

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys communicates directly with the internal network

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сами службы IIS выполняются в качестве HTTP-прослушивателя поверх HTTP.sys.

Поддержка HTTP/2

Протокол HTTP/2 включается для приложений ASP.NET Core, если выполнены следующие базовые требования:

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

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

Поддержка HTTP/3

Протокол HTTP/3 включается для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2022 либо Windows 11 или более поздних версий
  • Используется привязка URL-адреса https.
  • Задается раздел реестра EnableHttp3.

Предыдущие версии сборки Windows 11 могут потребовать сборку для участников программы предварительной оценки Windows.

HTTP/3 обнаруживается как обновление с HTTP/1.1 или HTTP/2 с помощью заголовка alt-svc. Это означает, что первый запрос обычно будет использовать HTTP/1.1 или HTTP/2 перед переключением на HTTP/3. Http.Sys не добавляет alt-svc заголовок автоматически, его необходимо добавить приложением. Следующий код является примером ПО промежуточного слоя, который добавляет заголовок ответа alt-svc.

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

Поместите предшествующий код в конвейер запросов на раннем этапе.

Чтобы уведомить клиента о доступности HTTP/3, HTTP.Sys также поддерживает отправку сообщения протокола HTTP/2 Alt-Svc вместо заголовка ответа. См. запись блога о задании раздела реестра EnableAltSvc. Для этого требуются привязки sslcert netsh, использующие имена узлов, а не IP-адреса.

Проверка подлинности в режиме ядра с помощью Kerberos

HTTP.sys делегирует задачи в проверку подлинности в режиме ядра с помощью протокола проверки подлинности Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Необходимо использовать учетную запись компьютера для расшифровки маркера/билета Kerberos, полученного из Active Directory и переадресованного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Поддержка буферизации ответов в режиме ядра

В некоторых сценариях большие объемы небольших операций записи с высокой задержкой могут привести к значительному влиянию HTTP.sysна производительность. Это влияние связано с отсутствием буфера Pipe в HTTP.sys реализации. Для повышения производительности в этих сценариях включена HTTP.sysподдержка буферизации ответов. Включите буферизацию, задав значение HttpSysOptions.EnableKernelResponseBufferingtrue.

Буферизация ответов должна быть включена приложением, выполняющим синхронные операции ввода-вывода или асинхронные операции ввода-вывода без одной выдающейся записи за раз. В этих сценариях буферизация ответов может значительно повысить пропускную способность по сравнению с подключениями с высокой задержкой.

Приложения, использующие асинхронные операции ввода-вывода и которые могут содержать несколько операций записи, не должны использовать этот флаг. Включение этого флага может привести к повышению использования ЦП и памяти http.Sys.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys(options =>
{
    options.AllowSynchronousIO = false;
    options.Authentication.Schemes = AuthenticationSchemes.None;
    options.Authentication.AllowAnonymous = true;
    options.MaxConnections = null;
    options.MaxRequestBodySize = 30_000_000;
    options.UrlPrefixes.Add("http://localhost:5005");
});

builder.Services.AddRazorPages();

var app = builder.Build();

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

Дополнительные сведения о параметрах HTTP.sys см. в статье HttpSysOptions.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Чтобы переопределить это ограничение в приложении ASP.NET Core MVC для IActionResult, рекомендуется использовать атрибут RequestSizeLimitAttribute в методе действия:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly указывает на то, что свойство MaxRequestBodySize находится в состоянии только для чтения и настраивать ограничение слишком поздно.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте IHttpMaxRequestBodySizeFeature:

app.Use((context, next) =>
{
    context.Features.GetRequiredFeature<IHttpMaxRequestBodySizeFeature>()
                                             .MaxRequestBodySize = 10 * 1024;

    var server = context.RequestServices
        .GetRequiredService<IServer>();
    var serverAddressesFeature = server.Features
                                 .GetRequiredFeature<IServerAddressesFeature>();

    var addresses = string.Join(", ", serverAddressesFeature.Addresses);

    var loggerFactory = context.RequestServices
        .GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    logger.LogInformation("Addresses: {addresses}", addresses);

    return next(context);
});

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию использует IIS Express. Чтобы запустить проект в качестве консольного приложения, вручную измените выбранный профиль, как показано на следующем снимке экрана:

Select console app profile

Настройка Windows Server

  1. Определите, какие порты нужно открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты брандмауэра для доступа трафика к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальных машинах Azure откройте эти порты в группе безопасности сети. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющие сертификаты с помощью командлета PowerShell New-SelfSignedCertificate. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самозаверяющие или подписанные центром сертификации сертификаты в хранилище сервера, выбрав Локальный компьютер>Личный.

  4. Если приложение является развертыванием, не зависящим от платформы, установите NET Core или .NET Framework (или обе платформы, если это приложение .NET Core, предназначенное для .NET Framework).

    • .NET Core: если приложению требуется .NET Core, получите и запустите установщик среды выполнения .NET Core из скачивания .NET Core. Не устанавливайте полный пакет SDK на сервере.
    • платформа .NET Framework. Если приложению требуется платформа .NET Framework, ознакомьтесь с руководством по установке платформа .NET Framework. Установите требуемую платформу .NET Framework. Установщик последней версии .NET Framework доступен на странице скачивания .NET.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию платформа ASP.NET Core привязана к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 443.

    var builder = WebApplication.CreateBuilder(args);
    
    builder.WebHost.UseHttpSys(options =>
    {
        options.UrlPrefixes.Add("https://10.0.0.4:443");
    });
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    

    Преимущество UrlPrefixes заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys распознает два типа диких карта в префиксах URL-адресов:

    • *является слабой привязкой, также известной как резервная привязка. Если префикс URL-адреса имеет http://*:5000значение и что-то другое привязано к порту 5000, эта привязка не будет использоваться.
    • +— это строгой привязка. Если префикс URL-адреса имеет значение http://+:5000, эта привязка будет использоваться перед другими привязками порта 5000.

    Дополнительные сведения см. в разделе UrlPrefix Strings.

    Предупреждение

    Не используйте привязки с подстановочными знаками (http://*:80/ и http://+:80) на верхнем уровне. Они создают уязвимости и ставят под угрозу безопасность приложения. Сюда относятся и строгие, и нестрогие подстановочные знаки. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

    Приложения и контейнеры часто получают только порт для прослушивания, например порта 80, без дополнительных ограничений, таких как узел или путь. HTTP_PORTS и HTTPS_PORTS — это ключи конфигурации, указывающие порты прослушивания для Kestrel серверов HTTP.sys. Эти ключи могут быть указаны в виде переменных среды, определенных с DOTNET_ префиксами или ASPNETCORE_ напрямую через любые другие входные данные конфигурации, например appsettings.json. Каждый из них представляет собой список значений портов с запятой, как показано в следующем примере:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Приведенный выше пример сокращен для следующей конфигурации, которая указывает схему (HTTP или HTTPS) и любой узел или IP-адрес.

    ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
    

    Ключи конфигурации HTTP_PORTS и HTTPS_PORTS имеют более низкий приоритет и переопределяются URL-адресами или значениями, предоставленными непосредственно в коде. Сертификаты по-прежнему необходимо настроить отдельно с помощью механики для HTTPS для конкретного сервера.

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

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полный универсальный указатель ресурсов (URL-адрес). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio выберите
      • Откройте свойства проекта приложения, щелкнув приложение правой кнопкой мыши в обозревателе решений и выбрав Properties (Свойства).
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы указали в поле Tags (Теги).
    • Если не используется Visual Studio:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новую или существующую группу <PropertyGroup> с GUID, который вы создали.

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Сетевой генератор случайных GUID задает значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Выполнить приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Browser window showing the app's Index page loaded

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных с помощью файла HTTP.sys, которые взаимодействуют с запросами из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и подсистемами балансировки нагрузки. Дополнительные сведения см. в разделе Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Получение подробных сведений о времени с помощью IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature предоставляет подробные сведения о времени для запросов:

  • Метки времени получаются с помощью QueryPerformanceCounter.
  • Частоту метки времени можно получить с помощью QueryPerformanceFrequency.
  • Индекс времени можно привести к HttpSysRequestTimingType , чтобы узнать, какое время представляет.
  • Значение может быть равно 0, если время недоступно для текущего запроса.
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
    
    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timestamps = feature.Timestamps;

    for (var i = 0; i < timestamps.Length; i++)
    {
        var timestamp = timestamps[i];
        var timingType = (HttpSysRequestTimingType)i;

        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetTimestamp извлекает метку времени для предоставленного типа времени:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetTimestamp(timingType, out var timestamp))
    {
        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }
    else
    {
        logger.LogInformation("Timestamp {timingType}: not available for the "
                                           + "current request",    timingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetElapsedTime дает время между двумя указанными сроками:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var startingTimingType = HttpSysRequestTimingType.RequestRoutingStart;
    var endingTimingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetElapsedTime(startingTimingType, endingTimingType, out var elapsed))
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}: {elapsed}",
            startingTimingType,
            endingTimingType,
            elapsed);
    }
    else
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}:"
            + " not available for the current request.",
            startingTimingType,
            endingTimingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.SYS поддерживают gRPC, включая трейлеры ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Windows 11 сборки 22000 или более поздней, Windows Server 2022 сборки 20348 или более поздней.
  • Подключение TLS 1.2 или более поздней версии.

Трейлеры

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Сброс позволяет серверу сбросить запрос HTTP/2 с указанным кодом ошибки. Сброшенный запрос считается прерванным.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Трассировка

Сведения о том, как получить трассировку из HTTP.sys, см . в сценариях управления HTTP.sys.

Дополнительные ресурсы

HTTP.sys — это веб-сервер для ASP.NET Core, который запускается только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Важно!

HTTP.sys не подходит для использования с IIS или IIS Express из-за несовместимости с модулем ASP.NET Core.

HTTP.sys поддерживает следующие функции:

  • Проверка подлинности Windows.
  • Совместное использование портов
  • Использование HTTPS с SNI
  • Использование HTTP/2 через TLS (Windows 10 и более поздние версии)
  • Прямая передача файлов
  • кэширование ответов;
  • Использование WebSockets (Windows 8 и более поздние версии)

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии.
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys удобно использовать с развертываниями в таких случаях:

  • когда нужно подключить сервер к Интернету напрямую без использования служб IIS;

    HTTP.sys communicates directly with the Internet

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys communicates directly with the internal network

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сами службы IIS выполняются в качестве HTTP-прослушивателя поверх HTTP.sys.

Поддержка HTTP/2

Протокол HTTP/2 включается для приложений ASP.NET Core, если выполнены следующие базовые требования:

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

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

Поддержка HTTP/3

Протокол HTTP/3 включается для приложений ASP.NET Core, если выполнены следующие базовые требования:

  • Windows Server 2022 либо Windows 11 или более поздних версий
  • Используется привязка URL-адреса https.
  • Задается раздел реестра EnableHttp3.

Предыдущие версии сборки Windows 11 могут потребовать сборку для участников программы предварительной оценки Windows.

HTTP/3 обнаруживается как обновление с HTTP/1.1 или HTTP/2 с помощью заголовка alt-svc. Это означает, что первый запрос обычно будет использовать HTTP/1.1 или HTTP/2 перед переключением на HTTP/3. Http.Sys не добавляет alt-svc заголовок автоматически, его необходимо добавить приложением. Следующий код является примером ПО промежуточного слоя, который добавляет заголовок ответа alt-svc.

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

Поместите предшествующий код в конвейер запросов на раннем этапе.

Чтобы уведомить клиента о доступности HTTP/3, HTTP.Sys также поддерживает отправку сообщения протокола HTTP/2 Alt-Svc вместо заголовка ответа. См. запись блога о задании раздела реестра EnableAltSvc. Для этого требуются привязки sslcert netsh, использующие имена узлов, а не IP-адреса.

Проверка подлинности в режиме ядра с помощью Kerberos

HTTP.sys делегирует задачи в проверку подлинности в режиме ядра с помощью протокола проверки подлинности Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Необходимо использовать учетную запись компьютера для расшифровки маркера/билета Kerberos, полученного из Active Directory и переадресованного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

Дополнительные сведения о параметрах HTTP.sys см. в статье HttpSysOptions.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Чтобы переопределить это ограничение в приложении ASP.NET Core MVC для IActionResult, рекомендуется использовать атрибут RequestSizeLimitAttribute в методе действия:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly указывает на то, что свойство MaxRequestBodySize находится в состоянии только для чтения и настраивать ограничение слишком поздно.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте IHttpMaxRequestBodySizeFeature:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию использует IIS Express. Чтобы запустить проект в качестве консольного приложения, вручную измените выбранный профиль, как показано на следующем снимке экрана:

Select console app profile

Настройка Windows Server

  1. Определите, какие порты нужно открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты брандмауэра для доступа трафика к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальных машинах Azure откройте эти порты в группе безопасности сети. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющие сертификаты с помощью командлета PowerShell New-SelfSignedCertificate. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самозаверяющие или подписанные центром сертификации сертификаты в хранилище сервера, выбрав Локальный компьютер>Личный.

  4. Если приложение является развертыванием, не зависящим от платформы, установите NET Core или .NET Framework (или обе платформы, если это приложение .NET Core, предназначенное для .NET Framework).

    • .NET Core: если приложению требуется .NET Core, получите и запустите установщик среды выполнения .NET Core из скачивания .NET Core. Не устанавливайте полный пакет SDK на сервере.
    • платформа .NET Framework. Если приложению требуется платформа .NET Framework, ознакомьтесь с руководством по установке платформа .NET Framework. Установите требуемую платформу .NET Framework. Установщик последней версии .NET Framework доступен на странице скачивания .NET.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию платформа ASP.NET Core привязана к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 443.

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    Преимущество UrlPrefixes заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys использует форматы строк UrlPrefix API HTTP-сервера.

    Предупреждение

    Не используйте привязки с подстановочными знаками (http://*:80/ и http://+:80) на верхнем уровне. Они создают уязвимости и ставят под угрозу безопасность приложения. Сюда относятся и строгие, и нестрогие подстановочные знаки. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полный универсальный указатель ресурсов (URL-адрес). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio выберите
      • Откройте свойства проекта приложения, щелкнув приложение правой кнопкой мыши в обозревателе решений и выбрав Properties (Свойства).
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы указали в поле Tags (Теги).
    • Если не используется Visual Studio:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новую или существующую группу <PropertyGroup> с GUID, который вы создали.

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Сетевой генератор случайных GUID задает значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Выполнить приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Browser window showing the app's Index page loaded

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных с помощью файла HTTP.sys, которые взаимодействуют с запросами из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и подсистемами балансировки нагрузки. Дополнительные сведения см. в разделе Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.SYS поддерживают gRPC, включая трейлеры ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Windows 11 сборки 22000 или более поздней, Windows Server 2022 сборки 20348 или более поздней.
  • Подключение TLS 1.2 или более поздней версии.

Трейлеры

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Сброс позволяет серверу сбросить запрос HTTP/2 с указанным кодом ошибки. Сброшенный запрос считается прерванным.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Дополнительные ресурсы

HTTP.sys — это веб-сервер для ASP.NET Core, который запускается только в Windows. HTTP.sys — это альтернатива серверу Kestrel с некоторыми функциями, которые отсутствуют в Kestrel.

Важно!

HTTP.sys не подходит для использования с IIS или IIS Express из-за несовместимости с модулем ASP.NET Core.

HTTP.sys поддерживает следующие функции:

  • Проверка подлинности Windows.
  • Совместное использование портов
  • Использование HTTPS с SNI
  • Использование HTTP/2 через TLS (Windows 10 и более поздние версии)
  • Прямая передача файлов
  • кэширование ответов;
  • Использование WebSockets (Windows 8 и более поздние версии)

Поддерживаемые версии Windows:

  • Windows 7 или более поздней версии.
  • Windows Server 2008 R2 или более поздней версии

Просмотреть или скачать образец кода (описание загрузки)

Условия для применения HTTP.sys

HTTP.sys удобно использовать с развертываниями в таких случаях:

  • когда нужно подключить сервер к Интернету напрямую без использования служб IIS;

    HTTP.sys communicates directly with the Internet

  • когда для внутренних развертываний нужна функция, отсутствующая в Kestrel. См. сравнение Kestrel и HTTP.sys.

    HTTP.sys communicates directly with the internal network

HTTP.sys — это проверенная технология, которая защищает от многих типов атак, а также обеспечивает надежность, безопасность и масштабируемость полнофункционального веб-сервера. Сами службы IIS выполняются в качестве HTTP-прослушивателя поверх HTTP.sys.

Поддержка HTTP/2

Протокол HTTP/2 включен для приложений ASP.NET Core, если выполнены следующие базовые требования:

Если установлено подключение HTTP/2, HttpRequest.Protocol возвращает HTTP/2.

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

Проверка подлинности в режиме ядра с помощью Kerberos

HTTP.sys делегирует задачи в проверку подлинности в режиме ядра с помощью протокола проверки подлинности Kerberos. Проверка подлинности в режиме пользователя не поддерживается с Kerberos и HTTP.sys. Необходимо использовать учетную запись компьютера для расшифровки маркера/билета Kerberos, полученного из Active Directory и переадресованного клиентом на сервер для проверки подлинности пользователя. Зарегистрируйте имя субъекта-службы (SPN) для узла, а не пользователя приложения.

Способы применения HTTP.sys

Настройка приложения ASP.NET Core для использования HTTP.sys

Вызовите метод расширения UseHttpSys при создании узла, указав все необходимые параметры HttpSysOptions. В следующем примере для параметров задаются значения по умолчанию:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

Дополнительная настройка HTTP.sys выполняется с помощью параметров реестра.

Параметры HTTP.sys

Свойство Description По умолч.
AllowSynchronousIO Указывает, разрешен ли синхронные операции ввода-вывода для HttpContext.Request.Body и HttpContext.Response.Body. false
Authentication.AllowAnonymous Разрешает анонимные запросы. true
Authentication.Schemes Указывает разрешенные схемы аутентификации. Может быть изменен в любое время до удаления прослушивателя. Предоставляет значения, полученные при перечислении AuthenticationSchemes: Basic, Kerberos, Negotiate, None и NTLM. None
EnableResponseCaching Выполняет попытку кэшировать режим ядра для ответов с допустимыми заголовками. Ответ не может включать заголовки Set-Cookie, Vary или Pragma. Он должен включать заголовок Cache-Control со значением public, а также значение shared-max-age или max-age заголовок Expires. true
Http503Verbosity Поведение HTTP.sys при отклонении запросов в соответствии с условиями регулирования. Http503VerbosityLevel.
Основные
MaxAccepts Максимальное число одновременных попыток. 5 × Environment.
ProcessorCount
MaxConnections Максимальное число попыток установить одновременное подключение. Использует -1 для бесконечных циклов. Использует null для работы с параметром реестра на уровне компьютера. null
(уровень компьютер
значение)
MaxRequestBodySize См. раздел MaxRequestBodySize. 30 000 000 байт.
(~28,6 МБ).
RequestQueueLimit Максимально допустимое число запросов в очереди. 1000
RequestQueueMode Указывает, отвечает ли сервер за создание и настройку очереди запросов или он должен подключаться к существующей очереди.
Большинство имеющихся параметров конфигурации не применяются при подключении к существующей очереди.
RequestQueueMode.Create
RequestQueueName Имя очереди запросов HTTP.sys. null (анонимная очередь)
ThrowWriteExceptions Указывает, следует ли вызывать исключение или завершать работу нормально, когда запись текста ответа завершается ошибкой из-за отключения клиента. false
Нормальное завершение.
Timeouts Предоставляет конфигурацию TimeoutManager HTTP.sys, которую также можно настроить в реестре. Дополнительные сведения о каждом параметре, включая значения по умолчанию, см. здесь:
  • TimeoutManager.DrainEntityBody: время, разрешенное API HTTP-сервера для очистки тела сущности в подключении Keep-Alive.
  • TimeoutManager.EntityBody: время, разрешенное для поступления текста сущности запроса.
  • TimeoutManager.HeaderWait: время, разрешено для API HTTP-сервера для анализа заголовка запроса.
  • TimeoutManager.IdleConnection: время, разрешенное для простоя подключения.
  • TimeoutManager.MinSendBytesPerSecond: минимальная скорость отправки ответа.
  • TimeoutManager.RequestQueue: время, разрешено для того, чтобы запрос оставался в очереди запросов, прежде чем приложение выберет его.
UrlPrefixes Указывает UrlPrefixCollection для регистрации с использованием HTTP.sys. Наиболее полезным является UrlPrefixCollection.Addто, что используется для добавления префикса в коллекцию. Могут быть изменены в любое время до удаления прослушивателя.

MaxRequestBodySize

Максимально допустимый размер текста запроса в байтах. Если задано значение null, размер максимального запроса не ограничен. Это ограничение не оказывает влияния на обновленные подключения, которые не имеют ограничений.

Чтобы переопределить это ограничение в приложении ASP.NET Core MVC для IActionResult, рекомендуется использовать атрибут RequestSizeLimitAttribute в методе действия:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

При попытке приложения настроить ограничение для запроса после того, как приложение начало считывать запрос, возникает исключение. Свойство IsReadOnly указывает на то, что свойство MaxRequestBodySize находится в состоянии только для чтения и настраивать ограничение слишком поздно.

Если приложение должно переопределять MaxRequestBodySize по запросу, используйте IHttpMaxRequestBodySizeFeature:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

При использовании Visual Studio убедитесь, что приложение не настроено для запуска IIS или IIS Express.

В Visual Studio профиль запуска по умолчанию использует IIS Express. Чтобы запустить проект как консольное приложение, измените выбранный профиль вручную, как показано на следующем снимке экрана.

Select console app profile

Настройка Windows Server

  1. Определите, какие порты нужно открыть для приложения, и используйте брандмауэр Windows или командлет PowerShell New-NetFirewallRule, чтобы открыть порты брандмауэра для доступа трафика к HTTP.sys. В следующих командах и конфигурации приложения используется порт 443.

  2. При развертывании на виртуальных машинах Azure откройте эти порты в группе безопасности сети. В следующих командах и конфигурации приложения используется порт 443.

  3. При необходимости получите и установите сертификаты X.509.

    В Windows создайте самозаверяющие сертификаты с помощью командлета PowerShell New-SelfSignedCertificate. Примеры, которые не поддерживаются, см. в разделе UpdateIISExpressSSLForChrome.ps1.

    Установите самозаверяющие или подписанные центром сертификации сертификаты в хранилище сервера, выбрав Локальный компьютер>Личный.

  4. Если приложение является развертыванием, не зависящим от платформы, установите NET Core или .NET Framework (или обе платформы, если это приложение .NET Core, предназначенное для .NET Framework).

    • .NET Core: если приложению требуется .NET Core, получите и запустите установщик среды выполнения .NET Core из скачивания .NET Core. Не устанавливайте полный пакет SDK на сервере.
    • платформа .NET Framework. Если приложению требуется платформа .NET Framework, ознакомьтесь с руководством по установке платформа .NET Framework. Установите требуемую платформу .NET Framework. Установщик последней версии .NET Framework доступен на странице скачивания .NET.

    Если приложение развертывается автономно, в его развертывание включена среда выполнения. Устанавливать .NET Framework на сервере не нужно.

  5. Настройте URL-адреса и порты в приложении.

    По умолчанию платформа ASP.NET Core привязана к http://localhost:5000. Чтобы настроить префиксы URL-адресов и порты, используйте следующие параметры:

    • UseUrls
    • Аргументы командной строки urls.
    • Переменная среды ASPNETCORE_URLS.
    • UrlPrefixes

    В следующем примере кода показано, как использовать UrlPrefixes с локальным IP-адресом сервера 10.0.0.4 через порт 443.

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    Преимущество UrlPrefixes заключается в том, что при неправильном формате префиксов сразу же создается сообщение об ошибке.

    Этот параметр в UrlPrefixes переопределяет параметры UseUrls/urls/ASPNETCORE_URLS. Таким образом, преимущество переменных средыUseUrls, urls и ASPNETCORE_URLS заключается в возможности быстрого переключения между Kestrel и HTTP.sys.

    HTTP.sys использует форматы строк UrlPrefix API HTTP-сервера.

    Предупреждение

    Не используйте привязки с подстановочными знаками (http://*:80/ и http://+:80) на верхнем уровне. Они создают уязвимости и ставят под угрозу безопасность приложения. Сюда относятся и строгие, и нестрогие подстановочные знаки. Вместо подстановочных знаков используйте имена узлов или IP-адреса в явном виде. Привязки с подстановочными знаками на уровне дочерних доменов (например, *.mysub.com) не создают таких угроз безопасности, если вы полностью контролируете родительский домен (в отличие от варианта *.com, создающего уязвимость). Дополнительные сведения см. в разделе RFC 9110: раздел 7.2: Host и :authority.

  6. Предварительно зарегистрируйте префиксы URL-адресов на сервере.

    Встроенным средством для настройки сервера HTTP.sys является netsh.exe. С помощьюnetsh.exe можно зарезервировать префиксы URL-адресов и назначить сертификаты X.509. Для использования этого средства требуются права администратора.

    Используйте средство netsh.exe для регистрации URL-адреса приложения.

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: полный универсальный указатель ресурсов (URL-адрес). Не используйте привязки с подстановочными знаками. Используйте допустимое имя узла или локальный IP-адрес. URL-адрес должен включать косую черту в конце.
    • <USER>: указывает имя пользователя или группы пользователей.

    В следующем примере сервер имеет локальный IP-адрес 10.0.0.4.

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    При регистрации URL-адреса средство возвращает ответ URL reservation successfully added.

    Чтобы удалить зарегистрированный URL-адрес, используйте команду delete urlacl.

    netsh http delete urlacl url=<URL>
    
  7. Зарегистрируйте сертификаты X.509 на сервере.

    Используйте средство netsh.exe для регистрации сертификатов приложения.

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: указывает локальный IP-адрес привязки. Не используйте привязки с подстановочными знаками. Используйте допустимый IP-адрес.
    • <PORT>: указывает порт для привязки.
    • <THUMBPRINT>: отпечаток сертификата X.509.
    • <GUID>: созданный разработчиком GUID для представления приложения в информационных целях.

    В справочных целях храните GUID в приложении в виде тега пакета.

    • В Visual Studio выберите
      • Откройте свойства проекта приложения, щелкнув приложение правой кнопкой мыши в обозревателе решений и выбрав Properties (Свойства).
      • Перейдите на вкладку Package (Пакет).
      • Введите GUID, который вы указали в поле Tags (Теги).
    • Если не используется Visual Studio:
      • Откройте файл проекта приложения.

      • Добавьте свойство <PackageTags> в новую или существующую группу <PropertyGroup> с GUID, который вы создали.

        <PropertyGroup>
          <PackageTags>9412ee86-c21b-4eb8-bd89-f650fbf44931</PackageTags>
        </PropertyGroup>
        

    В следующем примере :

    • Локальный IP-адрес сервера — 10.0.0.4.
    • Сетевой генератор случайных GUID задает значение appid.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{9412ee86-c21b-4eb8-bd89-f650fbf44931}"
    

    При регистрации сертификата средство возвращает ответ SSL Certificate successfully added.

    Чтобы удалить регистрацию сертификата, используйте команду delete sslcert.

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Дополнительные сведения см. в справочной документации по netsh.exe:

  8. Выполнить приложение.

    Если выполнена привязка к localhost через HTTP (не HTTPS) с номером порта больше 1024, для запуска приложения права администратора не требуются. При других конфигурациях (например, при использовании локального IP-адреса или привязки к порту 443) для запуска приложения требуются права администратора.

    Приложение отвечает по общедоступному IP-адресу сервера. В этом примере подключение к серверу происходит через Интернет по общедоступному IP-адресу 104.214.79.47 сервера.

    В этом примере используется сертификат разработки. После обхода предупреждения о ненадежном сертификате браузера происходит безопасная загрузка страницы.

    Browser window showing the app's Index page loaded

Сценарии использования прокси-сервера и подсистемы балансировки нагрузки

Для приложений, размещенных с помощью файла HTTP.sys, которые взаимодействуют с запросами из Интернета или корпоративной сети, может потребоваться дополнительная настройка при размещении за прокси-серверами и подсистемами балансировки нагрузки. Дополнительные сведения см. в разделе Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Расширенные возможности HTTP/2 для поддержки gRPC

Дополнительные возможности HTTP/2 в HTTP.SYS поддерживают gRPC, включая трейлеры ответов и отправку кадров сброса.

Требования для выполнения gRPC в HTTP.sys:

  • Сборка 19041.508 или более поздняя ОС Windows 10.
  • Подключение TLS 1.2 или более поздней версии

Трейлеры

Трейлеры HTTP похожи на заголовки HTTP, за исключением того, что они отправляются после отправки текста ответа. Для IIS и HTTP.sys поддерживаются только трейлеры ответов HTTP/2.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

В приведенном выше примере кода:

  • SupportsTrailers обеспечивает поддержку трейлеров для ответа;
  • DeclareTrailer добавляет заданное имя трейлера в заголовок ответа Trailer. Объявлять трейлеры ответа необязательно, но рекомендуется. Вызов DeclareTrailer должен производиться перед отправкой заголовков ответа.
  • AppendTrailer добавляет трейлер.

Reset

Сброс позволяет серверу сбросить запрос HTTP/2 с указанным кодом ошибки. Сброшенный запрос считается прерванным.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset в предыдущем примере кода задает код ошибки INTERNAL_ERROR. Дополнительные сведения о кодах ошибок HTTP/2 см. в соответствующем разделе спецификации HTTP/2.

Дополнительные ресурсы