ASP.NET Core에서 Kestrel 웹 서버 구현Kestrel web server implementation in ASP.NET Core

작성자: Tom Dykstra, Chris RossStephen HalterBy Tom Dykstra, Chris Ross, and Stephen Halter

Kestrel은 ASP.NET Core의 플랫폼 간 웹 서버입니다.Kestrel is a cross-platform web server for ASP.NET Core. Kestrel은 기본적으로 ASP.NET Core 프로젝트 템플릿에 포함된 웹 서버입니다.Kestrel is the web server that's included by default in ASP.NET Core project templates.

Kestrel은 다음과 같은 기능을 지원합니다.Kestrel supports the following features:

  • HTTPSHTTPS
  • Websocket을 활성화하는 데 사용되는 불투명 업그레이드Opaque upgrade used to enable WebSockets
  • Nginx 뒤의 고성능을 위한 Unix 소켓Unix sockets for high performance behind Nginx

Kestrel은 .NET Core에서 지원하는 모든 플랫폼 및 버전에서 지원됩니다.Kestrel is supported on all platforms and versions that .NET Core supports.

예제 코드 살펴보기 및 다운로드(다운로드 방법)View or download sample code (how to download)

Kestrel을 역방향 프록시와 함께 사용하는 경우When to use Kestrel with a reverse proxy

Kestrel을 단독으로 사용하거나 IIS, Nginx 또는 Apache 같은 역방향 프록시 서버와 함께 사용할 수 있습니다.You can use Kestrel by itself or with a reverse proxy server, such as IIS, Nginx, or Apache. 역방향 프록시 서버는 인터넷에서 HTTP 요청을 수신하고 몇몇 사전 처리 후에 Kestrel에 전달합니다.A reverse proxy server receives HTTP requests from the Internet and forwards them to Kestrel after some preliminary handling.

Kestrel은 역방향 프록시 서버 없이 직접 인터넷과 통신합니다.

Kestrel은 IIS, Nginx 또는 Apache 같은 역방향 프록시 서버를 통해 간접적으로 인터넷과 통신합니다.

—역방향 프록시 서버의 유무에 상관없이— ASP.NET Core 2.0 이상 앱에 대해 지원되는 유효한 호스팅 구성입니다.Either configuration—with or without a reverse proxy server—is a valid and supported hosting configuration for ASP.NET Core 2.0 or later apps.

역방향 프록시 시나리오는 동일한 IP 및 단일 서버에서 실행되는 포트를 공유하는 여러 앱이 있는 경우에 존재합니다.A reverse proxy scenario exists when there are multiple apps that share the same IP and port running on a single server. Kestrel은 여러 프로세스 간에 동일한 IP 및 포트 공유를 지원하지 않으므로 이 시나리오를 지원하지 않습니다.Kestrel doesn't support this scenario because Kestrel doesn't support sharing the same IP and port among multiple processes. Kestrel이 포트에서 수신 대기하도록 구성된 경우 Kestrel은 요청의 호스트 헤더에 관계 없이 해당 포트에 대한 모든 트래픽을 처리합니다.When Kestrel is configured to listen on a port, Kestrel handles all of the traffic for that port regardless of requests' host header. 포트를 공유할 수 있는 역방향 프록시는 고유 IP 및 포트에서 Kestrel에 요청을 전달할 수 있습니다.A reverse proxy that can share ports has the ability to forward requests to Kestrel on a unique IP and port.

역방향 프록시 서버가 필요하지 않은 경우에도 역방향 프록시 서버를 사용하는 것은 적합한 선택일 수 있습니다.Even if a reverse proxy server isn't required, using a reverse proxy server might be a good choice:

  • 호스트하는 앱의 공개된 공용 노출 영역을 제한할 수 있습니다.It can limit the exposed public surface area of the apps that it hosts.
  • 구성 및 방어의 추가 계층을 제공합니다.It provides an additional layer of configuration and defense.
  • 기존 인프라와 잘 통합될 수 있습니다.It might integrate better with existing infrastructure.
  • 부하 분산 및 SSL 구성을 간소화합니다.It simplifies load balancing and SSL configuration. 역방향 프록시 서버에 SSL 인증서가 필요한 경우에만 해당 서버는 일반 HTTP를 사용하여 내부 네트워크에서 앱 서버와 통신할 수 있습니다.Only the reverse proxy server requires an SSL certificate, and that server can communicate with your app servers on the internal network using plain HTTP.

경고

호스트 필터링을 사용하도록 설정된 역방향 프록시를 사용하지 않는 경우 호스트 필터링을 사용하도록 설정해야 합니다.If not using a reverse proxy with host filtering enabled, host filtering must be enabled.

ASP.NET Core 앱에서 Kestrel을 사용하는 방법How to use Kestrel in ASP.NET Core apps

Microsoft.AspNetCore.Server.Kestrel 패키지는 Microsoft.AspNetCore.App 메타패키지(ASP.NET Core 2.1 이상)에 포함되어 있습니다.The Microsoft.AspNetCore.Server.Kestrel package is included in the [Microsoft.AspNetCore.App metapackage] (xref:fundamentals/metapackage-app) (ASP.NET Core 2.1 or later).

ASP.NET Core 프로젝트 템플릿은 기본적으로 Kestrel을 사용합니다.ASP.NET Core project templates use Kestrel by default. Program.cs에서 템플릿 코드는 UseKestrel 숨은 기능을 호출하는 CreateDefaultBuilder를 호출합니다.In Program.cs, the template code calls CreateDefaultBuilder, which calls UseKestrel behind the scenes.

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>();

Kestrel 옵션Kestrel options

Kestrel 웹 서버에는 인터넷 연결 배포에 특히 유용한 제약 조건 구성 옵션이 있습니다.The Kestrel web server has constraint configuration options that are especially useful in Internet-facing deployments. 사용자 지정될 수 있는 몇 가지 중요 한 제한입니다.A few important limits that can be customized:

  • 최대 클라이언트 연결Maximum client connections
  • 최대 요청 본문 크기Maximum request body size
  • 최소 요청 본문 데이터 속도Minimum request body data rate

