다음을 통해 공유


ASP.NET Core Kestrel 웹 서버의 엔드포인트 구성

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.

Warning

이 버전의 ASP.NET Core는 더 이상 지원되지 않습니다. 자세한 내용은 .NET 및 .NET Core 지원 정책을 참조 하세요. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.

Warning

이 버전의 ASP.NET Core는 더 이상 지원되지 않습니다. 자세한 내용은 .NET 및 .NET Core 지원 정책을 참조 하세요. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.

Kestrel 엔드포인트는 들어오는 요청을 수신 대기하고 적절한 미들웨어로 라우팅하기 위한 인프라를 제공합니다. 주소와 프로토콜의 조합은 엔드포인트를 정의합니다.

  • 주소는 서버가 들어오는 요청(예: TCP 포트)을 수신 대기하는 네트워크 인터페이스를 지정합니다.
  • 프로토콜은 HTTP/1.1, HTTP/2 또는 HTTP/3과 같은 클라이언트와 서버 간의 통신을 지정합니다.
  • URL 구성표 또는 UseHttps 메서드를 사용하여 엔드포인트를 https 보호합니다.

URL, JSON in 및 코드를 사용하여 엔드포인트를 appsettings.json구성할 수 있습니다. 이 문서에서는 각 옵션을 사용하여 엔드포인트를 구성하는 방법을 설명합니다.

기본 엔드포인트

새 ASP.NET Core 프로젝트는 5000-5300 사이의 임의 HTTP 포트와 7000-7300 사이의 임의 HTTPS 포트에 바인딩하도록 구성됩니다. 선택한 포트는 생성된 Properties/launchSettings.json 파일에 저장되며 개발자가 수정할 수 있습니다. 이 launchSetting.json 파일은 로컬 개발에만 사용됩니다.

엔드포인트 구성 Kestrel 이 없으면 에 바인딩합니다 http://localhost:5000.

엔드포인트 구성

Kestrel 엔드포인트는 들어오는 연결을 수신 대기합니다. 엔드포인트가 만들어지면 수신 대기할 주소로 구성해야 합니다. 일반적으로 TCP 주소 및 포트 번호입니다.

엔드포인트를 구성하는 몇 가지 옵션이 있습니다.

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/
    

    [::]는 IPv4 0.0.0.0에 해당하는 IPv6입니다.

  • 포트 번호가 있는 와일드카드 호스트

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

    유효한 IP 주소로 인식되지 않거나 모든 IPv4 및 IPv6 주소 localhost 에 바인딩되는 와일드카드로 처리됩니다. 어떤 사람들은 사용 * 하거나 + 더 명시적이기를 좋아합니다. 다양한 호스트 이름을 같은 포트에서 서로 다른 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

자세한 내용은 구성 재정의를 참조 하세요.

HTTPS URL 접두사

HTTPS URL 접두사는 HTTPS 엔드포인트 구성에 기본 인증서가 제공된 경우에만 엔드포인트를 정의하는 데 사용할 수 있습니다. 예를 들어 이 문서의 뒷부분에 나와 있는 것처럼 구성 또는 구성 파일을 사용합니다KestrelServerOptions.

자세한 내용은 HTTPS 구성을 참조 하세요.

포트만 지정

앱 및 컨테이너에는 종종 호스트 또는 경로와 같은 추가 제약 조건 없이 포트 80과 같이 수신 대기할 포트만 제공됩니다. HTTP_PORTS 및 HTTPS_PORTS 및 HTTP.sys 서버에 대한 Kestrel 수신 대기 포트를 지정하는 구성 키입니다. 이러한 키는 접두사 또는 접두사로 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 구성 키는 우선 순위가 낮으며 코드에 직접 제공된 URLS 또는 값으로 재정의됩니다. HTTPS에 대한 서버별 메커니즘을 통해 인증서를 별도로 구성해야 합니다.

appsettings.json 엔드포인트 구성

Kestrel 는 인스턴스에서 엔드포인트를 로드할 수 있습니다 IConfiguration . 기본적으로 Kestrel 구성은 섹션에서 로드 Kestrel 되고 엔드포인트는 다음에서 Kestrel:Endpoints구성됩니다.

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpEndpoint": {
        "Url": "http://localhost:8080"
      }
    }
  }
}

위의 예제는 다음과 같습니다.

  • 구성 원본으로 사용합니다 appsettings.json . 그러나 모든 IConfiguration 원본을 사용할 수 있습니다.
  • 포트 8080에 명명된 MyHttpEndpoint 엔드포인트를 추가합니다.

JSON을 사용하여 엔드포인트를 구성하는 방법에 대한 자세한 내용은 이 문서의 뒷부분에서 HTTPS 구성 및 appsettings.json HTTP 프로토콜 구성에 대해 설명합니다.

구성에서 엔드포인트 다시 로드

구성 원본 변경이 기본적으로 사용하도록 설정된 경우 엔드포인트 구성을 다시 로드합니다. KestrelServerOptions.Configure(IConfiguration, Boolean)을 사용하여 사용하지 않도록 설정할 수 있습니다.

변경 신호가 표시되면 다음 단계를 수행합니다.

  • 새 구성은 이전 구성과 비교되며 구성이 변경되지 않은 엔드포인트는 수정되지 않습니다.
  • 제거되거나 수정된 엔드포인트에는 요청 처리를 완료하고 종료하는 데 5초가 주어집니다.
  • 새 엔드포인트 또는 수정된 엔드포인트가 시작됩니다.

엔드포인트가 다시 시작되는 동안 수정된 엔드포인트에 연결하는 클라이언트의 연결이 끊어졌거나 거부될 수 있습니다.

ConfigurationLoader

KestrelServerOptions.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에 액세스하여 WebApplicationBuilder.WebHost에서 제공한 로더와 같이 기존 로더에서 반복을 유지할 수 있습니다.

  • 각 엔드포인트에 대한 구성 섹션은 Endpoint 메서드의 옵션에서 사용 가능하므로 사용자 지정 설정을 읽을 수 있습니다.
  • KestrelServerOptions.Configure(IConfiguration) 는 여러 번 호출할 수 있지만 이전 인스턴스에서 명시적으로 호출되지 않는 한 Load 마지막 구성만 사용됩니다. 기본 호스트는 기본 구성 섹션을 바꿀 수 있도록 호출 Load 하지 않습니다.
  • KestrelConfigurationLoaderListen 는 오버로드에서 Endpoint API KestrelServerOptions 제품군을 미러링하므로 코드 및 구성 엔드포인트를 동일한 위치에서 구성할 수 있습니다. 이러한 오버로드는 이름을 사용하지 않고 구성에서 기본 설정만 사용합니다.

코드에서 엔드포인트 구성

KestrelServerOptions 에서는 코드에서 엔드포인트를 구성하는 메서드를 제공합니다.

UseUrls Listen API와 UseUrls API를 동시에 Listen 사용하는 경우 엔드포인트는 엔드포인트를 재정의 UseUrls 합니다.

TCP 소켓에 바인딩

, ListenLocalhostListenAnyIP 메서드는 ListenTCP 소켓에 바인딩됩니다.

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 cmdlet을 사용하여 만들 수 있습니다. 지원되지 않는 예제는 UpdateIISExpressSSLForChrome.ps1을 참조하세요.

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

Unix 소켓에 바인딩

이 예제에 나와 있는 것처럼 Nginx를 사용하여 성능을 향상하기 위해 ListenUnixSocket을 사용하여 Unix 소켓을 수신 대기할 수 있습니다.

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 =>
    {
        // ...
    });
});

참고 항목

ConfigureEndpointDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

동적 포트 바인딩

포트 번호를 0 지정 Kestrel 하면 사용 가능한 포트에 동적으로 바인딩됩니다. 다음 예제에서는 Kestrel이 런타임에 바인딩된 포트를 확인하는 방법을 보여줍니다.

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

경우에 따라 포트를 동적으로 바인딩할 수 없습니다.

