ASP.NET Core'u ara sunucular ve yük dengeleyicilerle çalışacak şekilde yapılandırma

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.

Uyarı

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.

Tarafından Chris Ross

ASP.NET Core için önerilen yapılandırmada uygulama IIS, Nginx veya Apache için ASP.NET Core Modülü (ANCM) kullanılarak barındırılır. Ara sunucular, yük dengeleyiciler ve diğer ağ gereçleri genellikle uygulamaya ulaşmadan önce istek hakkındaki bilgileri gizler:

  • HTTPS istekleri HTTP üzerinden proxylandığında, özgün düzen (HTTPS) kaybolur ve başlıkta iletilmesi gerekir.
  • Bir uygulama, İnternet veya şirket ağındaki gerçek kaynağından değil proxy'den istek aldığından, kaynak istemci IP adresi de üst bilgide iletilmelidir.

Bu bilgiler, yeniden yönlendirmeler, kimlik doğrulaması, bağlantı oluşturma, ilke değerlendirmesi ve istemci coğrafi konumu gibi istek işlemede önemli olabilir.

Web grubunda çalıştırılması amaçlanan uygulamalar, ASP.NET Core'u bir web çiftliğinde barındırma konusunu okumalıdır.

İletilen üst bilgiler

Kural gereği proxy'ler HTTP üst bilgilerinde bilgileri iletir.

Başlık Açıklama
X-Forwarded-For (XFF) İsteği başlatan istemci ve vekil sunucu zincirindeki sonraki vekil sunucular hakkında bilgi içerir. Bu parametre IP adresleri ve isteğe bağlı olarak bağlantı noktası numaraları içerebilir. Ara sunucu zincirinde, ilk parametre isteğin ilk yapıldığı istemciyi gösterir. Bundan sonra proxy tanımlayıcıları gelir. Zincirdeki son ara sunucu, parametre listesinde yer almıyor. Son proxy'nin IP adresi ve isteğe bağlı olarak bir bağlantı noktası numarası, aktarım katmanında uzak IP adresi olarak kullanılabilir.
X-Forwarded-Proto (XFP) Kaynak düzenin değeri, HTTP veya HTTPS. İstek birden çok ara sunucuya geçtiyse, değer bir şema listesi de olabilir.
X-Forwarded-Host (XFH) Host üst bilgisi alanının orijinal değeri. Proxy'ler genellikle Konak üst bilgisini değiştirmez. Bir proxy'nin Ana Bilgisayar başlıklarını doğrulamadığı veya bilinen uygun değerlerle sınırlandırmadığı sistemleri etkileyen ayrıcalık yükseltme güvenlik açığı hakkında bilgi için Microsoft Güvenlik Danışmanlığı CVE-2018-0787'ye bakın.
X-Forwarded-Prefix İstemci tarafından istenen özgün temel yol. Bu üst bilgi, uygulamaların url'leri, yeniden yönlendirmeleri veya istemciye yeniden bağlantıları doğru şekilde oluşturması için yararlı olabilir.

İletilen üst bilgi ara yazılımı, ForwardedHeadersMiddlewarebu üst bilgileri okur ve üzerindeki HttpContextilişkili alanları doldurur.

Ara yazılım güncelleştirmeleri:

Yukarıdakiler hakkında daha fazla bilgi için bu GitHub sorununa bakın.

İletilen başlıklar ara yazılımının varsayılan ayarları yapılandırılabilir. Varsayılan ayarlar için:

  • Uygulama ile isteklerin kaynağı arasında yalnızca bir ara sunucu vardır.
  • Bilinen proxy'ler ve bilinen ağlar için yalnızca geri döngü adresleri yapılandırılır.
  • İletilen başlıklar X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host ve X-Forwarded-Prefix olarak adlandırılır.
  • ForwardedHeaders değeri ForwardedHeaders.None. Ara yazılımı etkinleştirmek için istenen ileticilerin burada ayarlanması gerekir.

Her ağ gereci ek yapılandırma olmadan X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini eklemez. Proxy istekleri uygulamaya ulaştığında bu başlıklar içermiyorsa cihaz üreticinizin kılavuzuna başvurun. Cihaz X-Forwarded-For ve X-Forwarded-Proto'den farklı üst bilgi adları kullanıyorsa, ForwardedForHeaderName ve ForwardedProtoHeaderName seçeneklerini cihazın kullandığı üst bilgi adlarıyla eşleşecek şekilde ayarlayın. Daha fazla bilgi için bkz. İletilen üst bilgi ara yazılım seçenekleri ve Farklı üst bilgi adları kullanan bir ara sunucu için yapılandırma.

IIS/IIS Express ve ASP.NET Çekirdek Modülü

IIS tümleştirme ara yazılımı, uygulama IIS’in arkasında işlem dışı olarak ve IIS için ASP.NET Core Modülü (ANCM) ile barındırıldığında, iletilen üst bilgiler ara yazılımını varsayılan olarak etkinleştirir. İletilen üst bilgiler ara yazılımı, ASP.NET Core Modülüne özgü kısıtlı bir yapılandırmayla ilk olarak ara yazılım işlem hattında çalıştırılacak şekilde etkinleştirilir. Kısıtlanmış yapılandırma, iletilen üst bilgilerle (örneğin, IP kimlik sahtekarlığına) ilişkin güven endişelerinden kaynaklanır. Ara yazılım, X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini iletecek şekilde yapılandırılır ve tek bir localhost proxy'siyle sınırlıdır. Ek yapılandırma gerekiyorsa, iletilen üstbilgi ara yazılımı seçeneklerine bakın.

