프록시 서버 및 부하 분산 장치를 사용하도록 ASP.NET Core 구성Configure ASP.NET Core to work with proxy servers and load balancers

작성자: Chris RossBy Chris Ross

ASP.NET Core의 권장 구성에서 앱은 IIS/ASP.NET Core 모듈, Nginx 또는 Apache를 사용하여 호스트됩니다.In the recommended configuration for ASP.NET Core, the app is hosted using IIS/ASP.NET Core Module, Nginx, or Apache. 프록시 서버, 부하 분산 장치 및 기타 네트워크 어플라이언스는 종종 앱에 도달하기 전에 요청에 대한 정보를 숨깁니다.Proxy servers, load balancers, and other network appliances often obscure information about the request before it reaches the app:

  • HTTPS 요청이 HTTP를 통해 프록시된 경우 원래 스키마(HTTPS)가 손실되므로 헤더에서 전달되어야 합니다.When HTTPS requests are proxied over HTTP, the original scheme (HTTPS) is lost and must be forwarded in a header.
  • 앱은 프록시에서 요청을 수신하고 인터넷 또는 회사 네트워크의 실제 소스를 수신하는 것이 아니므로 원래 클라이언트 IP 주소도 헤더에서 전달되어야 합니다.Because an app receives a request from the proxy and not its true source on the Internet or corporate network, the originating client IP address must also be forwarded in a header.

이 정보는 요청 처리 시 중요할 수 있습니다(예: 리디렉션, 인증, 링크 생성, 정책 평가 및 클라이언트 지리적 위치).This information may be important in request processing, for example in redirects, authentication, link generation, policy evaluation, and client geolocation.

전달된 헤더Forwarded headers

규칙에 따라 프록시는 HTTP 헤더에서 정보를 전달합니다.By convention, proxies forward information in HTTP headers.

헤더Header 설명Description
X-Forwarded-ForX-Forwarded-For 요청 및 프록시 체인의 후속 프록시를 시작한 클라이언트에 대한 정보를 포함합니다.Holds information about the client that initiated the request and subsequent proxies in a chain of proxies. 이 매개 변수에는 IP 주소(및 선택적으로 포트 번호)가 포함될 수 있습니다.This parameter may contain IP addresses (and, optionally, port numbers). 프록시 서버의 체인에서 첫 번째 매개 변수는 요청이 처음 만들어진 클라이언트를 나타냅니다.In a chain of proxy servers, the first parameter indicates the client where the request was first made. 그 뒤에 후속 프록시 식별자가 추가됩니다.Subsequent proxy identifiers follow. 체인의 마지막 프록시는 매개 변수 목록에 없습니다.The last proxy in the chain isn't in the list of parameters. 마지막 프록시의 IP 주소 및 선택적으로 포트 번호는 전송 계층에서 원격 IP 주소로 사용할 수 있습니다.The last proxy's IP address, and optionally a port number, are available as the remote IP address at the transport layer.
X-Forwarded-ProtoX-Forwarded-Proto 원래 체계(HTTP/HTTPS)의 값입니다.The value of the originating scheme (HTTP/HTTPS). 요청이 여러 프록시를 트래버스한 경우에는 값이 체계 목록일 수도 있습니다.The value may also be a list of schemes if the request has traversed multiple proxies.
X-Forwarded-HostX-Forwarded-Host 호스트 헤더 필드의 원래 값입니다.The original value of the Host header field. 일반적으로 프록시는 호스트 헤더를 수정하지 않습니다.Usually, proxies don't modify the Host header. 프록시가 호스트 헤더를 유효성 검사하거나 알려진 정상 값으로 제한하지 않는 시스템에 영향을 미치는 권한 상승 취약성에 대한 자세한 내용은 Microsoft 보안 공지 CVE-2018-0787을 참조하세요.See Microsoft Security Advisory CVE-2018-0787 for information on an elevation-of-privileges vulnerability that affects systems where the proxy doesn't validate or restrict Host headers to known good values.

전달된 헤더 미들웨어(ForwardedHeadersMiddleware)는 헤더를 읽고 HttpContext의 관련 필드를 채웁니다.The Forwarded Headers Middleware (ForwardedHeadersMiddleware), reads these headers and fills in the associated fields on HttpContext.

미들웨어가 다음을 업데이트합니다.The middleware updates:

전달된 헤더 미들웨어 기본 설정을 구성할 수 있습니다.Forwarded Headers Middleware default settings can be configured. 기본 설정은 다음과 같습니다.The default settings are:

  • 앱과 요청 소스 사이에는 ‘하나의 프록시’만 있습니다.There is only one proxy between the app and the source of the requests.
  • 알려진 프록시 및 알려진 네트워크의 경우 루프백 주소만 구성됩니다.Only loopback addresses are configured for known proxies and known networks.
  • 전달된 헤더의 이름은 X-Forwarded-ForX-Forwarded-Proto입니다.The forwarded headers are named X-Forwarded-For and X-Forwarded-Proto.

일부 네트워크 어플라이언스는 X-Forwarded-ForX-Forwarded-Proto 헤더를 추가하려면 추가 구성이 필요합니다.Not all network appliances add the X-Forwarded-For and X-Forwarded-Proto headers without additional configuration. 프록시된 요청이 앱에 도달할 때 이러한 헤더를 포함하지 않는 경우에는 어플라이언스 제조업체의 지침을 참조하세요.Consult your appliance manufacturer's guidance if proxied requests don't contain these headers when they reach the app. 어플라이언스가 X-Forwarded-ForX-Forwarded-Proto와는 다른 헤더 이름을 사용하는 경우 ForwardedForHeaderNameForwardedProtoHeaderName 옵션을 어플라이언스에서 사용하는 헤더 이름과 일치하도록 설정합니다.If the appliance uses different header names than X-Forwarded-For and X-Forwarded-Proto, set the ForwardedForHeaderName and ForwardedProtoHeaderName options to match the header names used by the appliance. 자세한 내용은 전달된 헤더 미들웨어 옵션다른 헤더 이름을 사용하는 프록시 구성을 참조하세요.For more information, see Forwarded Headers Middleware options and Configuration for a proxy that uses different header names.

IIS/IIS Express 및 ASP.NET Core 모듈IIS/IIS Express and ASP.NET Core Module

앱이 IIS 및 ASP.NET Core 모듈 뒤에서 호스트되는 Out of Process인 경우 전달된 헤더 미들웨어가 IIS 통합 미들웨어에 의해 기본적으로 사용하도록 설정됩니다.Forwarded Headers Middleware is enabled by default by IIS Integration Middleware when the app is hosted out-of-process behind IIS and the ASP.NET Core Module. 전달된 헤더 미들웨어는 전달된 헤더 관련 신뢰 문제(예: IP 스푸핑)로 인해 ASP.NET Core 모듈에 특정한 제한된 구성을 사용하여 미들웨어 파이프라인에서 첫 번째로 실행될 수 있도록 활성화됩니다.Forwarded Headers Middleware is activated to run first in the middleware pipeline with a restricted configuration specific to the ASP.NET Core Module due to trust concerns with forwarded headers (for example, IP spoofing). 미들웨어는 X-Forwarded-ForX-Forwarded-Proto 헤더를 전달하도록 구성되고 단일 localhost 프록시로 제한됩니다.The middleware is configured to forward the X-Forwarded-For and X-Forwarded-Proto headers and is restricted to a single localhost proxy. 추가 구성이 필요한 경우 전달된 헤더 미들웨어 옵션을 참조하세요.If additional configuration is required, see the Forwarded Headers Middleware options.

기타 프록시 서버 및 부하 분산 장치 시나리오Other proxy server and load balancer scenarios

Out of Process를 호스트할 때 IIS 통합 사용 외에는 전달된 헤더 미들웨어가 기본적으로 사용하도록 설정되지 않습니다.Outside of using IIS Integration when hosting out-of-process, Forwarded Headers Middleware isn't enabled by default. 앱에서 UseForwardedHeaders를 사용하여 전달된 헤더를 처리하려면 전달된 헤더 미들웨어를 사용하도록 설정해야 합니다.Forwarded Headers Middleware must be enabled for an app to process forwarded headers with UseForwardedHeaders. 미들웨어를 사용하도록 설정한 후 미들웨어에 ForwardedHeadersOptions를 지정하지 않은 경우 기본 ForwardedHeadersOptions.ForwardedHeadersForwardedHeaders.None입니다.After enabling the middleware if no ForwardedHeadersOptions are specified to the middleware, the default ForwardedHeadersOptions.ForwardedHeaders are ForwardedHeaders.None.

ForwardedHeadersOptions를 사용하여 Startup.ConfigureServicesX-Forwarded-ForX-Forwarded-Proto 헤더를 전달하도록 미들웨어를 구성합니다.Configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices.

