Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.
Kestrel конечные точки предоставляют инфраструктуру для прослушивания входящих запросов и маршрутизации их в соответствующее ПО промежуточного слоя. Сочетание адреса и протокола определяет конечную точку.
- Адрес указывает сетевой интерфейс, который сервер прослушивает для входящих запросов, таких как TCP-порт.
- Протокол задает связь между клиентом и сервером, например HTTP/1.1, HTTP/2 или HTTP/3.
- Конечную точку можно обезопасить, используя схему
httpsURL или методUseHttps.
Конечные точки можно настроить с помощью URL-адресов, JSON, указанных в файле appsettings.json, и с помощью кода. В этой статье описывается, как использовать каждый параметр для настройки конечных точек, протоколов HTTPS и HTTP.
Определение конечной точки по умолчанию
Конфигурация новых ASP.NET Core проектов привязывает каждый проект к конечной точке по умолчанию. Конфигурация выбирает случайный HTTP-порт от 5000 до 5300 и случайный порт HTTPS от 7000 до 7300. Выбранные порты хранятся в созданном файле свойств/launchSettings.json и изменяются разработчиком. Файл launchSetting.json используется только для локальной разработки.
Если конфигурация конечной точки отсутствует, Kestrel привязывается к http://localhost:5000 URL-адресу.
Настройка конечных точек
Kestrel конечные точки прослушивают входящее подключение. При создании конечной точки необходимо настроить адрес, используемый для прослушивания. Адрес обычно является TCP-адресом и номером порта.
У вас есть несколько вариантов настройки конечных точек. Вы можете указать URL-адреса или порты напрямую, определить адреса в коде или создать конечные точки с помощью JSON в файле appsettings.json .
Указание конечных точек с URL-адресами
В следующих разделах объясняется, как настроить конечные точки с помощью следующих ресурсов:
- Переменная среды
ASPNETCORE_URLS. - Аргументы командной строки
--urls. - Ключ конфигурации узла
urls. - Метод расширения UseUrls
- Свойство WebApplication.Urls
Форматы URL-адресов
URL-адреса указывают IP-адреса или адреса узлов с портами и протоколами, которые прослушивает сервер. Можно опустить порт, если это протокол по умолчанию (обычно 80 и 443). URL-адреса могут находиться в любом из следующих форматов.
IPv4-адрес с номером порта:
http://65.55.39.10:80/0.0.0.0является особым случаем, который связывается со всеми IPv4-адресами.IPv6-адрес с номером порта:
http://[0:0:0:0:0:ffff:4137:270a]:80/[::]является IPv6-аналогом IPv4-адреса0.0.0.0.Подстановочный символ (
*) хост с номером порта:http://contoso.com:80/ http://*:80/Любое значение, не распознанное как допустимый IP-адрес или
localhost, рассматривается как подстановочный символ, связывающийся со всеми адресами IPv4 и IPv6. Некоторые разработчики предпочитают использовать звездочку*или символ+плюса, чтобы быть более явным. Чтобы привязать разные имена узлов к разным приложениям ASP.NET Core по одному порту, используйте HTTP.sys или обратный прокси-сервер. Примеры обратного прокси-сервера включают IIS, YARP, Nginx и Apache.Имя
localhostузла с номером порта или IP-адресом обратного цикла с номером порта:http://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/Если указать
localhost, Kestrel попытается привязаться к интерфейсам обратной связи IPv4 и IPv6. Если запрошенный порт уже используется другой службой на одном из интерфейсов обратной связи, Kestrel не сможет запуститься. Если один из интерфейсов обратной петли недоступен по любой другой причине (чаще всего из-за отсутствия поддержки IPv6), Kestrel выдаст предупреждение.Укажите несколько префиксов URL-адресов с помощью разделителя с запятой (
;например:http://*:5000;http://localhost:5001;https://hostname:5002
Дополнительные сведения см. в разделе "Переопределение конфигурации".
Префиксы URL-адреса HTTPS
Конечные точки можно определить с помощью префиксов URL-адреса HTTPS, только если сертификат по умолчанию указан в конфигурации конечной точки HTTPS. Например, используйте KestrelServerOptions конфигурацию или файл конфигурации. Этот подход описан в разделе "Настройка HTTPS" в разделе appsettings.json далее в этой статье. Дополнительные сведения см. в разделе "Настройка HTTPS ".
Укажите только порты
Большинство конфигураций для приложений и контейнеров определяют только порт для прослушивания, например порт 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.
Создание конечных точек в appsettings.json
Kestrel может загружать конечные точки из экземпляра IConfiguration . По умолчанию конфигурация Kestrel загружается из раздела Kestrel, а конечные точки настраиваются в Kestrel:Endpoints.
{
"Kestrel": {
"Endpoints": {
"MyHttpEndpoint": {
"Url": "http://localhost:8080"
}
}
}
}
Пример кода:
- В качестве источника конфигурации используется файл appsettings.json . Однако можно использовать любой
IConfigurationисточник. - Добавляет конечную точку с именем
MyHttpEndpointна порт 8080.
Дополнительные сведения о настройке конечных точек с помощью JSON см. в разделе "Настройка HTTPS" в appsettings.json и настройке протоколов HTTP в разделах appsettings.json далее в этой статье.
Перезагрузить конечные точки из конфигурации
По умолчанию конфигурацию конечной точки можно перезагрузить при изменении источника конфигурации. Его можно отключить с помощью Configure(IConfiguration, Boolean) метода.
При сигнале об изменении:
- Новая конфигурация сравнивается с старой версией. Любая конечная точка без изменений конфигурации не изменяется.
- Удаленные или измененные конечные точки имеют 5 секунд, чтобы завершить обработку запросов и отключиться.
- Запускаются новые или измененные конечные точки.
Клиенты, подключающиеся к измененной конечной точке, могут быть отключены или отклонены при перезапуске конечной точки.
ConfigurationLoader
Возвращает ConfigureKestrelConfigurationLoaderзначение . Метод загрузчика Endpoint(String, Action<EndpointConfiguration>) можно использовать для дополнения параметров настроенной конечной точки:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
Для прямого доступа к KestrelServerOptions.ConfigurationLoader можно продолжить итерацию существующего загрузчика, такого как предоставленный WebHost.
- Раздел конфигурации для каждой конечной точки доступен в параметрах Endpoint метода, чтобы пользовательские параметры можно было считывать.
-
KestrelServerOptions.Configure(IConfiguration) можно вызывать несколько раз, но используется только последняя конфигурация, если
Loadне вызывается явным образом в предыдущих экземплярах. Хост по умолчанию не вызываетLoad, поэтому его стандартный раздел конфигурации может быть заменен. -
KestrelConfigurationLoaderотражает семейство API изKestrelServerOptionsв виде перегрузокEndpoint, поэтому конечные точки кода и конфигурации можно настроить в том же месте. Эти перегрузки не используют имена и используют только параметры по умолчанию из конфигурации.
Определение конечных точек в коде
KestrelServerOptions предоставляет методы настройки конечных точек в коде:
Когда Listen и UseUrls API используются одновременно, Listen конечные точки переопределяют UseUrls конечные точки.
Привязка к TCP-сокету
Методы Listen, ListenLocalhost и ListenAnyIP привязываются к TCP-сокету:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
Пример кода:
- Настраивает конечные точки, прослушивающие порт 5000 и 5001.
- Настраивает HTTPS для конечной точки с помощью метода расширения UseHttps для объекта ListenOptions. Дополнительные сведения см. в разделе "Настройка HTTPS" в коде.
На Windows самозаверяющий сертификат можно создать с помощью командлета New-SelfSignedCertificate PowerShell. Неподдерживаемый пример см. в файле сертификата UpdateIISExpressSSLForChrome.ps1 на GitHub.
В macOS, Linux и Windows можно создавать сертификаты с помощью OpenSSL.
Привязка к сокету UNIX
Прослушивайте Unix-сокет с помощью ListenUnixSocket, чтобы повысить производительность с Nginx, как показано в примере ниже:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- В файле конфигурации Nginx задайте для записи
server>location>proxy_passзначениеhttp://unix:/tmp/{KESTREL SOCKET}:/;, где{KESTREL SOCKET}- это имя сокета, предоставленного для ListenUnixSocket. В примере кода имяkestrel-test.sock. - Убедитесь, что сокет доступен для записи Nginx. (Вы можете задать разрешения на запись в сокете с помощью
chmod go+w /tmp/kestrel-test.sockкоманды.
Настройка значений по умолчанию конечной точки
ConfigureEndpointDefaults(Action<ListenOptions>) указывает конфигурацию, которая выполняется для каждой указанной конечной точки. Несколько вызовов ConfigureEndpointDefaults заменяют предыдущую конфигурацию.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Примечание.
Конечные точки, созданные вызовом Listenперед вызовом ConfigureEndpointDefaults, не имеют применённых значений по умолчанию.
Использование динамической привязки портов
При указании номера порта 0, Kestrel динамически привязывается к доступному порту. В следующем примере показано, как определить порт, к которому Kestrel привязан во время выполнения.
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
Динамическое связывание порта недоступно в некоторых сценариях:
- Код вызывает ListenLocalhost.
- Код связывает HTTP/1.1 или HTTP/2 с HTTP/3 на основе QUIC.
Настройка HTTPS
Kestrel поддерживает защиту конечных точек с помощью HTTPS. Данные, отправляемые по протоколу HTTPS, шифруются с помощью TLS для повышения безопасности данных, передаваемых между клиентом и сервером.
Для HTTPS требуется сертификат TLS. Сертификат TLS хранится на сервере и Kestrel настроен для его использования. Приложение может использовать сертификат разработки ASP.NET Core HTTPS в локальной среде разработки. Сертификат разработки не установлен в неразвитых средах. В рабочей среде сертификат TLS должен быть явно настроен. Как минимум необходимо указать сертификат по умолчанию.
Настройка HTTPS и сертификата TLS зависит от того, как настроены конечные точки. Если префиксы URL-адресов или только указанные порты используются для определения конечных точек, HTTPS можно использовать только в том случае, если сертификат по умолчанию указан в конфигурации конечной точки HTTPS. Сертификат по умолчанию можно настроить с помощью следующих параметров:
Настройка HTTPS в appsettings.json
Для Kestrel доступна схема конфигурации настроек приложения HTTPS по умолчанию. Настройте несколько конечных точек, включая URL-адреса и сертификаты для использования, либо из файла на диске, либо из хранилища сертификатов.
Любая конечная точка HTTPS, которая не указывает сертификат (HttpsDefaultCert в следующем примере кода) возвращается к сертификату, определенному в Certificates:Default разделе или сертификате разработки.
В следующем примере используется файлappsettings.json , но можно использовать любой источник конфигурации:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5003",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В примере кода пароль сертификата хранится в виде обычного текста в файле appsettings.json .
Маркер $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля сертификата.
Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке.
Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault.
Рекомендуется не использовать секреты, предназначенные для разработки, в рабочей среде или для тестирования.
Заметки о схеме
- Имена конечных точек не учитывает регистр. Например,
HTTPSиHttpsэквивалентны. - Параметр
Urlявляется обязательным для каждой конечной точки. Формат этого параметра совпадает с параметром конфигурации верхнего уровняUrls, но может иметь только одно значение. Дополнительные сведения см. в разделе форматов URL-адресов в этой статье. - Эти конечные точки заменяют значения, определенные в конфигурации верхнего уровня
Urls, а не добавляются в них. Конечные точки API, определенные в коде с помощьюListen, дополняют точки, определенные в разделе конфигурации. - Раздел
Certificateявляется необязательным. Если разделCertificateне указан, используются значения по умолчанию, определенные вCertificates:Default. Если значения по умолчанию недоступны, используется сертификат разработки. Если значений по умолчанию нет и сертификат разработки отсутствует, сервер выдаст исключение и не сможет запуститься. - В
Certificateэтом разделе поддерживается несколько источников сертификатов. - Любое количество конечных точек можно определить в
Configuration, если они не вызывают конфликты портов.
Источники сертификатов
Узлы сертификатов можно настроить для загрузки сертификатов из различных источников:
-
PathиPassword: загрузка PFX-файлов . -
Path,KeyPathиPassword: загрузите .pem/, .crt и .key файлы. -
SubjectиStore: загрузка из хранилища сертификатов.
Например, Certificates:Default сертификат можно указать со следующим кодом JSON:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
Настройка сертификатов клиента в appsettings.json
ClientCertificateMode используется для настройки поведения сертификата клиента.
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В примере кода пароль сертификата хранится в виде обычного текста в файле appsettings.json .
Маркер $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля сертификата.
Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке.
Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault.
Рекомендуется не использовать секреты, предназначенные для разработки, в рабочей среде или для тестирования.
Значением по умолчанию является ClientCertificateMode.NoCertificate, при котором Kestrel не запрашивает или не требует сертификат от клиента.
Дополнительные сведения см. в статье Настройка проверки подлинности по сертификату в ASP.NET Core.
Настройка протоколов SSL/TLS в appsettings.json
Протоколы SSL — это протоколы, используемые для шифрования и расшифровки трафика между двумя одноранговыми узлами, которые традиционно являются клиентом и сервером.
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В примере кода пароль сертификата хранится в виде обычного текста в файле appsettings.json .
Маркер $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля сертификата.
Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке.
Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault.
Рекомендуется не использовать секреты, предназначенные для разработки, в рабочей среде или для тестирования.
Значение по умолчанию SslProtocols.None указывает Kestrel использовать параметры операционной системы по умолчанию для выбора оптимального протокола. Если вам не требуется по какой-либо причине выбрать определенный протокол, используйте значение по умолчанию.
Настройка HTTPS в коде
При использовании API Listen метод расширения UseHttps на ListenOptions доступен для настройки HTTPS.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
Параметры ListenOptions.UseHttps включают:
-
filename: путь и имя файла сертификата относительно каталога, содержащего файлы содержимого приложения. -
password: пароль, необходимый для доступа к данным сертификата X.509. -
configureOptions: элементActionдля настройкиHttpsConnectionAdapterOptions. ВозвращаетListenOptions. -
storeName: хранилище сертификатов, из которого необходимо загрузить сертификат. -
subject: имя владельца сертификата. -
allowInvalid: указывает, следует ли рассматривать недопустимые сертификаты, например самозаверяющий сертификат. -
location: расположение хранилища для загрузки сертификата. -
serverCertificate: сертификат X.509.
Полный UseHttps список перегрузок см. в разделе UseHttps.
Настройка сертификатов клиента в коде
ClientCertificateMode настраивает требования к клиентским сертификатам.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
Значение по умолчанию — NoCertificate (0), где Kestrel не запрашивается или требуется сертификат от клиента.
Дополнительные сведения см. в статье Настройка проверки подлинности по сертификату в ASP.NET Core.
Настройка по умолчанию HTTPS в коде
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) задает конфигурацию Action для каждой конечной точки HTTPS. Несколько вызовов ConfigureHttpsDefaults заменяют предыдущие экземпляры Action последним указанным Action.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Примечание.
Конечные точки, созданные вызовом Listenперед вызовом ConfigureHttpsDefaults, не имеют применённых значений по умолчанию.
Настройка протоколов SSL/TLS в коде
Протоколы SSL — это протоколы, используемые для шифрования и расшифровки трафика между двумя однорангами, которые традиционно являются клиентом и сервером.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
Настройка фильтра наборов шифров TLS в коде
В Linux объект CipherSuitesPolicy можно использовать для фильтрации рукопожатий TLS для каждого подключения.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Настройка указания имени сервера
Можно использовать указание имени сервера (SNI) для размещения нескольких доменов в одном IP-адресе и порте. SNI можно использовать для экономии ресурсов, обслуживая несколько сайтов с одного сервера.
Для работы SNI клиент отправляет имя узла для безопасного сеанса серверу во время подтверждения TLS, чтобы сервер смог предоставить правильный сертификат. Клиент использует предоставленный сертификат для зашифрованного соединения с сервером во время безопасного сеанса, который следует после подтверждения TLS.
Все веб-сайты нужно выполнять на одном и том же экземпляре Kestrel. Kestrel не поддерживает совместное использование одного и того же IP-адреса и порта на нескольких экземплярах без обратного прокси.
SNI можно настроить двумя способами:
- Настройте сопоставление имен узлов и параметров HTTPS в Configuration. Например, укажите JSON в файлеappsettings.json .
- Создайте endpoint в коде и выберите сертификат, используя имя хоста со свойством ServerCertificateSelector обратного вызова.
Настройка SNI в appsettings.json
Kestrel поддерживает SNI, как определено в конфигурации. Конечную точку можно настроить с помощью объекта Sni, который содержит сопоставление имен узлов и параметров HTTPS. Имя узла подключения сопоставляется с параметрами, и они используются для этого подключения.
Следующая конфигурация добавляет конечную точку с именем MySniEndpoint, которая использует SNI для выбора параметров HTTPS на основе имени узла:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В примере кода пароль сертификата хранится в виде обычного текста в файле appsettings.json .
Маркер $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля сертификата.
Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке.
Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault.
Рекомендуется не использовать секреты, предназначенные для разработки, в рабочей среде или для тестирования.
SNI может переопределить следующие параметры HTTPS:
-
Certificateнастраивает источник сертификата. -
Protocolsнастраивает разрешенные протоколы HTTP. -
SslProtocolsнастраивает разрешенные протоколы SSL. -
ClientCertificateModeнастраивает требования к сертификату клиента.
Имя узла поддерживает следующее сопоставление подстановочных знаков:
-
Точное совпадение: например,
a.example.orgсоответствуетa.example.org. - Префикс подстановочного знака: если есть несколько совпадений с префиксом подстановочного знака, будет выбран самый длинный шаблон. Например,
*.example.orgсоответствуетb.example.orgиc.example.org. -
Полный подстановочный знак: он
*соответствует всему остальному, включая клиентов, которые не используют SNI и не отправляют имя хоста.
Соответствующая конфигурация SNI применяется к конечной точке подключения, переопределяя значения в этой конечной точке. Если подключение не совпадает с настроенным именем узла SNI, такое подключение отклоняется.
Настройка SNI с помощью кода
Kestrel поддерживает SNI с помощью нескольких API для обратного вызова:
ServerCertificateSelectorServerOptionsSelectionCallbackTlsHandshakeCallbackOptions
SNI с ServerCertificateSelector
Kestrel поддерживает SNI через обратный вызов ServerCertificateSelector. Функция обратного вызова используется один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI с ServerOptionsSelectionCallback
Kestrel поддерживает более динамическую конфигурацию TLS через обратный ServerOptionsSelectionCallback вызов. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат и конфигурацию TLS. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этим обратным вызовом.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
SNI с TlsHandshakeCallbackOptions
Kestrel поддерживает более динамическую конфигурацию TLS через обратный TlsHandshakeCallbackOptions.OnConnection вызов. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат, конфигурацию TLS и другие параметры сервера. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этим обратным вызовом.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
// Different TLS requirements for this host
context.AllowDelayedClientCertificateNegotation = true;
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}
});
});
});
});
Настройка протоколов HTTP
Kestrel поддерживает все часто используемые версии HTTP. Конечные точки можно настроить для поддержки разных версий HTTP с помощью HttpProtocols перечисления, указывающего доступные параметры версии HTTP.
Протокол TLS требуется для поддержки нескольких версий HTTP. Рукопожатие TLS Application-Layer Protocol Negotiation (ALPN) используется для согласования протокола связи между клиентом и сервером в случае поддержки несколькими протоколами.
| Значение переменной HttpProtocols | Разрешенный протокол | Заметки |
|---|---|---|
Http1 |
HTTP/1.1 | Можно использовать с протоколом TLS или без него. |
Http2 |
HTTP/2 | Можно использовать без TLS, только если клиент поддерживает режим предварительного знания. |
Http3 |
HTTP/3 | Требуется TLS. Может потребоваться настроить клиент только для использования HTTP/3. |
Http1AndHttp2 |
HTTP/1.1 HTTP/2 |
HTTP/2 требует, чтобы клиент выбрал HTTP/2 в рукопожатии TLS согласовании протокола уровня приложений (ALPN). В противном случае подключение по умолчанию используется по протоколу HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1 HTTP/2 HTTP/3 |
Первый клиентский запрос обычно использует HTTP/1.1 или HTTP/2. Заголовок ответа alt-svc предложит клиенту обновиться до HTTP/3. Для HTTP/2 и HTTP/3 требуется TLS. В противном случае подключение по умолчанию используется по протоколу HTTP/1.1. |
Значение протокола по умолчанию для конечной точки HttpProtocols.Http1AndHttp2.
Ограничения TLS для HTTP/2
При использовании протокола HTTP/2 для подключения применяются следующие ограничения TLS:
- Требуется tls версии 1.2 или более поздней
- Повторное согласование отключено
- Сжатие отключено
- Минимальные размеры эфемерного обмена ключами
- Набор шифров не запрещен.
Формат TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (см. TLS-ECDHE в [RFC 8422]) с эллиптической кривой P-256 (см. [FIPS186]) поддерживается по умолчанию.
Настройка протоколов HTTP в appsettings.json
В следующем примере файла appsettings.json устанавливается протокол подключения HTTP/1.1 для определенной конечной точки:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Протокол по умолчанию можно настроить в Kestrel:EndpointDefaults разделе. В следующем примере файлаappsettings.json устанавливается протокол HTTP/1.1 в качестве протокола подключения по умолчанию для всех конечных точек:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
Указанные в коде протоколы переопределяют значения, заданные в конфигурации.
Настройка протоколов HTTP в коде
Элемент ListenOptions.Protocols используется для указания протоколов с помощью перечисления HttpProtocols.
В следующем примере настраивается конечная точка для подключений HTTP/1.1, HTTP/2 и HTTP/3 через порт 8000. Подключения защищены с помощью TLS и предоставленного сертификата:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
Настройка Kestrel конечных точек именованного канала
KestrelПоддержка именованных каналов включает расширенные параметры настройки. Свойство CreateNamedPipeServerStream в параметрах именованного канала позволяет настраивать каналы для каждой конечной точки.
Этот подход полезен в Kestrel приложении, требующего двух конечных точек канала с разными средствами безопасности доступа. Этот CreateNamedPipeServerStream параметр можно использовать для создания каналов с настраиваемыми параметрами безопасности в зависимости от имени канала.
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;
var builder = WebApplication.CreateBuilder();
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenNamedPipe("defaultPipe");
options.ListenNamedPipe("securedPipe");
});
builder.WebHost.UseNamedPipes(options =>
{
options.CreateNamedPipeServerStream = (context) =>
{
var pipeName = context.NamedPipeEndPoint.PipeName;
switch (pipeName)
{
case "defaultPipe":
return NamedPipeTransportOptions.CreateDefaultNamedPipeServerStream(context);
case "securedPipe":
var allowSecurity = new PipeSecurity();
allowSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.FullControl, AccessControlType.Allow));
return NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte,
context.PipeOptions, inBufferSize: 0, outBufferSize: 0, allowSecurity);
default:
throw new InvalidOperationException($"Unexpected pipe name: {pipeName}");
}
};
});
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
Связанный контент
Проекты ASP.NET Core настраиваются для привязки случайного порта HTTP в диапазоне 5000–5300 и случайного порта HTTPS в диапазоне 7000–7300. Эта конфигурация по умолчанию указана в созданном Properties/launchSettings.json файле и может быть переопределена. Если порты не указаны, Kestrel выполняет привязку к http://localhost:5000:
Укажите URL-адреса с помощью следующих параметров:
- Переменная среды
ASPNETCORE_URLS. - Аргумент командной строки
--urls. - Ключ конфигурации узла
urls. - Метод расширения UseUrls.
Значение, указанное с помощью этих подходов, может быть одной или несколькими конечными точками HTTP и HTTPS (HTTPS при наличии сертификата по умолчанию). Настройте значение в виде списка с разделением точкой с запятой (например, "Urls": "http://localhost:8000;http://localhost:8001").
Дополнительные сведения о таких подходах см. в разделах URL-адреса сервера и Переопределение конфигурации.
Сертификат разработки создается, когда:
- установлен пакет SDK для .NET;
- используется средство dev-certs для создания сертификата.
Сертификат разработки доступен только для пользователя, который создает сертификат. В некоторых браузерах требуется явное разрешение доверять локальному сертификату разработки.
Шаблоны проектов настраивают приложения так, чтобы они запускались на базе HTTPS по умолчанию и включали поддержку перенаправления HTTPS и HSTS.
Вызовите методы Listen или ListenUnixSocket из KestrelServerOptions, чтобы настроить префиксы URL-адресов и порты для Kestrel.
UseUrls, аргумент командной строки --urls, ключ конфигурации узла urls и переменная среды ASPNETCORE_URLS тоже работают, однако на них распространяются ограничения, указанные далее в этой статье (для конфигурации конечной точки HTTPS требуется сертификат по умолчанию).
Конфигурация KestrelServerOptions:
Настройка параметров конечной точки по умолчанию
ConfigureEndpointDefaults(Action<ListenOptions>) указывает конфигурацию Action для каждой указанной конечной точки. Если вызвать ConfigureEndpointDefaults несколько раз, предыдущие Action будут заменены на последний указанный Action:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Примечание.
К конечным точкам, созданным путем вызова Listenперед вызовом ConfigureEndpointDefaults, не будут применяться значения по умолчанию.
Configure(IConfiguration)
Позволяет Kestrel загружать конечные точки из IConfiguration. Для Kestrel конфигурация должна быть ограничена разделом конфигурации. Перегрузку Configure(IConfiguration, bool) можно использовать для включения перезагрузки конечных точек при изменении источника конфигурации.
По умолчанию конфигурация Kestrel загружается из раздела Kestrel и включается перезагрузка изменений:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Если включена перезагрузка конфигурации и сообщается об изменении, выполняются приведенные ниже действия.
- Новая конфигурация сравнивается со старой, все конечные точки без изменений конфигурации не изменяются.
- Для удаленных или измененных конечных точек выделяется 5 секунд для завершения обработки запросов и завершения работы.
- Запускаются новые или измененные конечные точки.
Клиенты, подключающиеся к измененной конечной точке, могут быть отключены или получить отказ в подключении при перезапуске конечной точки.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) указывает конфигурацию Action для каждой конечной точки HTTPS. Повторные вызовы ConfigureHttpsDefaults приведут к тому, что предыдущие Action будут заменены последним указанным Action.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Примечание.
К конечным точкам, созданным путем вызова Listenперед вызовом ConfigureHttpsDefaults, не будут применяться значения по умолчанию.
ListenOptions.UseHttps
Настройте Kestrel для использования протокола HTTPS.
Расширения ListenOptions.UseHttps:
-
UseHttps: настройте Kestrel для использования протокола HTTPS с сертификатом по умолчанию. Создает исключение, если сертификат по умолчанию не настроен. UseHttps(string fileName)UseHttps(string fileName, string password)UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(StoreName storeName, string subject)UseHttps(StoreName storeName, string subject, bool allowInvalid)UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(X509Certificate2 serverCertificate)UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)
Параметры ListenOptions.UseHttps:
-
filename— это путь и имя файла сертификата, связанного с каталогом, где находятся файлы содержимого приложения. -
password— это пароль для доступа к данным сертификата X.509. -
configureOptions— этоActionдля настройкиHttpsConnectionAdapterOptions. ВозвращаетListenOptions. -
storeName— это хранилище сертификатов, из которого выполняется загрузка сертификата. -
subject— это имя субъекта для сертификата. -
allowInvalidуказывает, следует ли учитывать недопустимые сертификаты, например, самоподписанные сертификаты. -
location— это расположение хранилища, из которого загружается сертификат. -
serverCertificate— это сертификат X.509.
В рабочей среде необходимо явно настроить HTTPS. Как минимум необходимо указать сертификат по умолчанию.
Если сертификаты считываются с диска, а не в Хранилище сертификатов Windows, содержащий каталог должен иметь соответствующие разрешения, чтобы предотвратить несанкционированный доступ.
Поддерживаемые конфигурации, описанные далее:
- Конфигурация отсутствует
- Замена сертификата по умолчанию из конфигурации
- Изменение значений по умолчанию в коде
Конфигурация отсутствует
Kestrel прослушивает http://localhost:5000.
Замена сертификата по умолчанию из конфигурации
Для Kestrel доступна схема конфигурации настроек приложения HTTPS по умолчанию. Настройте несколько конечных точек, включая URL-адреса и сертификаты для использования, либо из файла на диске, либо из хранилища сертификатов.
В следующем примере appsettings.json:
- Установите
AllowInvalidвtrue, чтобы разрешить использование недействительных сертификатов (например, самозаверяющих сертификатов). - Любая конечная точка HTTPS, которая не указывает сертификат (
HttpsDefaultCertв следующем примере), будет использовать сертификат, определенный в разделеCertificates:Default, или сертификат разработки.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5003",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать для производственной среды или тестирования.
Примечания к схеме.
- Имена конечных точек не зависят от регистра. Например,
HTTPSиHttpsявляются эквивалентными. - Параметр
Urlявляется обязательным для каждой конечной точки. Формат этого параметра такой же, как для параметра конфигурацииUrlsверхнего уровня, только он ограничен одиночным значением. - Эти конечные точки заменяют конечные точки, определенные в конфигурации
Urlsверхнего уровня, а не дополняют их. Конечные точки, определенные в коде черезListen, объединяются с конечными точками, определенными в разделе конфигурации. - Раздел
Certificateявляется необязательным. Если разделCertificateне указан, используются значения по умолчанию, определенные вCertificates:Default. Если значения по умолчанию недоступны, используется сертификат разработки. Если значений по умолчанию нет и сертификат разработки отсутствует, сервер выдаст исключение и не сможет запуститься. - Раздел
Certificateподдерживает несколько источников сертификатов. - В конфигурации можно определить любое количество конечных точек, если это не приводит к конфликту портов.
Источники сертификатов
Узлы сертификатов можно настроить для загрузки сертификатов из нескольких источников:
-
PathиPasswordдля загрузки файлов .pfx; -
Path,KeyPathиPasswordдля загрузки файлов .pem/.crt и .key; -
SubjectиStoreдля загрузки из хранилища сертификатов.
Например, Certificates:Default сертификат можно указать следующим образом:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
Configure(IConfiguration) возвращает KestrelConfigurationLoader с методом Endpoint(String, Action<EndpointConfiguration>), который может использоваться в качестве дополнения для параметров настроенной конечной точки:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
Можно обратиться напрямую к KestrelServerOptions.ConfigurationLoader, чтобы и далее выполнять итерацию с существующим загрузчиком, например, предоставленным WebApplicationBuilder.WebHost.
- Раздел конфигурации для каждой конечной точки доступен в параметрах в методе
Endpoint, чтобы можно было прочитать пользовательские параметры. - Можно загрузить несколько конфигураций, снова вызвав Configure(IConfiguration) с другим разделом. Используется только последняя конфигурация, если явным образом не вызвать
Loadв предыдущих экземплярах. Метапакет не вызываетLoad, чтобы можно было заменить его раздел конфигурации по умолчанию. -
KestrelConfigurationLoaderповторяет семейство APIListenизKestrelServerOptionsв виде перегрузокEndpoint, позволяя настраивать конечные точки кода и конфигурации в одном месте. Эти перегрузки не используют имена и используют только параметры по умолчанию из конфигурации.
Изменение значений по умолчанию в коде
Можно использовать ConfigureEndpointDefaults и ConfigureHttpsDefaults для изменения параметров по умолчанию для ListenOptions и HttpsConnectionAdapterOptions, включая переопределение сертификата по умолчанию, указанного в предыдущем сценарии. Необходимо вызвать ConfigureEndpointDefaults и ConfigureHttpsDefaults, прежде чем настраивать конечные точки.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Настройка конечных точек посредством указания имени сервера
Можно использовать указание имени сервера (SNI) для размещения нескольких доменов в одном IP-адресе и порте. Для использования SNI клиент отправляет имя узла для безопасного сеанса серверу во время подтверждения TLS, чтобы сервер предоставил правильный сертификат. Клиент использует предоставленный сертификат для зашифрованного соединения с сервером во время безопасного сеанса, который следует после подтверждения TLS.
SNI можно настроить двумя способами:
- Создайте конечную точку в коде и выберите сертификат, используя имя узла с обратным вызовом ServerCertificateSelector.
- Настройте сопоставление имен узлов и параметров HTTPS в Конфигурация. Например, JSON в файле
appsettings.json.
SNI с ServerCertificateSelector
Kestrel поддерживает SNI через обратный вызов ServerCertificateSelector. Функция обратного вызова используется один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI с ServerOptionsSelectionCallback
Kestrel поддерживает дополнительную динамическую конфигурацию TLS через обратный вызов ServerOptionsSelectionCallback. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат и конфигурацию TLS. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этой функцией обратного вызова.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
SNI с TlsHandshakeCallbackOptions
Kestrel поддерживает дополнительную динамическую конфигурацию TLS через обратный вызов TlsHandshakeCallbackOptions.OnConnection. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат, конфигурацию TLS и другие параметры сервера. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этой функцией обратного вызова.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
// Different TLS requirements for this host
context.AllowDelayedClientCertificateNegotation = true;
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}
});
});
});
});
SNI в конфигурации
Kestrel поддерживает SNI, как определено в конфигурации. Конечную точку можно настроить с помощью объекта Sni, который содержит сопоставление имен узлов и параметров HTTPS. Имя узла подключения сопоставляется с параметрами, которые затем используются для этого подключения.
Следующая конфигурация добавляет конечную точку с именем MySniEndpoint, которая использует SNI для выбора параметров HTTPS на основе имени узла:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать для производственной среды или тестирования.
Параметры HTTPS, которые можно переопределить с помощью SNI:
-
Certificateнастраивает источник сертификата. -
Protocolsнастраивает разрешенные протоколы HTTP. -
SslProtocolsнастраивает разрешенные протоколы SSL. -
ClientCertificateModeнастраивает требования к сертификату клиента.
Имя узла поддерживает сопоставление с подстановочными знаками:
- Точное соответствие. Например,
a.example.orgсоответствуетa.example.org. - Префикс подстановочного символа. Если имеется несколько совпадений с подстановочными знаками, выбирается самый длинный шаблон. Например,
*.example.orgсоответствуетb.example.orgиc.example.org. - Полный подстановочный знак.
*соответствует всему остальному, в том числе клиентам, которые не используют SNI и не отправляют имя хоста.
Соответствующая конфигурация SNI применяется к конечной точке подключения, переопределяя значения в этой конечной точке. Подключение будет отклонено, если оно не соответствует настроенному имени узла SNI.
Требования SNI
Все веб-сайты нужно выполнять на одном и том же экземпляре Kestrel. Kestrel не поддерживает совместное использование одного и того же IP-адреса и порта на нескольких экземплярах без обратного прокси.
Протоколы SSL/TLS
Протоколы SSL — это протоколы, используемые для шифрования и расшифровки трафика между двумя одноранговыми узлами, обычно клиентом и сервером.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Значение по умолчанию SslProtocols.None указывает Kestrel использовать параметры операционной системы по умолчанию для выбора оптимального протокола. Если вам не требуется по какой-либо причине выбрать определенный протокол, используйте значение по умолчанию.
Сертификаты клиента
ClientCertificateMode настраивает требования к сертификату клиента.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault.
По умолчанию используется значение ClientCertificateMode.NoCertificate, где Kestrel не будет запрашивать или требовать сертификат от клиента.
Дополнительные сведения см. в статье Настройка проверки подлинности по сертификату в ASP.NET Core.
Ведение журнала подключения
Вызовите UseConnectionLogging, чтобы выдать журналы уровня отладки для обмена данными на уровне байтов в рамках подключения. Ведение журнала подключения полезно для устранения неполадок, связанных с низкоуровневым взаимодействием, например при TLS-шифровании и работе за прокси-серверами. Если UseConnectionLogging поместить перед UseHttps, в журнале регистрируется зашифрованный трафик. Если UseConnectionLogging поместить после UseHttps, в журнале регистрируется расшифрованный трафик. Это встроенное промежуточное программное обеспечение для подключения.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Привязка к TCP-сокету
Метод Listen выполняет привязку к TCP-сокету, а лямбда-выражение параметров позволяет настроить конфигурацию сертификата X.509:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
В этом примере настраивается HTTPS для конечной точки с помощью ListenOptions. С помощью этого API можно настроить и другие параметры Kestrel для отдельных конечных точек.
На Windows самозаверяющий сертификат можно создать с помощью командлета New-SelfSignedCertificate PowerShell. Неподдерживаемый пример см. в файле сертификата UpdateIISExpressSSLForChrome.ps1 на GitHub.
В macOS, Linux и Windows можно создавать сертификаты с помощью OpenSSL.
Привязка к сокету UNIX
Прослушивайте Unix-сокет с помощью ListenUnixSocket, чтобы повысить производительность с Nginx, как показано в примере ниже:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- В файле конфигурации Nginx установите для записи
server>location>proxy_passзначениеhttp://unix:/tmp/{KESTREL SOCKET}:/;.{KESTREL SOCKET}— это имя сокета, предоставленного для ListenUnixSocket (какkestrel-test.sockв предыдущем примере). - Убедитесь, что сокет доступен для записи Nginx (например,
chmod go+w /tmp/kestrel-test.sock).
Порт 0
Если указать номер порта 0, Kestrel будет динамически привязан к доступному порту. В следующем примере показано, как определить, к какому порту привязан Kestrel во время выполнения:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
В некоторых ситуациях динамическая привязка порта недоступна:
ListenLocalhost- Объединение HTTP/1.1 или HTTP/2 на основе TCP и HTTP/3 на основе QUIC.
Ограничения
Настройте конечные точки с помощью следующих подходов:
- UseUrls
- Аргументы командной строки
--urls. - Ключ конфигурации узла
urls. - Переменная среды
ASPNETCORE_URLS.
Эти методы удобны, если нужно, чтобы код работал с серверами, отличающимися от Kestrel. Не забывайте о следующих ограничениях.
- С этими подходами нельзя использовать HTTPS, если в конфигурации конечной точки HTTPS не предоставлен сертификат по умолчанию (например, с помощью конфигурации
KestrelServerOptionsили файла конфигурации, как показано выше в этой статье). - Если подходы
ListenиUseUrlsиспользуются одновременно, конечные точкиListenпереопределяют конечные точкиUseUrls.
Конфигурация конечной точки IIS
При использовании IIS привязки URL-адресов для IIS задаются элементами Listen или UseUrls, которые переопределяют привязки. Дополнительные сведения см. в статье Модуль ASP.NET Core.
ListenOptions.Protocols
Свойство Protocols устанавливает протоколы HTTP (HttpProtocols), разрешенные для конечной точки подключения или для сервера. Присвойте значение свойству Protocols из перечисления HttpProtocols.
Значение перечисления HttpProtocols |
Допустимый протокол подключения |
|---|---|
Http1 |
Только HTTP/1.1. Можно использовать с протоколом TLS или без него. |
Http2 |
Только HTTP/2. Может использоваться без TLS только в том случае, если клиент поддерживает режим предварительного знания. |
Http3 |
Только HTTP/3. Требуется TLS. Клиент может потребоваться настроить только для использования ПРОТОКОЛА HTTP/3. |
Http1AndHttp2 |
HTTP/1.1 и HTTP/2. Для использования HTTP/2 требуется, чтобы клиент выбрал HTTP/2 в ходе согласования протокола уровня приложений (ALPN); в противном случае, по умолчанию используется HTTP/1.1. |
Http1AndHttp2AndHttp3 |
HTTP/1.1, HTTP/2 и HTTP/3. Первый клиентский запрос обычно использует HTTP/1.1 или HTTP/2, а alt-svc заголовок ответа запрашивает обновление клиента до HTTP/3. Для HTTP/2 и HTTP/3 требуется TLS; в противном случае подключение по умолчанию используется по протоколу HTTP/1.1. |
Значение ListenOptions.Protocols по умолчанию для любой конечной точки равно HttpProtocols.Http1AndHttp2.
Ограничения TLS для HTTP/2:
- TSL 1.2 или более поздней версии.
- Повторное согласование отключено.
- Сжатие отключено.
- Минимальные размеры эфемерного обмена ключами
- эллиптическая кривая Диффи — Хелмана (ECDHE) [RFC4492]: не менее 224 бит;
- конечное поле Диффи — Хелмана (DHE) [
TLS12]: не менее 2048 бит;
- Набор шифров не запрещен.
По умолчанию поддерживается TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] с эллиптической кривой P-256 [FIPS186].
Следующий пример разрешает подключения HTTP/1.1 и HTTP/2 через порт 8000. Эти подключения шифруются по протоколу TLS с использованием предоставленного сертификата:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
В Linux для фильтрации рукопожатий TLS для каждого соединения можно использовать CipherSuitesPolicy.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Промежуточное программное обеспечение подключения
При необходимости кастомное подключаемое промежуточное ПО может фильтровать рукопожатия TLS для каждого подключения на основе определенных шифров.
Следующий пример вызывает NotSupportedException для любого алгоритма шифрования, который не поддерживается приложением. Или определите и сравните ITlsHandshakeFeature.CipherAlgorithm с списком допустимых наборов шифров.
Шифрование не применяется с алгоритмом шифра CipherAlgorithmType.Null.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Use((context, next) =>
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>()!;
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException(
$"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
}
return next();
});
});
});
Установка протокола HTTP из конфигурации
По умолчанию конфигурация Kestrel загружается из раздела Kestrel. В следующем примере appsettings.json для всех конечных точек устанавливается протокол подключения по умолчанию HTTP/1.1:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
В следующем примере appsettings.json для отдельной конечной точки устанавливается протокол подключения HTTP/1.1:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Указанные в коде протоколы переопределяют значения, заданные в конфигурации.
Префиксы URL-адресов
Если вы используете UseUrls, аргумент командной строки --urls, ключ конфигурации узла urls или переменную среды ASPNETCORE_URLS, префиксы URL-адресов могут иметь любой из указанных ниже форматов.
Допустимы только префиксы URL-адресов HTTP.
Kestrel не поддерживает HTTP при настройке привязок URL-адресов с помощью UseUrls.
IPv4-адрес с номером порта
http://65.55.39.10:80/0.0.0.0является особым случаем, который связывается со всеми IPv4-адресами.IPv6-адрес с номером порта
http://[0:0:0:0:0:ffff:4137:270a]:80/[::]является IPv6-аналогом IPv4-адреса0.0.0.0.Имя узла с номером порта
http://contoso.com:80/ http://*:80/Имена узлов,
*и+, не имеют особого значения. Все, что не распознается как допустимый IP-адрес илиlocalhost, привязывается ко всем IP-адресам IPv4 и IPv6. Чтобы привязать разные имена узлов к разным приложениям ASP.NET Core по одному порту, используйте HTTP.sys или обратный прокси-сервер. В качестве обратного прокси-сервера можно использовать IIS, Nginx или Apache.Предупреждение
Для размещения в конфигурации обратного прокси-сервера требуется фильтрация хостов.
Имя узла
localhostс номером порта или локальный IP-адрес с номером портаhttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/Если указать
localhost, Kestrel попытается привязаться к интерфейсам обратной связи IPv4 и IPv6. Если запрошенный порт уже используется другой службой на одном из интерфейсов обратной связи, Kestrel не сможет запуститься. Если один из интерфейсов обратной петли недоступен по любой другой причине (чаще всего из-за отсутствия поддержки IPv6), Kestrel выдаст предупреждение.
Проекты ASP.NET Core настраиваются для привязки случайного порта HTTP в диапазоне 5000–5300 и случайного порта HTTPS в диапазоне 7000–7300. Эта конфигурация по умолчанию указана в созданном Properties/launchSettings.json файле и может быть переопределена. Если порты не указаны, Kestrel выполняет привязку к:
http://localhost:5000-
https://localhost:5001(если присутствует локальный сертификат разработки)
Укажите URL-адреса с помощью следующих параметров:
- Переменная среды
ASPNETCORE_URLS. - Аргумент командной строки
--urls. - Ключ конфигурации узла
urls. - Метод расширения UseUrls.
Значение, указанное с помощью этих подходов, может быть одной или несколькими конечными точками HTTP и HTTPS (HTTPS при наличии сертификата по умолчанию). Настройте значение в виде списка с разделением точкой с запятой (например, "Urls": "http://localhost:8000;http://localhost:8001").
Дополнительные сведения о таких подходах см. в разделах URL-адреса сервера и Переопределение конфигурации.
Сертификат разработки создается, когда:
- установлен пакет SDK для .NET;
- используется средство dev-certs для создания сертификата.
Сертификат разработки доступен только для пользователя, который создает сертификат. В некоторых браузерах требуется явное разрешение доверять локальному сертификату разработки.
Шаблоны проектов настраивают приложения так, чтобы они запускались на базе HTTPS по умолчанию и включали поддержку перенаправления HTTPS и HSTS.
Вызовите методы Listen или ListenUnixSocket из KestrelServerOptions, чтобы настроить префиксы URL-адресов и порты для Kestrel.
UseUrls, аргумент командной строки --urls, ключ конфигурации узла urls и переменная среды ASPNETCORE_URLS тоже работают, однако на них распространяются ограничения, указанные далее в этой статье (для конфигурации конечной точки HTTPS требуется сертификат по умолчанию).
Конфигурация KestrelServerOptions:
Настройка параметров конечной точки по умолчанию
ConfigureEndpointDefaults(Action<ListenOptions>) указывает конфигурацию Action для каждой указанной конечной точки. Если вызвать ConfigureEndpointDefaults несколько раз, предыдущие Action будут заменены на последний указанный Action:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
});
Примечание.
К конечным точкам, созданным путем вызова Listenперед вызовом ConfigureEndpointDefaults, не будут применяться значения по умолчанию.
Configure(IConfiguration)
Позволяет Kestrel загружать конечные точки из IConfiguration. Для Kestrel конфигурация должна быть ограничена разделом конфигурации. Перегрузку Configure(IConfiguration, bool) можно использовать для включения перезагрузки конечных точек при изменении источника конфигурации.
По умолчанию конфигурация Kestrel загружается из раздела Kestrel и включается перезагрузка изменений:
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Если включена перезагрузка конфигурации и сообщается об изменении, выполняются приведенные ниже действия.
- Новая конфигурация сравнивается со старой, все конечные точки без изменений конфигурации не изменяются.
- Для удаленных или измененных конечных точек выделяется 5 секунд для завершения обработки запросов и завершения работы.
- Запускаются новые или измененные конечные точки.
Клиенты, подключающиеся к измененной конечной точке, могут быть отключены или получить отказ в подключении при перезапуске конечной точки.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) указывает конфигурацию Action для каждой конечной точки HTTPS. Повторные вызовы ConfigureHttpsDefaults приведут к тому, что предыдущие Action будут заменены последним указанным Action.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Примечание.
К конечным точкам, созданным путем вызова Listenперед вызовом ConfigureHttpsDefaults, не будут применяться значения по умолчанию.
ListenOptions.UseHttps
Настройте Kestrel для использования протокола HTTPS.
Расширения ListenOptions.UseHttps:
-
UseHttps: настройте Kestrel для использования протокола HTTPS с сертификатом по умолчанию. Создает исключение, если сертификат по умолчанию не настроен. UseHttps(string fileName)UseHttps(string fileName, string password)UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(StoreName storeName, string subject)UseHttps(StoreName storeName, string subject, bool allowInvalid)UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(X509Certificate2 serverCertificate)UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)
Параметры ListenOptions.UseHttps:
-
filename— это путь и имя файла сертификата, связанного с каталогом, где находятся файлы содержимого приложения. -
password— это пароль для доступа к данным сертификата X.509. -
configureOptions— этоActionдля настройкиHttpsConnectionAdapterOptions. ВозвращаетListenOptions. -
storeName— это хранилище сертификатов, из которого выполняется загрузка сертификата. -
subject— это имя субъекта для сертификата. -
allowInvalidуказывает, следует ли учитывать недопустимые сертификаты, например, самоподписанные сертификаты. -
location— это расположение хранилища, из которого загружается сертификат. -
serverCertificate— это сертификат X.509.
В рабочей среде необходимо явно настроить HTTPS. Как минимум необходимо указать сертификат по умолчанию.
Поддерживаемые конфигурации, описанные далее:
- Конфигурация отсутствует
- Замена сертификата по умолчанию из конфигурации
- Изменение значений по умолчанию в коде
Конфигурация отсутствует
Kestrel прослушивает порты http://localhost:5000 и https://localhost:5001 (если доступен сертификат по умолчанию).
Замена сертификата по умолчанию из конфигурации
Для Kestrel доступна схема конфигурации настроек приложения HTTPS по умолчанию. Настройте несколько конечных точек, включая URL-адреса и сертификаты для использования, либо из файла на диске, либо из хранилища сертификатов.
В следующем примере appsettings.json:
- Установите
AllowInvalidвtrue, чтобы разрешить использование недействительных сертификатов (например, самозаверяющих сертификатов). - Любая конечная точка HTTPS, которая не указывает сертификат (
HttpsDefaultCertв следующем примере), будет использовать сертификат, определенный в разделеCertificates:Default, или сертификат разработки.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5003",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Примечания к схеме.
- Имена конечных точек не зависят от регистра. Например,
HTTPSиHttpsявляются эквивалентными. - Параметр
Urlявляется обязательным для каждой конечной точки. Формат этого параметра такой же, как для параметра конфигурацииUrlsверхнего уровня, только он ограничен одиночным значением. - Эти конечные точки заменяют конечные точки, определенные в конфигурации
Urlsверхнего уровня, а не дополняют их. Конечные точки, определенные в коде черезListen, объединяются с конечными точками, определенными в разделе конфигурации. - Раздел
Certificateявляется необязательным. Если разделCertificateне указан, используются значения по умолчанию, определенные вCertificates:Default. Если значения по умолчанию недоступны, используется сертификат разработки. Если значений по умолчанию нет и сертификат разработки отсутствует, сервер выдаст исключение и не сможет запуститься. - Раздел
Certificateподдерживает несколько источников сертификатов. - В конфигурации можно определить любое количество конечных точек, если это не приводит к конфликту портов.
Источники сертификатов
Узлы сертификатов можно настроить для загрузки сертификатов из нескольких источников:
-
PathиPasswordдля загрузки файлов .pfx; -
Path,KeyPathиPasswordдля загрузки файлов .pem/.crt и .key; -
SubjectиStoreдля загрузки из хранилища сертификатов.
Например, Certificates:Default сертификат можно указать следующим образом:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
Configure(IConfiguration) возвращает KestrelConfigurationLoader с методом Endpoint(String, Action<EndpointConfiguration>), который может использоваться в качестве дополнения для параметров настроенной конечной точки:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
var kestrelSection = context.Configuration.GetSection("Kestrel");
serverOptions.Configure(kestrelSection)
.Endpoint("HTTPS", listenOptions =>
{
// ...
});
});
Можно обратиться напрямую к KestrelServerOptions.ConfigurationLoader, чтобы и далее выполнять итерацию с существующим загрузчиком, например, предоставленным WebApplicationBuilder.WebHost.
- Раздел конфигурации для каждой конечной точки доступен в параметрах в методе
Endpoint, чтобы можно было прочитать пользовательские параметры. - Можно загрузить несколько конфигураций, снова вызвав Configure(IConfiguration) с другим разделом. Используется только последняя конфигурация, если явным образом не вызвать
Loadв предыдущих экземплярах. Метапакет не вызываетLoad, чтобы можно было заменить его раздел конфигурации по умолчанию. -
KestrelConfigurationLoaderповторяет семейство APIListenизKestrelServerOptionsв виде перегрузокEndpoint, позволяя настраивать конечные точки кода и конфигурации в одном месте. Эти перегрузки не используют имена и используют только параметры по умолчанию из конфигурации.
Изменение значений по умолчанию в коде
Можно использовать ConfigureEndpointDefaults и ConfigureHttpsDefaults для изменения параметров по умолчанию для ListenOptions и HttpsConnectionAdapterOptions, включая переопределение сертификата по умолчанию, указанного в предыдущем сценарии. Необходимо вызвать ConfigureEndpointDefaults и ConfigureHttpsDefaults, прежде чем настраивать конечные точки.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// ...
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// ...
});
});
Настройка конечных точек посредством указания имени сервера
Можно использовать указание имени сервера (SNI) для размещения нескольких доменов в одном IP-адресе и порте. Для использования SNI клиент отправляет имя узла для безопасного сеанса серверу во время подтверждения TLS, чтобы сервер предоставил правильный сертификат. Клиент использует предоставленный сертификат для зашифрованного соединения с сервером во время безопасного сеанса, который следует после подтверждения TLS.
SNI можно настроить двумя способами:
- Создайте конечную точку в коде и выберите сертификат, используя имя узла с обратным вызовом ServerCertificateSelector.
- Настройте сопоставление имен узлов и параметров HTTPS в Конфигурация. Например, JSON в файле
appsettings.json.
SNI с ServerCertificateSelector
Kestrel поддерживает SNI через обратный вызов ServerCertificateSelector. Функция обратного вызова используется один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(
StringComparer.OrdinalIgnoreCase)
{
["localhost"] = localhostCert,
["example.com"] = exampleCert,
["sub.example.com"] = subExampleCert
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name is not null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI с ServerOptionsSelectionCallback
Kestrel поддерживает дополнительную динамическую конфигурацию TLS через обратный вызов ServerOptionsSelectionCallback. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат и конфигурацию TLS. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этой функцией обратного вызова.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}, state: null!);
});
});
});
SNI с TlsHandshakeCallbackOptions
Kestrel поддерживает дополнительную динамическую конфигурацию TLS через обратный вызов TlsHandshakeCallbackOptions.OnConnection. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат, конфигурацию TLS и другие параметры сервера. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этой функцией обратного вызова.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps(new TlsHandshakeCallbackOptions
{
OnConnection = context =>
{
if (string.Equals(context.ClientHelloInfo.ServerName, "localhost",
StringComparison.OrdinalIgnoreCase))
{
// Different TLS requirements for this host
context.AllowDelayedClientCertificateNegotation = true;
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert
});
}
return new ValueTask<SslServerAuthenticationOptions>(
new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert
});
}
});
});
});
});
SNI в конфигурации
Kestrel поддерживает SNI, как определено в конфигурации. Конечную точку можно настроить с помощью объекта Sni, который содержит сопоставление имен узлов и параметров HTTPS. Имя узла подключения сопоставляется с параметрами, которые затем используются для этого подключения.
Следующая конфигурация добавляет конечную точку с именем MySniEndpoint, которая использует SNI для выбора параметров HTTPS на основе имени узла:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Параметры HTTPS, которые можно переопределить с помощью SNI:
-
Certificateнастраивает источник сертификата. -
Protocolsнастраивает разрешенные протоколы HTTP. -
SslProtocolsнастраивает разрешенные протоколы SSL. -
ClientCertificateModeнастраивает требования к сертификату клиента.
Имя узла поддерживает сопоставление с подстановочными знаками:
- Точное соответствие. Например,
a.example.orgсоответствуетa.example.org. - Префикс подстановочного символа. Если имеется несколько совпадений с подстановочными знаками, выбирается самый длинный шаблон. Например,
*.example.orgсоответствуетb.example.orgиc.example.org. - Полный подстановочный знак.
*соответствует всему остальному, в том числе клиентам, которые не используют SNI и не отправляют имя хоста.
Соответствующая конфигурация SNI применяется к конечной точке подключения, переопределяя значения в этой конечной точке. Подключение будет отклонено, если оно не соответствует настроенному имени узла SNI.
Требования SNI
Все веб-сайты нужно выполнять на одном и том же экземпляре Kestrel. Kestrel не поддерживает совместное использование одного и того же IP-адреса и порта на нескольких экземплярах без обратного прокси.
Протоколы SSL/TLS
Протоколы SSL — это протоколы, используемые для шифрования и расшифровки трафика между двумя одноранговыми узлами, обычно клиентом и сервером.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Значение по умолчанию SslProtocols.None указывает Kestrel использовать параметры операционной системы по умолчанию для выбора оптимального протокола. Если вам не требуется по какой-либо причине выбрать определенный протокол, используйте значение по умолчанию.
Сертификаты клиента
ClientCertificateMode настраивает требования к сертификату клиента.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault.
По умолчанию используется значение ClientCertificateMode.NoCertificate, где Kestrel не будет запрашивать или требовать сертификат от клиента.
Дополнительные сведения см. в статье Настройка проверки подлинности по сертификату в ASP.NET Core.
Ведение журнала подключения
Вызовите UseConnectionLogging, чтобы выдать журналы уровня отладки для обмена данными на уровне байтов в рамках подключения. Ведение журнала подключения полезно для устранения неполадок, связанных с низкоуровневым взаимодействием, например при TLS-шифровании и работе за прокси-серверами. Если UseConnectionLogging поместить перед UseHttps, в журнале регистрируется зашифрованный трафик. Если UseConnectionLogging поместить после UseHttps, в журнале регистрируется расшифрованный трафик. Это встроенное промежуточное программное обеспечение для подключения.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Привязка к TCP-сокету
Метод Listen выполняет привязку к TCP-сокету, а лямбда-выражение параметров позволяет настроить конфигурацию сертификата X.509:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
В этом примере настраивается HTTPS для конечной точки с помощью ListenOptions. С помощью этого API можно настроить и другие параметры Kestrel для отдельных конечных точек.
На Windows самозаверяющий сертификат можно создать с помощью командлета New-SelfSignedCertificate PowerShell. Неподдерживаемый пример см. в файле сертификата UpdateIISExpressSSLForChrome.ps1 на GitHub.
В macOS, Linux и Windows можно создавать сертификаты с помощью OpenSSL.
Привязка к сокету UNIX
Прослушивайте Unix-сокет с помощью ListenUnixSocket, чтобы повысить производительность с Nginx, как показано в примере ниже:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
});
- В файле конфигурации Nginx установите для записи
server>location>proxy_passзначениеhttp://unix:/tmp/{KESTREL SOCKET}:/;.{KESTREL SOCKET}— это имя сокета, предоставленного для ListenUnixSocket (какkestrel-test.sockв предыдущем примере). - Убедитесь, что сокет доступен для записи Nginx (например,
chmod go+w /tmp/kestrel-test.sock).
Порт 0
Если указать номер порта 0, Kestrel будет динамически привязан к доступному порту. В следующем примере показано, как определить, к какому порту привязан Kestrel во время выполнения:
app.Run(async (context) =>
{
var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();
if (serverAddressFeature is not null)
{
var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);
// ...
}
});
Ограничения
Настройте конечные точки с помощью следующих подходов:
- UseUrls
- Аргументы командной строки
--urls. - Ключ конфигурации узла
urls. - Переменная среды
ASPNETCORE_URLS.
Эти методы удобны, если нужно, чтобы код работал с серверами, отличающимися от Kestrel. Не забывайте о следующих ограничениях.
- С этими подходами нельзя использовать HTTPS, если в конфигурации конечной точки HTTPS не предоставлен сертификат по умолчанию (например, с помощью конфигурации
KestrelServerOptionsили файла конфигурации, как показано выше в этой статье). - Если подходы
ListenиUseUrlsиспользуются одновременно, конечные точкиListenпереопределяют конечные точкиUseUrls.
Конфигурация конечной точки IIS
При использовании IIS привязки URL-адресов для IIS задаются элементами Listen или UseUrls, которые переопределяют привязки. Дополнительные сведения см. в статье Модуль ASP.NET Core.
ListenOptions.Protocols
Свойство Protocols устанавливает протоколы HTTP (HttpProtocols), разрешенные для конечной точки подключения или для сервера. Присвойте значение свойству Protocols из перечисления HttpProtocols.
Значение перечисления HttpProtocols |
Допустимый протокол подключения |
|---|---|
Http1 |
Только HTTP/1.1. Можно использовать с протоколом TLS или без него. |
Http2 |
Только HTTP/2. Может использоваться без TLS только в том случае, если клиент поддерживает режим предварительного знания. |
Http1AndHttp2 |
HTTP/1.1 и HTTP/2. Для использования HTTP/2 требуется, чтобы клиент выбрал HTTP/2 в ходе согласования протокола уровня приложений (ALPN); в противном случае, по умолчанию используется HTTP/1.1. |
Значение ListenOptions.Protocols по умолчанию для любой конечной точки равно HttpProtocols.Http1AndHttp2.
Ограничения TLS для HTTP/2:
- TSL 1.2 или более поздней версии.
- Повторное согласование отключено.
- Сжатие отключено.
- Минимальные размеры эфемерного обмена ключами
- эллиптическая кривая Диффи — Хелмана (ECDHE) [RFC4492]: не менее 224 бит;
- конечное поле Диффи — Хелмана (DHE) [
TLS12]: не менее 2048 бит;
- Набор шифров не запрещен.
По умолчанию поддерживается TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] с эллиптической кривой P-256 [FIPS186].
Следующий пример разрешает подключения HTTP/1.1 и HTTP/2 через порт 8000. Эти подключения шифруются по протоколу TLS с использованием предоставленного сертификата:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
В Linux для фильтрации рукопожатий TLS для каждого соединения можно использовать CipherSuitesPolicy.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Промежуточное программное обеспечение подключения
При необходимости кастомное подключаемое промежуточное ПО может фильтровать рукопожатия TLS для каждого подключения на основе определенных шифров.
Следующий пример вызывает NotSupportedException для любого алгоритма шифрования, который не поддерживается приложением. Или определите и сравните ITlsHandshakeFeature.CipherAlgorithm с списком допустимых наборов шифров.
Шифрование не применяется с алгоритмом шифра CipherAlgorithmType.Null.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Use((context, next) =>
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>()!;
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException(
$"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
}
return next();
});
});
});
Установка протокола HTTP из конфигурации
По умолчанию конфигурация Kestrel загружается из раздела Kestrel. В следующем примере appsettings.json для всех конечных точек устанавливается протокол подключения по умолчанию HTTP/1.1:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
В следующем примере appsettings.json для отдельной конечной точки устанавливается протокол подключения HTTP/1.1:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Указанные в коде протоколы переопределяют значения, заданные в конфигурации.
Префиксы URL-адресов
Если вы используете UseUrls, аргумент командной строки --urls, ключ конфигурации узла urls или переменную среды ASPNETCORE_URLS, префиксы URL-адресов могут иметь любой из указанных ниже форматов.
Допустимы только префиксы URL-адресов HTTP.
Kestrel не поддерживает HTTP при настройке привязок URL-адресов с помощью UseUrls.
IPv4-адрес с номером порта
http://65.55.39.10:80/0.0.0.0является особым случаем, который связывается со всеми IPv4-адресами.IPv6-адрес с номером порта
http://[0:0:0:0:0:ffff:4137:270a]:80/[::]является IPv6-аналогом IPv4-адреса0.0.0.0.Имя узла с номером порта
http://contoso.com:80/ http://*:80/Имена узлов,
*и+, не имеют особого значения. Все, что не распознается как допустимый IP-адрес илиlocalhost, привязывается ко всем IP-адресам IPv4 и IPv6. Чтобы привязать разные имена узлов к разным приложениям ASP.NET Core по одному порту, используйте HTTP.sys или обратный прокси-сервер. В качестве обратного прокси-сервера можно использовать IIS, Nginx или Apache.Предупреждение
Для размещения в конфигурации обратного прокси-сервера требуется фильтрация хостов.
Имя узла
localhostс номером порта или локальный IP-адрес с номером портаhttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/Если указать
localhost, Kestrel попытается привязаться к интерфейсам обратной связи IPv4 и IPv6. Если запрошенный порт уже используется другой службой на одном из интерфейсов обратной связи, Kestrel не сможет запуститься. Если один из интерфейсов обратной петли недоступен по любой другой причине (чаще всего из-за отсутствия поддержки IPv6), Kestrel выдаст предупреждение.
По умолчанию платформа ASP.NET Core привязана к:
http://localhost:5000-
https://localhost:5001(если присутствует локальный сертификат разработки)
Укажите URL-адреса с помощью следующих параметров:
- Переменная среды
ASPNETCORE_URLS. - Аргумент командной строки
--urls. - Ключ конфигурации узла
urls. - Метод расширения UseUrls.
Значение, указанное с помощью этих подходов, может быть одной или несколькими конечными точками HTTP и HTTPS (HTTPS при наличии сертификата по умолчанию). Настройте значение в виде списка с разделением точкой с запятой (например, "Urls": "http://localhost:8000;http://localhost:8001").
Дополнительные сведения о таких подходах см. в разделах URL-адреса сервера и Переопределение конфигурации.
Сертификат разработки создается, когда:
- установлен пакет SDK для .NET;
- используется средство dev-certs для создания сертификата.
В некоторых браузерах требуется явное разрешение доверять локальному сертификату разработки.
Шаблоны проектов настраивают приложения так, чтобы они запускались на базе HTTPS по умолчанию и включали поддержку перенаправления HTTPS и HSTS.
Вызовите методы Listen или ListenUnixSocket из KestrelServerOptions, чтобы настроить префиксы URL-адресов и порты для Kestrel.
UseUrls, аргумент командной строки --urls, ключ конфигурации узла urls и переменная среды ASPNETCORE_URLS тоже работают, однако на них распространяются ограничения, указанные далее в этой статье (для конфигурации конечной точки HTTPS требуется сертификат по умолчанию).
Конфигурация KestrelServerOptions:
Настройка параметров конечной точки по умолчанию
ConfigureEndpointDefaults(Action<ListenOptions>) указывает конфигурацию Action для каждой указанной конечной точки. Повторные вызовы ConfigureEndpointDefaults приведут к тому, что предыдущие Action будут заменены последним указанным Action.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
});
Примечание.
К конечным точкам, созданным путем вызова Listenперед вызовом ConfigureEndpointDefaults, не будут применяться значения по умолчанию.
Configure(IConfiguration)
Позволяет Kestrel загружать конечные точки из IConfiguration. Для Kestrel конфигурация должна быть ограничена разделом конфигурации.
Перегрузку Configure(IConfiguration, bool) можно использовать для включения перезагрузки конечных точек при изменении источника конфигурации.
IHostBuilder.ConfigureWebHostDefaults по умолчанию вызывает Configure(context.Configuration.GetSection("Kestrel"), reloadOnChange: true), чтобы загрузить конфигурацию Kestrel и включить перезагрузку.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"Https": {
"Url": "https://localhost:5001"
}
}
}
}
Если включена перезагрузка конфигурации и сообщается об изменении, выполняются приведенные ниже действия.
- Новая конфигурация сравнивается со старой, все конечные точки без изменений конфигурации не изменяются.
- Для удаленных или измененных конечных точек выделяется 5 секунд для завершения обработки запросов и завершения работы.
- Запускаются новые или измененные конечные точки.
Клиенты, подключающиеся к измененной конечной точке, могут быть отключены или получить отказ в подключении при перезапуске конечной точки.
ConfigureHttpsDefaults
ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) указывает конфигурацию Action для каждой конечной точки HTTPS. Повторные вызовы ConfigureHttpsDefaults приведут к тому, что предыдущие Action будут заменены последним указанным Action.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
// certificate is an X509Certificate2
listenOptions.ServerCertificate = certificate;
});
});
Примечание.
К конечным точкам, созданным путем вызова Listenперед вызовом ConfigureHttpsDefaults, не будут применяться значения по умолчанию.
ListenOptions.UseHttps
Настройте Kestrel для использования протокола HTTPS.
Расширения ListenOptions.UseHttps:
-
UseHttps: настройте Kestrel для использования протокола HTTPS с сертификатом по умолчанию. Создает исключение, если сертификат по умолчанию не настроен. UseHttps(string fileName)UseHttps(string fileName, string password)UseHttps(string fileName, string password, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(StoreName storeName, string subject)UseHttps(StoreName storeName, string subject, bool allowInvalid)UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location)UseHttps(StoreName storeName, string subject, bool allowInvalid, StoreLocation location, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(X509Certificate2 serverCertificate)UseHttps(X509Certificate2 serverCertificate, Action<HttpsConnectionAdapterOptions> configureOptions)UseHttps(Action<HttpsConnectionAdapterOptions> configureOptions)
Параметры ListenOptions.UseHttps:
-
filename— это путь и имя файла сертификата, связанного с каталогом, где находятся файлы содержимого приложения. -
password— это пароль для доступа к данным сертификата X.509. -
configureOptions— этоActionдля настройкиHttpsConnectionAdapterOptions. ВозвращаетListenOptions. -
storeName— это хранилище сертификатов, из которого выполняется загрузка сертификата. -
subject— это имя субъекта для сертификата. -
allowInvalidуказывает, следует ли учитывать недопустимые сертификаты, например, самоподписанные сертификаты. -
location— это расположение хранилища, из которого загружается сертификат. -
serverCertificate— это сертификат X.509.
В рабочей среде необходимо явно настроить HTTPS. Как минимум необходимо указать сертификат по умолчанию.
Поддерживаемые конфигурации, описанные далее:
- Конфигурация отсутствует
- Замена сертификата по умолчанию из конфигурации
- Изменение значений по умолчанию в коде
Конфигурация отсутствует
Kestrel прослушивает порты http://localhost:5000 и https://localhost:5001 (если доступен сертификат по умолчанию).
Замена сертификата по умолчанию из конфигурации
Для Kestrel доступна схема конфигурации настроек приложения HTTPS по умолчанию. Настройте несколько конечных точек, включая URL-адреса и сертификаты для использования, либо из файла на диске, либо из хранилища сертификатов.
В следующем примере appsettings.json:
- Установите
AllowInvalidвtrue, чтобы разрешить использование недействительных сертификатов (например, самозаверяющих сертификатов). - Любая конечная точка HTTPS, которая не указывает сертификат (
HttpsDefaultCertв следующем примере), будет использовать сертификат, определенный в разделеCertificates:Default, или сертификат разработки.
{
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
},
"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertAndKeyFile": {
"Url": "https://localhost:5002",
"Certificate": {
"Path": "<path to .pem/.crt file>",
"KeyPath": "<path to .key file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"HttpsInlineCertStore": {
"Url": "https://localhost:5003",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},
"HttpsDefaultCert": {
"Url": "https://localhost:5004"
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Примечания к схеме.
- Имена конечных точек не зависят от регистра. Например,
HTTPSиHttpsявляются эквивалентными. - Параметр
Urlявляется обязательным для каждой конечной точки. Формат этого параметра такой же, как для параметра конфигурацииUrlsверхнего уровня, только он ограничен одиночным значением. - Эти конечные точки заменяют конечные точки, определенные в конфигурации
Urlsверхнего уровня, а не дополняют их. Конечные точки, определенные в коде черезListen, объединяются с конечными точками, определенными в разделе конфигурации. - Раздел
Certificateявляется необязательным. Если разделCertificateне указан, используются значения по умолчанию, определенные вCertificates:Default. Если значения по умолчанию недоступны, используется сертификат разработки. Если значений по умолчанию нет и сертификат разработки отсутствует, сервер выдаст исключение и не сможет запуститься. - Раздел
Certificateподдерживает несколько источников сертификатов. - В конфигурации можно определить любое количество конечных точек, если это не приводит к конфликту портов.
Источники сертификатов
Узлы сертификатов можно настроить для загрузки сертификатов из нескольких источников:
-
PathиPasswordдля загрузки файлов .pfx; -
Path,KeyPathиPasswordдля загрузки файлов .pem/.crt и .key; -
SubjectиStoreдля загрузки из хранилища сертификатов.
Например, Certificates:Default сертификат можно указать следующим образом:
"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; required>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
ConfigurationLoader
options.Configure(context.Configuration.GetSection("{SECTION}")) возвращает KestrelConfigurationLoader с методом .Endpoint(string name, listenOptions => { }), который может использоваться в качестве дополнения для параметров настроенной конечной точки:
webBuilder.UseKestrel((context, serverOptions) =>
{
serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
.Endpoint("HTTPS", listenOptions =>
{
listenOptions.HttpsOptions.SslProtocols = SslProtocols.Tls12;
});
});
Можно обратиться напрямую к KestrelServerOptions.ConfigurationLoader, чтобы и далее выполнять итерацию с существующим загрузчиком, например, предоставленным CreateDefaultBuilder.
- Раздел конфигурации для каждой конечной точки доступен в параметрах в методе
Endpoint, чтобы можно было прочитать пользовательские параметры. - Можно загрузить несколько конфигураций, снова вызвав
options.Configure(context.Configuration.GetSection("{SECTION}"))с другим разделом. Используется только последняя конфигурация, если явным образом не вызватьLoadв предыдущих экземплярах. Метапакет не вызываетLoad, чтобы можно было заменить его раздел конфигурации по умолчанию. -
KestrelConfigurationLoaderповторяет семейство APIListenизKestrelServerOptionsв виде перегрузокEndpoint, позволяя настраивать конечные точки кода и конфигурации в одном месте. Эти перегрузки не используют имена и используют только параметры по умолчанию из конфигурации.
Изменение значений по умолчанию в коде
Можно использовать ConfigureEndpointDefaults и ConfigureHttpsDefaults для изменения параметров по умолчанию для ListenOptions и HttpsConnectionAdapterOptions, включая переопределение сертификата по умолчанию, указанного в предыдущем сценарии. Необходимо вызвать ConfigureEndpointDefaults и ConfigureHttpsDefaults, прежде чем настраивать конечные точки.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureEndpointDefaults(listenOptions =>
{
// Configure endpoint defaults
});
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls12;
});
});
Настройка конечных точек посредством указания имени сервера
Можно использовать указание имени сервера (SNI) для размещения нескольких доменов в одном IP-адресе и порте. Для использования SNI клиент отправляет имя узла для безопасного сеанса серверу во время подтверждения TLS, чтобы сервер предоставил правильный сертификат. Клиент использует предоставленный сертификат для зашифрованного соединения с сервером во время безопасного сеанса, который следует после подтверждения TLS.
SNI можно настроить двумя способами:
- Создайте конечную точку в коде и выберите сертификат, используя имя узла с обратным вызовом ServerCertificateSelector.
- Настройте сопоставление имен узлов и параметров HTTPS в Конфигурация. Например, JSON в файле
appsettings.json.
SNI с ServerCertificateSelector
Kestrel поддерживает SNI через обратный вызов ServerCertificateSelector. Функция обратного вызова используется один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат. Приведенный ниже код обратного вызова можно использовать в вызове метода ConfigureWebHostDefaults файла Program.cs проекта:
// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var subExampleCert = CertificateLoader.LoadFromStoreCert(
"sub.example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var certs = new Dictionary<string, X509Certificate2>(StringComparer.OrdinalIgnoreCase)
{
{ "localhost", localhostCert },
{ "example.com", exampleCert },
{ "sub.example.com", subExampleCert },
};
httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name != null && certs.TryGetValue(name, out var cert))
{
return cert;
}
return exampleCert;
};
});
});
});
SNI с ServerOptionsSelectionCallback
Kestrel поддерживает дополнительную динамическую конфигурацию TLS через обратный вызов ServerOptionsSelectionCallback. Функция обратного вызова вызывается один раз за подключение, чтобы приложение проверило имя узла и выбрало соответствующий сертификат и конфигурацию TLS. Сертификаты по умолчанию и ConfigureHttpsDefaults не используются с этой функцией обратного вызова.
// using System.Security.Cryptography.X509Certificates;
// using Microsoft.AspNetCore.Server.Kestrel.Https;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5005, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
var localhostCert = CertificateLoader.LoadFromStoreCert(
"localhost", "My", StoreLocation.CurrentUser,
allowInvalid: true);
var exampleCert = CertificateLoader.LoadFromStoreCert(
"example.com", "My", StoreLocation.CurrentUser,
allowInvalid: true);
listenOptions.UseHttps((stream, clientHelloInfo, state, cancellationToken) =>
{
if (string.Equals(clientHelloInfo.ServerName, "localhost", StringComparison.OrdinalIgnoreCase))
{
return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
{
ServerCertificate = localhostCert,
// Different TLS requirements for this host
ClientCertificateRequired = true,
});
}
return new ValueTask<SslServerAuthenticationOptions>(new SslServerAuthenticationOptions
{
ServerCertificate = exampleCert,
});
}, state: null);
});
});
});
SNI в конфигурации
Kestrel поддерживает SNI, как определено в конфигурации. Конечную точку можно настроить с помощью объекта Sni, который содержит сопоставление имен узлов и параметров HTTPS. Имя узла подключения сопоставляется с параметрами, которые затем используются для этого подключения.
Следующая конфигурация добавляет конечную точку с именем MySniEndpoint, которая использует SNI для выбора параметров HTTPS на основе имени узла:
{
"Kestrel": {
"Endpoints": {
"MySniEndpoint": {
"Url": "https://*",
"SslProtocols": ["Tls11", "Tls12"],
"Sni": {
"a.example.org": {
"Protocols": "Http1AndHttp2",
"SslProtocols": ["Tls11", "Tls12", "Tls13"],
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; required>",
},
"ClientCertificateMode" : "NoCertificate"
},
"*.example.org": {
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
},
"*": {
// At least one subproperty needs to exist per SNI section or it
// cannot be discovered via IConfiguration
"Protocols": "Http1",
}
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Параметры HTTPS, которые можно переопределить с помощью SNI:
-
Certificateнастраивает источник сертификата. -
Protocolsнастраивает разрешенные протоколы HTTP. -
SslProtocolsнастраивает разрешенные протоколы SSL. -
ClientCertificateModeнастраивает требования к сертификату клиента.
Имя узла поддерживает сопоставление с подстановочными знаками:
- Точное соответствие. Например,
a.example.orgсоответствуетa.example.org. - Префикс подстановочного символа. Если имеется несколько совпадений с подстановочными знаками, выбирается самый длинный шаблон. Например,
*.example.orgсоответствуетb.example.orgиc.example.org. - Полный подстановочный знак.
*соответствует всему остальному, в том числе клиентам, которые не используют SNI и не отправляют имя хоста.
Соответствующая конфигурация SNI применяется к конечной точке подключения, переопределяя значения в этой конечной точке. Подключение будет отклонено, если оно не соответствует настроенному имени узла SNI.
Требования SNI
- Запуск на целевой платформе
netcoreapp2.1или более поздней версии. Приnet461или позже выполняется обратный вызов, ноnameвсегда равенnull.nameтакже имеет значениеnull, если клиент не предоставляет параметр имени узла при TLS рукопожатии. - Все веб-сайты выполняются на одном и том же экземпляре Kestrel. Kestrel не поддерживает совместное использование одного и того же IP-адреса и порта на нескольких экземплярах без обратного прокси.
Протоколы SSL/TLS
Протоколы SSL — это протоколы, используемые для шифрования и расшифровки трафика между двумя одноранговыми узлами, обычно клиентом и сервером.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.SslProtocols = SslProtocols.Tls13;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"SslProtocols": ["Tls12", "Tls13"],
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты разработки не следует использовать в продакшн или для тестирования.
Значение по умолчанию SslProtocols.None указывает Kestrel использовать параметры операционной системы по умолчанию для выбора оптимального протокола. Если вам не требуется по какой-либо причине выбрать определенный протокол, используйте значение по умолчанию.
Сертификаты клиента
ClientCertificateMode настраивает требования к сертификату клиента.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.ClientCertificateMode = ClientCertificateMode.AllowCertificate;
});
});
{
"Kestrel": {
"Endpoints": {
"MyHttpsEndpoint": {
"Url": "https://localhost:5001",
"ClientCertificateMode": "AllowCertificate",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "$CREDENTIAL_PLACEHOLDER$"
}
}
}
}
}
Предупреждение
В предыдущем примере пароли сертификатов хранятся в виде обычного текста в appsettings.json. Токен $CREDENTIAL_PLACEHOLDER$ используется в качестве заполнителя для пароля каждого сертификата. Сведения о безопасном хранении паролей сертификатов в средах разработки см. в статье Защита секретов в разработке. Сведения о безопасном хранении паролей сертификатов в рабочих средах см. в статье Поставщик конфигурации Azure Key Vault. Секреты, используемые для разработки, не следует использовать в производственной среде либо для тестирования.
По умолчанию используется значение ClientCertificateMode.NoCertificate, где Kestrel не будет запрашивать или требовать сертификат от клиента.
Дополнительные сведения см. в статье Настройка проверки подлинности по сертификату в ASP.NET Core.
Ведение журнала подключения
Вызовите UseConnectionLogging, чтобы выдать журналы уровня отладки для обмена данными на уровне байтов в рамках подключения. Ведение журнала подключения полезно для устранения неполадок, связанных с низкоуровневым взаимодействием, например при TLS-шифровании и работе за прокси-серверами. Если UseConnectionLogging поместить перед UseHttps, в журнале регистрируется зашифрованный трафик. Если UseConnectionLogging поместить после UseHttps, в журнале регистрируется расшифрованный трафик. Это встроенное промежуточное ПО.
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseConnectionLogging();
});
});
Привязка к TCP-сокету
Метод Listen выполняет привязку к TCP-сокету, а лямбда-выражение параметров позволяет настроить конфигурацию сертификата X.509:
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Loopback, 5000);
serverOptions.Listen(IPAddress.Loopback, 5001,
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testPassword");
});
})
.UseStartup<Startup>();
});
В этом примере настраивается HTTPS для конечной точки с помощью ListenOptions. С помощью этого API можно настроить и другие параметры Kestrel для отдельных конечных точек.
На Windows самозаверяющий сертификат можно создать с помощью командлета New-SelfSignedCertificate PowerShell. Неподдерживаемый пример см. в файле сертификата UpdateIISExpressSSLForChrome.ps1 на GitHub.
В macOS, Linux и Windows можно создавать сертификаты с помощью OpenSSL.
Привязка к сокету UNIX
Чтобы улучшить производительность Nginx, прослушивайте UNIX-сокет используя ListenUnixSocket, как показано в следующем примере:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock");
serverOptions.ListenUnixSocket("/tmp/kestrel-test.sock",
listenOptions =>
{
listenOptions.UseHttps("testCert.pfx",
"testpassword");
});
})
- В файле конфигурации Nginx установите для записи
server>location>proxy_passзначениеhttp://unix:/tmp/{KESTREL SOCKET}:/;.{KESTREL SOCKET}— это имя сокета, предоставленного для ListenUnixSocket (какkestrel-test.sockв предыдущем примере). - Убедитесь, что сокет доступен для записи Nginx (например,
chmod go+w /tmp/kestrel-test.sock).
Порт 0
Если указать номер порта 0, Kestrel будет динамически привязан к доступному порту. В следующем примере показано, как определить, к какому порту привязан Kestrel во время выполнения:
public void Configure(IApplicationBuilder app)
{
var serverAddressesFeature =
app.ServerFeatures.Get<IServerAddressesFeature>();
app.UseStaticFiles();
app.Run(async (context) =>
{
context.Response.ContentType = "text/html";
await context.Response
.WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" +
"<title></title></head><body><p>Hosted by Kestrel</p>");
if (serverAddressesFeature != null)
{
await context.Response
.WriteAsync("<p>Listening on the following addresses: " +
string.Join(", ", serverAddressesFeature.Addresses) +
"</p>");
}
await context.Response.WriteAsync("<p>Request URL: " +
$"{context.Request.GetDisplayUrl()}<p>");
});
}
Когда приложение выполняется, в выходных данных в окне консоли указывается динамический порт, по которому можно связаться с приложением:
Listening on the following addresses: http://127.0.0.1:48508
Ограничения
Настройте конечные точки с помощью следующих подходов:
- UseUrls
- Аргументы командной строки
--urls. - Ключ конфигурации узла
urls. - Переменная среды
ASPNETCORE_URLS.
Эти методы удобны, если нужно, чтобы код работал с серверами, отличающимися от Kestrel. Не забывайте о следующих ограничениях.
- С этими подходами нельзя использовать HTTPS, если в конфигурации конечной точки HTTPS не предоставлен сертификат по умолчанию (например, с помощью конфигурации
KestrelServerOptionsили файла конфигурации, как показано выше в этой статье). - Если подходы
ListenиUseUrlsиспользуются одновременно, конечные точкиListenпереопределяют конечные точкиUseUrls.
Конфигурация конечной точки IIS
При использовании IIS привязки URL-адресов для IIS задаются элементами Listen или UseUrls, которые переопределяют привязки. Дополнительные сведения см. в статье Модуль ASP.NET Core.
ListenOptions.Protocols
Свойство Protocols устанавливает протоколы HTTP (HttpProtocols), разрешенные для конечной точки подключения или для сервера. Присвойте значение свойству Protocols из перечисления HttpProtocols.
Значение перечисления HttpProtocols |
Допустимый протокол подключения |
|---|---|
Http1 |
Только HTTP/1.1. Можно использовать с протоколом TLS или без него. |
Http2 |
Только HTTP/2. Может использоваться без TLS только в том случае, если клиент поддерживает режим предварительного знания. |
Http1AndHttp2 |
HTTP/1.1 и HTTP/2. Для использования HTTP/2 требуется, чтобы клиент выбрал HTTP/2 в ходе согласования протокола уровня приложений (ALPN); в противном случае, по умолчанию используется HTTP/1.1. |
Значение ListenOptions.Protocols по умолчанию для любой конечной точки равно HttpProtocols.Http1AndHttp2.
Ограничения TLS для HTTP/2:
- TSL 1.2 или более поздней версии.
- Повторное согласование отключено.
- Сжатие отключено.
- Минимальные размеры эффемерного обмена ключами:
- эллиптическая кривая Диффи — Хелмана (ECDHE) [RFC4492]: не менее 224 бит;
- конечное поле Диффи — Хелмана (DHE) [
TLS12]: не менее 2048 бит;
- Набор шифров не запрещен.
По умолчанию поддерживается TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] с эллиптической кривой P-256 [FIPS186].
Следующий пример разрешает подключения HTTP/1.1 и HTTP/2 через порт 8000. Эти подключения шифруются по протоколу TLS с использованием предоставленного сертификата:
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
});
В Linux для фильтрации рукопожатий TLS для каждого соединения можно использовать CipherSuitesPolicy.
// using System.Net.Security;
// using Microsoft.AspNetCore.Hosting;
// using Microsoft.AspNetCore.Server.Kestrel.Core;
// using Microsoft.Extensions.DependencyInjection;
// using Microsoft.Extensions.Hosting;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(listenOptions =>
{
listenOptions.OnAuthenticate = (context, sslOptions) =>
{
sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(
new[]
{
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TlsCipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// ...
});
};
});
});
Промежуточное программное обеспечение подключения
При необходимости кастомное подключаемое промежуточное ПО может фильтровать рукопожатия TLS для каждого подключения на основе определенных шифров.
Следующий пример вызывает NotSupportedException для любого алгоритма шифрования, который не поддерживается приложением. Также можно определить и сравнить ITlsHandshakeFeature.CipherAlgorithm со списком приемлемых наборов шифров.
При использовании алгоритма шифрования CipherAlgorithmType.Null шифрование не используется.
// using System.Net;
// using Microsoft.AspNetCore.Connections;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.UseTlsFilter();
});
});
using System;
using System.Security.Authentication;
using Microsoft.AspNetCore.Connections.Features;
namespace Microsoft.AspNetCore.Connections
{
public static class TlsFilterConnectionMiddlewareExtensions
{
public static IConnectionBuilder UseTlsFilter(
this IConnectionBuilder builder)
{
return builder.Use((connection, next) =>
{
var tlsFeature = connection.Features.Get<ITlsHandshakeFeature>();
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException("Prohibited cipher: " +
tlsFeature.CipherAlgorithm);
}
return next();
});
}
}
}
Фильтрацию соединений также можно настроить с помощью лямбды IConnectionBuilder:
// using System;
// using System.Net;
// using System.Security.Authentication;
// using Microsoft.AspNetCore.Connections;
// using Microsoft.AspNetCore.Connections.Features;
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
listenOptions.Use((context, next) =>
{
var tlsFeature = context.Features.Get<ITlsHandshakeFeature>();
if (tlsFeature.CipherAlgorithm == CipherAlgorithmType.Null)
{
throw new NotSupportedException(
$"Prohibited cipher: {tlsFeature.CipherAlgorithm}");
}
return next();
});
});
});
Установка протокола HTTP из конфигурации
CreateDefaultBuilder по умолчанию вызывает serverOptions.Configure(context.Configuration.GetSection("Kestrel")), чтобы загрузить конфигурацию Kestrel.
В следующем примере appsettings.json для всех конечных точек устанавливается протокол подключения по умолчанию HTTP/1.1:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1"
}
}
}
В следующем примере appsettings.json для отдельной конечной точки устанавливается протокол подключения HTTP/1.1:
{
"Kestrel": {
"Endpoints": {
"HttpsDefaultCert": {
"Url": "https://localhost:5001",
"Protocols": "Http1"
}
}
}
}
Указанные в коде протоколы переопределяют значения, заданные в конфигурации.
Префиксы URL-адресов
Если вы используете UseUrls, аргумент командной строки --urls, ключ конфигурации узла urls или переменную среды ASPNETCORE_URLS, префиксы URL-адресов могут иметь любой из указанных ниже форматов.
Допустимы только префиксы URL-адресов HTTP.
Kestrel не поддерживает HTTP при настройке привязок URL-адресов с помощью UseUrls.
IPv4-адрес с номером порта
http://65.55.39.10:80/0.0.0.0является особым случаем, который связывается со всеми IPv4-адресами.IPv6-адрес с номером порта
http://[0:0:0:0:0:ffff:4137:270a]:80/[::]является IPv6-аналогом IPv4-адреса0.0.0.0.Имя узла с номером порта
http://contoso.com:80/ http://*:80/Имена узлов,
*и+, не имеют особого значения. Все, что не распознается как допустимый IP-адрес илиlocalhost, привязывается ко всем IP-адресам IPv4 и IPv6. Чтобы привязать разные имена узлов к разным приложениям ASP.NET Core по одному порту, используйте HTTP.sys или обратный прокси-сервер. В качестве обратного прокси-сервера можно использовать IIS, Nginx или Apache.Предупреждение
Для размещения в конфигурации обратного прокси-сервера требуется фильтрация хостов.
Имя узла
localhostс номером порта или локальный IP-адрес с номером портаhttp://localhost:5000/ http://127.0.0.1:5000/ http://[::1]:5000/Если указать
localhost, Kestrel попытается привязаться к интерфейсам обратной связи IPv4 и IPv6. Если запрошенный порт уже используется другой службой на одном из интерфейсов обратной связи, Kestrel не сможет запуститься. Если один из интерфейсов обратной петли недоступен по любой другой причине (чаще всего из-за отсутствия поддержки IPv6), Kestrel выдаст предупреждение.
ASP.NET Core