ASP.NET Core의 HTTP.sys 웹 서버 구현

등록일시: 2017-10-23 08:00,  수정일시: 2017-10-23 08:00
조회수: 6,455
이 문서는 ASP.NET Core 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.
본문에서는 ASP.NET Core 2.x 버전의 HTTP.sys 웹 서버 구현에 관해서 살펴봅니다.
노트

본문의 내용은 ASP.NET Core 2.0 이상에만 적용됩니다. 이전 버전의 ASP.NET Core에서는 HTTP.sys의 이름이 WebListener이었습니다.

HTTP.sys는 Windows 전용 ASP.NET Core 웹 서버로, Http.Sys 커널 모드 드라이버에 기반하고 있습니다. HTTP.sys는 Kestrel이 지원하지 않는 몇 가지 기능을 제공하는 Kestel의 대안입니다. HTTP.sys는 ASP.NET Core 모듈과 호환되지 않기 때문에 IIS 또는 IIS Express와 함께 사용할 수 없습니다.

HTTP.sys는 다음의 기능들을 지원합니다:

  • Windows 인증
  • 포트 공유
  • SNI를 지원하는 HTTPS
  • TLS를 이용한 HTTP/2 (Windows 10)
  • 직접 파일 전송
  • 응답 캐싱
  • WebSockets (Windows 8)

지원되는 Windows 버전:

  • Windows 7 및 Windows 서버 2008 R2 이상

예제 코드 살펴보기 및 다운로드

HTTP.sys를 사용해야 하는 경우

HTTP.sys는 IIS를 사용하지 않고 인터넷에 서버를 직접 노출해야 하는 배포에 유용합니다.

HTTP.sys communicates directly with the Internet

HTTP.sys는 Http.Sys를 기반으로 하기 때문에 공격을 방어하기 위한 역방향 프록시 서버가 필요 없습니다. Http.Sys는 다양한 형태의 공격을 방어할 수 있고, 완벽한 기능을 갖춘 웹 서버의 견고함과 보안 및 확장성을 제공하는 성숙한 기술입니다. IIS 자체도 Http.Sys 위에서 HTTP Listener로 실행됩니다.

HTTP.sys는 Windows 인증 같이 Kestrel이 지원하지 않는 기능을 필요로 하는 내부 배포 시에도 적합한 선택입니다.

HTTP.sys communicates directly with your internal network

HTTP.sys 사용 방법

다음은 호스트 OS 및 ASP.NET Core 응용 프로그램의 설정 작업에 대한 대략적인 설명입니다.

Windows 서버 구성하기

  • .NET Core 또는 .NET Framework 4.5.1 같은 응용 프로그램에 필요한 .NET 버전을 설치합니다.

  • HTTP.sys에 바인딩 할 URL 접두어를 미리 등록하고, SSL 인증서를 설정합니다.

    Windows에서 URL 접두어를 미리 등록해놓지 않으면 응용 프로그램을 관리자 권한으로 실행해야 합니다. 유일한 예외는 포트 번호가 1024 보다 큰 HTTP를 사용해서 (HTTPS는 해당되지 않습니다) localhost에 바인딩 하는 경우로, 이 때는 관리자 권한이 필요 없습니다.

    더 자세한 내용은 본문의 미리 접두사를 등록하고 SSL 구성하기 절을 참고하시기 바랍니다.

  • 트래픽이 HTTP.sys에 전달될 수 있도록 방화벽 포트를 엽니다.

    이 작업은 netsh.exe 또는 PowerShell 커맨드릿으로 수행할 수 있습니다.

마지막으로 Http.Sys 레지스트리 설정도 필요합니다.