전달된 헤더 미들웨어 순서Forwarded Headers Middleware order

전달된 헤더 미들웨어는 다른 미들웨어보다 먼저 실행해야 합니다.Forwarded Headers Middleware should run before other middleware. 이 순서를 지정하면 전달된 헤더 정보에 따라 달라지는 미들웨어는 처리하기 위해 헤더 값을 사용할 수 있습니다.This ordering ensures that the middleware relying on forwarded headers information can consume the header values for processing. 전달된 헤더 미들웨어는 진단 및 오류 처리 뒤에 실행될 수 있지만 UseHsts를 호출하기 전에 실행되어야 합니다.Forwarded Headers Middleware can run after diagnostics and error handling, but it must be run before calling UseHsts:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders =
                ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        });
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

또는 진단 전에 UseForwardedHeaders를 호출합니다.Alternatively, call UseForwardedHeaders before diagnostics:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseForwardedHeaders();

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

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

참고

Startup.ConfigureServices에서 ForwardedHeadersOptions를 지정하지 않거나 UseForwardedHeaders를 사용하여 확장 메서드에 직접 지정하지 않은 경우 전달할 기본 헤더는 ForwardedHeaders.None입니다.If no ForwardedHeadersOptions are specified in Startup.ConfigureServices or directly to the extension method with UseForwardedHeaders, the default headers to forward are ForwardedHeaders.None. 전달할 헤더를 사용하여 ForwardedHeaders 속성을 구성해야 합니다.The ForwardedHeaders property must be configured with the headers to forward.

Nginx 구성Nginx configuration

X-Forwarded-ForX-Forwarded-Proto 헤더를 전달하려면 Nginx를 사용하여 Linux에서 ASP.NET Core 호스트를 참조하세요.To forward the X-Forwarded-For and X-Forwarded-Proto headers, see Nginx를 사용하여 Linux에서 ASP.NET Core 호스트. 자세한 내용은 NGINX: 전달된 헤더 사용을 참조하세요.For more information, see NGINX: Using the Forwarded header.

Apache 구성Apache configuration

X-Forwarded-For가 자동으로 추가됩니다( Apache 모듈 mod_proxy: 역방향 프록시 요청 헤더 참조).X-Forwarded-For is added automatically (see Apache Module mod_proxy: Reverse Proxy Request Headers). X-Forwarded-Proto 헤더를 전달하는 방법에 대한 내용은 Apache를 사용하여 Linux에서 ASP.NET Core 호스트를 참조하세요.For information on how to forward the X-Forwarded-Proto header, see Apache를 사용하여 Linux에서 ASP.NET Core 호스트.

전달된 헤더 미들웨어 옵션Forwarded Headers Middleware options

ForwardedHeadersOptions는 전달된 헤더 미들웨어의 동작을 제어합니다.ForwardedHeadersOptions control the behavior of the Forwarded Headers Middleware. 다음 예제에서는 기본값을 변경합니다.The following example changes the default values:

  • 전달된 헤더의 항목 수를 2로 제한합니다.Limit the number of entries in the forwarded headers to 2.
  • 127.0.10.1의 알려진 프록시 주소를 추가합니다.Add a known proxy address of 127.0.10.1.
  • 전달된 헤더 이름을 기본값 X-Forwarded-For에서 X-Forwarded-For-My-Custom-Header-Name으로 변경합니다.Change the forwarded header name from the default X-Forwarded-For to X-Forwarded-For-My-Custom-Header-Name.
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
    options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
옵션Option 설명Description
AllowedHosts X-Forwarded-Host 헤더에 의한 호스트를 제공된 값으로 제한합니다.Restricts hosts by the X-Forwarded-Host header to the values provided.
  • 값은 ordinal-ignore-case를 사용하여 비교됩니다.Values are compared using ordinal-ignore-case.
  • 포트 번호는 제외해야 합니다.Port numbers must be excluded.
  • 목록이 비어 있으면 모든 호스트가 허용됩니다.If the list is empty, all hosts are allowed.
  • 최상위 수준 와일드카드 *는 비어 있지 않은 모든 호스트를 허용합니다.A top-level wildcard * allows all non-empty hosts.
  • 하위 도메인 와일드카드는 허용되지만 루트 도메인과 일치하지 않습니다.Subdomain wildcards are permitted but don't match the root domain. 예를 들어 *.contoso.com은 하위 도메인 foo.contoso.com과 일치하지만 루트 도메인 contoso.com과 일치하지 않습니다.For example, *.contoso.com matches the subdomain foo.contoso.com but not the root domain contoso.com.
  • 유니코드 호스트 이름은 허용되지만 일치시킬 Punycode로 변환됩니다.Unicode host names are allowed but are converted to Punycode for matching.
  • IPv6 주소는 경계 대괄호를 포함하고 기존 형식이어야 합니다(예: [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]).IPv6 addresses must include bounding brackets and be in conventional form (for example, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6 주소는 서로 다른 형식 간에 논리적 같음을 확인하기 위해 특별히 처리되지 않으며 정규화가 수행되지 않습니다.IPv6 addresses aren't special-cased to check for logical equality between different formats, and no canonicalization is performed.
  • 허용된 호스트를 제한하지 못하면 공격자가 서비스에서 생성된 링크를 스푸핑할 수 있습니다.Failure to restrict the allowed hosts may allow an attacker to spoof links generated by the service.
기본값은 빈 IList<string>입니다.The default value is an empty IList<string>.
ForwardedForHeaderName ForwardedHeadersDefaults.XForwardedForHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedForHeaderName. 이 옵션은 프록시/전달자가 X-Forwarded-For 헤더를 사용하지 않고 일부 다른 헤더를 사용하여 정보를 전달할 때 사용됩니다.This option is used when the proxy/forwarder doesn't use the X-Forwarded-For header but uses some other header to forward the information.

기본값은 X-Forwarded-For입니다.The default is X-Forwarded-For.
ForwardedHeaders 처리해야 할 전달자를 알려줍니다.Identifies which forwarders should be processed. 적용되는 필드 목록은 ForwardedHeaders 열거형을 참조하세요.See the ForwardedHeaders Enum for the list of fields that apply. 이 속성에 할당된 일반적인 값은 ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto입니다.Typical values assigned to this property are ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

기본값은 ForwardedHeaders.None입니다.The default value is ForwardedHeaders.None.
ForwardedHostHeaderName ForwardedHeadersDefaults.XForwardedHostHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedHostHeaderName. 이 옵션은 프록시/전달자가 X-Forwarded-Host 헤더를 사용하지 않고 일부 다른 헤더를 사용하여 정보를 전달할 때 사용됩니다.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Host header but uses some other header to forward the information.

기본값은 X-Forwarded-Host입니다.The default is X-Forwarded-Host.
ForwardedProtoHeaderName ForwardedHeadersDefaults.XForwardedProtoHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedProtoHeaderName. 이 옵션은 프록시/전달자가 X-Forwarded-Proto 헤더를 사용하지 않고 일부 다른 헤더를 사용하여 정보를 전달할 때 사용됩니다.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Proto header but uses some other header to forward the information.

기본값은 X-Forwarded-Proto입니다.The default is X-Forwarded-Proto.
ForwardLimit 처리되는 헤더의 항목 수를 제한합니다.Limits the number of entries in the headers that are processed. 제한을 사용하지 않도록 null로 설정하지만, KnownProxies 또는 KnownNetworks가 구성된 경우에만 사용해야 합니다.Set to null to disable the limit, but this should only be done if KnownProxies or KnownNetworks are configured. 비-null 값을 설정하면 잘못 구성된 프록시 및 네트워크에서 측면 채널에서 오는 악성 요청을 예방하지만 보증하지는 않습니다.Setting a non-null value is a precaution (but not a guarantee) to guard against misconfigured proxies and malicious requests arriving from side-channels on the network.

전달된 헤더 미들웨어는 헤더를 역순으로 오른쪽에서 왼쪽으로 처리합니다.Forwarded Headers Middleware processes headers in reverse order from right to left. 기본값(1)만 사용된다면 ForwardLimit의 값을 늘리지 않는 한, 헤더에서 맨 오른쪽 값만 처리됩니다.If the default value (1) is used, only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

기본값은 1입니다.The default is 1.
KnownNetworks 전달된 헤더를 허용하기 위한 알려진 네트워크의 주소 범위입니다.Address ranges of known networks to accept forwarded headers from. CIDR(Classless Interdomain Routing) 표기법을 사용하여 IP 범위를 제공합니다.Provide IP ranges using Classless Interdomain Routing (CIDR) notation.

서버에서 이중 모드 소켓을 사용하는 경우 IPv4 주소가 IPv6 형식(예: IPv4에서 10.0.0.1은 IPv6에서 ::ffff:10.0.0.1로 표시됨)으로 제공됩니다.If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). IPAddress.MapToIPv6를 참조하세요.See IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress를 참조하여 이 형식이 필요한지 확인하세요.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. 자세한 내용은 IPv6 주소로 표시되는 IPv4 주소 구성 섹션을 참조하세요.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