KestrelServerOptions 클래스의 한도 속성에서 이러한 제약 조건 및 기타 제약 조건을 설정합니다.Set these and other constraints on the Limits property of the KestrelServerOptions class. Limits 속성은 KestrelServerLimits 클래스의 인스턴스를 보유합니다.The Limits property holds an instance of the KestrelServerLimits class.

최대 클라이언트 연결Maximum client connections

MaxConcurrentConnectionsMaxConcurrentConnections
MaxConcurrentUpgradedConnectionsMaxConcurrentUpgradedConnections

다음 코드를 사용하여 전체 앱에 대한 동시 개방 TCP 연결의 최대 수를 설정할 수 있습니다.The maximum number of concurrent open TCP connections can be set for the entire app with the following code:

.UseKestrel(options =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

HTTP 또는 HTTPS에서 다른 프로토콜(예: WebSocket 요청에서)로 업그레이드된 연결에 대한 별도 제한이 있습니다.There's a separate limit for connections that have been upgraded from HTTP or HTTPS to another protocol (for example, on a WebSockets request). 연결이 업그레이드된 후 MaxConcurrentConnections 제한에 대해 계산되지 않습니다.After a connection is upgraded, it isn't counted against the MaxConcurrentConnections limit.

.UseKestrel(options =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

연결의 최대 수는 기본적으로 무제한(null)입니다.The maximum number of connections is unlimited (null) by default.

최대 요청 본문 크기Maximum request body size

MaxRequestBodySizeMaxRequestBodySize

기본 최대 요청 본문 크기는 약 28.6MB인 30,000,000바이트입니다.The default maximum request body size is 30,000,000 bytes, which is approximately 28.6 MB.

ASP.NET Core MVC 앱에서 한도를 재정의할 때는 작업 메서드에서 RequestSizeLimit 특성을 사용하는 방법이 좋습니다.The recommended approach to override the limit in an ASP.NET Core MVC app is to use the RequestSizeLimit attribute on an action method:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

다음 예제는 모든 요청에서 앱에 대한 제약 조건을 구성하는 방법을 보여 줍니다.Here's an example that shows how to configure the constraint for the app on every request:

.UseKestrel(options =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

미들웨어에서 특정 요청에 대한 설정을 재정의할 수 있습니다.You can override the setting on a specific request in middleware:

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;
    context.Features.Get<IHttpMinRequestBodyDataRateFeature>()
        .MinDataRate = new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    context.Features.Get<IHttpMinResponseDataRateFeature>()
        .MinDataRate = new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));

앱에서 요청을 읽기 시작한 후 요청에 대한 제한을 구성하려고 하면 예외가 throw됩니다.An exception is thrown if you attempt to configure the limit on a request after the app has started to read the request. MaxRequestBodySize 속성이 제한을 구성하기에 너무 늦은, 읽기 전용 상태인지를 알려주는 IsReadOnly 속성이 있습니다.There's an IsReadOnly property that indicates if the MaxRequestBodySize property is in read-only state, meaning it's too late to configure the limit.

최소 요청 본문 데이터 속도Minimum request body data rate

MinRequestBodyDataRateMinRequestBodyDataRate
MinResponseDataRateMinResponseDataRate

Kestrel은 데이터가 지정된 속도(바이트/초)로 도착하는지 1초마다 확인합니다.Kestrel checks every second if data is arriving at the specified rate in bytes/second. 속도가 최소 아래로 떨어지면 연결이 시간 초과됩니다. 유예 기간은 Kestrel에서 해당 전송 속도를 최소로 높이기 위해 클라이언트에 제공하는 총 시간입니다. 이 시간 동안 속도는 확인되지 않습니다.If the rate drops below the minimum, the connection is timed out. The grace period is the amount of time that Kestrel gives the client to increase its send rate up to the minimum; the rate isn't checked during that time. 유예 기간은 TCP 느린 시작으로 인해 느린 속도로 처음에 데이터를 보내는 연결 중단을 방지하는 데 도움이 됩니다.The grace period helps avoid dropping connections that are initially sending data at a slow rate due to TCP slow-start.

기본 최소 속도는 5초의 유예 기간으로 240바이트/초입니다.The default minimum rate is 240 bytes/second with a 5 second grace period.

최소 속도는 응답에도 적용됩니다.A minimum rate also applies to the response. 요청 제한 및 응답 제한을 설정하는 코드는 속성 및 인터페이스 이름에 RequestBody 또는 Response를 갖는 것을 제외하고 동일합니다.The code to set the request limit and the response limit is the same except for having RequestBody or Response in the property and interface names.

Program.cs에서 최소 데이터 속도를 구성하는 방법을 보여 주는 예제는 다음과 같습니다.Here's an example that shows how to configure the minimum data rates in Program.cs:

.UseKestrel(options =>
{
    options.Limits.MaxConcurrentConnections = 100;
    options.Limits.MaxConcurrentUpgradedConnections = 100;
    options.Limits.MaxRequestBodySize = 10 * 1024;
    options.Limits.MinRequestBodyDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Limits.MinResponseDataRate =
        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
    options.Listen(IPAddress.Loopback, 5000);
    options.Listen(IPAddress.Loopback, 5001, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

미들웨어에서 요청별 속도를 구성할 수 있습니다.You can configure the rates per request in middleware:

app.Run(async (context) =>
{
    context.Features.Get<IHttpMaxRequestBodySizeFeature>()
        .MaxRequestBodySize = 10 * 1024;
    context.Features.Get<IHttpMinRequestBodyDataRateFeature>()
        .MinDataRate = new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));
    context.Features.Get<IHttpMinResponseDataRateFeature>()
        .MinDataRate = new MinDataRate(bytesPerSecond: 100, 
            gracePeriod: TimeSpan.FromSeconds(10));

다른 Kestrel 옵션 및 제한에 대한 내용은 다음을 참조하세요.For information about other Kestrel options and limits, see:

엔드포인트 구성Endpoint configuration

기본적으로 ASP.NET Core는 http://localhost:5000으로 바인딩합니다.By default, ASP.NET Core binds to http://localhost:5000. Kestrel에 대한 URL 접두사 및 포트를 구성하려면 KestrelServerOptions에 대한 ListenUnixSocket 메서드 또는 수신 대기를 호출합니다.Call Listen or ListenUnixSocket methods on KestrelServerOptions to configure URL prefixes and ports for Kestrel. UseUrls, --urls 명령줄 인수 urls 호스트 구성 키 및 ASPNETCORE_URLS 환경 변수도 작동하지만 이 섹션의 뒷부분에 명시된 제한 사항이 있습니다.UseUrls, the --urls command-line argument, urls host configuration key, and the ASPNETCORE_URLS environment variable also work but have the limitations noted later in this section.

urls 호스트 구성 키는 앱 구성이 아닌 호스트 구성에서 와야 합니다.The urls host configuration key must come from the host configuration, not the app configuration. urls 키와 값을 appsettings.json에 추가하는 것은 구성 파일에서 구성을 읽을 때면 호스트가 완전히 초기화되기 때문에 호스트 구성에 영향을 주지 않습니다.Adding a urls key and value to appsettings.json doesn't affect host configuration because the host is completely initialized by the time the configuration is read from the configuration file. 그러나 호스트를 구성하려면 호스트 작성기에서 UseConfiguration을 통해 appsettings.json에서 urls 키를 사용할 수 있습니다.However, a urls key in appsettings.json can be used with UseConfiguration on the host builder to configure the host:

var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appSettings.json", optional: true, reloadOnChange: true)
.Build();

var host = new WebHostBuilder()
.UseKestrel()
.UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();

기본적으로 ASP.NET Core는 다음으로 바인딩합니다.By default, ASP.NET Core binds to:

  • http://localhost:5000
  • https://localhost:5001 (로컬 개발 인증서가 제공되는 경우)https://localhost:5001 (when a local development certificate is present)

개발 인증서를 만듭니다.A development certificate is created:

일부 브라우저에서 로컬 개발 인증서를 신뢰하도록 브라우저에 명시적 사용 권한을 부여할 것을 요구합니다.Some browsers require that you grant explicit permission to the browser to trust the local development certificate.

ASP.NET Core 2.1 이상 프로젝트 템플릿은 기본적으로 HTTPS에서 실행할 앱을 구성하고 HTTPS 리디렉션 및 HSTS 지원을 포함합니다.ASP.NET Core 2.1 and later project templates configure apps to run on HTTPS by default and include HTTPS redirection and HSTS support.

Kestrel에 대한 URL 접두사 및 포트를 구성하려면 KestrelServerOptions에 대한 ListenUnixSocket 메서드 또는 수신 대기를 호출합니다.Call Listen or ListenUnixSocket methods on KestrelServerOptions to configure URL prefixes and ports for Kestrel.

UseUrls, --urls 명령줄 인수 urls 호스트 구성 키 및 ASPNETCORE_URLS 환경 변수도 작동하지만 이 섹션의 뒷부분에 명시된 제한 사항이 있습니다(HTTPS 엔드포인트 구성에 대해 기본 인증서를 사용할 수 있어야 합니다).UseUrls, the --urls command-line argument, urls host configuration key, and the ASPNETCORE_URLS environment variable also work but have the limitations noted later in this section (a default certificate must be available for HTTPS endpoint configuration).

ASP.NET Core 2.1 KestrelServerOptions 구성:ASP.NET Core 2.1 KestrelServerOptions configuration:

ConfigureEndpointDefaults(Action<ListenOptions>)ConfigureEndpointDefaults(Action<ListenOptions>)
지정된 각 엔드포인트에 대해 실행할 구성 Action을 지정합니다.Specifies a configuration Action to run for each specified endpoint. ConfigureEndpointDefaults의 여러 차례 호출은 Action에 앞서 마지막으로 지정된 Action으로 바꿉니다.Calling ConfigureEndpointDefaults multiple times replaces prior Actions with the last Action specified.

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>)
각 HTTPS 엔드포인트에 대해 실행할 구성 Action을 지정합니다.Specifies a configuration Action to run for each HTTPS endpoint. ConfigureHttpsDefaults의 여러 차례 호출은 Action에 앞서 마지막으로 지정된 Action으로 바꿉니다.Calling ConfigureHttpsDefaults multiple times replaces prior Actions with the last Action specified.

Configure(IConfiguration)Configure(IConfiguration)
입력으로 IConfiguration을 받아들이는 Kestrel를 설정하기 위한 구성 로더를 만듭니다.Creates a configuration loader for setting up Kestrel that takes an IConfiguration as input. 구성은 Kestrel용 구성 섹션에 대해 범위를 지정해야 합니다.The configuration must be scoped to the configuration section for Kestrel.

ListenOptions.UseHttpsListenOptions.UseHttps
HTTPS를 사용하려면 Kestrel을 구성합니다.Configure Kestrel to use HTTPS.

ListenOptions.UseHttps 확장:ListenOptions.UseHttps extensions:

  • UseHttps – 기본 인증서를 통해 HTTPS를 사용하려면 Kestrel 구성합니다.UseHttps – Configure Kestrel to use HTTPS with the default certificate. 기본 인증서가 구성되지 않은 경우 예외를 throw합니다.Throws an exception if no default certificate is configured.
  • 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 매개 변수:ListenOptions.UseHttps parameters:

  • filename은 앱의 콘텐츠 파일을 포함하는 디렉터리와 관련된 인증서 파일의 경로 및 파일 이름입니다.filename is the path and file name of a certificate file, relative to the directory that contains the app's content files.
  • password은 X.509 인증서 데이터에 액세스하는 데 필요한 암호입니다.password is the password required to access the X.509 certificate data.
  • configureOptionsHttpsConnectionAdapterOptions를 구성하는 Action입니다.configureOptions is an Action to configure the HttpsConnectionAdapterOptions. ListenOptions를 반환합니다.Returns the ListenOptions.
  • storeName은 인증서를 로드할 수 있는 인증서 저장소입니다.storeName is the certificate store from which to load the certificate.
  • subject은 인증서의 주체 이름입니다.subject is the subject name for the certificate.
  • allowInvalid은 자체 서명된 인증서와 같이 잘못된 인증서를 고려해야 할 경우를 나타냅니다.allowInvalid indicates if invalid certificates should be considered, such as self-signed certificates.
  • location은 인증서를 로드할 수 있는 저장소 위치입니다.location is the store location to load the certificate from.
  • serverCertificate은 X.509 인증서입니다.serverCertificate is the X.509 certificate.

프로덕션 내에 HTTPS가 명시적으로 구성되어야 합니다.In production, HTTPS must be explicitly configured. 최소한 기본 인증서를 제공해야 합니다.At a minimum, a default certificate must be provided.

다음에 설명된 지원되는 구성입니다.Supported configurations described next:

  • 구성 없음No configuration
  • 구성에서 기본 인증서를 바꿈Replace the default certificate from configuration
  • 코드에서 기본값 변경Change the defaults in code

구성 없음No configuration

Kestrel은 http://localhost:5000https://localhost:5001에서 수신 대기합니다(기본 인증서가 사용 가능한 경우).Kestrel listens on http://localhost:5000 and https://localhost:5001 (if a default cert is available).

다음을 사용하여 URL을 지정합니다.Specify URLs using the:

  • ASPNETCORE_URLS 환경 변수.ASPNETCORE_URLS environment variable.
  • --urls 명령줄 인수.--urls command-line argument.
  • urls 호스트 구성 키.urls host configuration key.
  • UseUrls 확장명 메서드.UseUrls extension method.

자세한 내용은 서버 URL구성 재정의를 참조합니다.For more information, see Server URLs and Override configuration.

이러한 접근 방식을 사용하여 제공된 값은 하나 이상의 HTTP 및 HTTPS 엔드포인트(기본 인증서가 사용 가능한 경우의 HTTPS)일 수 있습니다.The value provided using these approaches can be one or more HTTP and HTTPS endpoints (HTTPS if a default cert is available). 값을 세미콜론으로 구분된 목록으로 구성합니다(예를 들어, "Urls": "http://localhost:8000;http://localhost:8001").Configure the value as a semicolon-separated list (for example, "Urls": "http://localhost:8000;http://localhost:8001").

구성에서 기본 인증서를 바꿈Replace the default certificate from configuration

WebHost.CreateDefaultBuilder는 Kestrel 구성을 로드하려면 기본적으로 serverOptions.Configure(context.Configuration.GetSection("Kestrel"))을 호출합니다.WebHost.CreateDefaultBuilder calls serverOptions.Configure(context.Configuration.GetSection("Kestrel")) by default to load Kestrel configuration. 기본 HTTPS 앱 설정 구성 스키마는 Kestrel에 대해 사용 가능합니다.A default HTTPS app settings configuration schema is available for Kestrel. 디스크 상의 파일에서 또는 인증서 저장소에서 사용할 인증서 및 URL을 포함하여 여러 엔드포인트를 구성합니다.Configure multiple endpoints, including the URLs and the certificates to use, either from a file on disk or from a certificate store.

다음 appsettings.json 예제에서:In the following appsettings.json example:

  • 잘못된 인증서 사용을 허가하려면 AllowInvalidtrue으로 설정합니다(예를 들어, 자체 서명된 인증서).Set AllowInvalid to true to permit the use of invalid certificates (for example, self-signed certificates).
  • 인증서를 지정하지 않는 모든 HTTPS 엔드포인트(다음 예제에서 HttpsDefaultCert)는 인증서 > 기본에서 정의된 인증서 또는 개발 인증서로 대체합니다.Any HTTPS endpoint that doesn't specify a certificate (HttpsDefaultCert in the example that follows) falls back to the cert defined under Certificates > Default or the development certificate.
{
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://localhost:5000"
},

"HttpsInlineCertFile": {
"Url": "https://localhost:5001",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
},

"HttpsInlineCertStore": {
"Url": "https://localhost:5002",
"Certificate": {
"Subject": "<subject; required>",
"Store": "<certificate store; defaults to My>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}
},

"HttpsDefaultCert": {
"Url": "https://localhost:5003"
},

"Https": {
"Url": "https://*:5004",
"Certificate": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
},
"Certificates": {
"Default": {
"Path": "<path to .pfx file>",
"Password": "<certificate password>"
}
}
}
}

모든 인증서 노드에 대해 경로암호를 사용하는 대신 인증서 저장소 필드를 지정합니다.An alternative to using Path and Password for any certificate node is to specify the certificate using certificate store fields. 예를 들어, 인증서 > 기본 인증서는 다음과 같이 지정될 수 있습니다.For example, the Certificates > Default certificate can be specified as:

"Default": {
"Subject": "<subject; required>",
"Store": "<cert store; defaults to My>",
"Location": "<location; defaults to CurrentUser>",
"AllowInvalid": "<true or false; defaults to false>"
}

스키마 참고 사항:Schema notes:

  • 엔드포인트 이름은 대/소문자를 구분하지 않습니다.Endpoints names are case-insensitive. 예를 들어, HTTPSHttps는 유효합니다.For example, HTTPS and Https are valid.
  • Url 매개 변수는 각 엔드포인트에 대해 필요합니다.The Url parameter is required for each endpoint. 이 매개 변수에 대한 형식은 단일 값으로 제한된 경우를 제외하고 최상위 Urls 구성 매개 변수와 동일합니다.The format for this parameter is the same as the top-level Urls configuration parameter except that it's limited to a single value.
  • 이러한 엔드포인트는 추가하기보다는 최상위 Urls 구성에서 정의된 엔드포인트를 바꿉니다.These endpoints replace those defined in the top-level Urls configuration rather than adding to them. Listen을 통해 코드에서 정의된 엔드포인트는 구성 섹션에서 정의된 엔드포인트로 누적됩니다.Endpoints defined in code via Listen are cumulative with the endpoints defined in the configuration section.
  • Certificate 섹션은 선택 사항입니다.The Certificate section is optional. Certificate 섹션이 지정되지 않은 경우 이전 시나리오에서 정의된 기본값이 사용됩니다.If the Certificate section isn't specified, the defaults defined in earlier scenarios are used. 기본값이 사용 가능하지 않은 경우 서버는 예외를 throw하고 시작되지 않습니다.If no defaults are available, the server throws an exception and fails to start.
  • Certificate 섹션은 경로암호주체저장소 인증서 모두를 지원합니다.The Certificate section supports both PathPassword and SubjectStore certificates.
  • 많은 엔드포인트가 포트 충돌을 일으키지 않는 한 이런 방식으로 정의될 수 있습니다.Any number of endpoints may be defined in this way so long as they don't cause port conflicts.
  • serverOptions.Configure(context.Configuration.GetSection("Kestrel"))은 구성된 엔드포인트의 설정을 보완하는 데 사용될 수 있는 .Endpoint(string name, options => { }) 메서드를 통해 KestrelConfigurationLoader를 반환합니다.serverOptions.Configure(context.Configuration.GetSection("Kestrel")) returns a KestrelConfigurationLoader with an .Endpoint(string name, options => { }) method that can be used to supplement a configured endpoint's settings:
serverOptions.Configure(context.Configuration.GetSection("Kestrel"))
.Endpoint("HTTPS", opt =>
{
opt.HttpsOptions.SslProtocols = SslProtocols.Tls12;
});

또한 KestrelServerOptions.ConfigurationLoader에 직접 액세스하여 WebHost.CreateDefaultBuilder에서 제공한 로더와 같이 기존 로더에서 반복을 유지할 수 있습니다.You can also directly access KestrelServerOptions.ConfigurationLoader to keep iterating on the existing loader, such as the one provided by WebHost.CreateDefaultBuilder.

  • 각 엔드포인트에 대한 구성 섹션은 Endpoint 메서드의 옵션에서 사용 가능하므로 사용자 지정 설정을 읽을 수 있습니다.The configuration section for each endpoint is a available on the options in the Endpoint method so that custom settings may be read.
  • 여러 구성은 다른 섹션을 통해 다시 serverOptions.Configure(context.Configuration.GetSection("Kestrel"))을 호출하여 로드할 수 있습니다.Multiple configurations may be loaded by calling serverOptions.Configure(context.Configuration.GetSection("Kestrel")) again with another section. Load은 이전 인스턴스에서 명시적으로 호출되지 않는 한 마지막 구성만 사용됩니다.Only the last configuration is used, unless Load is explicitly called on prior instances. 메타패키지는 Load을 호출하지 않으므로 기본 구성 섹션을 바꿀 수 있습니다.The metapackage doesn't call Load so that its default configuration section may be replaced.
  • KestrelConfigurationLoaderKestrelServerOptions에서 Endpoint 오버로드로 Listen API 제품군을 미러링하므로 코드 및 구성 엔드포인트를 동일 장소에서 구성할 수 있습니다.KestrelConfigurationLoader mirrors the Listen family of APIs from KestrelServerOptions as Endpoint overloads, so code and config endpoints may be configured in the same place. 이러한 오버로드는 이름을 사용하지 않고 구성에서 기본 설정만 사용합니다.These overloads don't use names and only consume default settings from configuration.

코드에서 기본값 변경Change the defaults in code

ConfigureEndpointDefaultsConfigureHttpsDefaults는 이전 시나리오에서 지정된 기본 인증서 재정의를 포함한 ListenOptionsHttpsConnectionAdapterOptions에 대해 기본 설정을 변경하는 데 사용될 수 있습니다.ConfigureEndpointDefaults and ConfigureHttpsDefaults can be used to change default settings for ListenOptions and HttpsConnectionAdapterOptions, including overriding the default certificate specified in the prior scenario. ConfigureEndpointDefaultsConfigureHttpsDefaults는 모든 엔드포인트가 구성되기 전에 호출해야 합니다.ConfigureEndpointDefaults and ConfigureHttpsDefaults should be called before any endpoints are configured.

options.ConfigureEndpointDefaults(opt =>
{
opt.NoDelay = true;
});

options.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.SslProtocols = SslProtocols.Tls12;
});