HTTPS 구성

Kestrel 는 HTTPS를 사용하여 엔드포인트 보안을 지원합니다. HTTPS를 통해 전송된 데이터는 TLS(전송 계층 보안)를 사용하여 암호화되어 클라이언트와 서버 간에 전송되는 데이터의 보안을 강화합니다.

HTTPS에는 TLS 인증서가 필요합니다. TLS 인증서는 서버에 저장되며 Kestrel 이를 사용하도록 구성됩니다. 앱은 로컬 개발 환경에서 ASP.NET Core HTTPS 개발 인증서를 사용할 수 있습니다. 개발 인증서는 비개발 환경에 설치되지 않습니다. 프로덕션 환경에서는 TLS 인증서를 명시적으로 구성해야 합니다. 최소한 기본 인증서를 제공해야 합니다.

HTTPS 및 TLS 인증서를 구성하는 방법은 엔드포인트를 구성하는 방법에 따라 달라집니다.

appsettings.json HTTPS 구성

기본 HTTPS 앱 설정 구성 스키마는 Kestrel에 대해 사용 가능합니다. 디스크 상의 파일에서 또는 인증서 저장소에서 사용할 인증서 및 URL을 포함하여 여러 엔드포인트를 구성합니다.

다음 예제에서 인증서HttpsDefaultCert 를 지정하지 않는 HTTPS 엔드포인트는 아래에 정의된 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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

스키마 노트

  • 엔드포인트 이름은 대/소문자를 구분하지 않습니다. 예를 들어 HTTPS and Https 와 동일합니다.
  • Url 매개 변수는 각 엔드포인트에 대해 필요합니다. 이 매개 변수에 대한 형식은 단일 값으로 제한된 경우를 제외하고 최상위 Urls 구성 매개 변수와 동일합니다. 이 문서의 앞부분에서 URL 형식을 참조하세요.
  • 이러한 엔드포인트는 추가하지 않고 최상위 Urls 구성에 정의된 엔드포인트를 대체합니다. Listen을 통해 코드에서 정의된 엔드포인트는 구성 섹션에서 정의된 엔드포인트로 누적됩니다.
  • Certificate 섹션은 선택 사항입니다. Certificate 섹션이 지정되지 않은 경우 Certificates:Default에 정의된 기본값이 사용됩니다. 사용할 수 있는 기본값이 없으면 개발 인증서가 사용됩니다. 기본값이 없고 개발 인증서가 없는 경우 서버가 예외를 throw하고 시작에 실패합니다.
  • 이 섹션에서는 Certificate 여러 인증서 원본을 지원합니다.
  • 포트 충돌을 일으키지 않는 한 많은 엔드포인트가 정의 Configuration될 수 있습니다.

인증서 원본

인증서 노드를 구성하여 여러 원본에서 인증서를 로드할 수 있습니다.

  • PathPassword: .pfx 파일 로드.
  • Path, KeyPathPassword: .pem/.crt.key 파일 로드.
  • SubjectStore: 인증서 저장소에서 로드.

예를 들어 인증서를 Certificates:Default 다음과 같이 지정할 수 있습니다.

"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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

기본값은 ClientCertificateMode.NoCertificate클라이언트에서 인증서를 요청하거나 요구하지 않는 위치 Kestrel 입니다.

자세한 내용은 ASP.NET Core에서 인증서 인증 구성을 참조하세요.

appsettings.json SSL/TLS 프로토콜 구성

SSL 프로토콜은 두 피어(일반적으로 클라이언트와 서버) 간 트래픽 암호화 및 암호 해독에 사용되는 프로토콜입니다.

{
  "Kestrel": {
    "Endpoints": {
      "MyHttpsEndpoint": {
        "Url": "https://localhost:5001",
        "SslProtocols": ["Tls12", "Tls13"],
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "$CREDENTIAL_PLACEHOLDER$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 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 인증서 데이터에 액세스하는 데 필요한 암호입니다.
  • configureOptionsHttpsConnectionAdapterOptions를 구성하는 Action입니다. 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클라이언트에서 인증서를 요청하거나 요구하지 않는 위치 Kestrel 입니다.

자세한 내용은 ASP.NET Core에서 인증서 인증 구성을 참조하세요.

코드에서 HTTPS 기본값 구성

ConfigureHttpsDefaults(Action<HttpsConnectionAdapterOptions>) 는 각 HTTPS 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. 여러 번 호출 ConfigureHttpsDefaults 하면 이전 Action 인스턴스가 마지막으로 Action 지정된 인스턴스로 바뀝니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

참고 항목

ConfigureHttpsDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

코드에서 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 옵션 간 매핑을 구성합니다. 예: appsettings.json 파일의 JSON
  • 코드로 엔드포인트를 만들고 호스트 이름을 ServerCertificateSelector 콜백과 함께 사용하여 인증서를 선택합니다.

appsettings.json SNI 구성

Kestrel은 구성에서 정의된 SNI를 지원합니다. 호스트 이름과 HTTPS 옵션 간의 매핑이 포함된 Sni 개체를 사용하여 엔드포인트를 구성할 수 있습니다. 연결 호스트 이름은 옵션과 일치하며 해당 연결에 사용됩니다.

다음 구성에서는 호스트 이름에 따라 HTTPS 옵션을 선택하기 위해 SNI를 사용하는 MySniEndpoint이라는 이름의 엔드포인트를 추가합니다.

{
  "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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

SNI로 재정의될 수 있는 HTTPS 옵션

호스트 이름은 와일드카드 일치를 지원합니다.

  • 정확한 일치. 예를 들어 a.example.orga.example.org와 일치합니다.
  • 와일드카드 접두사 와일드카드 일치 항목이 여러 대인 경우 가장 긴 패턴이 선택됩니다. 예를 들어 *.example.orgb.example.org, c.example.org과 일치합니다.
  • 전체 와일드카드 *은 SNI를 사용하지 않고 호스트 이름을 보내지 않은 클라이언트들을 포함하여 나머지 모두와 일치합니다.

일치하는 SNI 구성은 엔드포인트의 값을 재정의하는 연결의 엔드포인트에 적용됩니다. 연결이 구성된 SNI 호스트 이름과 일치하지 않으면 연결이 거부됩니다.

코드를 사용하여 SNI 구성

Kestrel 는 여러 콜백 API를 사용하여 SNI를 지원합니다.

  • ServerCertificateSelector
  • ServerOptionsSelectionCallback
  • TlsHandshakeCallbackOptions

ServerCertificateSelector과 SNI

Kestrel은 ServerCertificateSelector 콜백을 통해 SNI를 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서를 선택하도록 허용하려면 연결당 한 번씩 콜백이 호출됩니다.

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

ServerOptionsSelectionCallback과 SNI

Kestrel는 ServerOptionsSelectionCallback 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서와 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!);
        });
    });
});

TlsHandshakeCallbackOptions과 SNI

Kestrel는 TlsHandshakeCallbackOptions.OnConnection 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서, 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 버전을 지원하도록 엔드포인트를 구성할 수 있습니다.

둘 이상의 HTTP 버전을 지원하려면 TLS가 필요합니다. TLS ALPN(Application-Layer Protocol Negotiation) 핸드셰이크는 엔드포인트가 여러 프로토콜을 지원하는 경우 클라이언트와 서버 간의 연결 프로토콜을 협상하는 데 사용됩니다.

HttpProtocols 허용되는 연결 프로토콜
Http1 HTTP/1.1 전용. TLS와 함께 또는 TLS 없이 사용할 수 있습니다.
Http2 HTTP/2 전용. 클라이언트가 이전 기술 모드를 지원하는 경우에만 TLS 없이 사용할 수 있습니다.
Http3 HTTP/3 전용 TLS가 필요합니다. 클라이언트는 HTTP/3만 사용하도록 구성해야 할 수 있습니다.
Http1AndHttp2 HTTP/1.1 및 HTTP/2. HTTP/2를 사용하려면 클라이언트가 TLS ALPN(Application-Layer Protocol Negotiation) 핸드셰이크에서 HTTP/2를 선택해야 합니다. 그렇지 않으면 연결 기본값은 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.

