Konfigurowanie platformy ASP.NET Core pod kątem pracy z serwerami proxy i modułami równoważenia obciążenia

Autor: Chris Ross

W zalecanej konfiguracji dla ASP.NET Core aplikacja jest hostowana przy użyciu ASP.NET Core Module (ANCM) dla usług IIS, Nginx lub Apache. Serwery proxy, moduły równoważenia obciążenia i inne urządzenia sieciowe często ukrywają informacje o żądaniu przed dotarciem do aplikacji:

  • Gdy żądania HTTPS są proxied za pośrednictwem protokołu HTTP, oryginalny schemat (HTTPS) zostanie utracony i musi zostać przekazany w nagłówku.
  • Ponieważ aplikacja odbiera żądanie od serwera proxy, a nie jego prawdziwe źródło w Internecie lub sieci firmowej, źródłowy adres IP klienta musi być również przekazywany w nagłówku.

Te informacje mogą być ważne w przetwarzaniu żądań, na przykład w przypadku przekierowań, uwierzytelniania, generowania linków, oceny zasad i geolokalizacji klienta.

Aplikacje przeznaczone do uruchamiania w farmie internetowej powinny odczytywać artykuł Host ASP.NET Core w farmie internetowej.

Przekierowane nagłówki

Zgodnie z konwencją serwery proxy przesyłają dalej informacje w nagłówkach HTTP.

Nagłówek opis
X-Forwarded-For (XFF) Przechowuje informacje o kliencie, który zainicjował żądanie i kolejne serwery proxy w łańcuchu serwerów proxy. Ten parametr może zawierać adresy IP i, opcjonalnie, numery portów. W łańcuchu serwerów proxy pierwszy parametr wskazuje klienta, na którym zostało wykonane pierwsze żądanie. Kolejne identyfikatory serwera proxy są zgodne. Ostatni serwer proxy w łańcuchu nie znajduje się na liście parametrów. Adres IP ostatniego serwera proxy i opcjonalnie numer portu są dostępne jako zdalny adres IP w warstwie transportu.
X-Forwarded-Proto (XFP) Wartość schematu źródłowego, HTTP lub HTTPS. Wartość może być również listą schematów, jeśli żądanie przechodziło wiele serwerów proxy.
X-Forwarded-Host (XFH) Oryginalna wartość pola Nagłówek hosta. Zazwyczaj serwery proxy nie modyfikują nagłówka Host. Zobacz Biuletyn zabezpieczeń firmy Microsoft CVE-2018-0787 , aby uzyskać informacje na temat luki w zabezpieczeniach podniesienia uprawnień, która ma wpływ na systemy, w których serwer proxy nie weryfikuje ani nie ogranicza nagłówków hosta do znanych dobrych wartości.

Oprogramowanie pośredniczące Nagłówki przekazane, ForwardedHeadersMiddleware, odczytuje te nagłówki i wypełnia skojarzone pola w dniu HttpContext.

Oprogramowanie pośredniczące aktualizuje:

  • HttpContext.Connection.RemoteIpAddress: ustaw przy użyciu wartości nagłówka X-Forwarded-For . Dodatkowe ustawienia wpływają na sposób ustawiania RemoteIpAddressoprogramowania pośredniczącego. Aby uzyskać szczegółowe informacje, zobacz Opcje oprogramowania pośredniczącego dla nagłówków przekazywanych. Zużyte wartości są usuwane z X-Forwarded-Forklasy , a stara wartość jest utrwalana w elemecie HttpContext.Connection.RemoteIpAddressX-Original-For. Uwaga: Ten proces może być powtarzany kilka razy, jeśli istnieje wiele wartości w X-Forwarded-For/Proto/Hostelemecie , co powoduje przeniesienie kilku wartości do X-Original-*elementu , w tym oryginalnego RemoteIpAddress/Host/Schemeelementu .
  • HttpContext.Request.Scheme: ustaw przy użyciu wartości nagłówka X-Forwarded-Proto . Z klasy usunięto zużytą wartość X-Forwarded-Proto, a stara wartość HttpContext.Request.Scheme elementu jest utrwalana w elemecie X-Original-Proto.
  • HttpContext.Request.Host: ustaw przy użyciu wartości nagłówka X-Forwarded-Host . Z klasy usunięto zużytą wartość X-Forwarded-Host, a stara wartość HttpContext.Request.Host elementu jest utrwalana w elemecie X-Original-Host.

Aby uzyskać więcej informacji na temat powyższego, zobacz ten problem z usługą GitHub.

Można skonfigurować domyślne ustawienia oprogramowania pośredniczącego nagłówków. Dla ustawień domyślnych:

  • Istnieje tylko jeden serwer proxy między aplikacją a źródłem żądań.
  • Tylko adresy sprzężenia zwrotnego są skonfigurowane dla znanych serwerów proxy i znanych sieci.
  • Nagłówki przekazane są nazwane X-Forwarded-For i X-Forwarded-Proto.
  • Wartość ForwardedHeaders to ForwardedHeaders.None, wymagane usługi przesyłania dalej należy ustawić tutaj, aby włączyć oprogramowanie pośredniczące.

Nie wszystkie urządzenia sieciowe dodają X-Forwarded-For nagłówki i X-Forwarded-Proto bez dodatkowej konfiguracji. Jeśli żądania proxied nie zawierają tych nagłówków po dotarciu do aplikacji, zapoznaj się ze wskazówkami producenta urządzenia. Jeśli urządzenie używa różnych nazw nagłówków niż X-Forwarded-For i , ustaw ForwardedForHeaderName opcje i ForwardedProtoHeaderNameX-Forwarded-Proto, aby dopasować nazwy nagłówków używane przez urządzenie. Aby uzyskać więcej informacji, zobacz Forwarded Headers Middleware options (Opcje oprogramowania pośredniczącego dla nagłówków przekazywanych) i Configuration for a proxy that uses different header names (Konfiguracja serwera proxy używającego różnych nazw nagłówków).