SNI에 대한 Kestrel 지원Kestrel support for SNI

서버 이름 표시(SNI)는 동일한 IP 주소 및 포트에서 여러 도메인을 호스트하는 데 사용될 수 있습니다.Server Name Indication (SNI) can be used to host multiple domains on the same IP address and port. 함수에 대한 SNI의 경우 클라이언트는 TLS 핸드셰이크 동안 보안 세션에 대한 호스트 이름을 서버로 보내므로 서버에서 올바른 인증서를 제공할 수 있습니다.For SNI to function, the client sends the host name for the secure session to the server during the TLS handshake so that the server can provide the correct certificate. TLS 핸드셰이크 다음에 오는 보안 세션 동안 클라이언트는 서버와 암호화된 통신을 위해 제공된 인증서를 사용합니다.The client uses the furnished certificate for encrypted communication with the server during the secure session that follows the TLS handshake.

Kestrel은 ServerCertificateSelector 콜백을 통해 SNI를 지원합니다.Kestrel supports SNI via the ServerCertificateSelector callback. 앱이 호스트 이름을 검사하고 적절한 인증서를 선택하도록 허용하려면 연결당 한 번씩 콜백이 호출됩니다.The callback is invoked once per connection to allow the app to inspect the host name and select the appropriate certificate.