Diğer ara sunucu ve yük dengeleyici senaryoları

IIS Tümleştirmesi ile işlem dışı olarak barındırma kullanılması dışında, iletilen üst bilgiler ara yazılımı varsayılan olarak etkin değildir. Bir uygulamanın UseForwardedHeaders ile yönlendirilen üst bilgileri işleyebilmesi için Yönlendirilen Üst Bilgiler ara katmanının etkinleştirilmesi gerekir. Ara yazılım etkinleştirildikten sonra, middleware için hiçbir ForwardedHeadersOptions belirtilmemişse, varsayılan ForwardedHeadersOptions.ForwardedHeadersForwardedHeaders.None olur.

Orta yazılımı ForwardedHeadersOptions ile X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini iletmek için yapılandırın.

İletilen Üstbilgiler Ara Katmanı Sıralaması

İletilen üst bilgiler ara yazılımı diğer ara yazılımdan önce çalıştırılmalıdır. Bu sıralama, iletilen üst bilgilere dayalı ara yazılımların işlemek üzere üst bilgi değerlerini kullanabilmesini sağlar. İletilen Başlıklar ara yazılımı, tanılama ve hata işleme işlemlerinden sonra çalıştırılabilir; ancak UseHsts çağrılmadan önce çalıştırılmalıdır:

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

Alternatif olarak, tanılamadan önce UseForwardedHeaders arayın.

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

Not

Uzantı yöntemine ForwardedHeadersOptions ile doğrudan uygulanmaz veya UseForwardedHeaders belirtilmezse, iletilecek varsayılan üst bilgiler ForwardedHeaders.None olacaktır. İletilecek üst bilgileri ile ForwardedHeaders özelliğinin yapılandırılması gerekir.

Nginx yapılandırması

X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini iletmek için Nginx ile Linux üzerinde ASP.NET Core barındırma konusuna bakın.

Apache yapılandırması

X-Forwarded-For otomatik olarak eklenir. Daha fazla bilgi için bkz. Apache Modülü mod_proxy: Ters Proxy İstek Üst Bilgileri.

İletilen Başlıklar Ara Yazılımı Seçenekleri

