Konfigurowanie platformy ASP.NET Core pod kątem pracy z serwerami proxy i modułami równoważenia obciążenia
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
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. |
X-Forwarded-Prefix |
Oryginalna ścieżka podstawowa żądana przez klienta. Ten nagłówek może być przydatny w przypadku aplikacji do poprawnego generowania adresów URL, przekierowań lub linków z powrotem do klienta. |
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łówkaX-Forwarded-For
. Dodatkowe ustawienia wpływają na sposób ustawianiaRemoteIpAddress
oprogramowania 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 zX-Forwarded-For
klasy , a stara wartość jest utrwalana w elemecieHttpContext.Connection.RemoteIpAddress
X-Original-For
. Uwaga: Ten proces może być powtarzany kilka razy, jeśli istnieje wiele wartości wX-Forwarded-For/Proto/Host/Prefix
elemecie , co powoduje przeniesienie kilku wartości doX-Original-*
elementu , w tym oryginalnegoRemoteIpAddress/Host/Scheme/PathBase
elementu .HttpContext.Request.Scheme
: ustaw przy użyciu wartości nagłówkaX-Forwarded-Proto
. Z klasy usunięto zużytą wartośćX-Forwarded-Proto
, a stara wartośćHttpContext.Request.Scheme
elementu jest utrwalana w elemecieX-Original-Proto
.HttpContext.Request.Host
: ustaw przy użyciu wartości nagłówkaX-Forwarded-Host
. Z klasy usunięto zużytą wartośćX-Forwarded-Host
, a stara wartośćHttpContext.Request.Host
elementu jest utrwalana w elemecieX-Original-Host
.HttpContext.Request.PathBase
: ustaw przy użyciu wartości nagłówkaX-Forwarded-Prefix
. Z klasy usunięto zużytą wartośćX-Forwarded-Prefix
, a stara wartośćHttpContext.Request.PathBase
elementu jest utrwalana w elemecieX-Original-Prefix
.
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 przekazywane mają nazwy
X-Forwarded-For
,X-Forwarded-Proto
X-Forwarded-Host
iX-Forwarded-Prefix
. - Wartość
ForwardedHeaders
toForwardedHeaders.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 ForwardedProtoHeaderName X-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).
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
naX-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.
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.Connection.RemoteIpAddress.Wartość domyślna IList ><IPNetworkto pojedynczy wpis dla elementu .new IPNetwork(IPAddress.Loopback, 8) |
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.Connection.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:
- HttpContext.Connection.RemoteIpAddress: ustaw wartość nagłówka
X-Forwarded-For
. Dodatkowe ustawienia wpływają na sposób ustawianiaRemoteIpAddress
oprogramowania 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 zX-Forwarded-For
klasy , a stare wartości są utrwalane w elemecieX-Original-For
. Ten sam wzorzec jest stosowany do innych nagłówkówHost
iProto
. - HttpContext.Request.Scheme: ustaw wartość nagłówka
X-Forwarded-Proto
. - HttpContext.Request.Host: ustaw wartość nagłówka
X-Forwarded-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
iX-Forwarded-Proto
. - Wartość
ForwardedHeaders
toForwardedHeaders.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 ForwardedProtoHeaderName X-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 UseHsts
należ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).
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
naX-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.
IList<string> wartość . |
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. |
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 . |
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 . |
ForwardedPrefixHeaderName | Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XForwardedPrefixHeaderName. Ta opcja jest używana, gdy serwer proxy/usługa przesyłania dalej nie używa nagłówka X-Forwarded-Prefix , ale używa innego nagłówka do przekazywania informacji.Wartość domyślna to X-Forwarded-Prefix . |
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.Connection.RemoteIpAddress.Wartość domyślna IList ><IPNetworkto pojedynczy wpis dla elementu .new IPNetwork(IPAddress.Loopback, 8) |
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.Connection.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 . |
OriginalPrefixHeaderName | Użyj nagłówka określonego przez tę właściwość zamiast określonego przez ForwardedHeadersDefaults.XOriginalPrefixHeaderName. Wartość domyślna to X-Original-Prefix . |
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.ConfigureServices
pliku 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.Configure
pliku 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.ConfigureServices
pliku 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.Configure
pliku 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.ConfigureServices
pliku 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.Configure
pliku :
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:
- Wstrzykiwanie
ILogger<Startup>
do klasy zgodnie z opisemStartup
w temacie Tworzenie dzienników w uruchamianiu. - Umieść następujące wbudowane oprogramowanie pośredniczące bezpośrednio po wywołaniu metody UseForwardedHeaders w pliku
Startup.Configure
.
app.Use(async (context, next) =>
{
// Request method, scheme, path, and base 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);
_logger.LogDebug("Request Path Base: {PathBase}", context.Request.PathBase);
// 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|Prefix}
wartości są przenoszone do X-Original-{For|Proto|Host|Prefix}
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 KnownNetworks
programu ) 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.