Iis/IIS Express i ASP.NET Core Module

Oprogramowanie pośredniczące nagłówków przekazywanych jest domyślnie włączone przez oprogramowanie pośredniczące integracji usług IIS, gdy aplikacja jest hostowana poza procesem za usługami IIS i modułem ASP.NET Core Module (ANCM) dla usług IIS. Oprogramowanie pośredniczące nagłówków przekazywanych jest aktywowane w celu pierwszego uruchomienia w potoku oprogramowania pośredniczącego z ograniczoną konfiguracją specyficzną dla modułu ASP.NET Core. Konfiguracja z ograniczeniami jest spowodowana obawami dotyczącymi zaufania z przekierowanymi nagłówkami, na przykład fałszowaniem adresów IP. Oprogramowanie pośredniczące jest skonfigurowane do przekazywania X-Forwarded-For nagłówków i X-Forwarded-Proto i jest ograniczone do pojedynczego serwera proxy hosta lokalnego. Jeśli wymagana jest dodatkowa konfiguracja, zobacz opcje Oprogramowania pośredniczącego dla nagłówków przekazywanych.

Inne scenariusze serwera proxy i modułu równoważenia obciążenia

Poza używaniem integracji z usługami IIS podczas hostowania poza procesem oprogramowanie pośredniczące nagłówków przekazywanych nie jest domyślnie włączone. Oprogramowanie pośredniczące nagłówków przekazywanych musi być włączone, aby aplikacja przetwarzała nagłówki przekazywane za pomocą polecenia UseForwardedHeaders. Po włączeniu oprogramowania pośredniczącego, jeśli nie ForwardedHeadersOptions określono żadnego oprogramowania pośredniczącego, domyślna wartość ForwardedHeadersOptions.ForwardedHeaders to ForwardedHeaders.None.

Skonfiguruj oprogramowanie pośredniczące za pomocą polecenia ForwardedHeadersOptions , aby przekazywać dalej X-Forwarded-For nagłówki i X-Forwarded-Proto .

Kolejność oprogramowania pośredniczącego przekazanych nagłówków

Oprogramowanie pośredniczące nagłówków dalej powinno działać przed innym oprogramowaniem pośredniczącym. Takie określenie kolejności gwarantuje, że oprogramowanie pośredniczące polegające na informacjach przekazanych nagłówków może zużywać wartości nagłówków do przetwarzania. Oprogramowanie pośredniczące nagłówków przesłanych dalej może działać po zakończeniu diagnostyki i obsługi błędów, ale przed wywołaniem polecenia UseHstsnależy go uruchomić:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseForwardedHeaders();
    app.UseHsts();
}
else
{
    app.UseDeveloperExceptionPage();
    app.UseForwardedHeaders();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Alternatywnie wywołaj metodę UseForwardedHeaders przed diagnostyką:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Uwaga

Jeśli nie określono ani nie ForwardedHeadersOptions zastosowano bezpośrednio do metody rozszerzenia za pomocą UseForwardedHeaderspolecenia , domyślne nagłówki do przekazania to ForwardedHeaders.None. Właściwość ForwardedHeaders musi być skonfigurowana przy użyciu nagłówków do przekazywania dalej.

Konfiguracja serwera Nginx

Aby przekazać nagłówki X-Forwarded-For i X-Forwarded-Proto , zobacz Host ASP.NET Core w systemie Linux przy użyciu serwera Nginx. Aby uzyskać więcej informacji, zobacz NGINX: Using the Forwarded header (NGINX: Używanie nagłówka przekazywanego).

Konfiguracja platformy Apache

X-Forwarded-For jest dodawany automatycznie. Aby uzyskać więcej informacji, zobacz Apache Module mod_proxy: Reverse Proxy Request Headers (Moduł Apache mod_proxy: odwrotne nagłówki żądań serwera proxy). Aby uzyskać informacje na temat przesyłania dalej nagłówka X-Forwarded-Proto , zobacz Host ASP.NET Core w systemie Linux przy użyciu platformy Apache.

Opcje oprogramowania pośredniczącego nagłówków przekazywanych

ForwardedHeadersOptionssteruj zachowaniem oprogramowania pośredniczącego Nagłówki przekazywane. Poniższy przykład zmienia wartości domyślne:

  • Ogranicza liczbę wpisów w przekierowanych nagłówkach do 2.
  • Dodaje znany adres serwera proxy .127.0.10.1
  • Zmienia nazwę przekazanego nagłówka z domyślnego X-Forwarded-For na X-Forwarded-For-My-Custom-Header-Name.
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.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";
});