SNI 지원에는 다음 항목이 필요합니다.SNI support requires:

  • 대상 프레임워크 netcoreapp2.1에서 실행합니다.Running on target framework netcoreapp2.1. netcoreapp2.0net461에서 콜백이 호출되지만 name 은 항상 null입니다.On netcoreapp2.0 and net461, the callback is invoked but the name is always null. 클라이언트가 TLS 핸드셰이크에서 호스트 이름 매개 변수를 제공하지 않는 경우 name은 또한 null입니다.The name is also null if the client doesn't provide the host name parameter in the TLS handshake.
  • 모든 웹 사이트는 동일한 Kestrel 인스턴스에서 실행합니다.All websites run on the same Kestrel instance. Kestrel은 역방향 프록시 없이 여러 인스턴스에서 IP 주소와 포트를 공유하도록 지원하지 않습니다.Kestrel doesn't support sharing an IP address and port across multiple instances without a reverse proxy.
WebHost.CreateDefaultBuilder()
.UseKestrel((context, options) =>
{
options.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(StringComparer.OrdinalIgnoreCase);
certs["localhost"] = localhostCert;
certs["example.com"] = exampleCert;
certs["sub.example.com"] = subExampleCert;

httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
{
if (name != null && certs.TryGetValue(name, out var cert))
{
return cert;
}

return exampleCert;
};
});
});
});