HTTP/2에 대한 TLS 제한 사항:

  • TLS 버전 1.2 이상
  • 재협상 사용 안 함
  • 압축 사용 안함
  • 최소 임시 키 교환 크기:
    • ECDHE(타원 곡선 Diffie-Hellman) [RFC4492]: 최소 224비트
    • 유한 필드 DHE(Diffie-Hellman) [TLS12]: 최소 2048비트
  • 암호 도구 모음은 금지되지 않습니다.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE](P-256 타원 곡선 [FIPS186] 포함)는 기본적으로 지원됩니다.

appsettings.json HTTP 프로토콜 구성

다음 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 데 사용됩니다.

다음 예제에서는 포트 8000에서 HTTP/1.1, HTTP/2 및 HTTP/3 연결에 대한 엔드포인트를 구성합니다. 연결은 제공된 인증서를 사용하여 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;
    });
});

참고 항목

ASP.NET Core 프로젝트는 5000~5300 사이의 임의 HTTP 포트와 7000~7300 사이의 임의 HTTPS 포트에 바인딩하도록 구성됩니다. 이 기본 구성은 생성된 Properties/launchSettings.json 파일에 지정되며 재정의할 수 있습니다. 지정된 포트가 없으면 Kestrel이 http://localhost:5000에 바인딩됩니다.

다음을 사용하여 URL을 지정합니다.

  • ASPNETCORE_URLS 환경 변수.
  • --urls 명령줄 인수.
  • urls 호스트 구성 키.
  • UseUrls 확장명 메서드.

이러한 접근 방식을 사용하여 제공된 값은 하나 이상의 HTTP 및 HTTPS 엔드포인트(기본 인증서가 사용 가능한 경우의 HTTPS)일 수 있습니다. 값을 세미콜론으로 구분된 목록으로 구성합니다(예를 들어, "Urls": "http://localhost:8000;http://localhost:8001").

이러한 접근 방식에 대한 자세한 내용은 서버 URL구성 재정의를 참조하세요.

개발 인증서를 만듭니다.

개발 인증서는 인증서를 생성하는 사용자만 사용할 수 있습니다. 일부 브라우저에서는 로컬 개발 인증서를 신뢰하도록 명시적 권한을 부여해야 합니다.

프로젝트 템플릿은 기본적으로 HTTPS에서 실행되도록 앱을 구성하고 HTTPS 리디렉션 및 HSTS 지원을 포함합니다.

KestrelServerOptions에서 Listen 또는 ListenUnixSocket 메서드를 호출하여 Kestrel의 URL 접두사 및 포트를 구성합니다.

UseUrls, --urls 명령줄 인수 urls 호스트 구성 키 및 ASPNETCORE_URLS 환경 변수도 작동하지만 이 섹션의 뒷부분에 명시된 제한 사항이 있습니다(HTTPS 엔드포인트 구성에 대해 기본 인증서를 사용할 수 있어야 합니다).

KestrelServerOptions 구성:

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) 는 지정된 각 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. ConfigureEndpointDefaults를 여러 번 호출하면 이전 Action을 마지막으로 지정된 Action으로 바꿉니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

참고 항목

ConfigureEndpointDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

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>) 는 각 HTTPS 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. ConfigureHttpsDefaults의 여러 차례 호출은 Action에 앞서 마지막으로 지정된 Action으로 바꿉니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

참고 항목

ConfigureHttpsDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

ListenOptions.UseHttps

HTTPS를 사용하도록 Kestrel을 구성합니다.

ListenOptions.UseHttps 확장:

  • UseHttps: 기본 인증서를 통해 HTTPS를 사용하도록 Kestrel을 구성합니다. 기본 인증서가 구성되지 않은 경우 예외를 throw합니다.
  • 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 인증서 데이터에 액세스하는 데 필요한 암호입니다.
  • configureOptionsHttpsConnectionAdapterOptions를 구성하는 Action입니다. ListenOptions를 반환합니다.
  • storeName은 인증서를 로드할 수 있는 인증서 저장소입니다.
  • subject은 인증서의 주체 이름입니다.
  • allowInvalid은 자체 서명된 인증서와 같이 잘못된 인증서를 고려해야 할 경우를 나타냅니다.
  • location은 인증서를 로드할 수 있는 저장소 위치입니다.
  • serverCertificate은 X.509 인증서입니다.

프로덕션 내에 HTTPS가 명시적으로 구성되어야 합니다. 최소한 기본 인증서를 제공해야 합니다.

Windows 인증서 저장소와 달리 디스크에서 인증서를 읽는 경우 포함된 디렉터리에 권한 없는 액세스를 방지하기 위한 적절한 권한이 있어야 합니다.

다음에 설명된 지원되는 구성입니다.

  • 구성 없음
  • 구성에서 기본 인증서를 바꿈
  • 코드에서 기본값 변경

구성 없음

Kestrel은 http://localhost:5000에서 수신 대기합니다.

구성에서 기본 인증서를 바꿈

기본 HTTPS 앱 설정 구성 스키마는 Kestrel에 대해 사용 가능합니다. 디스크 상의 파일에서 또는 인증서 저장소에서 사용할 인증서 및 URL을 포함하여 여러 엔드포인트를 구성합니다.

다음 appsettings.json 예제에서

  • 잘못된 인증서(예: 자체 서명된 인증서)의 사용을 허용하도록 true 설정합니다AllowInvalid.
  • 인증서를 지정하지 않은 임의의 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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 각 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

스키마 참고 사항:

  • 엔드포인트 이름은 대/소문자를 구분하지 않습니다. 예를 들어 HTTPS and Https 와 동일합니다.
  • Url 매개 변수는 각 엔드포인트에 대해 필요합니다. 이 매개 변수에 대한 형식은 단일 값으로 제한된 경우를 제외하고 최상위 Urls 구성 매개 변수와 동일합니다.
  • 이러한 엔드포인트는 추가하기보다는 최상위 Urls 구성에서 정의된 엔드포인트를 바꿉니다. Listen을 통해 코드에서 정의된 엔드포인트는 구성 섹션에서 정의된 엔드포인트로 누적됩니다.
  • Certificate 섹션은 선택 사항입니다. Certificate 섹션이 지정되지 않은 경우 Certificates:Default에 정의된 기본값이 사용됩니다. 사용할 수 있는 기본값이 없으면 개발 인증서가 사용됩니다. 기본값이 없고 개발 인증서가 없는 경우 서버가 예외를 throw하고 시작에 실패합니다.
  • Certificate 섹션은 여러 인증서 원본을 지원합니다.
  • 포트 충돌을 일으키지 않는 한 구성에서 원하는 수의 엔드포인트를 정의할 수 있습니다.

인증서 원본

인증서 노드를 구성하여 여러 원본에서 인증서를 로드할 수 있습니다.

  • PathPassword: .pfx 파일 로드.
  • Path, KeyPathPassword: .pem/.crt.key 파일 로드.
  • SubjectStore: 인증서 저장소에서 로드.

예를 들어 인증서를 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)은 구성된 엔드포인트의 설정을 보완하는 데 사용될 수 있는 Endpoint(String, Action<EndpointConfiguration>) 메서드를 통해 KestrelConfigurationLoader를 반환합니다.

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을 호출하지 않으므로 기본 구성 섹션을 바꿀 수 있습니다.
  • KestrelConfigurationLoaderKestrelServerOptions에서 Endpoint 오버로드로 Listen API 제품군을 미러링하므로 코드 및 구성 엔드포인트를 동일 장소에서 구성할 수 있습니다. 이러한 오버로드는 이름을 사용하지 않고 구성에서 기본 설정만 사용합니다.

코드에서 기본값 변경