var app = builder.Build();

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();
Opcja Opis
AllowedHosts Ogranicza hosty według nagłówka X-Forwarded-Host do podanych wartości.
  • Wartości są porównywane przy użyciu porządkowego ignorowania wielkości liter.
  • Numery portów muszą być wykluczone.
  • Jeśli lista jest pusta, wszystkie hosty są dozwolone.
  • Symbol wieloznaczny * najwyższego poziomu zezwala na wszystkie niepuste hosty.
  • Symbole wieloznaczne poddomeny są dozwolone, ale nie są zgodne z domeną główną. Na przykład pasuje do poddomenyfoo.contoso.com, *.contoso.com ale nie domeny contoso.comgłównej .
  • Nazwy hostów Unicode są dozwolone, ale są konwertowane na punycode w celu dopasowania.
  • Adresy IPv6 muszą zawierać nawiasy ograniczenia i być w formie konwencjonalnej (na przykład [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Adresy IPv6 nie są specjalne, aby sprawdzić równość logiczną między różnymi formatami i nie jest wykonywana kanonizacja.
  • Niepowodzenie ograniczenia dozwolonych hostów może umożliwić atakującemu fałszowanie linków generowanych przez usługę.
Wartość domyślna to pusta IList<string>wartość .
ForwardedForHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedForHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-For , ale używa innego nagłówka do przekazywania informacji.

Wartość domyślna to X-Forwarded-For.
ForwardedHeaders Określa, które usługi przesyłania dalej powinny być przetwarzane. Zobacz wyliczenie ForwardedHeaders, aby uzyskać listę pól, które mają zastosowanie. Typowe wartości przypisane do tej właściwości to ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

Wartość domyślna to ForwardedHeaders.None.
ForwardedHostHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedHostHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-Host , ale używa innego nagłówka do przekazywania informacji.

Wartość domyślna to X-Forwarded-Host.
ForwardedProtoHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedProtoHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-Proto , ale używa innego nagłówka do przekazywania informacji.

Wartość domyślna to X-Forwarded-Proto.
ForwardLimit Ogranicza liczbę wpisów w przetworzonych nagłówkach. Ustaw wartość na wartość , aby null wyłączyć limit, ale należy to zrobić tylko wtedy, gdy KnownProxies jest skonfigurowany.KnownNetworks Ustawienie wartości innejnull niż wartość jest środkiem ostrożności (ale nie gwarancją), aby chronić przed nieprawidłowo skonfigurowanymi serwerami proxy i złośliwymi żądaniami przychodzącymi z kanałów bocznych w sieci.

Nagłówki oprogramowania pośredniczącego przekazywane przetwarzają nagłówki w odwrotnej kolejności od prawej do lewej. Jeśli jest używana wartość domyślna (1), tylko najbardziej odpowiednia wartość z nagłówków jest przetwarzana, chyba że wartość wartości ForwardLimit zostanie zwiększona.

Wartość domyślna to 1.
KnownNetworks Zakresy adresów znanych sieci do akceptowania przekierowanych nagłówków. Podaj zakresy adresów IP przy użyciu notacji routingu międzydomenowego (CIDR, Classless Interdomain Routing).

Jeśli serwer używa gniazd w trybie podwójnym, adresy IPv4 są dostarczane w formacie IPv6 (na przykład 10.0.0.1 w IPv4 reprezentowane w IPv6 jako ::ffff:10.0.0.1). Zobacz IPAddress.MapToIPv6. Ustal, czy ten format jest wymagany, patrząc na httpContext.PołączenieJonów. RemoteIpAddress.

Wartość domyślna IList><IPNetworkto pojedynczy wpis dla elementu .IPAddress.Loopback
KnownProxies Adresy znanych serwerów proxy do akceptowania przekierowanych nagłówków. Służy KnownProxies do określania dokładnych dopasowań adresów IP.

Jeśli serwer używa gniazd w trybie podwójnym, adresy IPv4 są dostarczane w formacie IPv6 (na przykład 10.0.0.1 w IPv4 reprezentowane w IPv6 jako ::ffff:10.0.0.1). Zobacz IPAddress.MapToIPv6. Ustal, czy ten format jest wymagany, patrząc na httpContext.PołączenieJonów. RemoteIpAddress.

Wartość domyślna IList><IPAddressto pojedynczy wpis dla elementu .IPAddress.IPv6Loopback
OriginalForHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalForHeaderName.

Wartość domyślna to X-Original-For.
OriginalHostHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalHostHeaderName.

Wartość domyślna to X-Original-Host.
OriginalProtoHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalProtoHeaderName.

Wartość domyślna to X-Original-Proto.
RequireHeaderSymmetry Wymagaj, aby liczba wartości nagłówka była zsynchronizowana między przetwarzanymi elementami ForwardedHeadersOptions.ForwardedHeaders .

Wartość domyślna w ASP.NET Core 1.x to true. Wartość domyślna w programie ASP.NET Core 2.0 lub nowszym to false.

Scenariusze i przypadki użycia

Gdy nie można dodać nagłówków przekazanych dalej i wszystkie żądania są bezpieczne

W niektórych przypadkach dodanie nagłówków przekazanych do aplikacji do aplikacji może nie być możliwe. Jeśli serwer proxy wymusza, że wszystkie publiczne żądania zewnętrzne to HTTPS, schemat można ustawić ręcznie przed użyciem dowolnego typu oprogramowania pośredniczącego:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

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

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Ten kod można wyłączyć za pomocą zmiennej środowiskowej lub innego ustawienia konfiguracji w środowisku programistycznym lub przejściowym:

using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

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

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Praca z bazą ścieżki i serwerami proxy, które zmieniają ścieżkę żądania

Niektóre serwery proxy przechodzą ścieżkę bez zmian, ale z ścieżką podstawową aplikacji, która powinna zostać usunięta, aby routing działał prawidłowo. Oprogramowanie pośredniczące UsePathBaseExtensions.UsePathBase dzieli ścieżkę na httpRequest.Path i ścieżkę podstawową aplikacji na httpRequest.PathBase.

Jeśli /foo jest ścieżką podstawową aplikacji dla ścieżki serwera proxy przekazanej jako /foo/api/1, oprogramowanie pośredniczące ustawia wartość Request.PathBase/foo i Request.Path na /api/1 za pomocą następującego polecenia:

app.UsePathBase("/foo");
// ...
app.UseRouting();

Uwaga

W przypadku korzystania z WebApplication (zobacz Migrowanie z platformy ASP.NET Core 5.0 do 6.0) należy wywołać app.UseRouting po UsePathBase, aby oprogramowanie pośredniczące routingu dostrzegło zmodyfikowaną ścieżkę przed dopasowaniem tras. W przeciwnym razie trasy zostaną dopasowane przed zmianą ścieżki przez UsePathBase zgodnie z opisem w artykułach Ustalanie kolejności oprogramowania pośredniczącego i Routing.

Oryginalna ścieżka i podstawa ścieżki są ponownie stosować, gdy oprogramowanie pośredniczące jest wywoływane ponownie w odwrotnie. Aby uzyskać więcej informacji na temat przetwarzania zamówień oprogramowania pośredniczącego, zobacz ASP.NET Core Middleware.

Jeśli serwer proxy przycina ścieżkę (na przykład przekazywanie /foo/api/1 dalej do /api/1), napraw przekierowania i łącza, ustawiając właściwość PathBase żądania:

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

Jeśli serwer proxy dodaje dane ścieżki, odrzuć część ścieżki, aby naprawić przekierowania i linki przy użyciu funkcji StartsWithSegments i przypisać ją do Path właściwości:

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

    return next(context);
});