ForwardedHeadersOptions iletilen üst bilgiler ara yazılımının davranışını kontrol eder. Aşağıdaki örnek varsayılan değerleri değiştirir:

  • İletilen üst bilgilerdeki girdilerin sayısını 2 ile sınırlar.
  • bilinen bir proxy adresi 127.0.10.1ekler.
  • İletilen üst bilgi adını varsayılandan X-Forwarded-For olarak X-Forwarded-For-My-Custom-Header-Namedeğiştirir.
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();
Seçenek Açıklama
AllowedHosts Başlık X-Forwarded-Host tarafından sağlanan değerlerle ana bilgisayarları kısıtlar.
  • Değerler ordinal-ignore-case kullanılarak karşılaştırılır.
  • Bağlantı noktası numaraları dışlanmalıdır.
  • Liste boşsa, tüm ana bilgisayarlara izin verilir.
  • Üst düzey joker karakter * , boş olmayan tüm konaklara izin verir.
  • Alt alan adı joker karakterlerine izin verilir, ancak ana etki alanıyla eşleşmezler. Örneğin, *.contoso.com alt etki foo.contoso.com alanı ile eşleşir ancak kök etki alanı contoso.comile eşleşmez.
  • Unicode ana bilgisayar adlarına izin verilir, ancak eşleştirme için Punycode'a dönüştürülür.
  • IPv6 adresleri sınırlayıcı köşeli ayraçlar içermeli ve geleneksel biçimde olmalıdır (örneğin, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6 adresleri, farklı biçimler arasındaki mantıksal eşitliği denetlemek için özel durumlu değildir ve kurallı hale getirme gerçekleştirilmez.
  • İzin verilen konakların kısıtlanmaması, bir siber saldırganın hizmet tarafından oluşturulan bağlantıları sahtelemek için imkan tanıyabilir.
Varsayılan değer boş IList<string>bir değerdir.
ForwardedForHeaderName ForwardedHeadersDefaults.XForwardedForHeaderName tarafından belirtilen üst bilgi yerine, bu özellik tarafından belirtilen üst bilgiyi kullanın. Proxy/iletici X-Forwarded-For üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-For.
ForwardedHeaders hangi ileticilerin işlenmesi gerektiğini tanımlar. Geçerli alanların listesi için bkz. ForwardedHeaders Sabit Listesi. Bu özelliğe atanan tipik değerler şunlardır: ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

Varsayılan değer ForwardedHeaders.None değeridir.
ForwardedHostHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XForwardedHostHeaderName tarafından belirtilen üst bilgi yerine kullanın. Proxy/iletici X-Forwarded-Host üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-Host.
ForwardedProtoHeaderName ForwardedHeadersDefaults.XForwardedProtoHeaderName tarafından belirtilen üst bilgi yerine bu özellik tarafından belirtilen üst bilgiyi kullanın. Proxy/iletici X-Forwarded-Proto üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-Proto.
ForwardLimit İşlenen üst bilgilerdeki girdi sayısını sınırlar. Sınırı devre dışı bırakmak için null olarak ayarlayın, ancak bu işlem yalnızca KnownProxies veya KnownNetworks yapılandırıldıysa yapılmalıdır. Değer olmayannull bir değer ayarlamak, yanlış yapılandırılmış proxy'lere ve ağ üzerindeki yan kanallardan gelen kötü amaçlı isteklere karşı koruma sağlamak için bir önlemdir (ancak garanti değildir).

İletilen Başlıklar Ara Yazılımı, başlıkları sağdan sola, yani ters sırayla işler. Varsayılan değer (1) kullanılırsa, değeri artırılmadığı sürece yalnızca üst bilgilerden en sağdaki değer ForwardLimit işlenir.

Varsayılan değer: 1.
KnownNetworks Bilinen ağların adres aralıklarını, iletilen üst bilgileri kabul etmek için ayarla. Sınıfsız Etki Alanı Arası Yönlendirme (CIDR) gösterimini kullanarak IP aralıkları sağlayın.

Sunucu çift modlu yuvalar kullanıyorsa, IPv4 adresleri IPv6 biçiminde sağlanır (örneğin, 10.0.0.1 IPv6 ile temsil edilen IPv4'te olarak ::ffff:10.0.0.1). Bkz. IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress'e bakarak bu biçimin gerekli olup olmadığını belirleyin.

Varsayılan, IList için tek bir giriş içeren bir <IPNetwork>new IPNetwork(IPAddress.Loopback, 8) öğesidir.
KnownProxies İletilen üst bilgileri kabul etmek için bilinen ara sunucuların adresleri. Tam IP adresi eşleşmelerini belirtmek için kullanın KnownProxies .

Sunucu çift modlu yuvalar kullanıyorsa, IPv4 adresleri IPv6 biçiminde sağlanır (örneğin, 10.0.0.1 IPv6 ile temsil edilen IPv4'te olarak ::ffff:10.0.0.1). Bkz. IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress'e bakarak bu biçimin gerekli olup olmadığını belirleyin.

Varsayılan, IList için tek bir giriş içeren bir <IPAddress>IPAddress.IPv6Loopback öğesidir.
OriginalForHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XOriginalForHeaderName tarafından belirtilen üst bilgi yerine kullanın.

Varsayılan değer: X-Original-For.
OriginalHostHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XOriginalHostHeaderName tarafından belirtilen üst bilgi yerine kullanın.

Varsayılan değer: X-Original-Host.
OriginalProtoHeaderName ForwardedHeadersDefaults.XOriginalProtoHeaderName tarafından belirtilen üst bilgi yerine bu özellik tarafından belirtilen üst bilgiyi kullanın.

Varsayılan değer: X-Original-Proto.
RequireHeaderSymmetry ForwardedHeadersOptions.ForwardedHeaders işlenirken üst bilgi değerlerinin eşitlenmesi gereklidir.

ASP.NET Core 1.x'teki varsayılan değerdir true. ASP.NET Core 2.0 veya sonraki sürümlerinde varsayılan değerdir false.

Senaryolar ve kullanım örnekleri

İletilen üst bilgileri eklemek mümkün olmadığında ve tüm istekler güvenli olduğunda

Uygulamaya proxy aracılığıyla gönderilen isteklere iletilen üstbilgileri eklemek bazı durumlarda mümkün olmayabilir. Proxy tüm dış genel isteklerin HTTPS olmasını zorunlu kılıyorsa, şema herhangi bir ara yazılımdan önce manuel olarak ayarlanabilir.

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

Bu kod, geliştirme veya hazırlama ortamında ortam değişkeni veya başka bir yapılandırma ayarıyla devre dışı bırakılabilir:

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

İstek yolunu değiştiren yol tabanı ve proxy'lerle çalışma

Bazı proxy'ler yolu olduğu gibi aktarır, ancak yönlendirmenin düzgün çalışması için kaldırılması gereken bir temel uygulama yolu vardır. UsePathBaseExtensions.UsePathBase ara yazılımı yolu HttpRequest.Path'a, uygulama temel yolunu da HttpRequest.PathBase'e böler.

Eğer /foo bir proxy yolu olarak /foo/api/1 geçirilirse, ara yazılım Request.PathBase değerini /foo ve Request.Path değerini /api/1 olarak ayarlar ve bunu aşağıdaki komutla gerçekleştirir:

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

Not

kullanırken WebApplication (bkz. .NET 5'te ASP.NET Core'dan .NET 6'ya geçiş), app.UseRouting yönlendirme ara yazılımının yolları eşleştirmeden önce değiştirilmiş yolu gözlemlemesi için bundan sonra UsePathBase çağrılmalıdır. Aksi takdirde, rotalar, ASP.NET Core ara yazılımı ve ASP.NET Core'da Yönlendirme bölümlerinde açıklandığı gibi UsePathBase yolu yeniden yazmadan önce eşleştirilir.

Ara yazılım ters olarak yeniden çağrıldığında özgün yol ve yol tabanı yeniden uygulanır. Ara yazılım sıralaması hakkında daha fazla bilgi için bkz. ASP.NET Core ara yazılımı.

Ara yol sunucusu yolu kırpıyorsa (örneğin, /foo/api/1'den /api/1'e iletme), isteğin PathBase özelliğini ayarlayarak yeniden yönlendirmeleri ve bağlantıları düzeltin.

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

Ara sunucu yol verileri ekliyorsa, StartsWithSegments kullanarak ve Path özelliğine atayarak yeniden yönlendirmeleri ve bağlantıları düzeltmek için yolun bir bölümünü atın.

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

    return next(context);
});

Farklı üst bilgi adları kullanan bir ara sunucu için yapılandırma

Proxy, proxy adresi/bağlantı noktası ve kaynak şeması bilgilerini iletmek için X-Forwarded-For ve X-Forwarded-Proto adında üst bilgileri kullanmıyorsa, ForwardedForHeaderName ve ForwardedProtoHeaderName seçeneklerini, proxy tarafından kullanılan üst bilgi adlarıyla eşleşecek şekilde ayarlayın.

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

Linux ve IIS dışı ters proxy'ler için şemayı iletme

Azure Linux App Service'e, Azure Linux sanal makinesine (VM) veya IIS dışındaki diğer ters ara sunucuların arkasına dağıtıldığında, UseHttpsRedirection ve UseHsts çağıran uygulamalar bir siteyi sonsuz döngüye sokar. Ters ara sunucu TLS'yi sonlandırır ve Kestrel doğru istek şemasının farkında değildir. OAuth ve OIDC de yanlış yeniden yönlendirmeler oluşturduğundan bu yapılandırmada başarısız olur. UseIISIntegration IIS arkasında çalıştığında iletilen üstbilgiler ara yazılımını ekler ve yapılandırır, ancak Linux için buna karşılık gelen otomatik bir yapılandırma yoktur (Apache veya Nginx entegrasyonu).

IIS dışı senaryolarda şemayı proxy'den iletmek için, ASPNETCORE_FORWARDEDHEADERS_ENABLED öğesini true olarak ayarlayarak iletilen üst bilgiler ara yazılımını etkinleştirin. Uyarı: Bu bayrak, bulut ortamları için tasarlanmış ayarları kullanır ve hangi IP ileticilerinin kabul edildiğine kısıtlama gibi KnownProxies option özellikleri etkinleştirmez.

Sertifika iletme

Gök mavisi

Azure Uygulaması Hizmeti'ni sertifika iletme için yapılandırmak için bkz. Azure Uygulaması Hizmeti için TLS karşılıklı kimlik doğrulamasını yapılandırma. Aşağıdaki kılavuz, ASP.NET Core uygulamasını yapılandırmayla ilgilidir.

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

Diğer web proxy'leri

IIS veya Azure Uygulama Hizmeti'nin Uygulama İsteği Yönlendirmesi (ARR) olmayan bir ara sunucu kullanılıyorsa, proxy'yi aldığı sertifikayı bir HTTP üst bilgisiyle iletecek şekilde yapılandırın.

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

Proxy, Nginx'de olduğu gibi sertifikayı base64 kodlaması yapmıyorsa seçeneğini ayarlayın HeaderConverter . Aşağıdaki örneği inceleyin:

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

Sorun giderme

Üst bilgiler beklendiği gibi iletilmiyorsa, debug düzeyinde günlük kaydı ve HTTP istek günlüğünü etkinleştirin. UseHttpLogging ' den sonra UseForwardedHeadersçağrılmalıdır:

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

Belirli bir üst bilgide birden çok değer varsa, iletilen üst bilgiler ara yazılım üst bilgileri sağdan sola doğru ters sırada işler. Varsayılan ForwardLimit (bir) olduğundan, 1 değeri artırılmadıkça üst bilgilerden yalnızca en sağdaki değer ForwardLimit işlenir.

İletilen üst bilgiler işlenmeden önce isteğin özgün uzak IP'sinin KnownProxies veya KnownNetworks listelerindeki bir girdiyle eşleşmesi gerekir. Bu, güvenilmeyen proxy'lerden ileticileri kabul etmeyerek üst bilgi yanıltma işlemini sınırlar. Bilinmeyen bir ara sunucu algılandığında günlüğe kayıt, proxy'nin adresini gösterir.

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

Yukarıdaki örnekte, 10.0.0.100 bir ara sunucudur. Sunucu güvenilen bir ara sunucuysa, KnownProxies'ye sunucunun IP adresini ekleyin veya güvenilen bir ağı KnownNetworks öğesine ekleyin. Daha fazla bilgi için iletme üstbilgileri ara yazılımı seçenekleri bölümüne bakın.

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

Günlükleri görüntülemek için dosyaya "Microsoft.AspNetCore.HttpLogging": "Information" ekleyinappsettings.Development.json:

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

Önemli

Yalnızca güvenilen proxy'lerin ve ağların üst bilgileri iletmesine izin verin. Aksi takdirde, IP adres sahteciliği saldırıları mümkündür.

Ek kaynaklar

ASP.NET Core için önerilen yapılandırmada uygulama IIS/ASP.NET Core Modülü, Nginx veya Apache kullanılarak barındırılır. Ara sunucular, yük dengeleyiciler ve diğer ağ gereçleri genellikle uygulamaya ulaşmadan önce istek hakkındaki bilgileri gizler:

  • HTTPS istekleri HTTP üzerinden proxylandığında, özgün düzen (HTTPS) kaybolur ve başlıkta iletilmesi gerekir.
  • Bir uygulama, İnternet veya şirket ağındaki gerçek kaynağından değil proxy'den istek aldığından, kaynak istemci IP adresi de üst bilgide iletilmelidir.

Bu bilgiler, yeniden yönlendirmeler, kimlik doğrulaması, bağlantı oluşturma, ilke değerlendirmesi ve istemci coğrafi konumu gibi istek işlemede önemli olabilir.

İletilen üst bilgiler

Kural gereği proxy'ler HTTP üst bilgilerinde bilgileri iletir.

Başlık Açıklama
X İletilmiş-For İsteği başlatan istemci ve vekil sunucu zincirindeki sonraki vekil sunucular hakkında bilgi içerir. Bu parametre IP adresleri (ve isteğe bağlı olarak bağlantı noktası numaraları) içerebilir. Ara sunucu zincirinde, ilk parametre isteğin ilk yapıldığı istemciyi gösterir. Bundan sonra proxy tanımlayıcıları gelir. Zincirdeki son ara sunucu, parametre listesinde yer almıyor. Son proxy'nin IP adresi ve isteğe bağlı olarak bir bağlantı noktası numarası, aktarım katmanında uzak IP adresi olarak kullanılabilir.
X-Forwarded-Proto Kaynak düzenin değeri (HTTP/HTTPS). İstek birden çok ara sunucuya geçtiyse, değer bir şema listesi de olabilir.
X-Forwarded-Host Host üst bilgisi alanının orijinal değeri. Proxy'ler genellikle Konak üst bilgisini değiştirmez. Bir proxy'nin Ana Bilgisayar başlıklarını doğrulamadığı veya bilinen uygun değerlerle sınırlandırmadığı sistemleri etkileyen ayrıcalık yükseltme güvenlik açığı hakkında bilgi için Microsoft Güvenlik Danışmanlığı CVE-2018-0787'ye bakın.

İletilen üst bilgi ara yazılımı (ForwardedHeadersMiddleware ), bu üst bilgileri okur ve üzerindeki HttpContextilişkili alanları doldurur.

Ara yazılım güncelleştirmeleri:

Yukarıdakiler hakkında daha fazla bilgi için bu GitHub sorununa bakın.

İletilen üst bilgi ara yazılımının varsayılan ayarları yapılandırılabilir. Varsayılan ayarlar için:

  • Uygulama ile isteklerin kaynağı arasında yalnızca bir ara sunucu vardır.
  • Bilinen proxy'ler ve bilinen ağlar için yalnızca geri döngü adresleri yapılandırılır.
  • İletilen üst bilgiler X-Forwarded-For ve X-Forwarded-Proto olarak adlandırılır.
  • ForwardedHeaders değeri ForwardedHeaders.None, orta katman yazılımı etkinleştirmek için istenen ileticilerin burada ayarlanması gerekir.

Her ağ gereci ek yapılandırma olmadan X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini eklemez. Proxy istekleri uygulamaya ulaştığında bu başlıklar içermiyorsa cihaz üreticinizin kılavuzuna başvurun. Cihaz X-Forwarded-For ve X-Forwarded-Proto'den farklı üst bilgi adları kullanıyorsa, ForwardedForHeaderName ve ForwardedProtoHeaderName seçeneklerini cihazın kullandığı üst bilgi adlarıyla eşleşecek şekilde ayarlayın. Daha fazla bilgi için bkz. İletilen üst bilgi ara yazılım seçenekleri ve Farklı üst bilgi adları kullanan bir ara sunucu için yapılandırma.

IIS/IIS Express ve ASP.NET Çekirdek Modülü

IIS tümleştirme ara yazılımı, uygulama IIS ve ASP.NET Core Modülü arkasında işlem dışı olarak barındırıldığında varsayılan olarak iletilen üst bilgi ara yazılımını etkinleştirir. İletilen üst bilgiler ara yazılımı, iletilen üst bilgilerle ilgili güven endişeleri (örneğin, IP sahteciliği) nedeniyle ASP.NET Core Modülü’ne özgü kısıtlı bir yapılandırmayla ara yazılım işlem hattında ilk çalışacak şekilde etkinleştirilir. Ara yazılım, X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini iletecek şekilde yapılandırılır ve tek bir localhost proxy'siyle sınırlıdır. Ek yapılandırma gerekliyse, İletilen Üst Bilgiler Ara Yazılımı seçeneklerine bakın.

Diğer ara sunucu ve yük dengeleyici senaryoları

IIS Tümleştirmesi'nin işlem dışı barındırmada kullanımı dışında, iletilen üstbilgiler ara yazılımı varsayılan olarak etkin değildir. Bir uygulamanın UseForwardedHeaders ile yönlendirilen üst bilgileri işleyebilmesi için Yönlendirilen Üst Bilgiler ara yazılımının etkinleştirilmesi gerekir. Ara yazılım etkinleştirildikten sonra, middleware için hiçbir ForwardedHeadersOptions belirtilmemişse, varsayılan ForwardedHeadersOptions.ForwardedHeadersForwardedHeaders.None olur.

Ara yazılımı ForwardedHeadersOptions ve X-Forwarded-For üst bilgilerini X-Forwarded-Proto içinde iletmek için Startup.ConfigureServices ile yapılandırın.

İletilen üst bilgiler ara yazılım sırası

İletilen üstbilgiler ara yazılımı, diğer ara yazılımlardan önce çalıştırılmalıdır. Bu sıralama, iletilen üst bilgilere dayalı ara yazılımların işlemek üzere üst bilgi değerlerini kullanabilmesini sağlar. İletilen üstbilgiler ara katmanı, tanılama ve hata işleme işleminden sonra çalıştırılabilir; ancak UseHsts çağrılmadan önce çalıştırılmalıdır:

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

Alternatif olarak, tanılamadan önce UseForwardedHeaders arayın.

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

Not

Eğer ForwardedHeadersOptions veya Startup.ConfigureServices ile uzantı yönteminde UseForwardedHeaders belirtilmemişse, iletecek varsayılan üst bilgiler ForwardedHeaders.None'dir. İletilecek üst bilgileri ile ForwardedHeaders özelliğinin yapılandırılması gerekir.

Nginx yapılandırması

X-Forwarded-For ve X-Forwarded-Proto üst bilgilerini iletmek için Nginx ile Linux üzerinde ASP.NET Core barındırma konusuna bakın.

Apache yapılandırması

X-Forwarded-For otomatik olarak eklenir (bkz . Apache Modülü mod_proxy: Ters Proxy İsteği Üst Bilgileri).

İletilen üst bilgiler ara yazılım seçenekleri

ForwardedHeadersOptions iletilen üstbilgiler ara yazılımının davranışını denetler. Aşağıdaki örnek varsayılan değerleri değiştirir:

  • İletilen üst bilgilerdeki girdi sayısını 2 ile sınırlayın.
  • bilinen bir proxy adresi 127.0.10.1ekleyin.
  • İletilen üst bilgi adını varsayılan X-Forwarded-For değerinden X-Forwarded-For-My-Custom-Header-Name olarak değiştirin.
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";
});
Seçenek Açıklama
AllowedHosts Başlık X-Forwarded-Host tarafından sağlanan değerlerle ana bilgisayarları kısıtlar.
  • Değerler ordinal-ignore-case kullanılarak karşılaştırılır.
  • Bağlantı noktası numaraları dışlanmalıdır.
  • Liste boşsa, tüm ana bilgisayarlara izin verilir.
  • Üst düzey joker karakter * , boş olmayan tüm konaklara izin verir.
  • Alt alan adı joker karakterlerine izin verilir, ancak ana etki alanıyla eşleşmezler. Örneğin, *.contoso.com alt etki foo.contoso.com alanı ile eşleşir ancak kök etki alanı contoso.comile eşleşmez.
  • Unicode ana bilgisayar adlarına izin verilir, ancak eşleştirme için Punycode'a dönüştürülür.
  • IPv6 adresleri sınırlayıcı köşeli ayraçlar içermeli ve geleneksel biçimde olmalıdır (örneğin, [ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]). IPv6 adresleri, farklı biçimler arasındaki mantıksal eşitliği denetlemek için özel durumlu değildir ve kurallı hale getirme gerçekleştirilmez.
  • İzin verilen konakların kısıtlanmaması, bir siber saldırganın hizmet tarafından oluşturulan bağlantıları sahtelemek için imkan tanıyabilir.