ConfigureEndpointDefaultsConfigureHttpsDefaults는 이전 시나리오에서 지정된 기본 인증서 재정의를 포함한 ListenOptionsHttpsConnectionAdapterOptions에 대해 기본 설정을 변경하는 데 사용될 수 있습니다. ConfigureEndpointDefaultsConfigureHttpsDefaults는 모든 엔드포인트가 구성되기 전에 호출해야 합니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

서버 이름 표시를 사용하여 엔드포인트 구성

서버 이름 표시(SNI)는 동일한 IP 주소 및 포트에서 여러 도메인을 호스트하는 데 사용될 수 있습니다. 함수에 대한 SNI의 경우 클라이언트는 TLS 핸드셰이크 동안 보안 세션에 대한 호스트 이름을 서버로 보내므로 서버에서 올바른 인증서를 제공할 수 있습니다. TLS 핸드셰이크 다음에 오는 보안 세션 동안 클라이언트는 서버와 암호화된 통신을 위해 제공된 인증서를 사용합니다.

SNI 구성 방법은 다음 두 가지입니다.

  • 코드로 엔드포인트를 만들고 호스트 이름을 ServerCertificateSelector 콜백과 함께 사용하여 인증서를 선택합니다.
  • 구성에서 호스트 이름과 HTTPS 옵션 간 매핑을 구성합니다. 예: appsettings.json 파일의 JSON

ServerCertificateSelector과 SNI

Kestrel은 ServerCertificateSelector 콜백을 통해 SNI를 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서를 선택하도록 허용하려면 연결당 한 번씩 콜백이 호출됩니다.

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

ServerOptionsSelectionCallback과 SNI

Kestrel는 ServerOptionsSelectionCallback 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서와 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!);
        });
    });
});

TlsHandshakeCallbackOptions과 SNI

Kestrel는 TlsHandshakeCallbackOptions.OnConnection 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서, 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를 지원합니다. 호스트 이름과 HTTPS 옵션 간의 매핑이 포함된 Sni 개체를 사용하여 엔드포인트를 구성할 수 있습니다. 연결 호스트 이름이 옵션과 일치하면 해당 연결에 사용됩니다.

다음 구성에서는 호스트 이름에 따라 HTTPS 옵션을 선택하기 위해 SNI를 사용하는 MySniEndpoint이라는 이름의 엔드포인트를 추가합니다.

{
  "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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 각 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

SNI로 재정의될 수 있는 HTTPS 옵션

호스트 이름은 와일드카드 일치를 지원합니다.

  • 정확한 일치. 예를 들어 a.example.orga.example.org와 일치합니다.
  • 와일드카드 접두사 와일드카드와 일치하는 항목이 여러 개 있는 경우 가장 긴 패턴이 선택됩니다. 예를 들어 *.example.orgb.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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요.

기본값은 ClientCertificateMode.NoCertificate입니다. 여기서 Kestrel는 클라이언트로부터 인증서를 요청하거나 요구하지 않습니다.

자세한 내용은 ASP.NET Core에서 인증서 인증 구성을 참조하세요.

연결 로깅

UseConnectionLogging을 호출하여 연결에 대한 바이트 수준 통신을 위한 디버그 수준을 내보냅니다. 연결 로깅은 낮은 수준 통신(예: TLS 암호화 중에, 프록시 뒤에서 등)에서 문제 해결을 진행하는 데 유용합니다. UseConnectionLoggingUseHttps 앞에 오면 암호화된 트래픽이 로깅됩니다. UseConnectionLoggingUseHttps 뒤에 오면 암호 해독된 트래픽이 로깅됩니다. 이는 기본 제공 연결 미들웨어입니다.

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

예제에서는 ListenOptions를 사용하여 엔드포인트에 대한 HTTPS를 구성합니다. 동일한 API를 사용하여 특정 엔드포인트에 대한 다른 Kestrel 설정을 구성합니다.

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

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

Unix 소켓에 바인딩

이 예제에 나와 있는 것처럼 Nginx를 사용하여 성능을 향상하기 위해 ListenUnixSocket을 사용하여 Unix 소켓을 수신 대기할 수 있습니다.

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
  • TCP 기반 HTTP/1.1 또는 HTTP/2와 QUIC 기반 HTTP/3을 함께 바인딩.

제한 사항

다음 방법으로 엔드포인트를 구성합니다.

  • UseUrls
  • --urls 명령줄 인수
  • urls 호스트 구성 키
  • ASPNETCORE_URLS환경 변수

이러한 메서드는 코드를 Kestrel이 아닌 서버와 작동하도록 하려는 경우 유용합니다. 그러나 다음과 같은 제한 사항에 유의하세요.

  • HTTPS 엔드포인트 구성에서 기본 인증서를 제공하지 않는 한 이러한 방법으로는 HTTPS를 사용할 수 없습니다(예: 이 문서의 앞부분에 표시된 것처럼 KestrelServerOptions 구성 또는 구성 파일 사용).
  • ListenUseUrls 방식 모두를 동시에 사용할 경우 Listen 엔드포인트는 UseUrls 엔드포인트를 재정의합니다.

IIS 엔드포인트 구성

IIS를 사용하는 경우 IIS 재정의 바인딩에 대한 URL 바인딩은 Listen 또는 UseUrls에 의해 설정됩니다. 자세한 내용은 ASP.NET Core 모듈을 참조하세요.

ListenOptions.Protocols

Protocols 속성은 연결 엔드포인트 또는 서버에 대해 사용할 수 있는 HTTP 프로토콜(HttpProtocols)을 설정합니다. HttpProtocols 열거형의 Protocols 속성에 값을 할당합니다.

HttpProtocols 열거형 값 허용되는 연결 프로토콜
Http1 HTTP/1.1 전용. TLS와 함께 또는 TLS 없이 사용할 수 있습니다.
Http2 HTTP/2 전용. 클라이언트가 이전 기술 모드를 지원하는 경우에만 TLS 없이 사용할 수 있습니다.
Http3 HTTP/3 전용 TLS가 필요합니다. 클라이언트는 HTTP/3만 사용하도록 구성해야 할 수 있습니다.
Http1AndHttp2 HTTP/1.1 및 HTTP/2. HTTP/2를 사용하려면 클라이언트가 TLS ALPN(Application-Layer Protocol Negotiation) 핸드셰이크에서 HTTP/2를 선택해야 합니다. 그렇지 않으면 연결 기본값은 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입니다.

HTTP/2에 대한 TLS 제한 사항:

  • TLS 버전 1.2 이상
  • 재협상 사용 안 함
  • 압축 사용 안함
  • 최소 임시 키 교환 크기:
    • ECDHE(타원 곡선 Diffie-Hellman) [RFC4492]: 최소 224비트
    • 유한 필드 DHE(Diffie-Hellman) [TLS12]: 최소 2048비트
  • 암호 도구 모음은 금지되지 않습니다.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE](P-256 타원 곡선 [FIPS186] 포함)는 기본적으로 지원됩니다.

다음 예제는 포트 8000에서 HTTP/1.1 및 HTTP/2 연결을 허용합니다. 연결은 제공된 인증서를 사용하여 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에서 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,
                    // ...
                });
        };
    });
});

연결 미들웨어

필요할 경우 사용자 지정 연결 미들웨어를 사용하여 각 연결을 기준으로 특정 암호에 대한 TLS 핸드셰이크를 필터링할 수 있습니다.

다음 예는 앱에서 지원하지 않는 모든 암호화 알고리즘에 대해 NotSupportedException을 throw합니다. 또는 허용되는 암호 그룹 목록을 정의하고 비교 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 접두사는 다음 형식 중 하나일 수 있습니다.