TCP 소켓에 바인딩Bind to a TCP socket

수신 대기 메서드는 TCP 소켓에 바인딩하고 옵션 람다는 SSL 인증서 구성을 허용합니다.The Listen method binds to a TCP socket, and an options lambda permits SSL certificate configuration:

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(options =>
        {
            options.Listen(IPAddress.Loopback, 8000);
            options.Listen(IPAddress.Loopback, 8001, listenOptions =>
            {
                listenOptions.UseHttps("testCert.pfx", "testPassword");
            });
        });

예제에서는 ListenOptions를 사용하여 끝점에 대한 SSL을 구성합니다.The example configures SSL for an endpoint with ListenOptions. 동일한 API를 사용하여 특정 엔드포인트에 대한 다른 Kestrel 설정을 구성합니다.Use the same API to configure other Kestrel settings for specific endpoints.

Windows에서 자체 서명된 인증서는 New-SelfSignedCertificate PowerShell cmdlet을 사용하여 만들 수 있습니다. 지원되지 않는 예는 UpdateIISExpressSSLForChrome.ps1을 참조하세요.

macOS, Linux 및 Windows에서는 OpenSSL을 사용하여 인증서를 만들 수 있습니다.

Unix 소켓에 바인딩Bind to a Unix socket

이 예제에 나와 있는 것처럼 Nginx를 사용하여 향상된 성능을 위해 ListenUnixSocket을 통해 Unix 소켓을 수신 대기합니다.Listen on a Unix socket with ListenUnixSocket for improved performance with Nginx, as shown in this example:

.UseKestrel(options =>
{
    options.ListenUnixSocket("/tmp/kestrel-test.sock");
    options.ListenUnixSocket("/tmp/kestrel-test.sock", listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testpassword");
    });
});

포트 0Port 0

포트 번호 0가 지정되는 경우 Kestrel은 동적으로 사용 가능한 포트에 바인딩합니다.When the port number 0 is specified, Kestrel dynamically binds to an available port. 다음 예제에서는 Kestrel이 실제로 런타임에 바인딩한 포트를 확인하는 방법을 보여 줍니다.The following example shows how to determine which port Kestrel actually bound at runtime:

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>");
    });
}

앱이 실행되는 경우 콘솔 창 출력은 앱이 연결될 수 있는 동적 포트를 나타냅니다.When the app is run, the console window output indicates the dynamic port where the app can be reached:

Listening on the following addresses: http://127.0.0.1:48508

UseUrls, --urls 명령 줄 인수, urls 호스트 구성 키 및 ASPNETCORE_URLS 환경 변수 제한 사항UseUrls, --urls command-line argument, urls host configuration key, and ASPNETCORE_URLS environment variable limitations

다음 방법으로 엔트포인트를 구성합니다.Configure endpoints with the following approaches:

  • UseUrlsUseUrls
  • --urls 명령줄 인수--urls command-line argument
  • urls 호스트 구성 키urls host configuration key
  • ASPNETCORE_URLS환경 변수ASPNETCORE_URLS environment variable

이러한 메서드는 코드를 Kestrel이 아닌 서버와 작동하도록 하려는 경우 유용합니다.These methods are useful for making code work with servers other than Kestrel. 그러나 이러한 제한 사항을 고려해야 합니다.However, be aware of these limitations:

  • HTTPS 끝점 구성에서 기본 인증서를 제공하지 않는 한 이러한 방법으로는 SSL을 사용할 수 없습니다(예: 이 항목의 앞부분에 표시된 것처럼 KestrelServerOptions 구성 또는 구성 파일 사용).SSL can't be used with these approaches unless a default certificate is provided in the HTTPS endpoint configuration (for example, using KestrelServerOptions configuration or a configuration file as shown earlier in this topic).
  • ListenUseUrls 방식 모두를 동시에 사용할 경우 Listen 엔드포인트는 UseUrls 엔드포인트를 재정의합니다.When both the Listen and UseUrls approaches are used simultaneously, the Listen endpoints override the UseUrls endpoints.

IIS 엔드포인트 구성IIS endpoint configuration

IIS를 사용하는 경우 IIS 재정의 바인딩에 대한 URL 바인딩은 Listen 또는 UseUrls에 의해 설정됩니다.When using IIS, the URL bindings for IIS override bindings are set by either Listen or UseUrls. 자세한 내용은 ASP.NET Core 모듈 항목을 참조하세요.For more information, see the ASP.NET Core Module topic.

전송 구성Transport configuration