Konfiguracja serwera proxy używającego różnych nazw nagłówków

Jeśli serwer proxy nie używa nagłówków o nazwie X-Forwarded-For i X-Forwarded-Proto przesyłać dalej informacje o adresie/porcie serwera proxy i schemacie źródłowym, ustaw ForwardedForHeaderName opcje i ForwardedProtoHeaderName , aby były zgodne z nazwami nagłówków używanymi przez serwer proxy:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedForHeaderName = "HeaderNamUsedByProxy_X-Forwarded-For_Header";
    options.ForwardedProtoHeaderName = "HeaderNamUsedByProxy_X-Forwarded-Proto_Header";
});

var app = builder.Build();

app.UseForwardedHeaders();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Przekazywanie schematu dla zwrotnych serwerów proxy systemu Linux i innych niż IIS

Aplikacje wywołujące UseHttpsRedirection i UseHsts umieszczające lokację w nieskończonej pętli, jeśli są wdrażane w usłudze Azure Linux App Service, maszynie wirtualnej z systemem Azure Linux lub za innym zwrotnym serwerem proxy oprócz usług IIS. Protokół TLS jest przerywany przez zwrotny serwer proxy i Kestrel nie jest świadomy prawidłowego schematu żądań. Uwierzytelnianie OAuth i OIDC również kończą się niepowodzeniem w tej konfiguracji, ponieważ generują nieprawidłowe przekierowania. UseIISIntegration dodaje i konfiguruje oprogramowanie pośredniczące nagłówków przekazywanych podczas uruchamiania za usługami IIS, ale nie ma zgodnej automatycznej konfiguracji dla systemu Linux (integracja z platformą Apache lub Nginx).

Aby przekazać schemat z serwera proxy w scenariuszach innych niż IIS, włącz oprogramowanie pośredniczące przesyłania dalej, ustawiając wartość ASPNETCORE_FORWARDEDHEADERS_ENABLED .true Ostrzeżenie: Ta flaga używa ustawień przeznaczonych dla środowisk w chmurze i nie włącza funkcji, takich jak KnownProxies option ograniczanie akceptowanych usług przesyłania dalej adresów IP.

Przekazywanie certyfikatów

Azure

Aby skonfigurować usługę aplikacja systemu Azure na potrzeby przekazywania certyfikatów, zobacz Konfigurowanie wzajemnego uwierzytelniania TLS dla usługi aplikacja systemu Azure. Poniższe wskazówki dotyczą konfigurowania aplikacji ASP.NET Core.

  • Skonfiguruj oprogramowanie pośredniczące przekazywania certyfikatów, aby określić nazwę nagłówka używaną przez platformę Azure. Dodaj następujący kod, aby skonfigurować nagłówek, z którego oprogramowanie pośredniczące tworzy certyfikat.
  • Wywołaj połączenie UseCertificateForwarding przed wywołaniem metody UseAuthentication.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
    options.CertificateHeader = "X-ARR-ClientCert");

var app = builder.Build();

app.UseCertificateForwarding();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();
app.UseAuthentication();

app.MapRazorPages();

app.Run();

Inne serwery proxy sieci Web

Jeśli używany jest serwer proxy, który nie jest usługami IIS ani routingiem żądań aplikacji usługi aplikacja systemu Azure (ARR), skonfiguruj serwer proxy do przekazywania certyfikatu otrzymanego w nagłówku HTTP.

  • Skonfiguruj oprogramowanie pośredniczące przekazywania certyfikatów, aby określić nazwę nagłówka. Dodaj następujący kod, aby skonfigurować nagłówek, z którego oprogramowanie pośredniczące tworzy certyfikat.
  • Wywołaj połączenie UseCertificateForwarding przed wywołaniem metody UseAuthentication.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
    options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");

var app = builder.Build();

app.UseCertificateForwarding();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();
app.UseAuthentication();

app.MapRazorPages();

app.Run();

Jeśli serwer proxy nie jest kodowaniem base64 certyfikatu, tak jak w przypadku serwera Nginx, ustaw HeaderConverter opcję. Rozważmy następujący przykład:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddCertificateForwarding(options =>
{
    options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME";
    options.HeaderConverter = (headerValue) =>
    {
        // Conversion logic to create an X509Certificate2.
        var clientCertificate = ConversionLogic.CreateAnX509Certificate2();
        return clientCertificate;
    };
});

var app = builder.Build();

app.UseCertificateForwarding();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();
app.UseAuthentication();

app.MapRazorPages();

app.Run();

Rozwiązywanie problemów

Gdy nagłówki nie są przekazywane zgodnie z oczekiwaniami, włącz debug rejestrowanie na poziomie i rejestrowanie żądań HTTP. UseHttpLoggingnależy wywołać po :UseForwardedHeaders

using Microsoft.AspNetCore.HttpLogging;
using Microsoft.AspNetCore.HttpOverrides;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddHttpLogging(options =>
{
    options.LoggingFields = HttpLoggingFields.RequestPropertiesAndHeaders;
});

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

var app = builder.Build();

app.UseForwardedHeaders();
app.UseHttpLogging();