기본값은 IPAddress.Loopback에 대한 단일 항목을 포함하는 IList<IPNetwork>입니다.The default is an IList<IPNetwork> containing a single entry for IPAddress.Loopback.
KnownProxies 전달된 헤더를 허용하기 위한 알려진 프록시의 주소입니다.Addresses of known proxies to accept forwarded headers from. KnownProxies를 사용하여 정확한 IP 주소 일치 항목을 지정합니다.Use KnownProxies to specify exact IP address matches.

서버에서 이중 모드 소켓을 사용하는 경우 IPv4 주소가 IPv6 형식(예: IPv4에서 10.0.0.1은 IPv6에서 ::ffff:10.0.0.1로 표시됨)으로 제공됩니다.If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). IPAddress.MapToIPv6를 참조하세요.See IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress를 참조하여 이 형식이 필요한지 확인하세요.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. 자세한 내용은 IPv6 주소로 표시되는 IPv4 주소 구성 섹션을 참조하세요.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

기본값은 IPAddress.IPv6Loopback에 대한 단일 항목을 포함하는 IList<IPAddress>입니다.The default is an IList<IPAddress> containing a single entry for IPAddress.IPv6Loopback.
OriginalForHeaderName ForwardedHeadersDefaults.XOriginalForHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalForHeaderName.

기본값은 X-Original-For입니다.The default is X-Original-For.
OriginalHostHeaderName ForwardedHeadersDefaults.XOriginalHostHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalHostHeaderName.

기본값은 X-Original-Host입니다.The default is X-Original-Host.
OriginalProtoHeaderName ForwardedHeadersDefaults.XOriginalProtoHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalProtoHeaderName.

기본값은 X-Original-Proto입니다.The default is X-Original-Proto.
RequireHeaderSymmetry 처리 중인 ForwardedHeadersOptions.ForwardedHeaders 간에 동기화할 헤더 값 수가 필요합니다.Require the number of header values to be in sync between the ForwardedHeadersOptions.ForwardedHeaders being processed.

ASP.NET Core 1.x의 기본값은 true입니다.The default in ASP.NET Core 1.x is true. ASP.NET Core 2.0 이상의 기본값은 false입니다.The default in ASP.NET Core 2.0 or later is false.

시나리오 및 사용 사례Scenarios and use cases

전달된 헤더를 추가할 수 없고 모든 요청이 안전한 경우When it isn't possible to add forwarded headers and all requests are secure

일부 경우에는 앱으로 프록시된 요청에 전달된 헤더를 추가할 수 없습니다.In some cases, it might not be possible to add forwarded headers to the requests proxied to the app. 모든 공용 외부 요청이 HTTPS가 되도록 프록시가 적용되는 경우 미들웨어를 사용하기 전에 Startup.Configure에서 체계를 수동으로 설정할 수 있습니다.If the proxy is enforcing that all public external requests are HTTPS, the scheme can be manually set in Startup.Configure before using any type of middleware:

app.Use((context, next) =>
{
    context.Request.Scheme = "https";
    return next();
});

이 코드는 개발 또는 스테이징 환경에서 환경 변수 또는 기타 구성 설정을 통해 사용하지 않도록 설정될 수 있습니다.This code can be disabled with an environment variable or other configuration setting in a development or staging environment.

요청 경로를 변경하는 프록시 및 경로 기준을 처리합니다.Deal with path base and proxies that change the request path

일부 프록시는 경로를 그대로 전달하지만 라우팅이 제대로 작동하도록 제거해야 하는 앱 기본 경로를 포함합니다.Some proxies pass the path intact but with an app base path that should be removed so that routing works properly. UsePathBaseExtensions.UsePathBase 미들웨어는 경로를 HttpRequest.Path로 분할하고 앱 기본 경로를 HttpRequest.PathBase로 분할합니다.UsePathBaseExtensions.UsePathBase middleware splits the path into HttpRequest.Path and the app base path into HttpRequest.PathBase.

/foo/foo/api/1로 전달되는 프록시 경로의 앱 기본 경로인 경우 미들웨어는 다음 명령을 사용하여 Request.PathBase/foo로 설정하고 Request.Path/api/1로 설정합니다.If /foo is the app base path for a proxy path passed as /foo/api/1, the middleware sets Request.PathBase to /foo and Request.Path to /api/1 with the following command:

app.UsePathBase("/foo");

미들웨어가 역방향으로 다시 호출되면 원래 경로 및 경로 기준이 다시 적용됩니다.The original path and path base are reapplied when the middleware is called again in reverse. 미들웨어 순서 처리에 대한 자세한 내용은 ASP.NET Core 미들웨어 기본 사항를 참조하세요.For more information on middleware order processing, see ASP.NET Core 미들웨어 기본 사항.

프록시가 경로를 자르는 경우(예: /foo/api/1/api/1에 전달) 요청의 PathBase 속성을 설정하여 리디렉션 및 링크를 수정합니다.If the proxy trims the path (for example, forwarding /foo/api/1 to /api/1), fix redirects and links by setting the request's PathBase property:

app.Use((context, next) =>
{
    context.Request.PathBase = new PathString("/foo");
    return next();
});

프록시가 경로 데이터를 추가하는 경우 경로의 일부를 삭제한 다음, StartsWithSegments를 사용하고 Path 속성에 할당하여 리디렉션 및 링크를 수정합니다.If the proxy is adding path data, discard part of the path to fix redirects and links by using StartsWithSegments and assigning to the Path property:

app.Use((context, next) =>
{
    if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
    {
        context.Request.Path = remainder;
    }

    return next();
});

다른 헤더 이름을 사용하는 프록시에 대한 구성Configuration for a proxy that uses different header names

프록시가 X-Forwarded-ForX-Forwarded-Proto라는 헤더를 사용하여 프록시 주소/포트 및 원래 체계 정보를 전달하지 않는 경우, ForwardedForHeaderNameForwardedProtoHeaderName 옵션을 프록시에서 사용하는 헤더 이름과 일치하도록 설정합니다.If the proxy doesn't use headers named X-Forwarded-For and X-Forwarded-Proto to forward the proxy address/port and originating scheme information, set the ForwardedForHeaderName and ForwardedProtoHeaderName options to match the header names used by the proxy:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedForHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-For_Header";
    options.ForwardedProtoHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-Proto_Header";
});

IPv6 주소로 표시되는 IPv4 주소 구성Configuration for an IPv4 address represented as an IPv6 address

서버에서 이중 모드 소켓을 사용하는 경우 IPv4 주소가 IPv6 형식(예: IPv4에서 10.0.0.1은 IPv6에서 ::ffff:10.0.0.1 또는 ::ffff:a00:1로 표시됨)으로 제공됩니다.If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1 or ::ffff:a00:1). IPAddress.MapToIPv6를 참조하세요.See IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress를 참조하여 이 형식이 필요한지 확인하세요.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress.

다음 예제에서는 전달된 헤더를 제공하는 네트워크 주소가 IPv6 형식의 KnownNetworks 목록에 추가됩니다.In the following example, a network address that supplies forwarded headers is added to the KnownNetworks list in IPv6 format.

IPv4 주소: 10.11.12.1/8IPv4 address: 10.11.12.1/8

변환된 IPv6 주소: ::ffff:10.11.12.1Converted IPv6 address: ::ffff:10.11.12.1
변환된 접두사 길이: 104Converted prefix length: 104

16진수 형식으로 주소를 제공할 수도 있습니다(IPv6에서 표시된 10.11.12.1::ffff:0a0b:0c01로 표시).You can also supply the address in hexadecimal format (10.11.12.1 represented in IPv6 as ::ffff:0a0b:0c01). IPv4 주소를 IPv6로 변환할 때 CIDR 접두사 길이(예제에서는 8)에 96을 추가하여 추가 ::ffff: IPv6 접두사를 처리합니다(8 + 96 = 104).When converting an IPv4 address to IPv6, add 96 to the CIDR Prefix Length (8 in the example) to account for the additional ::ffff: IPv6 prefix (8 + 96 = 104).

// To access IPNetwork and IPAddress, add the following namespaces:
// using System.Net;
// using Microsoft.AspNetCore.HttpOverrides;
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Add(new IPNetwork(
        IPAddress.Parse("::ffff:10.11.12.1"), 104));
});