ASP.NET Core 2.1 릴리스에서 Kestrel의 기본 전송은 더 이상 Libuv에 기반하지 않으며 대신 관리 소켓에 기반합니다.With the release of ASP.NET Core 2.1, Kestrel's default transport is no longer based on Libuv but instead based on managed sockets. WebHostBuilderLibuvExtensions.UseLibuv를 호출하고 다음 패키지 중 하나를 사용하는 2.1로 업그레이드된 ASP.NET Core 2.0 앱의 주요 변경 내용입니다.This is a breaking change for ASP.NET Core 2.0 apps upgrading to 2.1 that call WebHostBuilderLibuvExtensions.UseLibuv and depend on either of the following packages:

ASP.NET Core 2.1 이상의 경우 Microsoft.AspNetCore.App 메타패키지를 사용하고 Libuv를 사용해야 하는 프로젝트입니다.For ASP.NET Core 2.1 or later projects that use the Microsoft.AspNetCore.App metapackage and require the use of Libuv:

<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" 
Version="2.1.0" />
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseLibuv()
.UseStartup<Startup>();
}

URL 접두사URL prefixes

UseUrls, --urls 명령줄 인수, urls 호스트 구성 키 또는 ASPNETCORE_URLS 환경 변수를 사용하는 경우 URL 접두사는 다음 형식 중 하나일 수 있습니다.When using UseUrls, --urls command-line argument, urls host configuration key, or ASPNETCORE_URLS environment variable, the URL prefixes can be in any of the following formats.