Varsayılan değer boş IList<string>bir değerdir.
ForwardedHeaders hangi ileticilerin işlenmesi gerektiğini tanımlar. Geçerli alanların listesi için bkz. ForwardedHeaders Sabit Listesi. Bu özelliğe atanan tipik değerler şunlardır: ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto.

Varsayılan değer ForwardedHeaders.None değeridir.
ForwardedForHeaderName ForwardedHeadersDefaults.XForwardedForHeaderName tarafından belirtilen üst bilgi yerine, bu özellik tarafından belirtilen üst bilgiyi kullanın. Proxy/iletici X-Forwarded-For üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-For.
ForwardedHostHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XForwardedHostHeaderName tarafından belirtilen üst bilgi yerine kullanın. Proxy/iletici X-Forwarded-Host üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-Host.
ForwardedProtoHeaderName ForwardedHeadersDefaults.XForwardedProtoHeaderName tarafından belirtilen üst bilgi yerine bu özellik tarafından belirtilen üst bilgiyi kullanın. Proxy/iletici X-Forwarded-Proto üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-Proto.
ForwardedPrefixHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XForwardedPrefixHeaderName tarafından belirtilen üst bilgi yerine kullanın. Proxy/iletici X-Forwarded-Prefix üst bilgisini kullanmadığında ancak bilgileri iletmek için başka bir üst bilgi kullandığında bu seçenek kullanılır.