Linux용 스키마 및 비 IIS 역방향 프록시 전달Forward the scheme for Linux and non-IIS reverse proxies

UseHttpsRedirectionUseHsts을(를) 호출하는 앱은 Azure Linux App Service, Azure Linux VM(가상 머신) 또는 IIS 이외의 다른 역방향 프록시 뒤에 배포된 경우 사이트를 무한 루프에 배치합니다.Apps that call UseHttpsRedirection and UseHsts put a site into an infinite loop if deployed to an Azure Linux App Service, Azure Linux virtual machine (VM), or behind any other reverse proxy besides IIS. TLS는 역방향 프록시에 의해 종료되며, Kestrel은 올바른 요청 체계를 인식하지 못합니다.TLS is terminated by the reverse proxy, and Kestrel isn't made aware of the correct request scheme. OAuth 및 OIDC도 잘못된 리디렉션을 생성하므로 이 구성에서 실패합니다.OAuth and OIDC also fail in this configuration because they generate incorrect redirects. UseIISIntegration은 IIS 뒤에서 실행되는 경우 전달된 헤더 미들웨어를 추가하고 구성하지만 Linux에 대한 일치하는 자동 구성이 없습니다(Apache 또는 Nginx 통합).UseIISIntegration adds and configures Forwarded Headers Middleware when running behind IIS, but there's no matching automatic configuration for Linux (Apache or Nginx integration).

비 IIS 시나리오에서 프록시의 스키마를 전달하려면 전달된 헤더 미들웨어를 추가하고 구성합니다.To forward the scheme from the proxy in non-IIS scenarios, add and configure Forwarded Headers Middleware. Startup.ConfigureServices에서 다음 코드를 사용합니다.In Startup.ConfigureServices, use the following code:

// using Microsoft.AspNetCore.HttpOverrides;

if (string.Equals(
    Environment.GetEnvironmentVariable("ASPNETCORE_FORWARDEDHEADERS_ENABLED"), 
    "true", StringComparison.OrdinalIgnoreCase))
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
            ForwardedHeaders.XForwardedProto;
        // Only loopback proxies are allowed by default.
        // Clear that restriction because forwarders are enabled by explicit 
        // configuration.
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });
}

인증서 전달Certificate forwarding

AzureAzure

인증서 전달에 대한 Azure App Service를 구성하려면 Azure App Service에 대한 TLS 상호 인증 구성을 참조하세요.To configure Azure App Service for certificate forwarding, see Configure TLS mutual authentication for Azure App Service. 다음 지침은 ASP.NET Core 앱 구성과 관련됩니다.The following guidance pertains to configuring the ASP.NET Core app.

Startup.Configure에서 app.UseAuthentication(); 호출 앞에 다음 코드를 추가합니다.In Startup.Configure, add the following code before the call to app.UseAuthentication();:

app.UseCertificateForwarding();

인증서 전달 미들웨어를 구성하여 Azure를 사용하는 헤더 이름을 지정합니다.Configure Certificate Forwarding Middleware to specify the header name that Azure uses. Startup.ConfigureServices에서 다음 코드를 추가하여 미들웨어가 인증서를 빌드하는 헤더를 구성합니다.In Startup.ConfigureServices, add the following code to configure the header from which the middleware builds a certificate:

services.AddCertificateForwarding(options =>
    options.CertificateHeader = "X-ARR-ClientCert");

다른 웹 프록시Other web proxies

IIS 또는 Azure App Service의 ARR(애플리케이션 요청 라우팅)이 아닌 프록시를 사용하는 경우 HTTP 헤더에서 받은 인증서를 전달하도록 프록시를 구성합니다.If a proxy is used that isn't IIS or Azure App Service's Application Request Routing (ARR), configure the proxy to forward the certificate that it received in an HTTP header. Startup.Configure에서 app.UseAuthentication(); 호출 앞에 다음 코드를 추가합니다.In Startup.Configure, add the following code before the call to app.UseAuthentication();:

app.UseCertificateForwarding();

인증서 전달 미들웨어를 구성하여 헤더 이름을 지정합니다.Configure the Certificate Forwarding Middleware to specify the header name. Startup.ConfigureServices에서 다음 코드를 추가하여 미들웨어가 인증서를 빌드하는 헤더를 구성합니다.In Startup.ConfigureServices, add the following code to configure the header from which the middleware builds a certificate:

services.AddCertificateForwarding(options =>
    options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");

프록시가 Nginx에서와 같이 인증서를 base64 인코딩하지 않는 경우 HeaderConverter 옵션을 설정합니다.If the proxy isn't base64-encoding the certificate (as is the case with Nginx), set the HeaderConverter option. Startup.ConfigureServices에서 다음 예제를 참조하세요.Consider the following example in Startup.ConfigureServices:

services.AddCertificateForwarding(options =>
{
    options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME";
    options.HeaderConverter = (headerValue) => 
    {
        var clientCertificate = 
           /* some conversion logic to create an X509Certificate2 */
        return clientCertificate;
    }
});

문제 해결Troubleshoot

헤더가 예상대로 전달되지 않으면 로깅을 사용하도록 설정합니다.When headers aren't forwarded as expected, enable logging. 로그가 문제를 해결하기에 충분한 정보를 제공하지 않으면 서버가 수신하는 요청 헤더를 열거합니다.If the logs don't provide sufficient information to troubleshoot the problem, enumerate the request headers received by the server. 인라인 미들웨어를 사용하여 앱 응답에 요청 헤더를 쓰거나 헤더를 기록합니다.Use inline middleware to write request headers to an app response or log the headers.

앱 응답에 헤더를 기록하려면 Startup.Configure에서 UseForwardedHeaders 호출 바로 뒤에 다음 터미널 인라인 미들웨어를 넣습니다.To write the headers to the app's response, place the following terminal inline middleware immediately after the call to UseForwardedHeaders in Startup.Configure:

app.Run(async (context) =>
{
    context.Response.ContentType = "text/plain";

    // Request method, scheme, and path
    await context.Response.WriteAsync(
        $"Request Method: {context.Request.Method}{Environment.NewLine}");
    await context.Response.WriteAsync(
        $"Request Scheme: {context.Request.Scheme}{Environment.NewLine}");
    await context.Response.WriteAsync(
        $"Request Path: {context.Request.Path}{Environment.NewLine}");

    // Headers
    await context.Response.WriteAsync($"Request Headers:{Environment.NewLine}");

    foreach (var header in context.Request.Headers)
    {
        await context.Response.WriteAsync($"{header.Key}: " +
            $"{header.Value}{Environment.NewLine}");
    }

    await context.Response.WriteAsync(Environment.NewLine);

    // Connection: RemoteIp
    await context.Response.WriteAsync(
        $"Request RemoteIp: {context.Connection.RemoteIpAddress}");
});

응답 본문 대신 로그에 기록할 수 있습니다.You can write to logs instead of the response body. 로그에 기록하면 디버깅 중 사이트가 정상적으로 작동할 수 있습니다.Writing to logs allows the site to function normally while debugging.

응답 본문이 아닌 로그를 기록하려면:To write logs rather than to the response body:

app.Use(async (context, next) =>
{
    // Request method, scheme, and path
    _logger.LogDebug("Request Method: {Method}", context.Request.Method);
    _logger.LogDebug("Request Scheme: {Scheme}", context.Request.Scheme);
    _logger.LogDebug("Request Path: {Path}", context.Request.Path);

    // Headers
    foreach (var header in context.Request.Headers)
    {
        _logger.LogDebug("Header: {Key}: {Value}", header.Key, header.Value);
    }

    // Connection: RemoteIp
    _logger.LogDebug("Request RemoteIp: {RemoteIpAddress}", 
        context.Connection.RemoteIpAddress);

    await next();
});

처리 시 X-Forwarded-{For|Proto|Host} 값이 X-Original-{For|Proto|Host}로 이동됩니다.When processed, X-Forwarded-{For|Proto|Host} values are moved to X-Original-{For|Proto|Host}. 제공된 헤더에 여러 값이 있는 경우 전달된 헤더 미들웨어는 오른쪽에서 왼쪽으로 역순으로 헤더를 처리합니다.If there are multiple values in a given header, Forwarded Headers Middleware processes headers in reverse order from right to left. 기본 ForwardLimit1(일)이므로 ForwardLimit의 값을 늘리지 않는 한, 헤더에서 맨 오른쪽 값만 처리됩니다.The default ForwardLimit is 1 (one), so only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

요청의 원래 원격 IP는 전달된 헤더가 처리되기 전에 KnownProxies 또는 KnownNetworks 목록의 항목과 일치해야 합니다.The request's original remote IP must match an entry in the KnownProxies or KnownNetworks lists before forwarded headers are processed. 이렇게 하면 신뢰할 수 없는 프록시에서 전달자가 허용되지 않아 헤더 스푸핑이 제한됩니다.This limits header spoofing by not accepting forwarders from untrusted proxies. 알 수 없는 프록시가 검색되면 로그에 프록시 주소가 기록됩니다.When an unknown proxy is detected, logging indicates the address of the proxy:

September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321

앞의 예제에서 10.0.0.100은 프록시 서버입니다.In the preceding example, 10.0.0.100 is a proxy server. 서버가 신뢰할 수 있는 프록시인 경우 서버의 IP 주소를 Startup.ConfigureServicesKnownProxies에 추가합니다(또는 신뢰할 수 있는 네트워크를 KnownNetworks에 추가).If the server is a trusted proxy, add the server's IP address to KnownProxies (or add a trusted network to KnownNetworks) in Startup.ConfigureServices. 자세한 내용은 전달된 헤더 미들웨어 옵션 섹션을 참조하세요.For more information, see the Forwarded Headers Middleware options section.

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

중요

신뢰할 수 있는 프록시 및 네트워크만 헤더를 전달할 수 있습니다.Only allow trusted proxies and networks to forward headers. 그렇지 않을 경우 IP 스푸핑 공격이 가능합니다.Otherwise, IP spoofing attacks are possible.

추가 자료Additional resources

ASP.NET Core의 권장 구성에서 앱은 IIS/ASP.NET Core 모듈, Nginx 또는 Apache를 사용하여 호스트됩니다.In the recommended configuration for ASP.NET Core, the app is hosted using IIS/ASP.NET Core Module, Nginx, or Apache. 프록시 서버, 부하 분산 장치 및 기타 네트워크 어플라이언스는 종종 앱에 도달하기 전에 요청에 대한 정보를 숨깁니다.Proxy servers, load balancers, and other network appliances often obscure information about the request before it reaches the app:

  • HTTPS 요청이 HTTP를 통해 프록시된 경우 원래 스키마(HTTPS)가 손실되므로 헤더에서 전달되어야 합니다.When HTTPS requests are proxied over HTTP, the original scheme (HTTPS) is lost and must be forwarded in a header.
  • 앱은 프록시에서 요청을 수신하고 인터넷 또는 회사 네트워크의 실제 소스를 수신하는 것이 아니므로 원래 클라이언트 IP 주소도 헤더에서 전달되어야 합니다.Because an app receives a request from the proxy and not its true source on the Internet or corporate network, the originating client IP address must also be forwarded in a header.

이 정보는 요청 처리 시 중요할 수 있습니다(예: 리디렉션, 인증, 링크 생성, 정책 평가 및 클라이언트 지리적 위치).This information may be important in request processing, for example in redirects, authentication, link generation, policy evaluation, and client geolocation.

전달된 헤더Forwarded headers

규칙에 따라 프록시는 HTTP 헤더에서 정보를 전달합니다.By convention, proxies forward information in HTTP headers.

헤더Header 설명Description
X-Forwarded-ForX-Forwarded-For 요청 및 프록시 체인의 후속 프록시를 시작한 클라이언트에 대한 정보를 포함합니다.Holds information about the client that initiated the request and subsequent proxies in a chain of proxies. 이 매개 변수에는 IP 주소(및 선택적으로 포트 번호)가 포함될 수 있습니다.This parameter may contain IP addresses (and, optionally, port numbers). 프록시 서버의 체인에서 첫 번째 매개 변수는 요청이 처음 만들어진 클라이언트를 나타냅니다.In a chain of proxy servers, the first parameter indicates the client where the request was first made. 그 뒤에 후속 프록시 식별자가 추가됩니다.Subsequent proxy identifiers follow. 체인의 마지막 프록시는 매개 변수 목록에 없습니다.The last proxy in the chain isn't in the list of parameters. 마지막 프록시의 IP 주소 및 선택적으로 포트 번호는 전송 계층에서 원격 IP 주소로 사용할 수 있습니다.The last proxy's IP address, and optionally a port number, are available as the remote IP address at the transport layer.
X-Forwarded-ProtoX-Forwarded-Proto 원래 체계(HTTP/HTTPS)의 값입니다.The value of the originating scheme (HTTP/HTTPS). 요청이 여러 프록시를 트래버스한 경우에는 값이 체계 목록일 수도 있습니다.The value may also be a list of schemes if the request has traversed multiple proxies.
X-Forwarded-HostX-Forwarded-Host 호스트 헤더 필드의 원래 값입니다.The original value of the Host header field. 일반적으로 프록시는 호스트 헤더를 수정하지 않습니다.Usually, proxies don't modify the Host header. 프록시가 호스트 헤더를 유효성 검사하거나 알려진 정상 값으로 제한하지 않는 시스템에 영향을 미치는 권한 상승 취약성에 대한 자세한 내용은 Microsoft 보안 공지 CVE-2018-0787을 참조하세요.See Microsoft Security Advisory CVE-2018-0787 for information on an elevation-of-privileges vulnerability that affects systems where the proxy doesn't validate or restrict Host headers to known good values.

Microsoft.AspNetCore.HttpOverrides 패키지의 전달된 헤더 미들웨어는 헤더를 읽고 HttpContext의 관련 필드를 채웁니다.The Forwarded Headers Middleware, from the Microsoft.AspNetCore.HttpOverrides package, reads these headers and fills in the associated fields on HttpContext.

미들웨어가 다음을 업데이트합니다.The middleware updates:

전달된 헤더 미들웨어 기본 설정을 구성할 수 있습니다.Forwarded Headers Middleware default settings can be configured. 기본 설정은 다음과 같습니다.The default settings are:

  • 앱과 요청 소스 사이에는 ‘하나의 프록시’만 있습니다.There is only one proxy between the app and the source of the requests.
  • 알려진 프록시 및 알려진 네트워크의 경우 루프백 주소만 구성됩니다.Only loopback addresses are configured for known proxies and known networks.
  • 전달된 헤더의 이름은 X-Forwarded-ForX-Forwarded-Proto입니다.The forwarded headers are named X-Forwarded-For and X-Forwarded-Proto.

일부 네트워크 어플라이언스는 X-Forwarded-ForX-Forwarded-Proto 헤더를 추가하려면 추가 구성이 필요합니다.Not all network appliances add the X-Forwarded-For and X-Forwarded-Proto headers without additional configuration. 프록시된 요청이 앱에 도달할 때 이러한 헤더를 포함하지 않는 경우에는 어플라이언스 제조업체의 지침을 참조하세요.Consult your appliance manufacturer's guidance if proxied requests don't contain these headers when they reach the app. 어플라이언스가 X-Forwarded-ForX-Forwarded-Proto와는 다른 헤더 이름을 사용하는 경우 ForwardedForHeaderNameForwardedProtoHeaderName 옵션을 어플라이언스에서 사용하는 헤더 이름과 일치하도록 설정합니다.If the appliance uses different header names than X-Forwarded-For and X-Forwarded-Proto, set the ForwardedForHeaderName and ForwardedProtoHeaderName options to match the header names used by the appliance. 자세한 내용은 전달된 헤더 미들웨어 옵션다른 헤더 이름을 사용하는 프록시 구성을 참조하세요.For more information, see Forwarded Headers Middleware options and Configuration for a proxy that uses different header names.

IIS/IIS Express 및 ASP.NET Core 모듈IIS/IIS Express and ASP.NET Core Module

앱이 IIS 및 ASP.NET Core 모듈 뒤에서 호스트되는 Out of Process인 경우 전달된 헤더 미들웨어가 IIS 통합 미들웨어에 의해 기본적으로 사용하도록 설정됩니다.Forwarded Headers Middleware is enabled by default by IIS Integration Middleware when the app is hosted out-of-process behind IIS and the ASP.NET Core Module. 전달된 헤더 미들웨어는 전달된 헤더 관련 신뢰 문제(예: IP 스푸핑)로 인해 ASP.NET Core 모듈에 특정한 제한된 구성을 사용하여 미들웨어 파이프라인에서 첫 번째로 실행될 수 있도록 활성화됩니다.Forwarded Headers Middleware is activated to run first in the middleware pipeline with a restricted configuration specific to the ASP.NET Core Module due to trust concerns with forwarded headers (for example, IP spoofing). 미들웨어는 X-Forwarded-ForX-Forwarded-Proto 헤더를 전달하도록 구성되고 단일 localhost 프록시로 제한됩니다.The middleware is configured to forward the X-Forwarded-For and X-Forwarded-Proto headers and is restricted to a single localhost proxy. 추가 구성이 필요한 경우 전달된 헤더 미들웨어 옵션을 참조하세요.If additional configuration is required, see the Forwarded Headers Middleware options.

기타 프록시 서버 및 부하 분산 장치 시나리오Other proxy server and load balancer scenarios

Out of Process를 호스트할 때 IIS 통합 사용 외에는 전달된 헤더 미들웨어가 기본적으로 사용하도록 설정되지 않습니다.Outside of using IIS Integration when hosting out-of-process, Forwarded Headers Middleware isn't enabled by default. 앱에서 UseForwardedHeaders를 사용하여 전달된 헤더를 처리하려면 전달된 헤더 미들웨어를 사용하도록 설정해야 합니다.Forwarded Headers Middleware must be enabled for an app to process forwarded headers with UseForwardedHeaders. 미들웨어를 사용하도록 설정한 후 미들웨어에 ForwardedHeadersOptions를 지정하지 않은 경우 기본 ForwardedHeadersOptions.ForwardedHeadersForwardedHeaders.None입니다.After enabling the middleware if no ForwardedHeadersOptions are specified to the middleware, the default ForwardedHeadersOptions.ForwardedHeaders are ForwardedHeaders.None.

ForwardedHeadersOptions를 사용하여 Startup.ConfigureServicesX-Forwarded-ForX-Forwarded-Proto 헤더를 전달하도록 미들웨어를 구성합니다.Configure the middleware with ForwardedHeadersOptions to forward the X-Forwarded-For and X-Forwarded-Proto headers in Startup.ConfigureServices. 다른 미들웨어를 호출하기 전에 Startup.Configure에서 UseForwardedHeaders 메서드를 호출합니다.Invoke the UseForwardedHeaders method in Startup.Configure before calling other middleware:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = 
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseForwardedHeaders();

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

    app.UseStaticFiles();
    // In ASP.NET Core 1.x, replace the following line with: app.UseIdentity();
    app.UseAuthentication();
    app.UseMvc();
}