app.Use(async (context, next) =>
{
    // Connection: RemoteIp
    app.Logger.LogInformation("Request RemoteIp: {RemoteIpAddress}",
        context.Connection.RemoteIpAddress);

    await next(context);
});

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Jeśli w danym nagłówku znajduje się wiele wartości, nagłówki oprogramowania pośredniczącego przekazywane przetwarzają nagłówki w odwrotnej kolejności od prawej do lewej. Wartość domyślna ForwardLimit to 1 (jeden), więc tylko najbardziej odpowiednia wartość z nagłówków jest przetwarzana, chyba że wartość ForwardLimit wartości zostanie zwiększona.

Oryginalny zdalny adres IP żądania musi być zgodny z wpisem na KnownProxies listach lub KnownNetworks przed przetworzeniem nagłówków przekazywanych. Ogranicza to fałszowanie nagłówków, nie akceptując usług przesyłania dalej z niezaufanych serwerów proxy. Po wykryciu nieznanego serwera proxy rejestrowanie wskazuje adres serwera proxy:

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

W poprzednim przykładzie 10.0.0.100 jest serwerem proxy. Jeśli serwer jest zaufanym serwerem proxy, dodaj adres IP serwera do KnownProxies, lub dodaj zaufaną sieć do usługi KnownNetworks. Aby uzyskać więcej informacji, zobacz sekcję Opcje oprogramowania pośredniczącego dla nagłówków przekazywanych.

using Microsoft.AspNetCore.HttpOverrides;
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseForwardedHeaders();
    app.UseHsts();
}
else
{
    app.UseDeveloperExceptionPage();
    app.UseForwardedHeaders();
}

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Aby wyświetlić dzienniki, dodaj "Microsoft.AspNetCore.HttpLogging": "Information" do appsettings.Development.json pliku:

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging": "Information"
    }
  }
}

Ważne

Zezwalaj tylko zaufanym serwerom proxy i sieciom na przekazywanie nagłówków. W przeciwnym razie możliwe jest fałszowanie adresów IP.

Dodatkowe zasoby

W zalecanej konfiguracji dla ASP.NET Core aplikacja jest hostowana przy użyciu usług IIS/ASP.NET Core Module, Nginx lub Apache. Serwery proxy, moduły równoważenia obciążenia i inne urządzenia sieciowe często ukrywają informacje o żądaniu przed dotarciem do aplikacji:

  • Gdy żądania HTTPS są proxied za pośrednictwem protokołu HTTP, oryginalny schemat (HTTPS) zostanie utracony i musi zostać przekazany w nagłówku.
  • Ponieważ aplikacja odbiera żądanie od serwera proxy, a nie jego prawdziwe źródło w Internecie lub sieci firmowej, źródłowy adres IP klienta musi być również przekazywany w nagłówku.

Te informacje mogą być ważne w przetwarzaniu żądań, na przykład w przypadku przekierowań, uwierzytelniania, generowania linków, oceny zasad i geolokalizacji klienta.

Przekierowane nagłówki

Zgodnie z konwencją serwery proxy przesyłają dalej informacje w nagłówkach HTTP.

Nagłówek opis
X-Forwarded-for Przechowuje informacje o kliencie, który zainicjował żądanie i kolejne serwery proxy w łańcuchu serwerów proxy. Ten parametr może zawierać adresy IP (i, opcjonalnie, numery portów). W łańcuchu serwerów proxy pierwszy parametr wskazuje klienta, na którym zostało wykonane pierwsze żądanie. Kolejne identyfikatory serwera proxy są zgodne. Ostatni serwer proxy w łańcuchu nie znajduje się na liście parametrów. Adres IP ostatniego serwera proxy i opcjonalnie numer portu są dostępne jako zdalny adres IP w warstwie transportu.
X-Forwarded-Proto Wartość schematu źródłowego (HTTP/HTTPS). Wartość może być również listą schematów, jeśli żądanie przechodziło wiele serwerów proxy.
Host przesłany dalej X Oryginalna wartość pola Nagłówek hosta. Zazwyczaj serwery proxy nie modyfikują nagłówka Host. Zobacz Biuletyn zabezpieczeń firmy Microsoft CVE-2018-0787 , aby uzyskać informacje na temat luki w zabezpieczeniach podniesienia uprawnień, która ma wpływ na systemy, w których serwer proxy nie weryfikuje ani nie ogranicza nagłówków hosta do znanych dobrych wartości.

Oprogramowanie pośredniczące nagłówków przekazywanych (ForwardedHeadersMiddleware), odczytuje te nagłówki i wypełnia skojarzone pola w witrynie HttpContext.

Oprogramowanie pośredniczące aktualizuje:

Aby uzyskać więcej informacji na temat powyższego, zobacz ten problem z usługą GitHub.

Można skonfigurować domyślne ustawienia oprogramowania pośredniczącego nagłówków. Dla ustawień domyślnych:

  • Istnieje tylko jeden serwer proxy między aplikacją a źródłem żądań.
  • Tylko adresy sprzężenia zwrotnego są skonfigurowane dla znanych serwerów proxy i znanych sieci.
  • Nagłówki przekazane są nazwane X-Forwarded-For i X-Forwarded-Proto.
  • Wartość ForwardedHeaders to ForwardedHeaders.None, wymagane usługi przesyłania dalej należy ustawić tutaj, aby włączyć oprogramowanie pośredniczące.

Nie wszystkie urządzenia sieciowe dodają X-Forwarded-For nagłówki i X-Forwarded-Proto bez dodatkowej konfiguracji. Jeśli żądania proxied nie zawierają tych nagłówków po dotarciu do aplikacji, zapoznaj się ze wskazówkami producenta urządzenia. Jeśli urządzenie używa różnych nazw nagłówków niż X-Forwarded-For i , ustaw ForwardedForHeaderName opcje i ForwardedProtoHeaderNameX-Forwarded-Proto, aby dopasować nazwy nagłówków używane przez urządzenie. Aby uzyskać więcej informacji, zobacz Forwarded Headers Middleware options (Opcje oprogramowania pośredniczącego dla nagłówków przekazywanych) i Configuration for a proxy that uses different header names (Konfiguracja serwera proxy używającego różnych nazw nagłówków).