Varsayılan değer: X-Forwarded-Prefix.
ForwardLimit İşlenen üst bilgilerdeki girdi sayısını sınırlar. Sınırı devre dışı bırakmak için null olarak ayarlayın, ancak bu işlem yalnızca KnownProxies veya KnownNetworks yapılandırıldıysa yapılmalıdır. Değer olmayannull bir değer ayarlamak, yanlış yapılandırılmış proxy'lere ve ağ üzerindeki yan kanallardan gelen kötü amaçlı isteklere karşı koruma sağlamak için bir önlemdir (ancak garanti değildir).

İletilen üst bilgiler ara yazılım, üst bilgileri sağdan sola doğru ters sırada işler. Varsayılan değer (1) kullanılırsa, değeri artırılmadığı sürece yalnızca üst bilgilerden en sağdaki değer ForwardLimit işlenir.

Varsayılan değer: 1.
KnownNetworks Bilinen ağların adres aralıklarını, iletilen üst bilgileri kabul etmek için ayarla. Sınıfsız Etki Alanı Arası Yönlendirme (CIDR) gösterimini kullanarak IP aralıkları sağlayın.

Sunucu çift modlu yuvalar kullanıyorsa, IPv4 adresleri IPv6 biçiminde sağlanır (örneğin, 10.0.0.1 IPv6 ile temsil edilen IPv4'te olarak ::ffff:10.0.0.1). Bkz. IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress'e bakarak bu biçimin gerekli olup olmadığını belirleyin.

Varsayılan, IList için tek bir giriş içeren bir <IPNetwork>new IPNetwork(IPAddress.Loopback, 8) öğesidir.
KnownProxies İletilen üst bilgileri kabul etmek için bilinen ara sunucuların adresleri. Tam IP adresi eşleşmelerini belirtmek için kullanın KnownProxies .

Sunucu çift modlu yuvalar kullanıyorsa, IPv4 adresleri IPv6 biçiminde sağlanır (örneğin, 10.0.0.1 IPv6 ile temsil edilen IPv4'te olarak ::ffff:10.0.0.1). Bkz. IPAddress.MapToIPv6. HttpContext.Connection.RemoteIpAddress'e bakarak bu biçimin gerekli olup olmadığını belirleyin.

Varsayılan, IList için tek bir giriş içeren bir <IPAddress>IPAddress.IPv6Loopback öğesidir.
OriginalForHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XOriginalForHeaderName tarafından belirtilen üst bilgi yerine kullanın.

Varsayılan değer: X-Original-For.
OriginalHostHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XOriginalHostHeaderName tarafından belirtilen üst bilgi yerine kullanın.

Varsayılan değer: X-Original-Host.
OriginalProtoHeaderName ForwardedHeadersDefaults.XOriginalProtoHeaderName tarafından belirtilen üst bilgi yerine bu özellik tarafından belirtilen üst bilgiyi kullanın.

Varsayılan değer: X-Original-Proto.
OriginalPrefixHeaderName Bu özellik tarafından belirtilen üst bilgiyi, ForwardedHeadersDefaults.XOriginalPrefixHeaderName tarafından belirtilen üst bilgi yerine kullanın.

Varsayılan değer: X-Original-Prefix.
RequireHeaderSymmetry ForwardedHeadersOptions.ForwardedHeaders işlenirken üst bilgi değerlerinin eşitlenmesi gereklidir.

ASP.NET Core 1.x'teki varsayılan değerdir true. ASP.NET Core 2.0 veya sonraki sürümlerinde varsayılan değerdir false.

Senaryolar ve kullanım örnekleri

İletilen üst bilgileri eklemek mümkün olmadığında ve tüm istekler güvenli olduğunda

Uygulamaya proxy aracılığıyla gönderilen isteklere iletilen üstbilgileri eklemek bazı durumlarda mümkün olmayabilir. Ara sunucu tüm genel dış isteklerin HTTPS olduğunu zorunlu kılıyorsa, düzen, herhangi bir ara yazılım türü kullanılmadan önce el ile Startup.Configure içinde ayarlanabilir:

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

Bu kod, geliştirme veya hazırlama ortamında ortam değişkeni veya başka bir yapılandırma ayarıyla devre dışı bırakılabilir.

İstek yolunda değişiklik yapan yol tabanı ve proxy'lerle başa çıkma

Bazı proxy'ler yolu olduğu gibi aktarır, ancak yönlendirmenin düzgün çalışması için kaldırılması gereken bir temel uygulama yolu vardır. UsePathBaseExtensions.UsePathBase ara yazılımı yolu HttpRequest.Path'a, uygulama temel yolunu da HttpRequest.PathBase'e böler.

Eğer /foo bir proxy yolu olarak /foo/api/1 geçirilirse, ara yazılım Request.PathBase değerini /foo ve Request.Path değerini /api/1 olarak ayarlar ve bunu aşağıdaki komutla gerçekleştirir:

app.UsePathBase("/foo");

Ara yazılım ters olarak yeniden çağrıldığında özgün yol ve yol tabanı yeniden uygulanır. Ara yazılım işleme sırası hakkında daha fazla bilgi için bkz. ASP.NET Core ara yazılımı.

Ara yol sunucusu yolu kırpıyorsa (örneğin, /foo/api/1'den /api/1'e iletme), isteğin PathBase özelliğini ayarlayarak yeniden yönlendirmeleri ve bağlantıları düzeltin.

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

Ara sunucu yol verileri ekliyorsa, StartsWithSegments kullanarak ve Path özelliğine atayarak yeniden yönlendirmeleri ve bağlantıları düzeltmek için yolun bir bölümünü atın.

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

    return next();
});