참고

Startup.ConfigureServices에서 ForwardedHeadersOptions를 지정하지 않거나 UseForwardedHeaders를 사용하여 확장 메서드에 직접 지정하지 않은 경우 전달할 기본 헤더는 ForwardedHeaders.None입니다.If no ForwardedHeadersOptions are specified in Startup.ConfigureServices or directly to the extension method with UseForwardedHeaders, the default headers to forward are ForwardedHeaders.None. 전달할 헤더를 사용하여 ForwardedHeaders 속성을 구성해야 합니다.The ForwardedHeaders property must be configured with the headers to forward.

Nginx 구성Nginx configuration

X-Forwarded-ForX-Forwarded-Proto 헤더를 전달하려면 Nginx를 사용하여 Linux에서 ASP.NET Core 호스트를 참조하세요.To forward the X-Forwarded-For and X-Forwarded-Proto headers, see Nginx를 사용하여 Linux에서 ASP.NET Core 호스트. 자세한 내용은 NGINX: 전달된 헤더 사용을 참조하세요.For more information, see NGINX: Using the Forwarded header.

Apache 구성Apache configuration

X-Forwarded-For가 자동으로 추가됩니다( Apache 모듈 mod_proxy: 역방향 프록시 요청 헤더 참조).X-Forwarded-For is added automatically (see Apache Module mod_proxy: Reverse Proxy Request Headers). X-Forwarded-Proto 헤더를 전달하는 방법에 대한 내용은 Apache를 사용하여 Linux에서 ASP.NET Core 호스트를 참조하세요.For information on how to forward the X-Forwarded-Proto header, see Apache를 사용하여 Linux에서 ASP.NET Core 호스트.

전달된 헤더 미들웨어 옵션Forwarded Headers Middleware options

ForwardedHeadersOptions는 전달된 헤더 미들웨어의 동작을 제어합니다.ForwardedHeadersOptions control the behavior of the Forwarded Headers Middleware. 다음 예제에서는 기본값을 변경합니다.The following example changes the default values:

  • 전달된 헤더의 항목 수를 2로 제한합니다.Limit the number of entries in the forwarded headers to 2.
  • 127.0.10.1의 알려진 프록시 주소를 추가합니다.Add a known proxy address of 127.0.10.1.
  • 전달된 헤더 이름을 기본값 X-Forwarded-For에서 X-Forwarded-For-My-Custom-Header-Name으로 변경합니다.Change the forwarded header name from the default X-Forwarded-For to X-Forwarded-For-My-Custom-Header-Name.
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
    options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
옵션Option 설명Description
AllowedHosts X-Forwarded-Host 헤더에 의한 호스트를 제공된 값으로 제한합니다.Restricts hosts by the X-Forwarded-Host header to the values provided.
  • 값은 ordinal-ignore-case를 사용하여 비교됩니다.Values are compared using ordinal-ignore-case.
  • 포트 번호는 제외해야 합니다.Port numbers must be excluded.
  • 목록이 비어 있으면 모든 호스트가 허용됩니다.If the list is empty, all hosts are allowed.
  • 최상위 수준 와일드카드 *는 비어 있지 않은 모든 호스트를 허용합니다.A top-level wildcard * allows all non-empty hosts.
  • 하위 도메인 와일드카드는 허용되지만 루트 도메인과 일치하지 않습니다.Subdomain wildcards are permitted but don't match the root domain. 예를 들어 *.contoso.com은 하위 도메인 foo.contoso.com과 일치하지만 루트 도메인 contoso.com과 일치하지 않습니다.For example, *.contoso.com matches the subdomain foo.contoso.com but not the root domain contoso.com.
  • 유니코드 호스트 이름은 허용되지만 일치시킬 Punycode로 변환됩니다.Unicode host names are allowed but are converted to Punycode for matching.
  • IPv6 주소는 경계 대괄호를 포함하고 기존 형식이어야 합니다(예: [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]).IPv6 addresses must include bounding brackets and be in conventional form (for example, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6 주소는 서로 다른 형식 간에 논리적 같음을 확인하기 위해 특별히 처리되지 않으며 정규화가 수행되지 않습니다.IPv6 addresses aren't special-cased to check for logical equality between different formats, and no canonicalization is performed.
  • 허용된 호스트를 제한하지 못하면 공격자가 서비스에서 생성된 링크를 스푸핑할 수 있습니다.Failure to restrict the allowed hosts may allow an attacker to spoof links generated by the service.
기본값은 빈 IList<string>입니다.The default value is an empty IList<string>.
ForwardedForHeaderName ForwardedHeadersDefaults.XForwardedForHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedForHeaderName. 이 옵션은 프록시/전달자가 X-Forwarded-For 헤더를 사용하지 않고 일부 다른 헤더를 사용하여 정보를 전달할 때 사용됩니다.This option is used when the proxy/forwarder doesn't use the X-Forwarded-For header but uses some other header to forward the information.

기본값은 X-Forwarded-For입니다.The default is X-Forwarded-For.
ForwardedHeaders 처리해야 할 전달자를 알려줍니다.Identifies which forwarders should be processed. 적용되는 필드 목록은 ForwardedHeaders 열거형을 참조하세요.See the ForwardedHeaders Enum for the list of fields that apply. 이 속성에 할당된 일반적인 값은 ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto입니다.Typical values assigned to this property are ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

기본값은 ForwardedHeaders.None입니다.The default value is ForwardedHeaders.None.
ForwardedHostHeaderName ForwardedHeadersDefaults.XForwardedHostHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedHostHeaderName. 이 옵션은 프록시/전달자가 X-Forwarded-Host 헤더를 사용하지 않고 일부 다른 헤더를 사용하여 정보를 전달할 때 사용됩니다.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Host header but uses some other header to forward the information.

기본값은 X-Forwarded-Host입니다.The default is X-Forwarded-Host.
ForwardedProtoHeaderName ForwardedHeadersDefaults.XForwardedProtoHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XForwardedProtoHeaderName. 이 옵션은 프록시/전달자가 X-Forwarded-Proto 헤더를 사용하지 않고 일부 다른 헤더를 사용하여 정보를 전달할 때 사용됩니다.This option is used when the proxy/forwarder doesn't use the X-Forwarded-Proto header but uses some other header to forward the information.

기본값은 X-Forwarded-Proto입니다.The default is X-Forwarded-Proto.
ForwardLimit 처리되는 헤더의 항목 수를 제한합니다.Limits the number of entries in the headers that are processed. 제한을 사용하지 않도록 null로 설정하지만, KnownProxies 또는 KnownNetworks가 구성된 경우에만 사용해야 합니다.Set to null to disable the limit, but this should only be done if KnownProxies or KnownNetworks are configured. 비-null 값을 설정하면 잘못 구성된 프록시 및 네트워크에서 측면 채널에서 오는 악성 요청을 예방하지만 보증하지는 않습니다.Setting a non-null value is a precaution (but not a guarantee) to guard against misconfigured proxies and malicious requests arriving from side-channels on the network.

전달된 헤더 미들웨어는 헤더를 역순으로 오른쪽에서 왼쪽으로 처리합니다.Forwarded Headers Middleware processes headers in reverse order from right to left. 기본값(1)만 사용된다면 ForwardLimit의 값을 늘리지 않는 한, 헤더에서 맨 오른쪽 값만 처리됩니다.If the default value (1) is used, only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

기본값은 1입니다.The default is 1.
KnownNetworks 전달된 헤더를 허용하기 위한 알려진 네트워크의 주소 범위입니다.Address ranges of known networks to accept forwarded headers from. CIDR(Classless Interdomain Routing) 표기법을 사용하여 IP 범위를 제공합니다.Provide IP ranges using Classless Interdomain Routing (CIDR) notation.

서버에서 이중 모드 소켓을 사용하는 경우 IPv4 주소가 IPv6 형식(예: IPv4에서 10.0.0.1은 IPv6에서 ::ffff:10.0.0.1로 표시됨)으로 제공됩니다.If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). IPAddress.MapToIPv6를 참조하세요.See IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress를 참조하여 이 형식이 필요한지 확인하세요.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. 자세한 내용은 IPv6 주소로 표시되는 IPv4 주소 구성 섹션을 참조하세요.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

