Sdílet prostřednictvím


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:

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-ProtoX-Forwarded-Host a X-Forwarded-Prefix.
  • Hodnota ForwardedHeaders je ForwardedHeaders.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 na X-Forwarded-For-My-Custom-Header-Name.
using System.Net;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
    options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});

var app = builder.Build();

app.UseForwardedHeaders();

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

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

app.UseAuthorization();

app.MapRazorPages();

app.Run();
Možnost Popis
AllowedHosts Omezí hostitele podle X-Forwarded-Host záhlaví na zadané hodnoty.
  • Hodnoty se porovnávají pomocí řadového a přeskakování velkých a malých písmen.
  • Čísla portů musí být vyloučena.
  • Pokud je seznam prázdný, jsou všichni hostitelé povoleni.
  • Zástupný znak * nejvyšší úrovně umožňuje všem neprázdným hostitelům.
  • Zástupné dokumentace subdomény jsou povolené, ale neodpovídají kořenové doméně. Například odpovídá subdoméněfoo.contoso.com, *.contoso.com ale ne kořenové doméně contoso.com.
  • Názvy hostitelů Unicode jsou povoleny, ale jsou převedeny na punycode pro porovnávání.
  • Adresy IPv6 musí obsahovat ohraničující hranaté závorky a musí být v konvenční podobě (například [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Adresy IPv6 nejsou speciální, aby bylo možné zkontrolovat logickou rovnost mezi různými formáty a neprovádí se kanonizace.
  • Pokud nepovolíte omezení povolených hostitelů, může kyberattackeru umožnit falšování odkazů generovaných službou.
Výchozí hodnota je prázdná 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 KnownProxiesnebo 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í RemoteIpAddressmiddlewaru . Podrobnosti najdete v možnostech middlewaru Forwarded Headers. Spotřebované hodnoty jsou odebrány z X-Forwarded-Fora staré hodnoty jsou trvalé v X-Original-For. Stejný vzor se použije u ostatních hlaviček Host a Proto.
  • 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 a X-Forwarded-Proto.
  • Hodnota ForwardedHeaders je ForwardedHeaders.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.ConfigureServicessouboru .

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.1adresu proxy serveru .
  • Změňte název přeposlané hlavičky z výchozí X-Forwarded-For hodnoty na X-Forwarded-For-My-Custom-Header-Name.
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardLimit = 2;
    options.KnownProxies.Add(IPAddress.Parse("127.0.10.1"));
    options.ForwardedForHeaderName = "X-Forwarded-For-My-Custom-Header-Name";
});
Možnost Popis
AllowedHosts Omezí hostitele podle X-Forwarded-Host záhlaví na zadané hodnoty.
  • Hodnoty se porovnávají pomocí řadového a přeskakování velkých a malých písmen.
  • Čísla portů musí být vyloučena.
  • Pokud je seznam prázdný, jsou všichni hostitelé povoleni.
  • Zástupný znak * nejvyšší úrovně umožňuje všem neprázdným hostitelům.
  • Zástupné dokumentace subdomény jsou povolené, ale neodpovídají kořenové doméně. Například odpovídá subdoméněfoo.contoso.com, *.contoso.com ale ne kořenové doméně contoso.com.
  • Názvy hostitelů Unicode jsou povoleny, ale jsou převedeny na punycode pro porovnávání.
  • Adresy IPv6 musí obsahovat ohraničující hranaté závorky a musí být v konvenční podobě (například [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). Adresy IPv6 nejsou speciální, aby bylo možné zkontrolovat logickou rovnost mezi různými formáty a neprovádí se kanonizace.
  • Pokud nepovolíte omezení povolených hostitelů, může kyberattackeru umožnit falšování odkazů generovaných službou.
Výchozí hodnota je prázdná 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.ConfigureServicesaplikaci 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.Configurevolá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.ConfigureServicespole 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.Configurevolá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.ConfigureServicespole 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:

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 KnownNetworksStartup.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.

Další materiály