Farklı üst bilgi adları kullanan bir ara sunucu için yapılandırma

Proxy, proxy adresi/bağlantı noktası ve kaynak şeması bilgilerini iletmek için X-Forwarded-For ve X-Forwarded-Proto adında üst bilgileri kullanmıyorsa, ForwardedForHeaderName ve ForwardedProtoHeaderName seçeneklerini, proxy tarafından kullanılan üst bilgi adlarıyla eşleşecek şekilde ayarlayın.

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

Linux ve IIS dışı ters proxy'ler için şemayı iletme

Azure Linux App Service'e, Azure Linux sanal makinesine (VM) veya IIS dışındaki diğer ters ara sunucuların arkasına dağıtıldığında, UseHttpsRedirection ve UseHsts çağıran uygulamalar bir siteyi sonsuz döngüye sokar. Ters ara sunucu TLS'yi sonlandırır ve Kestrel doğru istek şemasının farkında değildir. OAuth ve OIDC de yanlış yeniden yönlendirmeler oluşturduğundan bu yapılandırmada başarısız olur. UseIISIntegration, IIS arkasında çalışırken iletilen üstbilgiler ara yazılımını ekler ve yapılandırır, ancak Linux için (Apache ya da Nginx ile tümleştirme) buna karşılık gelen otomatik bir yapılandırma yoktur.