기본값은 IPAddress.Loopback에 대한 단일 항목을 포함하는 IList<IPNetwork>입니다.The default is an IList<IPNetwork> containing a single entry for IPAddress.Loopback.
KnownProxies 전달된 헤더를 허용하기 위한 알려진 프록시의 주소입니다.Addresses of known proxies to accept forwarded headers from. KnownProxies를 사용하여 정확한 IP 주소 일치 항목을 지정합니다.Use KnownProxies to specify exact IP address matches.

서버에서 이중 모드 소켓을 사용하는 경우 IPv4 주소가 IPv6 형식(예: IPv4에서 10.0.0.1은 IPv6에서 ::ffff:10.0.0.1로 표시됨)으로 제공됩니다.If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1). IPAddress.MapToIPv6를 참조하세요.See IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress를 참조하여 이 형식이 필요한지 확인하세요.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress. 자세한 내용은 IPv6 주소로 표시되는 IPv4 주소 구성 섹션을 참조하세요.For more information, see the Configuration for an IPv4 address represented as an IPv6 address section.

기본값은 IPAddress.IPv6Loopback에 대한 단일 항목을 포함하는 IList<IPAddress>입니다.The default is an IList<IPAddress> containing a single entry for IPAddress.IPv6Loopback.
OriginalForHeaderName ForwardedHeadersDefaults.XOriginalForHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalForHeaderName.

기본값은 X-Original-For입니다.The default is X-Original-For.
OriginalHostHeaderName ForwardedHeadersDefaults.XOriginalHostHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalHostHeaderName.

기본값은 X-Original-Host입니다.The default is X-Original-Host.
OriginalProtoHeaderName ForwardedHeadersDefaults.XOriginalProtoHeaderName에서 지정된 헤더 대신 이 속성에서 지정된 헤더를 사용합니다.Use the header specified by this property instead of the one specified by ForwardedHeadersDefaults.XOriginalProtoHeaderName.

기본값은 X-Original-Proto입니다.The default is X-Original-Proto.
RequireHeaderSymmetry 처리 중인 ForwardedHeadersOptions.ForwardedHeaders 간에 동기화할 헤더 값 수가 필요합니다.Require the number of header values to be in sync between the ForwardedHeadersOptions.ForwardedHeaders being processed.

ASP.NET Core 1.x의 기본값은 true입니다.The default in ASP.NET Core 1.x is true. ASP.NET Core 2.0 이상의 기본값은 false입니다.The default in ASP.NET Core 2.0 or later is false.

시나리오 및 사용 사례Scenarios and use cases

전달된 헤더를 추가할 수 없고 모든 요청이 안전한 경우When it isn't possible to add forwarded headers and all requests are secure

일부 경우에는 앱으로 프록시된 요청에 전달된 헤더를 추가할 수 없습니다.In some cases, it might not be possible to add forwarded headers to the requests proxied to the app. 모든 공용 외부 요청이 HTTPS가 되도록 프록시가 적용되는 경우 미들웨어를 사용하기 전에 Startup.Configure에서 체계를 수동으로 설정할 수 있습니다.If the proxy is enforcing that all public external requests are HTTPS, the scheme can be manually set in Startup.Configure before using any type of middleware:

app.Use((context, next) =>
{
    context.Request.Scheme = "https";
    return next();
});

이 코드는 개발 또는 스테이징 환경에서 환경 변수 또는 기타 구성 설정을 통해 사용하지 않도록 설정될 수 있습니다.This code can be disabled with an environment variable or other configuration setting in a development or staging environment.

요청 경로를 변경하는 프록시 및 경로 기준을 처리합니다.Deal with path base and proxies that change the request path

일부 프록시는 경로를 그대로 전달하지만 라우팅이 제대로 작동하도록 제거해야 하는 앱 기본 경로를 포함합니다.Some proxies pass the path intact but with an app base path that should be removed so that routing works properly. UsePathBaseExtensions.UsePathBase 미들웨어는 경로를 HttpRequest.Path로 분할하고 앱 기본 경로를 HttpRequest.PathBase로 분할합니다.UsePathBaseExtensions.UsePathBase middleware splits the path into HttpRequest.Path and the app base path into HttpRequest.PathBase.

/foo/foo/api/1로 전달되는 프록시 경로의 앱 기본 경로인 경우 미들웨어는 다음 명령을 사용하여 Request.PathBase/foo로 설정하고 Request.Path/api/1로 설정합니다.If /foo is the app base path for a proxy path passed as /foo/api/1, the middleware sets Request.PathBase to /foo and Request.Path to /api/1 with the following command:

app.UsePathBase("/foo");

미들웨어가 역방향으로 다시 호출되면 원래 경로 및 경로 기준이 다시 적용됩니다.The original path and path base are reapplied when the middleware is called again in reverse. 미들웨어 순서 처리에 대한 자세한 내용은 ASP.NET Core 미들웨어 기본 사항를 참조하세요.For more information on middleware order processing, see ASP.NET Core 미들웨어 기본 사항.

프록시가 경로를 자르는 경우(예: /foo/api/1/api/1에 전달) 요청의 PathBase 속성을 설정하여 리디렉션 및 링크를 수정합니다.If the proxy trims the path (for example, forwarding /foo/api/1 to /api/1), fix redirects and links by setting the request's PathBase property:

app.Use((context, next) =>
{
    context.Request.PathBase = new PathString("/foo");
    return next();
});

프록시가 경로 데이터를 추가하는 경우 경로의 일부를 삭제한 다음, StartsWithSegments를 사용하고 Path 속성에 할당하여 리디렉션 및 링크를 수정합니다.If the proxy is adding path data, discard part of the path to fix redirects and links by using StartsWithSegments and assigning to the Path property:

app.Use((context, next) =>
{
    if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
    {
        context.Request.Path = remainder;
    }

    return next();
});

다른 헤더 이름을 사용하는 프록시에 대한 구성Configuration for a proxy that uses different header names

프록시가 X-Forwarded-ForX-Forwarded-Proto라는 헤더를 사용하여 프록시 주소/포트 및 원래 체계 정보를 전달하지 않는 경우, ForwardedForHeaderNameForwardedProtoHeaderName 옵션을 프록시에서 사용하는 헤더 이름과 일치하도록 설정합니다.If the proxy doesn't use headers named X-Forwarded-For and X-Forwarded-Proto to forward the proxy address/port and originating scheme information, set the ForwardedForHeaderName and ForwardedProtoHeaderName options to match the header names used by the proxy:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedForHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-For_Header";
    options.ForwardedProtoHeaderName = "Header_Name_Used_By_Proxy_For_X-Forwarded-Proto_Header";
});

IPv6 주소로 표시되는 IPv4 주소 구성Configuration for an IPv4 address represented as an IPv6 address

서버에서 이중 모드 소켓을 사용하는 경우 IPv4 주소가 IPv6 형식(예: IPv4에서 10.0.0.1은 IPv6에서 ::ffff:10.0.0.1 또는 ::ffff:a00:1로 표시됨)으로 제공됩니다.If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format (for example, 10.0.0.1 in IPv4 represented in IPv6 as ::ffff:10.0.0.1 or ::ffff:a00:1). IPAddress.MapToIPv6를 참조하세요.See IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress를 참조하여 이 형식이 필요한지 확인하세요.Determine if this format is required by looking at the HttpContext.Connection.RemoteIpAddress.