HTTP URL 접두사만 유효합니다.Only HTTP URL prefixes are valid. Kestrel은 UseUrls을 사용하여 URL 바인딩을 구성하는 경우 SSL을 지원하지 않습니다.Kestrel doesn't support SSL when configuring URL bindings using UseUrls.

  • 포트 번호가 있는 IPv4 주소IPv4 address with port number

    http://65.55.39.10:80/
    

    0.0.0.0은 모든 IPv4 주소에 바인딩하는 특별한 경우입니다.0.0.0.0 is a special case that binds to all IPv4 addresses.

  • 포트 번호가 있는 IPv6 주소IPv6 address with port number

    http://[0:0:0:0:0:ffff:4137:270a]:80/
    

    [::]는 IPv4 0.0.0.0에 해당하는 IPv6입니다.[::] is the IPv6 equivalent of IPv4 0.0.0.0.

  • 포트 번호가 있는 호스트 이름Host name with port number

    http://contoso.com:80/
    http://*:80/
    

    호스트 이름, *+는 특별하지 않습니다.Host names, *, and +, aren't special. 유효한 IP 주소 또는 localhost로 인식하지 않는 모든 항목은 모든 IPv4 및 IPv6 IP에 바인딩합니다.Anything not recognized as a valid IP address or localhost binds to all IPv4 and IPv6 IPs. 서로 다른 호스트 이름을 같은 포트에서 서로 다른 ASP.NET Core 앱에 바인딩하려면 IIS, Nginx 또는 Apache와 같은 역방향 프록시 서버 또는 HTTP.sys를 사용합니다.To bind different host names to different ASP.NET Core apps on the same port, use HTTP.sys or a reverse proxy server, such as IIS, Nginx, or Apache.

    경고

    호스트 필터링을 사용하도록 설정된 역방향 프록시를 사용하지 않는 경우 호스트 필터링을 사용하도록 설정합니다.If not using a reverse proxy with host filtering enabled, enable host filtering.

  • 포트 번호가 있는 호스트 localhost 이름 또는 포트 번호가 있는 루프백 IPHost localhost name with port number or loopback IP with port number

    http://localhost:5000/
    http://127.0.0.1:5000/
    http://[::1]:5000/
    

    localhost가 지정되면 Kestrel은 IPv4 및 IPv6 루프백 인터페이스 모두에 바인딩하려고 합니다.When localhost is specified, Kestrel attempts to bind to both IPv4 and IPv6 loopback interfaces. 요청된 포트가 루프백 인터페이스 중 하나의 다른 서비스에서 사용 중인 경우 Kestrel은 시작에 실패합니다.If the requested port is in use by another service on either loopback interface, Kestrel fails to start. 루프백 인터페이스 중 하나를 다른 이유(일반적으로 IPv6이 지원되지 않으므로)로 사용할 수 없는 경우 Kestrel은 경고를 기록합니다.If either loopback interface is unavailable for any other reason (most commonly because IPv6 isn't supported), Kestrel logs a warning.

호스트 필터링Host filtering

Kestrel은 http://example.com:5000과 같은 접두사에 따라 구성을 지원하지만 일반적으로 호스트 이름을 무시합니다.While Kestrel supports configuration based on prefixes such as http://example.com:5000, Kestrel largely ignores the host name. 호스트 localhost은 루프백 주소에 바인딩하는 데 사용된 특별한 경우입니다.Host localhost is a special case used for binding to loopback addresses. 명시적 IP 주소를 제외한 모든 호스트는 모든 공용 IP 주소에 바인딩합니다.Any host other than an explicit IP address binds to all public IP addresses. 이 정보 중 어느 것도 요청 Host 헤더의 유효성을 검사하는 데 사용됩니다.None of this information is used to validate request Host headers.

해결 방법은 호스트 헤더 필터링을 사용한 역방향 프록시 뒤의 호스트입니다.As a workaround, host behind a reverse proxy with host header filtering. ASP.NET Core 1.x에서 Kestrel에 대한 유일한 지원 시나리오입니다.This is the only supported scenario for Kestrel in ASP.NET Core 1.x.

해결 방법으로 미들웨어를 사용하여 Host 헤더로 요청을 필터링합니다.As a workaround, use middleware to filter requests by the Host header:

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

// A normal middleware would provide an options type, config binding, extension methods, etc..
// This intentionally does all of the work inside of the middleware so it can be
// easily copy-pasted into docs and other projects.
public class HostFilteringMiddleware
{
private readonly RequestDelegate _next;
private readonly IList<string> _hosts;
private readonly ILogger<HostFilteringMiddleware> _logger;

public HostFilteringMiddleware(RequestDelegate next, IConfiguration config, ILogger<HostFilteringMiddleware> logger)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}

_next = next ?? throw new ArgumentNullException(nameof(next));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

// A semicolon separated list of host names without the port numbers.
// IPv6 addresses must use the bounding brackets and be in their normalized form.
_hosts = config["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (_hosts == null || _hosts.Count == 0)
{
throw new InvalidOperationException("No configuration entry found for AllowedHosts.");
}
}

public Task Invoke(HttpContext context)
{
if (!ValidateHost(context))
{
context.Response.StatusCode = 400;
_logger.LogDebug("Request rejected due to incorrect Host header.");
return Task.CompletedTask;
}

return _next(context);
}

// This does not duplicate format validations that are expected to be performed by the host.
private bool ValidateHost(HttpContext context)
{
StringSegment host = context.Request.Headers[HeaderNames.Host].ToString().Trim();

if (StringSegment.IsNullOrEmpty(host))
{
// Http/1.0 does not require the Host header.
// Http/1.1 requires the header but the value may be empty.
return true;
}

// Drop the port

var colonIndex = host.LastIndexOf(':');

// IPv6 special case
if (host.StartsWith("[", StringComparison.Ordinal))
{
var endBracketIndex = host.IndexOf(']');
if (endBracketIndex < 0)
{
// Invalid format
return false;
}
if (colonIndex < endBracketIndex)
{
// No port, just the IPv6 Host
colonIndex = -1;
}
}

if (colonIndex > 0)
{
host = host.Subsegment(0, colonIndex);
}

foreach (var allowedHost in _hosts)
{
if (StringSegment.Equals(allowedHost, host, StringComparison.OrdinalIgnoreCase))
{
return true;
}

// Sub-domain wildcards: *.example.com
if (allowedHost.StartsWith("*.", StringComparison.Ordinal) && host.Length >= allowedHost.Length)
{
// .example.com
var allowedRoot = new StringSegment(allowedHost, 1, allowedHost.Length - 1);

var hostRoot = host.Subsegment(host.Length - allowedRoot.Length, allowedRoot.Length);
if (hostRoot.Equals(allowedRoot, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
}

return false;
}
}

Startup.Configure에 위의 HostFilteringMiddleware을 등록합니다.Register the preceding HostFilteringMiddleware in Startup.Configure. 미들웨어 등록 순서가 중요합니다.Note that the ordering of middleware registration is important. 등록은 진단 미들웨어 등록 후 즉시 이뤄져야 합니다(예: app.UseExceptionHandler).Registration should occur immediately after Diagnostic Middleware registration (for example, app.UseExceptionHandler).

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}

app.UseMiddleware<HostFilteringMiddleware>();

app.UseMvcWithDefaultRoute();
}

미들웨어는 appsettings.json/appsettings.<EnvironmentName>.json에서 AllowedHosts 키를 예상합니다.The middleware expects an AllowedHosts key in appsettings.json/appsettings.<EnvironmentName>.json. 값은 포트 번호 없이 세미콜론으로 구분된 호스트 이름 목록입니다.The value is a semicolon-delimited list of host names without port numbers:

해결 방법으로 호스트 필터링 미들웨어를 사용합니다.As a workaround, use Host Filtering Middleware. 호스트 필터링 미들웨어는 Microsoft.AspNetCore.HostFiltering 패키지에서 제공되고 Microsoft.AspNetCore.App metapackage(ASP.NET Core 2.1 이상)에 포함됩니다.Host Filtering Middleware is provided by the Microsoft.AspNetCore.HostFiltering package, which is included in the Microsoft.AspNetCore.App metapackage (ASP.NET Core 2.1 or later). 미들웨어는 CreateDefaultBuilder에 의해 추가되고 AddHostFiltering을 호출합니다.The middleware is added by CreateDefaultBuilder, which calls AddHostFiltering:

[!code-csharp][!code-csharp]

호스트 필터링 미들웨어는 기본적으로 비활성화됩니다.Host Filtering Middleware is disabled by default. 미들웨어를 활성화하려면 appsettings.json/appsettings.<EnvironmentName>.json에서 AllowedHosts 키를 정의합니다.To enable the middleware, define an AllowedHosts key in appsettings.json/appsettings.<EnvironmentName>.json. 값은 포트 번호 없이 세미콜론으로 구분된 호스트 이름 목록입니다.The value is a semicolon-delimited list of host names without port numbers:

appsettings.json:appsettings.json:

{
"AllowedHosts": "example.com;localhost"
}

참고

전달된 헤더 미들웨어에는 ForwardedHeadersOptions.AllowedHosts 옵션이 포함됩니다.Forwarded Headers Middleware also has an ForwardedHeadersOptions.AllowedHosts option. 전달된 헤더 미들웨어 및 호스트 필터링 미들웨어는 다양한 시나리오에 대해 유사한 기능을 제공합니다.Forwarded Headers Middleware and Host Filtering Middleware have similar functionality for different scenarios. 전달된 헤더 미들웨어를 사용하여 AllowedHosts를 설정하는 작업은 역방향 프록시 서버 또는 부하 분산 장치를 사용하여 요청을 전달하는 동안 호스트 헤더가 유지되지 않는 경우에 적합합니다.Setting AllowedHosts with Forwarded Headers Middleware is appropriate when the Host header isn't preserved while forwarding requests with a reverse proxy server or load balancer. 호스트 필터링 미들웨어를 사용하여 AllowedHosts를 설정하는 작업은 Kestrel을 에지 서버로 사용하는 경우 또는 호스트 헤더를 직접 전달하는 경우에 적합합니다.Setting AllowedHosts with Host Filtering Middleware is appropriate when Kestrel is used as an edge server or when the Host header is directly forwarded.

전달된 헤더 미들웨어에 대한 자세한 내용은 프록시 서버 및 부하 분산 장치를 사용하도록 ASP.NET Core 구성을 참조하세요.For more information on Forwarded Headers Middleware, see Configure ASP.NET Core to work with proxy servers and load balancers.

추가 자료Additional resources