HTTP URL 접두사만 유효합니다. Kestrel은 UseUrls를 사용하여 URL 바인딩을 구성하는 경우 HTTPS를 지원하지 않습니다.

  • 포트 번호가 있는 IPv4 주소

    http://65.55.39.10:80/
    

    0.0.0.0은 모든 IPv4 주소에 바인딩하는 특별한 경우입니다.

  • 포트 번호가 있는 IPv6 주소

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

    [::]는 IPv4 0.0.0.0에 해당하는 IPv6입니다.

  • 포트 번호가 있는 호스트 이름

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

    호스트 이름, *+는 특별하지 않습니다. 유효한 IP 주소 또는 localhost로 인식하지 않는 모든 항목은 모든 IPv4 및 IPv6 IP에 바인딩합니다. 다양한 호스트 이름을 같은 포트에서 서로 다른 ASP.NET Core 앱에 바인딩하려면 역방향 프록시 서버 또는 HTTP.sys를 사용합니다. 역방향 프록시 서버의 예로는 IIS, Nginx 또는 Apache가 있습니다.

    Warning

    역방향 프록시 구성에서 호스팅하려면 호스트 필터링이 필요합니다.

  • 포트 번호가 있는 호스트 localhost 이름 또는 포트 번호가 있는 루프백 IP

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

    localhost가 지정되면 Kestrel은 IPv4 및 IPv6 루프백 인터페이스 모두에 바인딩하려고 합니다. 요청된 포트가 루프백 인터페이스 중 하나의 다른 서비스에서 사용 중인 경우 Kestrel은 시작에 실패합니다. 루프백 인터페이스 중 하나를 다른 이유(일반적으로 IPv6이 지원되지 않으므로)로 사용할 수 없는 경우 Kestrel은 경고를 기록합니다.

ASP.NET Core 프로젝트는 5000~5300 사이의 임의 HTTP 포트와 7000~7300 사이의 임의 HTTPS 포트에 바인딩하도록 구성됩니다. 이 기본 구성은 생성된 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구성 재정의를 참조하세요.

개발 인증서를 만듭니다.

개발 인증서는 인증서를 생성하는 사용자만 사용할 수 있습니다. 일부 브라우저에서는 로컬 개발 인증서를 신뢰하도록 명시적 권한을 부여해야 합니다.

프로젝트 템플릿은 기본적으로 HTTPS에서 실행되도록 앱을 구성하고 HTTPS 리디렉션 및 HSTS 지원을 포함합니다.

KestrelServerOptions에서 Listen 또는 ListenUnixSocket 메서드를 호출하여 Kestrel의 URL 접두사 및 포트를 구성합니다.

UseUrls, --urls 명령줄 인수 urls 호스트 구성 키 및 ASPNETCORE_URLS 환경 변수도 작동하지만 이 섹션의 뒷부분에 명시된 제한 사항이 있습니다(HTTPS 엔드포인트 구성에 대해 기본 인증서를 사용할 수 있어야 합니다).

KestrelServerOptions 구성:

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) 는 지정된 각 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. ConfigureEndpointDefaults를 여러 번 호출하면 이전 Action을 마지막으로 지정된 Action으로 바꿉니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });
});

참고 항목

ConfigureEndpointDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

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>) 는 각 HTTPS 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. ConfigureHttpsDefaults의 여러 차례 호출은 Action에 앞서 마지막으로 지정된 Action으로 바꿉니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

참고 항목

ConfigureHttpsDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

ListenOptions.UseHttps

HTTPS를 사용하도록 Kestrel을 구성합니다.

ListenOptions.UseHttps 확장:

  • UseHttps: 기본 인증서를 통해 HTTPS를 사용하도록 Kestrel을 구성합니다. 기본 인증서가 구성되지 않은 경우 예외를 throw합니다.
  • 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 인증서 데이터에 액세스하는 데 필요한 암호입니다.
  • configureOptionsHttpsConnectionAdapterOptions를 구성하는 Action입니다. ListenOptions를 반환합니다.
  • storeName은 인증서를 로드할 수 있는 인증서 저장소입니다.
  • subject은 인증서의 주체 이름입니다.
  • allowInvalid은 자체 서명된 인증서와 같이 잘못된 인증서를 고려해야 할 경우를 나타냅니다.
  • location은 인증서를 로드할 수 있는 저장소 위치입니다.
  • serverCertificate은 X.509 인증서입니다.

프로덕션 내에 HTTPS가 명시적으로 구성되어야 합니다. 최소한 기본 인증서를 제공해야 합니다.

다음에 설명된 지원되는 구성입니다.

  • 구성 없음
  • 구성에서 기본 인증서를 바꿈
  • 코드에서 기본값 변경

구성 없음

Kestrel은 http://localhost:5000https://localhost:5001에서 수신 대기합니다(기본 인증서가 사용 가능한 경우).

구성에서 기본 인증서를 바꿈

기본 HTTPS 앱 설정 구성 스키마는 Kestrel에 대해 사용 가능합니다. 디스크 상의 파일에서 또는 인증서 저장소에서 사용할 인증서 및 URL을 포함하여 여러 엔드포인트를 구성합니다.

다음 appsettings.json 예제에서

  • 잘못된 인증서(예: 자체 서명된 인증서)의 사용을 허용하도록 true 설정합니다AllowInvalid.
  • 인증서를 지정하지 않은 임의의 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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 각 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

스키마 참고 사항:

  • 엔드포인트 이름은 대/소문자를 구분하지 않습니다. 예를 들어 HTTPS and Https 와 동일합니다.
  • Url 매개 변수는 각 엔드포인트에 대해 필요합니다. 이 매개 변수에 대한 형식은 단일 값으로 제한된 경우를 제외하고 최상위 Urls 구성 매개 변수와 동일합니다.
  • 이러한 엔드포인트는 추가하기보다는 최상위 Urls 구성에서 정의된 엔드포인트를 바꿉니다. Listen을 통해 코드에서 정의된 엔드포인트는 구성 섹션에서 정의된 엔드포인트로 누적됩니다.
  • Certificate 섹션은 선택 사항입니다. Certificate 섹션이 지정되지 않은 경우 Certificates:Default에 정의된 기본값이 사용됩니다. 사용할 수 있는 기본값이 없으면 개발 인증서가 사용됩니다. 기본값이 없고 개발 인증서가 없는 경우 서버가 예외를 throw하고 시작에 실패합니다.
  • Certificate 섹션은 여러 인증서 원본을 지원합니다.
  • 포트 충돌을 일으키지 않는 한 구성에서 원하는 수의 엔드포인트를 정의할 수 있습니다.

인증서 원본

인증서 노드를 구성하여 여러 원본에서 인증서를 로드할 수 있습니다.

  • PathPassword: .pfx 파일 로드.
  • Path, KeyPathPassword: .pem/.crt.key 파일 로드.
  • SubjectStore: 인증서 저장소에서 로드.

예를 들어 인증서를 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)은 구성된 엔드포인트의 설정을 보완하는 데 사용될 수 있는 Endpoint(String, Action<EndpointConfiguration>) 메서드를 통해 KestrelConfigurationLoader를 반환합니다.

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을 호출하지 않으므로 기본 구성 섹션을 바꿀 수 있습니다.
  • KestrelConfigurationLoaderKestrelServerOptions에서 Endpoint 오버로드로 Listen API 제품군을 미러링하므로 코드 및 구성 엔드포인트를 동일 장소에서 구성할 수 있습니다. 이러한 오버로드는 이름을 사용하지 않고 구성에서 기본 설정만 사용합니다.

코드에서 기본값 변경

ConfigureEndpointDefaultsConfigureHttpsDefaults는 이전 시나리오에서 지정된 기본 인증서 재정의를 포함한 ListenOptionsHttpsConnectionAdapterOptions에 대해 기본 설정을 변경하는 데 사용될 수 있습니다. ConfigureEndpointDefaultsConfigureHttpsDefaults는 모든 엔드포인트가 구성되기 전에 호출해야 합니다.

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // ...
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // ...
    });
});

서버 이름 표시를 사용하여 엔드포인트 구성

서버 이름 표시(SNI)는 동일한 IP 주소 및 포트에서 여러 도메인을 호스트하는 데 사용될 수 있습니다. 함수에 대한 SNI의 경우 클라이언트는 TLS 핸드셰이크 동안 보안 세션에 대한 호스트 이름을 서버로 보내므로 서버에서 올바른 인증서를 제공할 수 있습니다. TLS 핸드셰이크 다음에 오는 보안 세션 동안 클라이언트는 서버와 암호화된 통신을 위해 제공된 인증서를 사용합니다.

SNI 구성 방법은 다음 두 가지입니다.

  • 코드로 엔드포인트를 만들고 호스트 이름을 ServerCertificateSelector 콜백과 함께 사용하여 인증서를 선택합니다.
  • 구성에서 호스트 이름과 HTTPS 옵션 간 매핑을 구성합니다. 예: appsettings.json 파일의 JSON

ServerCertificateSelector과 SNI

Kestrel은 ServerCertificateSelector 콜백을 통해 SNI를 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서를 선택하도록 허용하려면 연결당 한 번씩 콜백이 호출됩니다.

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

ServerOptionsSelectionCallback과 SNI

Kestrel는 ServerOptionsSelectionCallback 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서와 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!);
        });
    });
});

TlsHandshakeCallbackOptions과 SNI

Kestrel는 TlsHandshakeCallbackOptions.OnConnection 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서, 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를 지원합니다. 호스트 이름과 HTTPS 옵션 간의 매핑이 포함된 Sni 개체를 사용하여 엔드포인트를 구성할 수 있습니다. 연결 호스트 이름이 옵션과 일치하면 해당 연결에 사용됩니다.

다음 구성에서는 호스트 이름에 따라 HTTPS 옵션을 선택하기 위해 SNI를 사용하는 MySniEndpoint이라는 이름의 엔드포인트를 추가합니다.

{
  "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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 각 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

SNI로 재정의될 수 있는 HTTPS 옵션

호스트 이름은 와일드카드 일치를 지원합니다.

  • 정확한 일치. 예를 들어 a.example.orga.example.org와 일치합니다.
  • 와일드카드 접두사 와일드카드와 일치하는 항목이 여러 개 있는 경우 가장 긴 패턴이 선택됩니다. 예를 들어 *.example.orgb.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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요.

기본값은 ClientCertificateMode.NoCertificate입니다. 여기서 Kestrel는 클라이언트로부터 인증서를 요청하거나 요구하지 않습니다.

자세한 내용은 ASP.NET Core에서 인증서 인증 구성을 참조하세요.

연결 로깅

UseConnectionLogging을 호출하여 연결에 대한 바이트 수준 통신을 위한 디버그 수준을 내보냅니다. 연결 로깅은 낮은 수준 통신(예: TLS 암호화 중에, 프록시 뒤에서 등)에서 문제 해결을 진행하는 데 유용합니다. UseConnectionLoggingUseHttps 앞에 오면 암호화된 트래픽이 로깅됩니다. UseConnectionLoggingUseHttps 뒤에 오면 암호 해독된 트래픽이 로깅됩니다. 이는 기본 제공 연결 미들웨어입니다.

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

예제에서는 ListenOptions를 사용하여 엔드포인트에 대한 HTTPS를 구성합니다. 동일한 API를 사용하여 특정 엔드포인트에 대한 다른 Kestrel 설정을 구성합니다.

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

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

Unix 소켓에 바인딩

이 예제에 나와 있는 것처럼 Nginx를 사용하여 성능을 향상하기 위해 ListenUnixSocket을 사용하여 Unix 소켓을 수신 대기할 수 있습니다.

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 구성 또는 구성 파일 사용).
  • ListenUseUrls 방식 모두를 동시에 사용할 경우 Listen 엔드포인트는 UseUrls 엔드포인트를 재정의합니다.

IIS 엔드포인트 구성

IIS를 사용하는 경우 IIS 재정의 바인딩에 대한 URL 바인딩은 Listen 또는 UseUrls에 의해 설정됩니다. 자세한 내용은 ASP.NET Core 모듈을 참조하세요.

ListenOptions.Protocols

Protocols 속성은 연결 엔드포인트 또는 서버에 대해 사용할 수 있는 HTTP 프로토콜(HttpProtocols)을 설정합니다. HttpProtocols 열거형의 Protocols 속성에 값을 할당합니다.

HttpProtocols 열거형 값 허용되는 연결 프로토콜
Http1 HTTP/1.1 전용. TLS와 함께 또는 TLS 없이 사용할 수 있습니다.
Http2 HTTP/2 전용. 클라이언트가 이전 기술 모드를 지원하는 경우에만 TLS 없이 사용할 수 있습니다.
Http1AndHttp2 HTTP/1.1 및 HTTP/2. HTTP/2를 사용하려면 클라이언트가 TLS ALPN(Application-Layer Protocol Negotiation) 핸드셰이크에서 HTTP/2를 선택해야 합니다. 그렇지 않으면 연결 기본값은 HTTP/1.1입니다.

모든 엔드포인트의 기본 ListenOptions.Protocols 값은 HttpProtocols.Http1AndHttp2입니다.

HTTP/2에 대한 TLS 제한 사항:

  • TLS 버전 1.2 이상
  • 재협상 사용 안 함
  • 압축 사용 안함
  • 최소 임시 키 교환 크기:
    • ECDHE(타원 곡선 Diffie-Hellman) [RFC4492]: 최소 224비트
    • 유한 필드 DHE(Diffie-Hellman) [TLS12]: 최소 2048비트
  • 암호 도구 모음은 금지되지 않습니다.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE](P-256 타원 곡선 [FIPS186] 포함)는 기본적으로 지원됩니다.

다음 예제는 포트 8000에서 HTTP/1.1 및 HTTP/2 연결을 허용합니다. 연결은 제공된 인증서를 사용하여 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에서 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,
                    // ...
                });
        };
    });
});

연결 미들웨어

필요할 경우 사용자 지정 연결 미들웨어를 사용하여 각 연결을 기준으로 특정 암호에 대한 TLS 핸드셰이크를 필터링할 수 있습니다.

다음 예는 앱에서 지원하지 않는 모든 암호화 알고리즘에 대해 NotSupportedException을 throw합니다. 또는 허용되는 암호 그룹 목록을 정의하고 비교 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 접두사는 다음 형식 중 하나일 수 있습니다.

HTTP URL 접두사만 유효합니다. Kestrel은 UseUrls를 사용하여 URL 바인딩을 구성하는 경우 HTTPS를 지원하지 않습니다.

  • 포트 번호가 있는 IPv4 주소

    http://65.55.39.10:80/
    

    0.0.0.0은 모든 IPv4 주소에 바인딩하는 특별한 경우입니다.

  • 포트 번호가 있는 IPv6 주소

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

    [::]는 IPv4 0.0.0.0에 해당하는 IPv6입니다.

  • 포트 번호가 있는 호스트 이름

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

    호스트 이름, *+는 특별하지 않습니다. 유효한 IP 주소 또는 localhost로 인식하지 않는 모든 항목은 모든 IPv4 및 IPv6 IP에 바인딩합니다. 다양한 호스트 이름을 같은 포트에서 서로 다른 ASP.NET Core 앱에 바인딩하려면 역방향 프록시 서버 또는 HTTP.sys를 사용합니다. 역방향 프록시 서버의 예로는 IIS, Nginx 또는 Apache가 있습니다.

    Warning

    역방향 프록시 구성에서 호스팅하려면 호스트 필터링이 필요합니다.

  • 포트 번호가 있는 호스트 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구성 재정의를 참조하세요.

개발 인증서를 만듭니다.

일부 브라우저에서는 로컬 개발 인증서를 신뢰하도록 명시적 권한을 부여해야 합니다.

프로젝트 템플릿은 기본적으로 HTTPS에서 실행되도록 앱을 구성하고 HTTPS 리디렉션 및 HSTS 지원을 포함합니다.

KestrelServerOptions에서 Listen 또는 ListenUnixSocket 메서드를 호출하여 Kestrel의 URL 접두사 및 포트를 구성합니다.

UseUrls, --urls 명령줄 인수 urls 호스트 구성 키 및 ASPNETCORE_URLS 환경 변수도 작동하지만 이 섹션의 뒷부분에 명시된 제한 사항이 있습니다(HTTPS 엔드포인트 구성에 대해 기본 인증서를 사용할 수 있어야 합니다).

KestrelServerOptions 구성:

ConfigureEndpointDefaults

ConfigureEndpointDefaults(Action<ListenOptions>) 는 지정된 각 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. ConfigureEndpointDefaults의 여러 차례 호출은 Action에 앞서 마지막으로 지정된 Action으로 바꿉니다.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });
});

참고 항목

ConfigureEndpointDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

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>) 는 각 HTTPS 엔드포인트에 대해 실행할 구성 Action 을 지정합니다. ConfigureHttpsDefaults의 여러 차례 호출은 Action에 앞서 마지막으로 지정된 Action으로 바꿉니다.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        // certificate is an X509Certificate2
        listenOptions.ServerCertificate = certificate;
    });
});

참고 항목

ConfigureHttpsDefaults를 호출하기 전에 Listen을 호출하여 생성된 엔드포인트는 기본값이 적용되지 않습니다.

ListenOptions.UseHttps

HTTPS를 사용하도록 Kestrel을 구성합니다.

ListenOptions.UseHttps 확장:

  • UseHttps: 기본 인증서를 통해 HTTPS를 사용하도록 Kestrel을 구성합니다. 기본 인증서가 구성되지 않은 경우 예외를 throw합니다.
  • 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 인증서 데이터에 액세스하는 데 필요한 암호입니다.
  • configureOptionsHttpsConnectionAdapterOptions를 구성하는 Action입니다. ListenOptions를 반환합니다.
  • storeName은 인증서를 로드할 수 있는 인증서 저장소입니다.
  • subject은 인증서의 주체 이름입니다.
  • allowInvalid은 자체 서명된 인증서와 같이 잘못된 인증서를 고려해야 할 경우를 나타냅니다.
  • location은 인증서를 로드할 수 있는 저장소 위치입니다.
  • serverCertificate은 X.509 인증서입니다.

프로덕션 내에 HTTPS가 명시적으로 구성되어야 합니다. 최소한 기본 인증서를 제공해야 합니다.

다음에 설명된 지원되는 구성입니다.

  • 구성 없음
  • 구성에서 기본 인증서를 바꿈
  • 코드에서 기본값 변경

구성 없음

Kestrel은 http://localhost:5000https://localhost:5001에서 수신 대기합니다(기본 인증서가 사용 가능한 경우).

구성에서 기본 인증서를 바꿈

기본 HTTPS 앱 설정 구성 스키마는 Kestrel에 대해 사용 가능합니다. 디스크 상의 파일에서 또는 인증서 저장소에서 사용할 인증서 및 URL을 포함하여 여러 엔드포인트를 구성합니다.

다음 appsettings.json 예제에서

  • 잘못된 인증서(예: 자체 서명된 인증서)의 사용을 허용하도록 true 설정합니다AllowInvalid.
  • 인증서를 지정하지 않은 임의의 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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 각 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

스키마 참고 사항:

  • 엔드포인트 이름은 대/소문자를 구분하지 않습니다. 예를 들어 HTTPS and Https 와 동일합니다.
  • Url 매개 변수는 각 엔드포인트에 대해 필요합니다. 이 매개 변수에 대한 형식은 단일 값으로 제한된 경우를 제외하고 최상위 Urls 구성 매개 변수와 동일합니다.
  • 이러한 엔드포인트는 추가하기보다는 최상위 Urls 구성에서 정의된 엔드포인트를 바꿉니다. Listen을 통해 코드에서 정의된 엔드포인트는 구성 섹션에서 정의된 엔드포인트로 누적됩니다.
  • Certificate 섹션은 선택 사항입니다. Certificate 섹션이 지정되지 않은 경우 Certificates:Default에 정의된 기본값이 사용됩니다. 사용할 수 있는 기본값이 없으면 개발 인증서가 사용됩니다. 기본값이 없고 개발 인증서가 없는 경우 서버가 예외를 throw하고 시작에 실패합니다.
  • Certificate 섹션은 여러 인증서 원본을 지원합니다.
  • 포트 충돌을 일으키지 않는 한 구성에서 원하는 수의 엔드포인트를 정의할 수 있습니다.

인증서 원본

인증서 노드를 구성하여 여러 원본에서 인증서를 로드할 수 있습니다.

  • PathPassword: .pfx 파일 로드.
  • Path, KeyPathPassword: .pem/.crt.key 파일 로드.
  • SubjectStore: 인증서 저장소에서 로드.

예를 들어 인증서를 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}"))은 구성된 엔드포인트의 설정을 보완하는 데 사용될 수 있는 .Endpoint(string name, listenOptions => { }) 메서드를 통해 KestrelConfigurationLoader를 반환합니다.

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을 호출하지 않으므로 기본 구성 섹션을 바꿀 수 있습니다.
  • KestrelConfigurationLoaderKestrelServerOptions에서 Endpoint 오버로드로 Listen API 제품군을 미러링하므로 코드 및 구성 엔드포인트를 동일 장소에서 구성할 수 있습니다. 이러한 오버로드는 이름을 사용하지 않고 구성에서 기본 설정만 사용합니다.

코드에서 기본값 변경

ConfigureEndpointDefaultsConfigureHttpsDefaults는 이전 시나리오에서 지정된 기본 인증서 재정의를 포함한 ListenOptionsHttpsConnectionAdapterOptions에 대해 기본 설정을 변경하는 데 사용될 수 있습니다. ConfigureEndpointDefaultsConfigureHttpsDefaults는 모든 엔드포인트가 구성되기 전에 호출해야 합니다.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions =>
    {
        // Configure endpoint defaults
    });

    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.SslProtocols = SslProtocols.Tls12;
    });
});

서버 이름 표시를 사용하여 엔드포인트 구성

서버 이름 표시(SNI)는 동일한 IP 주소 및 포트에서 여러 도메인을 호스트하는 데 사용될 수 있습니다. 함수에 대한 SNI의 경우 클라이언트는 TLS 핸드셰이크 동안 보안 세션에 대한 호스트 이름을 서버로 보내므로 서버에서 올바른 인증서를 제공할 수 있습니다. TLS 핸드셰이크 다음에 오는 보안 세션 동안 클라이언트는 서버와 암호화된 통신을 위해 제공된 인증서를 사용합니다.

SNI 구성 방법은 다음 두 가지입니다.

  • 코드로 엔드포인트를 만들고 호스트 이름을 ServerCertificateSelector 콜백과 함께 사용하여 인증서를 선택합니다.
  • 구성에서 호스트 이름과 HTTPS 옵션 간 매핑을 구성합니다. 예: appsettings.json 파일의 JSON

ServerCertificateSelector과 SNI

Kestrel은 ServerCertificateSelector 콜백을 통해 SNI를 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서를 선택하도록 허용하려면 연결당 한 번씩 콜백이 호출됩니다. 다음 콜백 코드는 프로젝트 Program.cs 파일의 ConfigureWebHostDefaults 메서드 호출에서 사용할 수 있습니다.

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

ServerOptionsSelectionCallback과 SNI

Kestrel는 ServerOptionsSelectionCallback 콜백을 통해 추가 동적 TLS 구성을 지원합니다. 앱이 호스트 이름을 검사하고 적절한 인증서와 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를 지원합니다. 호스트 이름과 HTTPS 옵션 간의 매핑이 포함된 Sni 개체를 사용하여 엔드포인트를 구성할 수 있습니다. 연결 호스트 이름이 옵션과 일치하면 해당 연결에 사용됩니다.

