Konfigurace ASP.NET Core pro práci s proxy servery a nástroji pro vyrovnávání zatížení
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Autor: Chris Ross
V doporučené konfiguraci pro ASP.NET Core je aplikace hostovaná pomocí modulu ASP.NET Core (ANCM) pro službu IIS, Nginx nebo Apache. Proxy servery, nástroje pro vyrovnávání zatížení a další síťová zařízení často zakrývají informace o požadavku před dosažením aplikace:
- Když se požadavky HTTPS přesměrují přes PROTOKOL HTTP, původní schéma (HTTPS) se ztratí a musí se předávat v hlavičce.
- Vzhledem k tomu, že aplikace přijímá požadavek z proxy serveru, a ne jeho skutečný zdroj v internetu nebo podnikové síti, musí se v hlavičce předávat také původní IP adresa klienta.
Tyto informace můžou být důležité při zpracování požadavků, například při přesměrování, ověřování, generování propojení, vyhodnocení zásad a geografické poloze klienta.
Aplikace určené ke spuštění ve webové farmě by měly číst hostování ASP.NET Core ve webové farmě.
Přeposílané hlavičky
Podle konvence předávají proxy informace v hlavičkách HTTP.
Hlavička | Popis |
---|---|
X-Forwarded-For (XFF) |
Obsahuje informace o klientovi, který inicioval požadavek a následné proxy servery v řetězci proxy serverů. Tento parametr může obsahovat IP adresy a volitelně čísla portů. V řetězci proxy serverů první parametr indikuje klienta, u kterého byl požadavek proveden jako první. Následující identifikátory proxy serveru následují. Poslední proxy server v řetězci není v seznamu parametrů. IP adresa posledního proxy serveru a volitelně číslo portu jsou k dispozici jako vzdálená IP adresa v přenosové vrstvě. |
X-Forwarded-Proto (XFP) |
Hodnota původního schématu, HTTP nebo HTTPS. Hodnota může být také seznam schémat, pokud požadavek prochází více proxy serverů. |
X-Forwarded-Host (XFH) |
Původní hodnota pole Hlavička hostitele. Proxy servery obvykle neupravují hlavičku hostitele. Informace o ohrožení zabezpečení, které má vliv na systémy, ve kterých proxy server neověřuje nebo neomezuje hlavičky hostitele na známé dobré hodnoty, najdete v článku CVE-2018-0787 , který obsahuje informace o ohrožení zabezpečení spočívající ve zvýšení oprávnění. |
X-Forwarded-Prefix |
Původní základní cesta požadovaná klientem. Tato hlavička může být užitečná pro aplikace, které správně generují adresy URL, přesměrování nebo odkazy zpět na klienta. |
Middleware Forwarded Headers , ForwardedHeadersMiddlewarepřečte tyto hlavičky a vyplní přidružená pole na HttpContext.
Aktualizace middlewaru:
HttpContext.Connection.RemoteIpAddress
: Nastavte hodnotuX-Forwarded-For
záhlaví. Další nastavení ovlivňují způsob nastaveníRemoteIpAddress
middlewaru . Podrobnosti najdete v možnostech middlewaru Forwarded Headers. Spotřebované hodnoty jsou odebrány zX-Forwarded-For
a stará hodnotaHttpContext.Connection.RemoteIpAddress
je zachována vX-Original-For
. Poznámka: Tento proces se může několikrát opakovat, pokud existuje více hodnotX-Forwarded-For/Proto/Host/Prefix
, což vede k přesunutí několika hodnot doX-Original-*
, včetně původníRemoteIpAddress/Host/Scheme/PathBase
.HttpContext.Request.Scheme
: Nastavte hodnotuX-Forwarded-Proto
záhlaví. Spotřebovaná hodnota je odebrána zX-Forwarded-Proto
a stará hodnotaHttpContext.Request.Scheme
je zachována vX-Original-Proto
.HttpContext.Request.Host
: Nastavte hodnotuX-Forwarded-Host
záhlaví. Spotřebovaná hodnota je odebrána zX-Forwarded-Host
a stará hodnotaHttpContext.Request.Host
je zachována vX-Original-Host
.HttpContext.Request.PathBase
: Nastavte hodnotuX-Forwarded-Prefix
záhlaví. Spotřebovaná hodnota je odebrána zX-Forwarded-Prefix
a stará hodnotaHttpContext.Request.PathBase
je zachována vX-Original-Prefix
.
Další informace o předchozím problému najdete v tomto problému na GitHubu.
Výchozí nastavení middlewaru předávaných hlaviček je možné nakonfigurovat. Výchozí nastavení:
- Mezi aplikací a zdrojem požadavků je jenom jeden proxy server .
- Pro známé proxy a známé sítě jsou nakonfigurované pouze adresy zpětné smyčky.
- Přeposílané hlavičky mají název
X-Forwarded-For
,X-Forwarded-Proto
X-Forwarded-Host
aX-Forwarded-Prefix
. - Hodnota
ForwardedHeaders
jeForwardedHeaders.None
, požadované služby předávání musí být nastaveny zde, aby bylo možné middleware.
Ne všechna síťová zařízení přidávají X-Forwarded-For
hlavičky bez X-Forwarded-Proto
další konfigurace. Pokud žádosti o směrování neobsahují tyto hlavičky, obraťte se na pokyny výrobce zařízení, když se dostanou k aplikaci. Pokud zařízení používá jiné názvy hlaviček než X-Forwarded-For
a X-Forwarded-Proto
, nastavte a nastavte ForwardedForHeaderName možnosti ForwardedProtoHeaderName tak, aby odpovídaly názvům hlaviček používaným zařízením. Další informace naleznete v tématu Forwarded Headers Middleware options and Configuration for a proxy, který používá různé názvy hlaviček.
Modul IIS/IIS Express a ASP.NET Core
Middleware předávaných hlaviček je ve výchozím nastavení povolený middlewarem integrace služby IIS, když je aplikace hostovaná mimo proces za službou IIS a modul ASP.NET Core (ANCM) pro službu IIS. Middleware forwarded Headers se aktivuje tak, aby se nejprve spustil v kanálu middlewaru s omezenou konfigurací specifickou pro modul ASP.NET Core. Omezená konfigurace je způsobená obavami důvěryhodnosti u předávaných hlaviček, například falšování identity IP adres. Middleware je nakonfigurovaný tak, aby předával X-Forwarded-For
hlavičky a X-Forwarded-Proto
je omezen na jeden proxy server místního hostitele. Pokud je vyžadována další konfigurace, podívejte se na možnosti middlewaru Předávané hlavičky.
Další scénáře proxy serveru a nástroje pro vyrovnávání zatížení
Mimo použití integrace služby IIS při hostování mimo proces není ve výchozím nastavení povolený middleware předávané hlavičky. Middleware předávaných hlaviček musí být povolený, aby aplikace zpracovávala hlavičky přeposílané pomocí UseForwardedHeaders. Po povolení middlewaru, pokud ForwardedHeadersOptions není zadán žádný middleware, výchozí ForwardedHeadersOptions.ForwardedHeaders.ForwardedHeaders.None.
Nakonfigurujte middleware tak ForwardedHeadersOptions , aby předával X-Forwarded-For
hlavičky a X-Forwarded-Proto
předával je.
Pořadí middlewaru Forwarded Headers
Middleware forwarded Headers by měl běžet před jiným middlewarem. Toto řazení zajišťuje, že middleware, který spoléhá na informace předávaných hlaviček, může využívat hodnoty hlaviček ke zpracování. Middleware předávaných hlaviček může běžet po diagnostice a zpracování chyb, ale musí být spuštěn před voláním UseHsts:
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();
Případně volejte UseForwardedHeaders
před diagnostikou:
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();
Poznámka:
ForwardedHeadersOptions Pokud nejsou zadány nebo použity přímo na rozšiřující metodu s UseForwardedHeaders, výchozí hlavičky pro předávání jsou ForwardedHeaders.None. Vlastnost ForwardedHeaders musí být nakonfigurována s hlavičkami pro předávání.
Konfigurace Nginx
Pokud chcete předávat X-Forwarded-For
hlavičky a X-Forwarded-Proto
předávat je, přečtěte si téma Host ASP.NET Core v Linuxu s Nginxem. Další informace najdete v tématu NGINX: Použití předávané hlavičky.
Konfigurace Apache
X-Forwarded-For
se přidá automaticky. Další informace najdete v tématu mod_proxy modulu Apache: Hlavičky reverzních požadavků proxy serveru.
Možnosti middlewaru předávaných hlaviček
ForwardedHeadersOptionsřídí chování middlewaru Forwarded Headers. Následující příklad změní výchozí hodnoty:
- Omezuje počet položek v přeposlaných záhlavích na
2
. - Přidá známou adresu proxy serveru .
127.0.10.1
- Změní název přeposlané hlavičky z výchozí
X-Forwarded-For
hodnoty 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();
Možnost | Popis |
---|---|
AllowedHosts | Omezí hostitele podle X-Forwarded-Host záhlaví na zadané hodnoty.
IList<string> . |
ForwardedForHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedForHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-For , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-For . |
ForwardedHeaders | Určuje, které předávání by se měly zpracovat. Seznam polí, která se vztahují, najdete v výčtu ForwardedHeaders. Typické hodnoty přiřazené této vlastnosti jsou ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto .Výchozí hodnota je ForwardedHeaders.None. |
ForwardedHostHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedHostHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Host , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-Host . |
ForwardedProtoHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedProtoHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Proto , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-Proto . |
ForwardLimit | Omezuje počet položek v záhlavích, která se zpracovávají. Nastavte na zakázání null limitu, ale mělo by se to provést jenom v případě, že KnownProxies KnownNetworks je nakonfigurovaný. Nastavení jinénull hodnoty je preventivní opatření (ale ne záruka), která chrání před chybně nakonfigurovanými proxy servery a škodlivými požadavky přicházejícími ze strany kanálů v síti.Middlewarové hlavičky předávané hlavičky zpracovávají hlavičky v obráceném pořadí zprava doleva. Pokud se použije výchozí hodnota ( 1 ), zpracuje se pouze hodnota úplně vpravo ze záhlaví, pokud se nezvětší ForwardLimit hodnota.Výchozí hodnota je 1 . |
KnownNetworks | Rozsahy adres známých sítí pro příjem předávaných hlaviček. Zadejte rozsahy IP adres pomocí zápisu technologie CIDR (Classless Interdomain Routing) (CIDR). Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.Výchozí hodnota je IList ><IPNetworkobsahující jednu položku pro .new IPNetwork(IPAddress.Loopback, 8) |
KnownProxies | Adresy známých proxy serverů pro příjem předávaných hlaviček. Slouží KnownProxies k určení přesné shody IP adres.Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.Výchozí hodnota je IList ><IPAddressobsahující jednu položku pro .IPAddress.IPv6Loopback |
OriginalForHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalForHeaderName. Výchozí hodnota je X-Original-For . |
OriginalHostHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalHostHeaderName. Výchozí hodnota je X-Original-Host . |
OriginalProtoHeaderName | Použijte hlavičku určenou touto vlastností místo toho, kterou určuje ForwardedHeadersDefaults.XOriginalProtoHeaderName. Výchozí hodnota je X-Original-Proto . |
RequireHeaderSymmetry | Vyžaduje synchronizaci počtu hodnot záhlaví mezi zpracovávanými forwardedHeadersOptions.ForwardedHeaders.ForwardedHeaders . Výchozí hodnota v ASP.NET Core 1.x je true . Výchozí hodnota v ASP.NET Core 2.0 nebo novější je false . |
Scénáře a případy použití
Pokud není možné přidávat přeposílané hlavičky a všechny požadavky jsou zabezpečené
V některých případech nemusí být možné přidat předávané hlavičky do požadavků přesměrovaných do aplikace. Pokud proxy server vynucuje, že všechny veřejné externí požadavky jsou HTTPS, můžete schéma nastavit ručně před použitím libovolného typu middlewaru:
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();
Tento kód lze zakázat pomocí proměnné prostředí nebo jiného nastavení konfigurace ve vývojovém nebo přípravném prostředí:
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();
Práce se základní cestou a proxy servery, které mění cestu požadavku
Některé proxy servery předávají cestu beze změny, ale se základní cestou aplikace, která by se měla odebrat, aby směrování fungovalo správně. Middleware UsePathBaseExtensions.UsePathBase rozdělí cestu na HttpRequest.Path a základní cestu aplikace na HttpRequest.PathBase.
Pokud /foo
se jedná o základní cestu aplikace pro cestu proxy předanou jako /foo/api/1
, middleware se nastaví Request.PathBase
na /foo
a Request.Path
na /api/1
následující příkaz:
app.UsePathBase("/foo");
// ...
app.UseRouting();
Poznámka:
Při použití WebApplication (viz Migrace z ASP.NET Core 5.0 na verzi 6.0) je nutné volat app.UseRouting
po UsePathBase
, aby middleware směrování mohl sledovat upravenou cestu před hledáním shodných tras. Jinak se trasy shodují před přepsáním cesty pomocí UsePathBase
, jak je popsáno v článcích Řazení middlewaru a Směrování.
Původní cesta a základ cesty se znovu povolají při opětovném zavolání middlewaru v obráceném směru. Další informace o zpracování objednávek middlewaru najdete v tématu ASP.NET Core Middleware.
Pokud proxy oříznou cestu (například přesměrování /foo/api/1
na/api/1
), opraví přesměrování a odkazy nastavením vlastnosti PathBase požadavku:
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/foo");
return next(context);
});
Pokud proxy přidává data cesty, zahoďte část cesty, abyste opravili přesměrování a odkazy pomocí StartsWithSegments a přiřazením Path vlastnosti:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next(context);
});
Konfigurace proxy serveru, který používá různé názvy hlaviček
Pokud proxy server nepoužívá hlavičky pojmenované X-Forwarded-For
a X-Forwarded-Proto
předávat adresu proxy serveru nebo port a informace o schématu původu, nastavte ForwardedForHeaderName a ForwardedProtoHeaderName možnosti tak, aby odpovídaly názvům hlaviček používaných proxy serverem:
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();
Přeposlání schématu pro reverzní proxy servery linuxu a jiné služby než IIS
Aplikace, které volají UseHttpsRedirection a UseHsts umístí web do nekonečné smyčky, pokud jsou nasazené do služby Azure Linux App Service, virtuálního počítače Azure s Linuxem nebo za jakýmkoli jiným reverzním proxy serverem kromě služby IIS. Protokol TLS je ukončen reverzním proxy serverem a Kestrel není informován o správném schématu požadavků. OAuth a OIDC také v této konfiguraci selžou, protože generují nesprávné přesměrování. UseIISIntegration přidává a konfiguruje middleware Forwarded Headers při spouštění za službou IIS, ale neexistuje žádná odpovídající automatická konfigurace pro Linux (integrace Apache nebo Nginx).
Chcete-li předat schéma z proxy ve scénářích, které nejsou službami IIS, povolte middleware Forwarded Headers nastavením ASPNETCORE_FORWARDEDHEADERS_ENABLED
na true
. Upozornění: Tento příznak používá nastavení navržená pro cloudová prostředí a neumožňuje funkce, jako KnownProxies option
je omezení, ze kterých jsou přijímány služby předávání IP adres.
Předávání certifikátů
Azure
Pokud chcete nakonfigurovat službu Aplikace Azure service pro předávání certifikátů, přečtěte si téma Konfigurace vzájemného ověřování TLS pro službu Aplikace Azure Service. Následující pokyny se týkají konfigurace aplikace ASP.NET Core.
- Nakonfigurujte middleware pro předávání certifikátů tak, aby určil název hlavičky, kterou Azure používá. Přidejte následující kód pro konfiguraci hlavičky, ze které middleware vytvoří certifikát.
- Zavolejte UseCertificateForwarding před voláním 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();
Další webové proxy servery
Pokud se používá proxy server, který není iis nebo směrování žádostí o aplikaci služby Aplikace Azure Service (ARR), nakonfigurujte proxy server tak, aby předával certifikát, který přijal v hlavičce HTTP.
- Nakonfigurujte middleware pro předávání certifikátů tak, aby zadal název hlavičky. Přidejte následující kód pro konfiguraci hlavičky, ze které middleware vytvoří certifikát.
- Zavolejte UseCertificateForwarding před voláním 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();
Pokud proxy server není kódováním base64 certifikát, jak je tomu u serveru Nginx, nastavte HeaderConverter
tuto možnost. Představte si následující příklad:
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();
Odstraňování potíží
Pokud hlavičky nejsou přeposílané podle očekávání, povolte debug
protokolování na úrovni a protokolování požadavků HTTP. UseHttpLogging musí být volána za 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();
Pokud v dané hlavičce existuje více hodnot, middlewarové hlavičky přeposílané hlavičky zpracovávají hlavičky v opačném pořadí zprava doleva. Výchozí hodnota ForwardLimit
je 1
(jedna), takže pouze hodnota nejvíce vpravo ze záhlaví se zpracuje, pokud se nezvětší ForwardLimit
hodnota.
Původní vzdálená IP adresa požadavku musí odpovídat položce v KnownProxies seznamech před KnownNetworks zpracováním předávaných hlaviček. Toto omezení falšování identity hlaviček tím, že nepřijímá předávání z nedůvěryhodných proxy serverů. Když se zjistí neznámý proxy server, protokolování označuje adresu proxy serveru:
September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321
V předchozím příkladu je 10.0.0.100 proxy server. Pokud je server důvěryhodným proxy serverem, přidejte IP adresu serveru do KnownProxies
nebo přidejte důvěryhodnou síť do KnownNetworks
. Další informace najdete v části Možnosti middlewaru předávané hlavičky.
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();
Pokud chcete zobrazit protokoly, přidejte "Microsoft.AspNetCore.HttpLogging": "Information"
do appsettings.Development.json
souboru:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging": "Information"
}
}
}
Důležité
Povolit předávání hlaviček jenom důvěryhodným proxy serverům a sítím. V opačném případě jsou možné útoky falšování identity IP adres.
Další materiály
V doporučené konfiguraci pro ASP.NET Core je aplikace hostovaná pomocí modulu IIS/ASP.NET Core, Nginx nebo Apache. Proxy servery, nástroje pro vyrovnávání zatížení a další síťová zařízení často zakrývají informace o požadavku před dosažením aplikace:
- Když se požadavky HTTPS přesměrují přes PROTOKOL HTTP, původní schéma (HTTPS) se ztratí a musí se předávat v hlavičce.
- Vzhledem k tomu, že aplikace přijímá požadavek z proxy serveru, a ne jeho skutečný zdroj v internetu nebo podnikové síti, musí se v hlavičce předávat také původní IP adresa klienta.
Tyto informace můžou být důležité při zpracování požadavků, například při přesměrování, ověřování, generování propojení, vyhodnocení zásad a geografické poloze klienta.
Přeposílané hlavičky
Podle konvence předávají proxy informace v hlavičkách HTTP.
Hlavička | Popis |
---|---|
X-forwarded-for | Obsahuje informace o klientovi, který inicioval požadavek a následné proxy servery v řetězci proxy serverů. Tento parametr může obsahovat IP adresy (a volitelně čísla portů). V řetězci proxy serverů první parametr indikuje klienta, u kterého byl požadavek proveden jako první. Následující identifikátory proxy serveru následují. Poslední proxy server v řetězci není v seznamu parametrů. IP adresa posledního proxy serveru a volitelně číslo portu jsou k dispozici jako vzdálená IP adresa v přenosové vrstvě. |
X-forwarded-Proto | Hodnota původního schématu (HTTP/HTTPS). Hodnota může být také seznam schémat, pokud požadavek prochází více proxy serverů. |
X-forwarded-host | Původní hodnota pole Hlavička hostitele. Proxy servery obvykle neupravují hlavičku hostitele. Informace o ohrožení zabezpečení, které má vliv na systémy, ve kterých proxy server neověřuje nebo neomezuje hlavičky hostitele na známé dobré hodnoty, najdete v článku CVE-2018-0787 , který obsahuje informace o ohrožení zabezpečení spočívající ve zvýšení oprávnění. |
Middleware Forwarded Headers (ForwardedHeadersMiddlewareForwarded Headers) čte tyto hlavičky a vyplní přidružená pole na HttpContext.
Aktualizace middlewaru:
- HttpContext.Connection.RemoteIpAddress: Nastavte hodnotu hlavičky
X-Forwarded-For
. Další nastavení ovlivňují způsob nastaveníRemoteIpAddress
middlewaru . Podrobnosti najdete v možnostech middlewaru Forwarded Headers. Spotřebované hodnoty jsou odebrány zX-Forwarded-For
a staré hodnoty jsou trvalé vX-Original-For
. Stejný vzor se použije u ostatních hlavičekHost
aProto
. - HttpContext.Request.Scheme: Nastavte hodnotu hlavičky
X-Forwarded-Proto
. - HttpContext.Request.Host: Nastavte hodnotu hlavičky
X-Forwarded-Host
.
Další informace o předchozím problému najdete v tomto problému na GitHubu.
Výchozí nastavení middlewaru předávaných hlaviček je možné nakonfigurovat. Výchozí nastavení:
- Mezi aplikací a zdrojem požadavků je jenom jeden proxy server .
- Pro známé proxy a známé sítě jsou nakonfigurované pouze adresy zpětné smyčky.
- Přeposílané hlavičky jsou pojmenované
X-Forwarded-For
aX-Forwarded-Proto
. - Hodnota
ForwardedHeaders
jeForwardedHeaders.None
, požadované služby předávání musí být nastaveny zde, aby bylo možné middleware.
Ne všechna síťová zařízení přidávají X-Forwarded-For
hlavičky bez X-Forwarded-Proto
další konfigurace. Pokud žádosti o směrování neobsahují tyto hlavičky, obraťte se na pokyny výrobce zařízení, když se dostanou k aplikaci. Pokud zařízení používá jiné názvy hlaviček než X-Forwarded-For
a X-Forwarded-Proto
, nastavte a nastavte ForwardedForHeaderName možnosti ForwardedProtoHeaderName tak, aby odpovídaly názvům hlaviček používaným zařízením. Další informace naleznete v tématu Forwarded Headers Middleware options and Configuration for a proxy, který používá různé názvy hlaviček.
Modul IIS/IIS Express a ASP.NET Core
Middleware předávaných hlaviček je ve výchozím nastavení povolený middlewarem integrace služby IIS, když je aplikace hostovaná mimo proces za službou IIS a modulem ASP.NET Core. Middleware forwarded Headers se aktivuje tak, aby se spustil jako první v kanálu middlewaru s omezenou konfigurací specifickou pro modul ASP.NET Core kvůli obavám důvěryhodnosti se předávanými hlavičkami (například falšování identity IP adres). Middleware je nakonfigurovaný tak, aby předával X-Forwarded-For
hlavičky a X-Forwarded-Proto
je omezen na jeden proxy server místního hostitele. Pokud je vyžadována další konfigurace, podívejte se na možnosti middlewaru Předávané hlavičky.
Další scénáře proxy serveru a nástroje pro vyrovnávání zatížení
Mimo použití integrace služby IIS při hostování mimo proces není ve výchozím nastavení povolený middleware předávané hlavičky. Middleware předávaných hlaviček musí být povolený, aby aplikace zpracovávala hlavičky přeposílané pomocí UseForwardedHeaders. Po povolení middlewaru, pokud ForwardedHeadersOptions není zadán žádný middleware, výchozí ForwardedHeadersOptions.ForwardedHeaders.ForwardedHeaders.None.
Nakonfigurujte middleware tak ForwardedHeadersOptions , aby předával X-Forwarded-For
hlavičky a X-Forwarded-Proto
hlavičky v Startup.ConfigureServices
souboru .
Pořadí middlewaru Forwarded Headers
Middleware Forwarded Headers by měl běžet před ostatním middlewarem. Toto řazení zajišťuje, že middleware, který spoléhá na informace předávaných hlaviček, může využívat hodnoty hlaviček ke zpracování. Middleware předávaných hlaviček může běžet po diagnostice a zpracování chyb, ale musí být spuštěn před voláním UseHsts
:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseForwardedHeaders();
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Případně volejte UseForwardedHeaders
před diagnostikou:
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?}");
});
}
Poznámka:
ForwardedHeadersOptions Pokud nejsou zadány v Startup.ConfigureServices
nebo přímo do rozšiřující metody s UseForwardedHeaders, výchozí hlavičky pro předávání jsou ForwardedHeaders.None. Vlastnost ForwardedHeaders musí být nakonfigurována s hlavičkami pro předávání.
Konfigurace Nginx
Pokud chcete předávat X-Forwarded-For
hlavičky a X-Forwarded-Proto
předávat je, přečtěte si téma Host ASP.NET Core v Linuxu s Nginxem. Další informace najdete v tématu NGINX: Použití předávané hlavičky.
Konfigurace Apache
X-Forwarded-For
se přidá automaticky (viz modul Apache mod_proxy: Hlavičky reverzních požadavků proxy serveru).
Možnosti middlewaru předávaných hlaviček
ForwardedHeadersOptions řídí chování middlewaru Forwarded Headers. Následující příklad změní výchozí hodnoty:
- Omezte počet položek v přeposlaných záhlavích na
2
. - Přidejte známou
127.0.10.1
adresu proxy serveru . - Změňte název přeposlané hlavičky z výchozí
X-Forwarded-For
hodnoty 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";
});
Možnost | Popis |
---|---|
AllowedHosts | Omezí hostitele podle X-Forwarded-Host záhlaví na zadané hodnoty.
IList<string> . |
ForwardedHeaders | Určuje, které předávání by se měly zpracovat. Seznam polí, která se vztahují, najdete v výčtu ForwardedHeaders. Typické hodnoty přiřazené této vlastnosti jsou ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto .Výchozí hodnota je ForwardedHeaders.None. |
ForwardedForHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedForHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-For , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-For . |
ForwardedHostHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedHostHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Host , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-Host . |
ForwardedProtoHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedProtoHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Proto , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-Proto . |
ForwardedPrefixHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XForwardedPrefixHeaderName. Tato možnost se používá, když proxy nebo předávač nepoužívá hlavičku X-Forwarded-Prefix , ale k předávání informací používá jiné hlavičky.Výchozí hodnota je X-Forwarded-Prefix . |
ForwardLimit | Omezuje počet položek v záhlavích, která se zpracovávají. Nastavte na zakázání null limitu, ale mělo by se to provést jenom v případě, že KnownProxies KnownNetworks je nakonfigurovaný. Nastavení jinénull hodnoty je preventivní opatření (ale ne záruka), která chrání před chybně nakonfigurovanými proxy servery a škodlivými požadavky přicházejícími ze strany kanálů v síti.Middlewarové hlavičky předávané hlavičky zpracovávají hlavičky v obráceném pořadí zprava doleva. Pokud se použije výchozí hodnota ( 1 ), zpracuje se pouze hodnota úplně vpravo ze záhlaví, pokud se nezvětší ForwardLimit hodnota.Výchozí hodnota je 1 . |
KnownNetworks | Rozsahy adres známých sítí pro příjem předávaných hlaviček. Zadejte rozsahy IP adres pomocí zápisu technologie CIDR (Classless Interdomain Routing) (CIDR). Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.Výchozí hodnota je IList ><IPNetworkobsahující jednu položku pro .new IPNetwork(IPAddress.Loopback, 8) |
KnownProxies | Adresy známých proxy serverů pro příjem předávaných hlaviček. Slouží KnownProxies k určení přesné shody IP adres.Pokud server používá sokety se dvěma režimy, adresy IPv4 se zadají ve formátu IPv6 (například 10.0.0.1 v IPv4 reprezentované jako IPv6).::ffff:10.0.0.1 Viz IPAddress.MapToIPv6. Zjistěte, jestli je tento formát vyžadován pomocí httpContext.Connection.RemoteIpAddress.Výchozí hodnota je IList ><IPAddressobsahující jednu položku pro .IPAddress.IPv6Loopback |
OriginalForHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalForHeaderName. Výchozí hodnota je X-Original-For . |
OriginalHostHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalHostHeaderName. Výchozí hodnota je X-Original-Host . |
OriginalProtoHeaderName | Použijte hlavičku určenou touto vlastností místo toho, kterou určuje ForwardedHeadersDefaults.XOriginalProtoHeaderName. Výchozí hodnota je X-Original-Proto . |
OriginalPrefixHeaderName | Místo hlavičky určené touto vlastností použijte hlavičku určenou forwardedHeadersDefaults.XOriginalPrefixHeaderName. Výchozí hodnota je X-Original-Prefix . |
RequireHeaderSymmetry | Vyžaduje synchronizaci počtu hodnot záhlaví mezi zpracovávanými forwardedHeadersOptions.ForwardedHeaders.ForwardedHeaders . Výchozí hodnota v ASP.NET Core 1.x je true . Výchozí hodnota v ASP.NET Core 2.0 nebo novější je false . |
Scénáře a případy použití
Pokud není možné přidávat přeposílané hlavičky a všechny požadavky jsou zabezpečené
V některých případech nemusí být možné přidat předávané hlavičky do požadavků přesměrovaných do aplikace. Pokud proxy server vynucuje, že všechny veřejné externí požadavky jsou HTTPS, můžete schéma před použitím libovolného typu middlewaru nastavit Startup.Configure
ručně:
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
Tento kód může být zakázán s proměnnou prostředí nebo jiným nastavením konfigurace ve vývojovém nebo přípravném prostředí.
Řešení základní cesty a proxy serverů, které mění cestu požadavku
Některé proxy servery předávají cestu beze změny, ale se základní cestou aplikace, která by se měla odebrat, aby směrování fungovalo správně. Middleware UsePathBaseExtensions.UsePathBase rozdělí cestu na HttpRequest.Path a základní cestu aplikace na HttpRequest.PathBase.
Pokud /foo
se jedná o základní cestu aplikace pro cestu proxy předanou jako /foo/api/1
, middleware se nastaví Request.PathBase
na /foo
a Request.Path
na /api/1
následující příkaz:
app.UsePathBase("/foo");
Původní cesta a základ cesty se znovu povolají při opětovném zavolání middlewaru v obráceném směru. Další informace o zpracování objednávek middlewaru najdete v tématu ASP.NET Core Middleware.
Pokud proxy oříznou cestu (například přesměrování /foo/api/1
na/api/1
), opraví přesměrování a odkazy nastavením vlastnosti PathBase požadavku:
app.Use((context, next) =>
{
context.Request.PathBase = new PathString("/foo");
return next();
});
Pokud proxy přidává data cesty, zahoďte část cesty, abyste opravili přesměrování a odkazy pomocí StartsWithSegments a přiřazením Path vlastnosti:
app.Use((context, next) =>
{
if (context.Request.Path.StartsWithSegments("/foo", out var remainder))
{
context.Request.Path = remainder;
}
return next();
});
Konfigurace proxy serveru, který používá různé názvy hlaviček
Pokud proxy server nepoužívá hlavičky pojmenované X-Forwarded-For
a X-Forwarded-Proto
předávat adresu proxy serveru nebo port a informace o schématu původu, nastavte ForwardedForHeaderName a ForwardedProtoHeaderName možnosti tak, aby odpovídaly názvům hlaviček používaných proxy serverem:
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";
});
Přeposlání schématu pro reverzní proxy servery linuxu a jiné služby než IIS
Aplikace, které volají UseHttpsRedirection a UseHsts umístí web do nekonečné smyčky, pokud jsou nasazené do služby Azure Linux App Service, virtuálního počítače Azure s Linuxem nebo za jakýmkoli jiným reverzním proxy serverem kromě služby IIS. Protokol TLS je ukončen reverzním proxy serverem a Kestrel není informován o správném schématu požadavků. OAuth a OIDC také v této konfiguraci selžou, protože generují nesprávné přesměrování. UseIISIntegration přidává a konfiguruje middleware Forwarded Headers při spouštění za službou IIS, ale neexistuje žádná odpovídající automatická konfigurace pro Linux (integrace Apache nebo Nginx).
Pokud chcete schéma předat z proxy serveru ve scénářích, které nejsou službami IIS, přidejte a nakonfigurujte middleware Forwarded Headers. V Startup.ConfigureServices
aplikaci použijte následující kód:
// 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();
});
}
Předávání certifikátů
Azure
Pokud chcete nakonfigurovat službu Aplikace Azure service pro předávání certifikátů, přečtěte si téma Konfigurace vzájemného ověřování TLS pro službu Aplikace Azure Service. Následující pokyny se týkají konfigurace aplikace ASP.NET Core.
Před Startup.Configure
voláním app.UseAuthentication();
přidejte následující kód:
app.UseCertificateForwarding();
Nakonfigurujte middleware pro předávání certifikátů tak, aby určil název hlavičky, kterou Azure používá. Do Startup.ConfigureServices
pole přidejte následující kód pro konfiguraci hlavičky, ze které middleware vytvoří certifikát:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "X-ARR-ClientCert");
Další webové proxy servery
Pokud se používá proxy server, který není iis nebo směrování žádostí o aplikaci služby Aplikace Azure Service (ARR), nakonfigurujte proxy server tak, aby předával certifikát, který přijal v hlavičce HTTP. Před Startup.Configure
voláním app.UseAuthentication();
přidejte následující kód:
app.UseCertificateForwarding();
Nakonfigurujte middleware pro předávání certifikátů tak, aby zadal název hlavičky. Do Startup.ConfigureServices
pole přidejte následující kód pro konfiguraci hlavičky, ze které middleware vytvoří certifikát:
services.AddCertificateForwarding(options =>
options.CertificateHeader = "YOUR_CERTIFICATE_HEADER_NAME");
Pokud proxy server není kódováním base64 certifikát (stejně jako u serveru Nginx), nastavte tuto HeaderConverter
možnost. Podívejte se na následující příklad v 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;
}
});
Odstraňování potíží
Pokud se hlavičky nepřesměrují podle očekávání, povolte protokolování. Pokud protokoly neobsahují dostatečné informace pro řešení problému, uveďte výčet hlaviček požadavků přijatých serverem. K zápisu hlaviček požadavků do odpovědi aplikace nebo protokolování hlaviček použijte vložený middleware.
Pokud chcete napsat hlavičky do odpovědi aplikace, umístěte následující vložený middleware terminálu hned po volání UseForwardedHeaders Startup.Configure
:
app.Run(async (context) =>
{
context.Response.ContentType = "text/plain";
// Request method, scheme, and path
await context.Response.WriteAsync(
$"Request Method: {context.Request.Method}{Environment.NewLine}");
await context.Response.WriteAsync(
$"Request Scheme: {context.Request.Scheme}{Environment.NewLine}");
await context.Response.WriteAsync(
$"Request Path: {context.Request.Path}{Environment.NewLine}");
// Headers
await context.Response.WriteAsync($"Request Headers:{Environment.NewLine}");
foreach (var header in context.Request.Headers)
{
await context.Response.WriteAsync($"{header.Key}: " +
$"{header.Value}{Environment.NewLine}");
}
await context.Response.WriteAsync(Environment.NewLine);
// Connection: RemoteIp
await context.Response.WriteAsync(
$"Request RemoteIp: {context.Connection.RemoteIpAddress}");
});
Místo textu odpovědi můžete zapisovat do protokolů. Zápis do protokolů umožňuje, aby web při ladění fungoval normálně.
Zápis protokolů místo textu odpovědi:
- Vložte
ILogger<Startup>
doStartup
třídy, jak je popsáno v části Vytvoření protokolů při spuštění. - Umístěte následující vložený middleware ihned po volání UseForwardedHeaders do
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();
});
Při zpracování X-Forwarded-{For|Proto|Host|Prefix}
se hodnoty přesunou do X-Original-{For|Proto|Host|Prefix}
. Pokud v dané hlavičce existuje více hodnot, middlewarové hlavičky přeposílané hlavičky zpracovávají hlavičky v opačném pořadí zprava doleva. Výchozí hodnota ForwardLimit
je 1
(jedna), takže pouze hodnota nejvíce vpravo ze záhlaví se zpracuje, pokud se nezvětší ForwardLimit
hodnota.
Původní vzdálená IP adresa požadavku musí odpovídat položce v KnownProxies
seznamech před KnownNetworks
zpracováním předávaných hlaviček. Toto omezení falšování identity hlaviček tím, že nepřijímá předávání z nedůvěryhodných proxy serverů. Když se zjistí neznámý proxy server, protokolování označuje adresu proxy serveru:
September 20th 2018, 15:49:44.168 Unknown proxy: 10.0.0.100:54321
V předchozím příkladu je 10.0.0.100 proxy server. Pokud je server důvěryhodným proxy serverem, přidejte IP adresu serveru do KnownProxies
(nebo přidejte důvěryhodnou síť) do KnownNetworks
Startup.ConfigureServices
. Další informace najdete v části Možnosti middlewaru předávané hlavičky.
services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("10.0.0.100"));
});
Důležité
Povolit předávání hlaviček jenom důvěryhodným proxy serverům a sítím. V opačném případě jsou možné útoky falšování identity IP adres.