IIS dışı senaryolarda proxy'den şemayı iletmek için, iletilen üst bilgiler ara yazılımını ekleyin ve yapılandırın. içinde Startup.ConfigureServicesaşağıdaki kodu kullanın:

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

Sertifika iletme

Gök mavisi

Azure Uygulaması Hizmeti'ni sertifika iletme için yapılandırmak için bkz. Azure Uygulaması Hizmeti için TLS karşılıklı kimlik doğrulamasını yapılandırma. Aşağıdaki kılavuz, ASP.NET Core uygulamasını yapılandırmayla ilgilidir.

Startup.Configure içinde, app.UseAuthentication(); çağrısından önce aşağıdaki kodu ekleyin:

app.UseCertificateForwarding();

Azure tarafından kullanılan üst bilgi adını belirtmek için sertifika iletme ara yazılımını yapılandırın. Startup.ConfigureServices'da, ara yazılımın sertifikayı oluşturduğu üst bilgiyi yapılandırmak için aşağıdaki kodu ekleyin.

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

Diğer web proxy'leri

IIS veya Azure Uygulama Hizmeti'nin Uygulama İsteği Yönlendirmesi (ARR) olmayan bir ara sunucu kullanılıyorsa, proxy'yi aldığı sertifikayı bir HTTP üst bilgisiyle iletecek şekilde yapılandırın. Startup.Configure içinde, app.UseAuthentication(); çağrısından önce aşağıdaki kodu ekleyin:

app.UseCertificateForwarding();

Üst bilgi adını belirtmek için sertifika iletme ara yazılımını yapılandırın. Startup.ConfigureServices'da, ara yazılımın sertifikayı oluşturduğu üst bilgiyi yapılandırmak için aşağıdaki kodu ekleyin.

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

Ara sunucu sertifikayı base64 kodlaması yapmıyorsa (Nginx'de olduğu gibi) seçeneğini ayarlayın HeaderConverter . aşağıdaki örneği Startup.ConfigureServices göz önünde bulundurun.

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

Sorun giderme

Üst bilgiler beklendiği gibi iletilmiyorsa, günlük kaydını etkinleştirin. ** Günlükler sorunu gidermek için yeterli bilgi sağlamıyorsa, sunucuya gelen istek başlıklarını numaralandırın. Uygulama yanıtına istek üst bilgileri yazmak veya üst bilgileri günlüğe kaydetmek için satır içi ara yazılımı kullanın.

Uygulamanın yanıtına üst bilgileri yazdırmak için, UseForwardedHeaders çağrısından hemen sonra aşağıdaki terminal satır içi ara yazılımını Startup.Configure konumuna yerleştirin.

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

Yanıt gövdesi yerine log dosyalarına yazabilirsiniz. Günlüklere yazma, hata ayıklama sırasında sitenin normal çalışmasını sağlar.

Yanıt gövdesi yerine logları başka bir yere yazmak için:

  • ILogger<Startup> öğesini Startup sınıfına Günlük iletileri oluşturma bölümünde açıklandığı gibi enjekte edin.
  • çağrısından hemen sonra aşağıdaki 'satır içi ara yazılımı' UseForwardedHeadersStartup.Configure'e yerleştirin.
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();
});

İşlendiğinde, X-Forwarded-{For|Proto|Host|Prefix} değerleri X-Original-{For|Proto|Host|Prefix} taşınır. Belirli bir üst bilgide birden çok değer varsa, iletilen üst bilgiler ara yazılım üst bilgileri sağdan sola doğru ters sırada işler. Varsayılan ForwardLimit (bir) olduğundan, 1 değeri artırılmadıkça üst bilgilerden yalnızca en sağdaki değer ForwardLimit işlenir.

İletilen üst bilgiler işlenmeden önce isteğin özgün uzak IP'sinin KnownProxies veya KnownNetworks listelerindeki bir girdiyle eşleşmesi gerekir. Bu, güvenilmeyen proxy'lerden ileticileri kabul etmeyerek üst bilgi yanıltma işlemini sınırlar. Bilinmeyen bir ara sunucu algılandığında günlüğe kayıt, proxy'nin adresini gösterir.

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

Yukarıdaki örnekte, 10.0.0.100 bir ara sunucudur. Sunucu güvenilen bir ara sunucuysa, sunucunun IP adresini KnownProxies ekleyin (veya KnownNetworks içine güvenilen bir ağ ekleyin) Startup.ConfigureServices. Daha fazla bilgi için iletilen üstbilgiler ara yazılım seçenekleri bölümüne bakın.

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

Önemli

Yalnızca güvenilen proxy'lerin ve ağların üst bilgileri iletmesine izin verin. Aksi takdirde, IP adres sahteciliği saldırıları mümkündür.

Ek kaynaklar