Iis/IIS Express i ASP.NET Core Module

Oprogramowanie pośredniczące nagłówków przekazywanych jest domyślnie włączone przez oprogramowanie pośredniczące integracji usług IIS, gdy aplikacja jest hostowana poza procesem za usługami IIS i modułem ASP.NET Core Module. Oprogramowanie pośredniczące nagłówków przekazywanych jest aktywowane w celu uruchomienia najpierw w potoku oprogramowania pośredniczącego z ograniczoną konfiguracją specyficzną dla modułu ASP.NET Core ze względu na obawy dotyczące przekazywania nagłówków (na przykład fałszowanie adresów IP). Oprogramowanie pośredniczące jest skonfigurowane do przekazywania X-Forwarded-For nagłówków i X-Forwarded-Proto i jest ograniczone do pojedynczego serwera proxy hosta lokalnego. Jeśli wymagana jest dodatkowa konfiguracja, zobacz opcje Oprogramowania pośredniczącego dla nagłówków przekazywanych.

Inne scenariusze serwera proxy i modułu równoważenia obciążenia

Poza używaniem integracji z usługami IIS podczas hostowania poza procesem oprogramowanie pośredniczące nagłówków przekazywanych nie jest domyślnie włączone. Oprogramowanie pośredniczące nagłówków przekazywanych musi być włączone, aby aplikacja przetwarzała nagłówki przekazywane za pomocą polecenia UseForwardedHeaders. Po włączeniu oprogramowania pośredniczącego, jeśli nie ForwardedHeadersOptions określono żadnego oprogramowania pośredniczącego, domyślna wartość ForwardedHeadersOptions.ForwardedHeaders to ForwardedHeaders.None.

Skonfiguruj oprogramowanie pośredniczące za pomocą polecenia ForwardedHeadersOptions , aby przekazywać X-Forwarded-For dalej nagłówki i X-Forwarded-Proto w pliku Startup.ConfigureServices.

Kolejność oprogramowania pośredniczącego przekazanych nagłówków

Oprogramowanie pośredniczące przekazanych nagłówków powinno być uruchamiane przed innym oprogramowaniem pośredniczącym. Takie określenie kolejności gwarantuje, że oprogramowanie pośredniczące polegające na informacjach przekazanych nagłówków może zużywać wartości nagłówków do przetwarzania. Oprogramowanie pośredniczące nagłówków przesłanych dalej może działać po zakończeniu diagnostyki i obsługi błędów, ale przed wywołaniem polecenia UseHstsnależy go uruchomić:

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

Alternatywnie wywołaj metodę UseForwardedHeaders przed diagnostyką:

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

Uwaga

Jeśli nie określono ForwardedHeadersOptions wartości w Startup.ConfigureServices metodzie rozszerzenia lub bezpośrednio do metody UseForwardedHeaders, domyślne nagłówki do przekazania to ForwardedHeaders.None. Właściwość ForwardedHeaders musi być skonfigurowana przy użyciu nagłówków do przekazywania dalej.

Konfiguracja serwera Nginx

Aby przekazać nagłówki X-Forwarded-For i X-Forwarded-Proto , zobacz Host ASP.NET Core w systemie Linux przy użyciu serwera Nginx. Aby uzyskać więcej informacji, zobacz NGINX: Using the Forwarded header (NGINX: Używanie nagłówka przekazywanego).

Konfiguracja platformy Apache

X-Forwarded-For jest dodawany automatycznie (zobacz Apache Module mod_proxy: Reverse Proxy Request Headers (Zobacz temat Apache Module mod_proxy: Reverse Proxy Request Headers (Nagłówki żądań zwrotnego serwera proxy). Aby uzyskać informacje na temat przesyłania dalej nagłówka X-Forwarded-Proto , zobacz Host ASP.NET Core w systemie Linux przy użyciu platformy Apache.

Opcje oprogramowania pośredniczącego nagłówków przekazywanych

ForwardedHeadersOptions steruj zachowaniem oprogramowania pośredniczącego Nagłówki przekazywane. Poniższy przykład zmienia wartości domyślne:

  • Ogranicz liczbę wpisów w przekierowanych nagłówkach do 2.
  • Dodaj znany adres serwera proxy .127.0.10.1
  • Zmień nazwę przekazanego nagłówka z domyślnej X-Forwarded-For na 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";
});
Opcja Opis
AllowedHosts Ogranicza hosty według nagłówka X-Forwarded-Host do podanych wartości.
  • Wartości są porównywane przy użyciu porządkowego ignorowania wielkości liter.
  • Numery portów muszą być wykluczone.
  • Jeśli lista jest pusta, wszystkie hosty są dozwolone.
  • Symbol wieloznaczny * najwyższego poziomu zezwala na wszystkie niepuste hosty.
  • Symbole wieloznaczne poddomeny są dozwolone, ale nie są zgodne z domeną główną. Na przykład pasuje do poddomenyfoo.contoso.com, *.contoso.com ale nie domeny contoso.comgłównej .
  • Nazwy hostów Unicode są dozwolone, ale są konwertowane na punycode w celu dopasowania.
  • Adresy IPv6 muszą zawierać nawiasy ograniczenia i być w formie konwencjonalnej (na przykład [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Adresy IPv6 nie są specjalne, aby sprawdzić równość logiczną między różnymi formatami i nie jest wykonywana kanonizacja.
  • Niepowodzenie ograniczenia dozwolonych hostów może umożliwić atakującemu fałszowanie linków generowanych przez usługę.
Wartość domyślna to pusta IList<string>wartość .
ForwardedForHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedForHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-For , ale używa innego nagłówka do przekazywania informacji.

Wartość domyślna to X-Forwarded-For.
ForwardedHeaders Określa, które usługi przesyłania dalej powinny być przetwarzane. Zobacz wyliczenie ForwardedHeaders, aby uzyskać listę pól, które mają zastosowanie. Typowe wartości przypisane do tej właściwości to ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

Wartość domyślna to ForwardedHeaders.None.
ForwardedHostHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedHostHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-Host , ale używa innego nagłówka do przekazywania informacji.

Wartość domyślna to X-Forwarded-Host.
ForwardedProtoHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedProtoHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-Proto , ale używa innego nagłówka do przekazywania informacji.

Wartość domyślna to X-Forwarded-Proto.
ForwardLimit Ogranicza liczbę wpisów w przetworzonych nagłówkach. Ustaw wartość na wartość , aby null wyłączyć limit, ale należy to zrobić tylko wtedy, gdy KnownProxies jest skonfigurowany.KnownNetworks Ustawienie wartości innejnull niż wartość jest środkiem ostrożności (ale nie gwarancją), aby chronić przed nieprawidłowo skonfigurowanymi serwerami proxy i złośliwymi żądaniami przychodzącymi z kanałów bocznych w sieci.

Nagłówki oprogramowania pośredniczącego przekazywane przetwarzają nagłówki w odwrotnej kolejności od prawej do lewej. Jeśli jest używana wartość domyślna (1), tylko najbardziej odpowiednia wartość z nagłówków jest przetwarzana, chyba że wartość wartości ForwardLimit zostanie zwiększona.

Wartość domyślna to 1.
KnownNetworks Zakresy adresów znanych sieci do akceptowania przekierowanych nagłówków. Podaj zakresy adresów IP przy użyciu notacji routingu międzydomenowego (CIDR, Classless Interdomain Routing).

Jeśli serwer używa gniazd w trybie podwójnym, adresy IPv4 są dostarczane w formacie IPv6 (na przykład 10.0.0.1 w IPv4 reprezentowane w IPv6 jako ::ffff:10.0.0.1). Zobacz IPAddress.MapToIPv6. Ustal, czy ten format jest wymagany, patrząc na httpContext.PołączenieJonów. RemoteIpAddress.

Wartość domyślna IList><IPNetworkto pojedynczy wpis dla elementu .IPAddress.Loopback
KnownProxies Adresy znanych serwerów proxy do akceptowania przekierowanych nagłówków. Służy KnownProxies do określania dokładnych dopasowań adresów IP.

Jeśli serwer używa gniazd w trybie podwójnym, adresy IPv4 są dostarczane w formacie IPv6 (na przykład 10.0.0.1 w IPv4 reprezentowane w IPv6 jako ::ffff:10.0.0.1). Zobacz IPAddress.MapToIPv6. Ustal, czy ten format jest wymagany, patrząc na httpContext.PołączenieJonów. RemoteIpAddress.

Wartość domyślna IList><IPAddressto pojedynczy wpis dla elementu .IPAddress.IPv6Loopback
OriginalForHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalForHeaderName.

Wartość domyślna to X-Original-For.
OriginalHostHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalHostHeaderName.

Wartość domyślna to X-Original-Host.
OriginalProtoHeaderName Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalProtoHeaderName.

Wartość domyślna to X-Original-Proto.
RequireHeaderSymmetry Wymagaj, aby liczba wartości nagłówka była zsynchronizowana między przetwarzanymi elementami ForwardedHeadersOptions.ForwardedHeaders .

Wartość domyślna w ASP.NET Core 1.x to true. Wartość domyślna w programie ASP.NET Core 2.0 lub nowszym to false.

Scenariusze i przypadki użycia

Gdy nie można dodać nagłówków przekazanych dalej i wszystkie żądania są bezpieczne

W niektórych przypadkach dodanie nagłówków przekazanych do aplikacji do aplikacji może nie być możliwe. Jeśli serwer proxy wymusza, że wszystkie publiczne żądania zewnętrzne to HTTPS, schemat można ustawić Startup.Configure ręcznie przed użyciem dowolnego typu oprogramowania pośredniczącego:

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

Ten kod można wyłączyć za pomocą zmiennej środowiskowej lub innego ustawienia konfiguracji w środowisku programistycznym lub przejściowym.

Zajmowanie się bazą ścieżki i serwerami proxy, które zmieniają ścieżkę żądania

Niektóre serwery proxy przechodzą ścieżkę bez zmian, ale z ścieżką podstawową aplikacji, która powinna zostać usunięta, aby routing działał prawidłowo. Oprogramowanie pośredniczące UsePathBaseExtensions.UsePathBase dzieli ścieżkę na httpRequest.Path i ścieżkę podstawową aplikacji na httpRequest.PathBase.

Jeśli /foo jest ścieżką podstawową aplikacji dla ścieżki serwera proxy przekazanej jako /foo/api/1, oprogramowanie pośredniczące ustawia wartość Request.PathBase/foo i Request.Path na /api/1 za pomocą następującego polecenia:

app.UsePathBase("/foo");

Oryginalna ścieżka i podstawa ścieżki są ponownie stosować, gdy oprogramowanie pośredniczące jest wywoływane ponownie w odwrotnie. Aby uzyskać więcej informacji na temat przetwarzania zamówień oprogramowania pośredniczącego, zobacz ASP.NET Core Middleware.

Jeśli serwer proxy przycina ścieżkę (na przykład przekazywanie /foo/api/1 dalej do /api/1), napraw przekierowania i łącza, ustawiając właściwość PathBase żądania:

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

Jeśli serwer proxy dodaje dane ścieżki, odrzuć część ścieżki, aby naprawić przekierowania i linki przy użyciu funkcji StartsWithSegments i przypisać ją do Path właściwości:

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

    return next();
});

Konfiguracja serwera proxy używającego różnych nazw nagłówków