다음 예제에서는 전달된 헤더를 제공하는 네트워크 주소가 IPv6 형식의 KnownNetworks 목록에 추가됩니다.In the following example, a network address that supplies forwarded headers is added to the KnownNetworks list in IPv6 format.

IPv4 주소: 10.11.12.1/8IPv4 address: 10.11.12.1/8

변환된 IPv6 주소: ::ffff:10.11.12.1Converted IPv6 address: ::ffff:10.11.12.1
변환된 접두사 길이: 104Converted prefix length: 104

16진수 형식으로 주소를 제공할 수도 있습니다(IPv6에서 표시된 10.11.12.1::ffff:0a0b:0c01로 표시).You can also supply the address in hexadecimal format (10.11.12.1 represented in IPv6 as ::ffff:0a0b:0c01). IPv4 주소를 IPv6로 변환할 때 CIDR 접두사 길이(예제에서는 8)에 96을 추가하여 추가 ::ffff: IPv6 접두사를 처리합니다(8 + 96 = 104).When converting an IPv4 address to IPv6, add 96 to the CIDR Prefix Length (8 in the example) to account for the additional ::ffff: IPv6 prefix (8 + 96 = 104).

// To access IPNetwork and IPAddress, add the following namespaces:
// using System.Net;
// using Microsoft.AspNetCore.HttpOverrides;
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Add(new IPNetwork(
        IPAddress.Parse("::ffff:10.11.12.1"), 104));
});

Linux용 스키마 및 비 IIS 역방향 프록시 전달Forward the scheme for Linux and non-IIS reverse proxies

UseHttpsRedirectionUseHsts을(를) 호출하는 앱은 Azure Linux App Service, Azure Linux VM(가상 머신) 또는 IIS 이외의 다른 역방향 프록시 뒤에 배포된 경우 사이트를 무한 루프에 배치합니다.Apps that call UseHttpsRedirection and UseHsts put a site into an infinite loop if deployed to an Azure Linux App Service, Azure Linux virtual machine (VM), or behind any other reverse proxy besides IIS. TLS는 역방향 프록시에 의해 종료되며, Kestrel은 올바른 요청 체계를 인식하지 못합니다.TLS is terminated by the reverse proxy, and Kestrel isn't made aware of the correct request scheme. OAuth 및 OIDC도 잘못된 리디렉션을 생성하므로 이 구성에서 실패합니다.OAuth and OIDC also fail in this configuration because they generate incorrect redirects. UseIISIntegration은 IIS 뒤에서 실행되는 경우 전달된 헤더 미들웨어를 추가하고 구성하지만 Linux에 대한 일치하는 자동 구성이 없습니다(Apache 또는 Nginx 통합).UseIISIntegration adds and configures Forwarded Headers Middleware when running behind IIS, but there's no matching automatic configuration for Linux (Apache or Nginx integration).

비 IIS 시나리오에서 프록시의 스키마를 전달하려면 전달된 헤더 미들웨어를 추가하고 구성합니다.To forward the scheme from the proxy in non-IIS scenarios, add and configure Forwarded Headers Middleware. Startup.ConfigureServices에서 다음 코드를 사용합니다.In Startup.ConfigureServices, use the following code:

// using Microsoft.AspNetCore.HttpOverrides;

if (string.Equals(
    Environment.GetEnvironmentVariable("ASPNETCORE_FORWARDEDHEADERS_ENABLED"), 
    "true", StringComparison.OrdinalIgnoreCase))
{
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
            ForwardedHeaders.XForwardedProto;
        // Only loopback proxies are allowed by default.
        // Clear that restriction because forwarders are enabled by explicit 
        // configuration.
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });
}

문제 해결Troubleshoot

헤더가 예상대로 전달되지 않으면 로깅을 사용하도록 설정합니다.When headers aren't forwarded as expected, enable logging. 로그가 문제를 해결하기에 충분한 정보를 제공하지 않으면 서버가 수신하는 요청 헤더를 열거합니다.If the logs don't provide sufficient information to troubleshoot the problem, enumerate the request headers received by the server. 인라인 미들웨어를 사용하여 앱 응답에 요청 헤더를 쓰거나 헤더를 기록합니다.Use inline middleware to write request headers to an app response or log the headers.

앱 응답에 헤더를 기록하려면 Startup.Configure에서 UseForwardedHeaders 호출 바로 뒤에 다음 터미널 인라인 미들웨어를 넣습니다.To write the headers to the app's response, place the following terminal inline middleware immediately after the call to UseForwardedHeaders in Startup.Configure:

app.Run(async (context) =>
{
    context.Response.ContentType = "text/plain";

    // Request method, scheme, and path
    await context.Response.WriteAsync(
        $"Request Method: {context.Request.Method}{Environment.NewLine}");
    await context.Response.WriteAsync(
        $"Request Scheme: {context.Request.Scheme}{Environment.NewLine}");
    await context.Response.WriteAsync(
        $"Request Path: {context.Request.Path}{Environment.NewLine}");

    // Headers
    await context.Response.WriteAsync($"Request Headers:{Environment.NewLine}");

    foreach (var header in context.Request.Headers)
    {
        await context.Response.WriteAsync($"{header.Key}: " +
            $"{header.Value}{Environment.NewLine}");
    }

    await context.Response.WriteAsync(Environment.NewLine);

    // Connection: RemoteIp
    await context.Response.WriteAsync(
        $"Request RemoteIp: {context.Connection.RemoteIpAddress}");
});

응답 본문 대신 로그에 기록할 수 있습니다.You can write to logs instead of the response body. 로그에 기록하면 디버깅 중 사이트가 정상적으로 작동할 수 있습니다.Writing to logs allows the site to function normally while debugging.

응답 본문이 아닌 로그를 기록하려면:To write logs rather than to the response body:

app.Use(async (context, next) =>
{
    // Request method, scheme, and path
    _logger.LogDebug("Request Method: {Method}", context.Request.Method);
    _logger.LogDebug("Request Scheme: {Scheme}", context.Request.Scheme);
    _logger.LogDebug("Request Path: {Path}", context.Request.Path);

    // Headers
    foreach (var header in context.Request.Headers)
    {
        _logger.LogDebug("Header: {Key}: {Value}", header.Key, header.Value);
    }

    // Connection: RemoteIp
    _logger.LogDebug("Request RemoteIp: {RemoteIpAddress}", 
        context.Connection.RemoteIpAddress);

    await next();
});

처리 시 X-Forwarded-{For|Proto|Host} 값이 X-Original-{For|Proto|Host}로 이동됩니다.When processed, X-Forwarded-{For|Proto|Host} values are moved to X-Original-{For|Proto|Host}. 제공된 헤더에 여러 값이 있는 경우 전달된 헤더 미들웨어는 오른쪽에서 왼쪽으로 역순으로 헤더를 처리합니다.If there are multiple values in a given header, Forwarded Headers Middleware processes headers in reverse order from right to left. 기본 ForwardLimit1(일)이므로 ForwardLimit의 값을 늘리지 않는 한, 헤더에서 맨 오른쪽 값만 처리됩니다.The default ForwardLimit is 1 (one), so only the rightmost value from the headers is processed unless the value of ForwardLimit is increased.

요청의 원래 원격 IP는 전달된 헤더가 처리되기 전에 KnownProxies 또는 KnownNetworks 목록의 항목과 일치해야 합니다.The request's original remote IP must match an entry in the KnownProxies or KnownNetworks lists before forwarded headers are processed. 이렇게 하면 신뢰할 수 없는 프록시에서 전달자가 허용되지 않아 헤더 스푸핑이 제한됩니다.This limits header spoofing by not accepting forwarders from untrusted proxies. 알 수 없는 프록시가 검색되면 로그에 프록시 주소가 기록됩니다.When an unknown proxy is detected, logging indicates the address of the proxy:

September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321

앞의 예제에서 10.0.0.100은 프록시 서버입니다.In the preceding example, 10.0.0.100 is a proxy server. 서버가 신뢰할 수 있는 프록시인 경우 서버의 IP 주소를 Startup.ConfigureServicesKnownProxies에 추가합니다(또는 신뢰할 수 있는 네트워크를 KnownNetworks에 추가).If the server is a trusted proxy, add the server's IP address to KnownProxies (or add a trusted network to KnownNetworks) in Startup.ConfigureServices. 자세한 내용은 전달된 헤더 미들웨어 옵션 섹션을 참조하세요.For more information, see the Forwarded Headers Middleware options section.

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

중요

신뢰할 수 있는 프록시 및 네트워크만 헤더를 전달할 수 있습니다.Only allow trusted proxies and networks to forward headers. 그렇지 않을 경우 IP 스푸핑 공격이 가능합니다.Otherwise, IP spoofing attacks are possible.

추가 자료Additional resources