다음 구성에서는 호스트 이름에 따라 HTTPS 옵션을 선택하기 위해 SNI를 사용하는 MySniEndpoint이라는 이름의 엔드포인트를 추가합니다.

{
  "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$"
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 각 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

SNI로 재정의될 수 있는 HTTPS 옵션

호스트 이름은 와일드카드 일치를 지원합니다.

  • 정확한 일치. 예를 들어 a.example.orga.example.org와 일치합니다.
  • 와일드카드 접두사 와일드카드와 일치하는 항목이 여러 개 있는 경우 가장 긴 패턴이 선택됩니다. 예를 들어 *.example.orgb.example.org, c.example.org과 일치합니다.
  • 전체 와일드카드 *은 SNI를 사용하지 않고 호스트 이름을 보내지 않은 클라이언트들을 포함하여 나머지 모두와 일치합니다.

일치하는 SNI 구성은 엔드포인트의 값을 재정의하는 연결의 엔드포인트에 적용됩니다. 연결이 구성된 SNI 호스트 이름과 일치하지 않는 경우 연결이 거부됩니다.

SNI 요구 사항

  • 대상 프레임워크 netcoreapp2.1 이상에서 실행합니다. net461 이상에서 콜백이 호출되지만 name는 항상 null입니다. 클라이언트가 TLS 핸드셰이크에서 호스트 이름 매개 변수를 제공하지 않는 경우 name은 또한 null입니다.
  • 모든 웹 사이트는 동일한 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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 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$"
        }
      }
    }
  }
}

Warning

앞의 예제에서 인증서 암호는 appsettings.json에 일반 텍스트로 저장됩니다. $CREDENTIAL_PLACEHOLDER$ 토큰은 인증서의 암호에 대한 자리 표시자로 사용됩니다. 개발 환경에서 인증서 암호를 안전하게 저장하려면 개발 시 비밀 보호를 참조하세요. 프로덕션 환경에서 인증서 암호를 안전하게 저장하려면 Azure Key Vault 구성 공급자를 참조하세요. 개발 비밀은 프로덕션 또는 테스트에 사용하면 안 됩니다.

기본값은 ClientCertificateMode.NoCertificate입니다. 여기서 Kestrel는 클라이언트로부터 인증서를 요청하거나 요구하지 않습니다.

자세한 내용은 ASP.NET Core에서 인증서 인증 구성을 참조하세요.

연결 로깅

UseConnectionLogging을 호출하여 연결에 대한 바이트 수준 통신을 위한 디버그 수준을 내보냅니다. 연결 로깅은 낮은 수준 통신(예: TLS 암호화 중에, 프록시 뒤에서 등)에서 문제 해결을 진행하는 데 유용합니다. UseConnectionLoggingUseHttps 앞에 오면 암호화된 트래픽이 로깅됩니다. UseConnectionLoggingUseHttps 뒤에 오면 암호 해독된 트래픽이 로깅됩니다. 이는 기본 제공 연결 미들웨어입니다.

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

예제에서는 ListenOptions를 사용하여 엔드포인트에 대한 HTTPS를 구성합니다. 동일한 API를 사용하여 특정 엔드포인트에 대한 다른 Kestrel 설정을 구성합니다.

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

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

Unix 소켓에 바인딩

이 예제에 나와 있는 것처럼 Nginx를 사용하여 성능을 향상하기 위해 ListenUnixSocket을 사용하여 Unix 소켓을 수신 대기할 수 있습니다.

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 구성 또는 구성 파일 사용).
  • ListenUseUrls 방식 모두를 동시에 사용할 경우 Listen 엔드포인트는 UseUrls 엔드포인트를 재정의합니다.

IIS 엔드포인트 구성

IIS를 사용하는 경우 IIS 재정의 바인딩에 대한 URL 바인딩은 Listen 또는 UseUrls에 의해 설정됩니다. 자세한 내용은 ASP.NET Core 모듈을 참조하세요.

ListenOptions.Protocols

Protocols 속성은 연결 엔드포인트 또는 서버에 대해 사용할 수 있는 HTTP 프로토콜(HttpProtocols)을 설정합니다. HttpProtocols 열거형의 Protocols 속성에 값을 할당합니다.

HttpProtocols 열거형 값 허용되는 연결 프로토콜
Http1 HTTP/1.1 전용. TLS와 함께 또는 TLS 없이 사용할 수 있습니다.
Http2 HTTP/2 전용. 클라이언트가 이전 기술 모드를 지원하는 경우에만 TLS 없이 사용할 수 있습니다.
Http1AndHttp2 HTTP/1.1 및 HTTP/2. HTTP/2를 사용하려면 클라이언트가 TLS ALPN(Application-Layer Protocol Negotiation) 핸드셰이크에서 HTTP/2를 선택해야 합니다. 그렇지 않으면 연결 기본값은 HTTP/1.1입니다.

모든 엔드포인트의 기본 ListenOptions.Protocols 값은 HttpProtocols.Http1AndHttp2입니다.

HTTP/2에 대한 TLS 제한 사항:

  • TLS 버전 1.2 이상
  • 재협상 사용 안 함
  • 압축 사용 안함
  • 최소 임시 키 교환 크기:
    • ECDHE(타원 곡선 Diffie-Hellman) [RFC4492]: 최소 224비트
    • 유한 필드 DHE(Diffie-Hellman) [TLS12]: 최소 2048비트
  • 암호 도구 모음은 금지되지 않습니다.

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE](P-256 타원 곡선 [FIPS186] 포함)는 기본적으로 지원됩니다.

다음 예제는 포트 8000에서 HTTP/1.1 및 HTTP/2 연결을 허용합니다. 연결은 제공된 인증서를 사용하여 TLS로 보호됩니다.

webBuilder.ConfigureKestrel(serverOptions =>
{
    serverOptions.Listen(IPAddress.Any, 8000, listenOptions =>
    {
        listenOptions.UseHttps("testCert.pfx", "testPassword");
    });
});

Linux에서 CipherSuitesPolicy를 사용하여 각 연결을 기준으로 TLS 핸드셰이크를 필터링할 수 있습니다.

// 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을 throw합니다. 또는 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 접두사는 다음 형식 중 하나일 수 있습니다.

HTTP URL 접두사만 유효합니다. Kestrel은 UseUrls를 사용하여 URL 바인딩을 구성하는 경우 HTTPS를 지원하지 않습니다.

  • 포트 번호가 있는 IPv4 주소

    http://65.55.39.10:80/
    

    0.0.0.0은 모든 IPv4 주소에 바인딩하는 특별한 경우입니다.

  • 포트 번호가 있는 IPv6 주소

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

    [::]는 IPv4 0.0.0.0에 해당하는 IPv6입니다.

  • 포트 번호가 있는 호스트 이름

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

    호스트 이름, *+는 특별하지 않습니다. 유효한 IP 주소 또는 localhost로 인식하지 않는 모든 항목은 모든 IPv4 및 IPv6 IP에 바인딩합니다. 다양한 호스트 이름을 같은 포트에서 서로 다른 ASP.NET Core 앱에 바인딩하려면 역방향 프록시 서버 또는 HTTP.sys를 사용합니다. 역방향 프록시 서버의 예로는 IIS, Nginx 또는 Apache가 있습니다.

    Warning

    역방향 프록시 구성에서 호스팅하려면 호스트 필터링이 필요합니다.

  • 포트 번호가 있는 호스트 localhost 이름 또는 포트 번호가 있는 루프백 IP

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

    localhost가 지정되면 Kestrel은 IPv4 및 IPv6 루프백 인터페이스 모두에 바인딩하려고 합니다. 요청된 포트가 루프백 인터페이스 중 하나의 다른 서비스에서 사용 중인 경우 Kestrel은 시작에 실패합니다. 루프백 인터페이스 중 하나를 다른 이유(일반적으로 IPv6이 지원되지 않으므로)로 사용할 수 없는 경우 Kestrel은 경고를 기록합니다.