Jeśli serwer proxy nie używa nagłówków o nazwie X-Forwarded-For i X-Forwarded-Proto przesyłać dalej informacje o adresie/porcie serwera proxy i schemacie źródłowym, ustaw ForwardedForHeaderName opcje i ForwardedProtoHeaderName , aby były zgodne z nazwami nagłówków używanymi przez serwer 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";
});

Przekazywanie schematu dla zwrotnych serwerów proxy systemu Linux i innych niż IIS

Aplikacje wywołujące UseHttpsRedirection i UseHsts umieszczające lokację w nieskończonej pętli, jeśli są wdrażane w usłudze Azure Linux App Service, maszynie wirtualnej z systemem Azure Linux lub za innym zwrotnym serwerem proxy oprócz usług IIS. Protokół TLS jest przerywany przez zwrotny serwer proxy i Kestrel nie jest świadomy prawidłowego schematu żądań. Uwierzytelnianie OAuth i OIDC również kończą się niepowodzeniem w tej konfiguracji, ponieważ generują nieprawidłowe przekierowania. UseIISIntegration dodaje i konfiguruje oprogramowanie pośredniczące nagłówków przekazywanych podczas uruchamiania za usługami IIS, ale nie ma zgodnej automatycznej konfiguracji dla systemu Linux (integracja z platformą Apache lub Nginx).

Aby przekazać schemat z serwera proxy w scenariuszach innych niż IIS, dodaj i skonfiguruj oprogramowanie pośredniczące nagłówków przekazanych. W Startup.ConfigureServicespliku użyj następującego kodu:

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

Przekazywanie certyfikatów

Azure

Aby skonfigurować usługę aplikacja systemu Azure na potrzeby przekazywania certyfikatów, zobacz Konfigurowanie wzajemnego uwierzytelniania TLS dla usługi aplikacja systemu Azure. Poniższe wskazówki dotyczą konfigurowania aplikacji ASP.NET Core.

W Startup.Configurepliku dodaj następujący kod przed wywołaniem metody app.UseAuthentication();:

app.UseCertificateForwarding();

Skonfiguruj oprogramowanie pośredniczące przekazywania certyfikatów, aby określić nazwę nagłówka używaną przez platformę Azure. W Startup.ConfigureServicespliku dodaj następujący kod, aby skonfigurować nagłówek, z którego oprogramowanie pośredniczące tworzy certyfikat:

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

Inne serwery proxy sieci Web

Jeśli używany jest serwer proxy, który nie jest usługami IIS ani routingiem żądań aplikacji usługi aplikacja systemu Azure (ARR), skonfiguruj serwer proxy do przekazywania certyfikatu otrzymanego w nagłówku HTTP. W Startup.Configurepliku dodaj następujący kod przed wywołaniem metody app.UseAuthentication();:

app.UseCertificateForwarding();

Skonfiguruj oprogramowanie pośredniczące przekazywania certyfikatów, aby określić nazwę nagłówka. W Startup.ConfigureServicespliku dodaj następujący kod, aby skonfigurować nagłówek, z którego oprogramowanie pośredniczące tworzy certyfikat:

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

Jeśli serwer proxy nie jest zakodowany w formacie base64 certyfikatu (tak jak w przypadku serwera Nginx), ustaw HeaderConverter opcję . Rozważmy następujący przykład w pliku 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;
    }
});

Rozwiązywanie problemów

Gdy nagłówki nie są przekazywane zgodnie z oczekiwaniami, włącz rejestrowanie. Jeśli dzienniki nie udostępniają wystarczających informacji, aby rozwiązać ten problem, wylicz nagłówki żądań odebrane przez serwer. Użyj wbudowanego oprogramowania pośredniczącego, aby zapisywać nagłówki żądań w odpowiedzi aplikacji lub rejestrować nagłówki.

Aby zapisać nagłówki w odpowiedzi aplikacji, umieść następujące wbudowane oprogramowanie pośredniczące terminalu bezpośrednio po wywołaniu metody UseForwardedHeaders w Startup.Configurepliku :

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

Możesz zapisywać w dziennikach zamiast treści odpowiedzi. Zapisywanie w dziennikach umożliwia normalne działanie witryny podczas debugowania.

Aby zapisać dzienniki, a nie do treści odpowiedzi:

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

Podczas przetwarzania X-Forwarded-{For|Proto|Host} wartości są przenoszone do X-Original-{For|Proto|Host}elementu . Jeśli w danym nagłówku znajduje się wiele wartości, nagłówki oprogramowania pośredniczącego przekazywane przetwarzają nagłówki w odwrotnej kolejności od prawej do lewej. Wartość domyślna ForwardLimit to 1 (jeden), więc tylko najbardziej odpowiednia wartość z nagłówków jest przetwarzana, chyba że wartość ForwardLimit wartości zostanie zwiększona.

Oryginalny zdalny adres IP żądania musi być zgodny z wpisem na KnownProxies listach lub KnownNetworks przed przetworzeniem nagłówków przekazywanych. Ogranicza to fałszowanie nagłówków, nie akceptując usług przesyłania dalej z niezaufanych serwerów proxy. Po wykryciu nieznanego serwera proxy rejestrowanie wskazuje adres serwera proxy:

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

W poprzednim przykładzie 10.0.0.100 jest serwerem proxy. Jeśli serwer jest zaufanym serwerem proxy, dodaj adres IP serwera do KnownProxies (lub dodaj zaufaną sieć do KnownNetworksprogramu ) w pliku Startup.ConfigureServices. Aby uzyskać więcej informacji, zobacz sekcję Opcje oprogramowania pośredniczącego dla nagłówków przekazywanych.

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

Ważne

Zezwalaj tylko zaufanym serwerom proxy i sieciom na przekazywanie nagłówków. W przeciwnym razie możliwe jest fałszowanie adresów IP.

Dodatkowe zasoby