HTTP.sys를 사용하도록 ASP.NET Core 응용 프로그램 구성하기

  • Microsoft.AspNetCore.All 메타패키지를 사용하고 있다면 별도의 패키지 설치는 필요 없습니다. Microsoft.AspNetCore.Server.HttpSys 패키지도 이 메타패키지에 포함되어 있습니다.

  • 다음 예제에서 볼 수 있는 것처럼, Main 메서드에서 WebHostBuilderUseHttpSys 확장 메서드를 호출해서 필요한 HTTP.sys 옵션을 지정합니다:

    public static void Main(string[] args)
    {
        Console.WriteLine("Running demo with HTTP.sys.");
    
        BuildWebHost(args).Run();
    }
    
    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseHttpSys(options =>
            {
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = 100;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5000");
            })
            .Build();

HTTP.sys 옵션 구성하기

다음은 구성 가능한 HTTP.sys 설정 및 제약 사항들 중 일부입니다.

최대 클라이언트 연결 수

Program.cs 파일에서 다음과 같은 코드를 사용해서 전체 응용 프로그램이 동시에 열 수 있는 TCP 연결의 최대 수를 설정할 수 있습니다:

.UseHttpSys(options =>
{
    options.Authentication.Schemes = AuthenticationSchemes.None;
    options.Authentication.AllowAnonymous = true;
    options.MaxConnections = 100;
    options.MaxRequestBodySize = 30000000;
    options.UrlPrefixes.Add("http://localhost:5000");
})

최대 연결 수의 기본값은 무제한 (null) 입니다.

최대 요청 본문 크기

기본 최대 요청 본문 크기는 30,000,000 바이트로, 이는 약 28.6MB 입니다.

ASP.NET Core MVC 응용 프로그램에서 이 제한을 재정의 할 때 권장하는 방법은 액션 메서드에 RequestSizeLimit 어트리뷰트를 지정하는 것입니다:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

반면 다음 예제는 전체 응용 프로그램, 모든 요청에 대한 제약 조건을 구성하는 방법을 보여줍니다:

.UseHttpSys(options =>
{
    options.Authentication.Schemes = AuthenticationSchemes.None;
    options.Authentication.AllowAnonymous = true;
    options.MaxConnections = 100;
    options.MaxRequestBodySize = 30000000;
    options.UrlPrefixes.Add("http://localhost:5000");
})

Startup.cs에서 특정 요청에 대한 설정을 재정의 할 수도 있습니다:

public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
    var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>();

    app.UseStaticFiles();

    app.Run(async (context) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        context.Response.ContentType = "text/html";
        await context.Response.WriteAsync("<p>Hosted by HTTP.sys</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>");
    });
}

응용 프로그램이 이미 요청을 읽기 시작한 다음에 요청의 제한 사항을 구성하려고 시도하면 예외가 발생합니다. 참고로 MaxRequestBodySize 속성이 읽기 전용 상태인지, 즉, 제한을 구성하기에는 너무 늦었는지 여부를 알려주는 IsReadOnly 속성도 지원됩니다.

다른 HTTP.sys 옵션에 대한 보다 자세한 내용은 HttpSysOptions를 참조하십시오.

수신 대기 URL 및 포트 구성

기본적으로 ASP.NET Core는 http://localhost:5000에 바인딩됩니다. URL 접두사 및 포트는 UseUrls 확장 메서드, urls 명령줄 인수 또는 HttpSysOptions 클래스의 UrlPrefixes 속성을 이용해서 구성할 수 있습니다. 다음 예제는 UrlPrefixes의 사용법을 보여줍니다:

public static void Main(string[] args)
{
    Console.WriteLine("Running demo with HTTP.sys.");

    BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseHttpSys(options =>
        {
            options.Authentication.Schemes = AuthenticationSchemes.None;
            options.Authentication.AllowAnonymous = true;
            options.MaxConnections = 100;
            options.MaxRequestBodySize = 30000000;
            options.UrlPrefixes.Add("http://localhost:5000");
        })
        .Build();

UrlPrefixes의 장점은 잘못된 형식의 접두사를 추가하려고 하면 즉시 오류 메시지가 나타난다는 것입니다. 반면 UseUrls의 장점은 (urls 및 ASPNETCORE_URLS와 공유하는) 보다 손쉽게 Kestrel과 HTTP.sys를 전환할 수 있다는 점입니다.

UseUrls와 (또는 urls나 ASPNETCORE_URLS와) UrlPrefixes를 모두 사용할 경우, UrlPrefixes의 설정이 UseUrls 보다 우선합니다. 보다 자세한 내용은 ASP.NET Core의 호스팅 살펴보기 문서를 참조하시기 바랍니다.

HTTP.sys는 HTTP Server API UrlPrefix 문자열 형식을 사용합니다.

노트

UseUrls이나 UrlPrefixes에도 서버에서 사전 등록한 것과 동일한 접두사 문자열을 지정해야합니다.

IIS를 사용하지 마십시오.

응용 프로그램이 IIS 또는 IIS Express를 실행하도록 구성되어 있지는 않은지 확인합니다.

Visual Studio의 기본 실행 프로필은 IIS Express 용입니다. 프로젝트를 콘솔 응용 프로그램으로 실행하려면 다음 그림과 같이 선택된 프로필을 직접 변경해야합니다.

Select console app profile

미리 접두사를 등록하고 SSL 구성하기

IIS 및 HTTP.sys는 모두 기반 Http.Sys 커널 모드 드라이버를 이용해서 요청을 수신하고 초기 처리를 수행합니다. IIS의 경우, 관리 UI를 사용해서 모든 옵션을 비교적 손쉽게 구성할 수 있습니다. 반면 Http.Sys는 직접 구성해야 합니다. 이를 위한 기본 제공 도구는 netsh.exe 입니다.

netsh.exe 를 사용하면 URL 접두사를 예약하고 SSL 인증서를 할당할 수 있습니다. 이 도구는 관리자 권한을 필요로 합니다.

다음 예제는 포트 80 및 443에 대한 URL 접두사를 예약하기 위해서 필요한 최소한의 작업을 보여줍니다:

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

다음 예제는 SSL 인증서를 할당하는 방법을 보여줍니다:

netsh http add sslcert ipport=0.0.0.0:443 certhash=MyCertHash_Here appid={00000000-0000-0000-0000-000000000000}

다음은 netsh.exe 의 공식 참조 문서입니다:

다음 문서들은 다양한 시나리오에 대응하는 상세한 지침을 제공합니다. HttpListener와 HTTP.sys는 모두 Http.Sys를 기반으로 하기 때문에, HttpListener를 다루는 문서는 HTTP.sys에도 동일하게 적용됩니다.

다음은 netsh.exe 명령줄 도구보다 사용하기 쉬운 타사 도구들입니다. 이 도구들은 Microsoft가 제공하거나 보증하지 않습니다. netsh.exe 자체가 관리자 권한이 필요하기 때문에, 기본적으로 이 도구들도 관리자 권한으로 실행됩니다.

  • http.sys Manager는 SSL 인증서 및 옵션들을 나열하고 구성하기 위한 UI 및 접두사 예약과 인증서 신뢰 목록을 위한 UI를 제공합니다.
  • HttpConfig를 사용하면 SSL 인증서 및 URL 접두어를 나열하거나 구성할 수 있습니다. http.sys Manager보다 UI가 세련되고 몇 가지 더 많은 구성 옵션을 제공하지만, 그것 말고는 대부분 비슷한 기능을 제공합니다. 새로운 인증서 신뢰 목록(CTL, Certificate Trust List)을 만들 수는 없지만, 기존 인증서 신뢰 목록을 할당할 수는 있습니다.

Windows에서는 PowerShell New-SelfSignedCertificate 커맨드릿을 사용해서 자체 서명 SSL 인증서를 생성할 수 있습니다. 또한 자체 서명 인증서를 손쉽게 생성할 수 있게 도와주는 서드 파티 도구들도 존재합니다:

macOS나 Linux에서는 OpenSSL을 사용해서 자체 서명 인증서를 생성할 수 있습니다.

보다 자세한 정보는 Setting up HTTPS for development 문서를 참고하시기 바랍니다.

다음 단계

보다 자세한 내용은 다음 문서를 참고하시기 바랍니다: