Zagadnienia dotyczące zabezpieczeń obciążeń o znaczeniu krytycznym
Obciążenia o znaczeniu krytycznym muszą być z natury zabezpieczone. W przypadku naruszenia zabezpieczeń aplikacji lub jej infrastruktury dostępność jest zagrożona. Celem tej architektury jest maksymalizacja niezawodności, dzięki czemu aplikacja pozostaje wydajna i dostępna we wszystkich okolicznościach. Mechanizmy kontroli zabezpieczeń są stosowane głównie w celu łagodzenia zagrożeń wpływających na dostępność i niezawodność.
Uwaga
Wymagania biznesowe mogą wymagać większej liczby środków zabezpieczeń. Zdecydowanie zalecamy rozszerzenie mechanizmów kontroli w implementacji zgodnie ze wskazówkami w temacie Zagadnienia dotyczące zabezpieczeń platformy Azure Well-Architected Framework dotyczące obciążeń o znaczeniu krytycznym.
Zarządzanie tożsamościami i dostępem
Na poziomie aplikacji ta architektura używa prostego schematu uwierzytelniania opartego na kluczach interfejsu API w przypadku niektórych operacji z ograniczeniami, takich jak tworzenie elementów wykazu lub usuwanie komentarzy. Zaawansowane scenariusze, takie jak uwierzytelnianie użytkowników i role użytkowników, wykraczają poza zakres architektury punktu odniesienia.
Jeśli aplikacja wymaga uwierzytelniania użytkowników i zarządzania kontami, postępuj zgodnie z zaleceniami dotyczącymi zarządzania tożsamościami i dostępem. Niektóre strategie obejmują używanie dostawców tożsamości zarządzanych, unikanie niestandardowego zarządzania tożsamościami i używanie uwierzytelniania bez hasła, jeśli jest to możliwe.
Najmniej uprzywilejowany dostęp
Skonfiguruj zasady dostępu, aby użytkownicy i aplikacje uzyskiwali minimalny poziom dostępu potrzebny do spełnienia funkcji. Deweloperzy zazwyczaj nie potrzebują dostępu do infrastruktury produkcyjnej, ale potok wdrażania wymaga pełnego dostępu. Klastry Kubernetes nie wypychają obrazów kontenerów do rejestru, ale przepływy pracy usługi GitHub mogą. Interfejsy API frontonu zwykle nie pobierają komunikatów z brokera komunikatów, a pracownicy zaplecza nie muszą wysyłać nowych komunikatów do brokera. Te decyzje zależą od obciążenia, a przypisany poziom dostępu powinien odzwierciedlać funkcjonalność każdego składnika.
Przykłady z implementacji referencyjnej o znaczeniu krytycznym platformy Azure obejmują:
- Każdy składnik aplikacji współdziałający z usługą Azure Event Hubs używa parametry połączenia z uprawnieniami nasłuchiwania (
BackgroundProcessor
) lub wysyłania (CatalogService
). Ten poziom dostępu zapewnia, że każdy zasobnik ma tylko minimalny dostęp wymagany do spełnienia jego funkcji. - Jednostka usługi dla puli agentów usługi Azure Kubernetes Service (AKS) ma tylko uprawnienia Get and List dla wpisów tajnych w usłudze Azure Key Vault.
- Tożsamość usługi AKS Kubelet ma tylko uprawnienie AcrPull do uzyskiwania dostępu do globalnego rejestru kontenerów.
Tożsamości zarządzane
Aby zwiększyć bezpieczeństwo obciążenia o krytycznym znaczeniu, należy unikać używania wpisów tajnych opartych na usłudze, takich jak parametry połączenia lub kluczy interfejsu API, jeśli to możliwe. Zalecamy używanie tożsamości zarządzanych, jeśli usługa platformy Azure obsługuje tę funkcję.
Implementacja referencyjna używa tożsamości zarządzanej przypisanej przez usługę w puli agentów usługi AKS ("Tożsamość Kubelet") w celu uzyskania dostępu do globalnego rejestru Azure Container Registry i magazynu kluczy sygnatury. Odpowiednie role wbudowane są używane do ograniczania dostępu. Na przykład ten kod narzędzia Terraform przypisuje tylko AcrPull
rolę do tożsamości Kubelet:
resource "azurerm_role_assignment" "acrpull_role" {
scope = data.azurerm_container_registry.global.id
role_definition_name = "AcrPull"
principal_id = azurerm_kubernetes_cluster.stamp.kubelet_identity.0.object_id
}
Wpisy tajne
Jeśli to możliwe, użyj uwierzytelniania Entra firmy Microsoft zamiast kluczy podczas uzyskiwania dostępu do zasobów platformy Azure. Wiele usług platformy Azure, takich jak Azure Cosmos DB i Azure Storage, obsługuje opcję całkowitego wyłączenia uwierzytelniania klucza. Usługa AKS obsługuje Tożsamość obciążeń Microsoft Entra.
W przypadku scenariuszy, w których nie można używać uwierzytelniania firmy Microsoft Entra, każda sygnatura wdrożenia ma dedykowane wystąpienie usługi Key Vault do przechowywania kluczy. Te klucze są tworzone automatycznie podczas wdrażania i są przechowywane w usłudze Key Vault za pomocą narzędzia Terraform. Żaden operator ludzki, z wyjątkiem deweloperów w środowiskach end-to-end, może wchodzić w interakcje z wpisami tajnymi. Ponadto zasady dostępu usługi Key Vault są konfigurowane tak, aby żadne konta użytkowników nie mogły uzyskiwać dostępu do wpisów tajnych.
Uwaga
To obciążenie nie używa certyfikatów niestandardowych, ale mają zastosowanie te same zasady.
W klastrze usługi AKS dostawca usługi Key Vault dla magazynu wpisów tajnych umożliwia aplikacji korzystanie z wpisów tajnych. Sterownik CSI ładuje klucze z usługi Key Vault i instaluje je jako pliki w poszczególnych zasobnikach.
#
# /src/config/csi-secrets-driver/chart/csi-secrets-driver-config/templates/csi-secrets-driver.yaml
#
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kv
spec:
provider: azure
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "true"
userAssignedIdentityID: {{ .Values.azure.managedIdentityClientId | quote }}
keyvaultName: {{ .Values.azure.keyVaultName | quote }}
tenantId: {{ .Values.azure.tenantId | quote }}
objects: |
array:
{{- range .Values.kvSecrets }}
- |
objectName: {{ . | quote }}
objectAlias: {{ . | lower | replace "-" "_" | quote }}
objectType: secret
{{- end }}
Implementacja referencyjna używa programu Helm z usługą Azure Pipelines do wdrożenia sterownika CSI zawierającego wszystkie nazwy kluczy z usługi Key Vault. Sterownik jest również odpowiedzialny za odświeżanie zainstalowanych wpisów tajnych, jeśli zmienią się w usłudze Key Vault.
Na końcu klienta obie aplikacje platformy .NET używają wbudowanej funkcji odczytu konfiguracji z plików (AddKeyPerFile
):
//
// /src/app/AlwaysOn.BackgroundProcessor/Program.cs
// + using Microsoft.Extensions.Configuration;
//
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
// Load values from Kubernetes CSI Key Vault driver mount point.
config.AddKeyPerFile(directoryPath: "/mnt/secrets-store/", optional: true, reloadOnChange: true);
// More configuration if needed...
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Połączenie automatycznego ponownego ładowania sterownika CSI i reloadOnChange: true
zapewnia, że po zmianie kluczy w usłudze Key Vault nowe wartości są instalowane w klastrze. Ten proces nie gwarantuje rotacji wpisów tajnych w aplikacji. Implementacja używa pojedynczego wystąpienia klienta usługi Azure Cosmos DB, które wymaga ponownego uruchomienia zasobnika w celu zastosowania zmiany.
Domeny niestandardowe i protokół TLS
Obciążenia internetowe powinny używać protokołu HTTPS, aby zapobiec atakom typu man-in-the-middle na wszystkich poziomach interakcji, takich jak komunikacja od klienta do interfejsu API lub z interfejsu API do interfejsu API. Pamiętaj, aby zautomatyzować rotację certyfikatów, ponieważ wygasłe certyfikaty są nadal częstą przyczyną awarii i obniżonej wydajności środowiska.
Implementacja referencyjna w pełni obsługuje protokół HTTPS z niestandardowymi nazwami domen, takimi jak contoso.com
. Stosuje również odpowiednią konfigurację zarówno do środowisk, jak int
i prod
. Można również dodawać domeny niestandardowe dla e2e
środowisk. Jednak ta implementacja referencyjna nie używa niestandardowych nazw domen ze względu na krótkotrwały e2e
charakter i zwiększony czas wdrażania, gdy używasz domen niestandardowych z certyfikatami SSL w usłudze Azure Front Door.
Aby włączyć pełną automatyzację wdrożenia, należy zarządzać domeną niestandardową za pośrednictwem strefy usługi Azure DNS. Potok wdrażania infrastruktury dynamicznie tworzy rekordy CNAME w strefie usługi Azure DNS i mapuje te rekordy automatycznie na wystąpienie usługi Azure Front Door.
Certyfikaty SSL zarządzane przez usługę Azure Front Door są włączone, co eliminuje wymaganie ręcznego odnawiania certyfikatów SSL. Protokół TLS 1.2 jest skonfigurowany jako minimalna wersja.
#
# /src/infra/workload/globalresources/frontdoor.tf
#
resource "azurerm_frontdoor_custom_https_configuration" "custom_domain_https" {
count = var.custom_fqdn != "" ? 1 : 0
frontend_endpoint_id = "${azurerm_frontdoor.main.id}/frontendEndpoints/${local.frontdoor_custom_frontend_name}"
custom_https_provisioning_enabled = true
custom_https_configuration {
certificate_source = "FrontDoor"
}
}
Środowiska, które nie są aprowidowane z domenami niestandardowymi, są dostępne za pośrednictwem domyślnego punktu końcowego usługi Azure Front Door. Możesz na przykład uzyskać do nich dostęp pod adresem, na przykład env123.azurefd.net
.
Uwaga
Na kontrolerze ruchu przychodzącego klastra domeny niestandardowe nie są używane w obu przypadkach. Zamiast tego podana przez platformę Azure nazwa DNS, taka jak [prefix]-cluster.[region].cloudapp.azure.com
jest używana z funkcją Let's Encrypt, która może wystawiać bezpłatne certyfikaty SSL dla tych punktów końcowych.
Implementacja referencyjna używa biblioteki Jetstack cert-manager
do automatycznego aprowizowania certyfikatów SSL/TLS z obszaru Let's Encrypt dla reguł ruchu przychodzącego. Więcej ustawień konfiguracji, takich jak ClusterIssuer
, które żąda certyfikatów z let's Encrypt, są wdrażane za pomocą oddzielnego cert-manager-config
wykresu helm przechowywanego w pliku src/config/cert-manager/chart.
Ta implementacja Issuer
używa ClusterIssuer
zamiast, aby uniknąć wystawców dla każdej przestrzeni nazw. Aby uzyskać więcej informacji, zobacz dokumentację menedżera certyfikatów i informacje o wersji programu cert-manager.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
Konfigurowanie
Cała konfiguracja środowiska uruchomieniowego aplikacji jest przechowywana w usłudze Key Vault, w tym wpisów tajnych i niewrażliwych ustawień. Do przechowywania ustawień można użyć magazynu konfiguracji, takiego jak aplikacja systemu Azure Configuration. Jednak posiadanie jednego magazynu zmniejsza liczbę potencjalnych punktów awarii dla aplikacji o krytycznym znaczeniu. Użyj usługi Key Vault do konfiguracji środowiska uruchomieniowego, aby uprościć ogólną implementację.
Magazyny kluczy powinny być wypełniane przez potok wdrażania. W implementacji wymagane wartości są pochodzące bezpośrednio z programu Terraform, takie jak parametry połączenia bazy danych, lub przekazywane jako zmienne terraform z potoku wdrażania.
Konfiguracja infrastruktury i wdrażania poszczególnych środowisk, takich jak e2e
, int
i prod
, jest przechowywana w plikach zmiennych, które są częścią repozytorium kodu źródłowego. Takie podejście ma dwie korzyści:
- Wszystkie zmiany w środowisku są śledzone i przechodzą przez potoki wdrażania przed ich zastosowaniem do środowiska.
- Poszczególne
e2e
środowiska można skonfigurować inaczej, ponieważ wdrożenie jest oparte na kodzie w gałęzi.
Jednym z wyjątków jest przechowywanie poufnych wartości dla potoków. Te wartości są przechowywane jako wpisy tajne w grupach zmiennych usługi Azure DevOps.
Zabezpieczenia kontenerów
Należy zabezpieczyć obrazy kontenerów dla wszystkich konteneryzowanych obciążeń.
Ta implementacja referencyjna używa kontenerów platformy Docker obciążenia opartych na obrazach środowiska uruchomieniowego, a nie na zestawie SDK, aby zminimalizować ślad i potencjalny obszar ataków. Nie zainstalowano żadnych innych narzędzi, takich jak ping
, wget
lub curl
.
Aplikacja działa w ramach nieuprzywilejowanego użytkownika workload
, który został utworzony w ramach procesu kompilacji obrazu:
RUN groupadd -r workload && useradd --no-log-init -r -g workload workload
USER workload
Implementacja referencyjna używa programu Helm do spakowania manifestów YAML, których potrzebuje do wdrożenia poszczególnych składników. Ten proces obejmuje wdrożenie platformy Kubernetes, usługi, konfigurację skalowania automatycznego zasobnika poziomego i kontekst zabezpieczeń. Wszystkie wykresy programu Helm zawierają podstawowe środki zabezpieczeń, które są zgodne z najlepszymi rozwiązaniami dotyczącymi platformy Kubernetes.
Te środki bezpieczeństwa to:
readOnlyFilesystem
: główny system/
plików w każdym kontenerze jest ustawiony na wartość tylko do odczytu, aby zapobiec zapisywaniu kontenera w systemie plików hosta. To ograniczenie uniemożliwia osobom atakującym pobieranie większej liczby narzędzi i utrwalanie kodu w kontenerze. Katalogi wymagające dostępu do odczytu i zapisu są instalowane jako woluminy.privileged
: Wszystkie kontenery są ustawione tak, aby działały jako nieuprzywilejowane. Uruchomienie kontenera jako uprzywilejowanego zapewnia wszystkie możliwości kontenerowi, a także podnosi wszystkie ograniczenia wymuszane przez kontroler grupy kontroli urządzeń.allowPrivilegeEscalation
: Uniemożliwia wewnątrz kontenera uzyskanie większej liczby uprawnień niż proces nadrzędny.
Te środki zabezpieczeń są również konfigurowane dla kontenerów innych niż Microsoft i wykresów helm, takich jak cert-manager
w miarę możliwości. Za pomocą usługi Azure Policy można przeprowadzać inspekcję tych środków zabezpieczeń.
#
# Example:
# /src/app/charts/backgroundprocessor/values.yaml
#
containerSecurityContext:
privileged: false
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
Każde środowisko, w tym prod
, int
i każde e2e
środowisko, ma dedykowane wystąpienie usługi Container Registry, które ma globalną replikację do każdego z regionów, w których są wdrażane sygnatury.
Uwaga
Ta implementacja referencyjna nie używa skanowania luk w zabezpieczeniach obrazów platformy Docker. Zalecamy używanie usługi Microsoft Defender dla rejestrów kontenerów, potencjalnie z funkcją GitHub Actions.
Ruch przychodzący
Usługa Azure Front Door to globalny moduł równoważenia obciążenia w tej architekturze. Wszystkie żądania internetowe są kierowane przez usługę Azure Front Door, która wybiera odpowiedni zaplecze. Aplikacje o znaczeniu krytycznym powinny korzystać z innych funkcji usługi Azure Front Door, takich jak zapory aplikacji internetowej (WAFs).
Zapora aplikacji internetowej
Ważną funkcją usługi Azure Front Door jest zapora aplikacji internetowej, ponieważ umożliwia usłudze Azure Front Door inspekcję ruchu przechodzącego. W trybie zapobiegania wszystkie podejrzane żądania są blokowane. W implementacji skonfigurowano dwa zestawy reguł. Te zestawy reguł to Microsoft_DefaultRuleSet
i Microsoft_BotManagerRuleSet
.
Napiwek
Podczas wdrażania usługi Azure Front Door za pomocą zapory aplikacji internetowej zalecamy rozpoczęcie od trybu wykrywania . Uważnie monitoruj swoje zachowanie przy użyciu naturalnego ruchu klientów i dostosuj reguły wykrywania. Po wyeliminowaniu wyników fałszywie dodatnich lub jeśli wyniki fałszywie dodatnie są rzadkie, przełącz się do trybu zapobiegania . Ten proces jest niezbędny, ponieważ każda aplikacja jest inna, a niektóre ładunki mogą być uznawane za złośliwe, mimo że są one uzasadnione dla tego konkretnego obciążenia.
Routing
Tylko te żądania, które przechodzą przez usługę Azure Front Door, są kierowane do kontenerów interfejsu API, takich jak CatalogService
i HealthService
. Użyj konfiguracji ruchu przychodzącego Nginx, aby wymusić to zachowanie. Sprawdza obecność nagłówka X-Azure-FDID
i określa, czy jest to właściwe dla globalnego wystąpienia usługi Azure Front Door określonego środowiska.
#
# /src/app/charts/catalogservice/templates/ingress.yaml
#
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
# ...
annotations:
# To restrict traffic coming only through our Azure Front Door instance, we use a header check on the X-Azure-FDID.
# The pipeline injects the value. Therefore, it's important to treat this ID as a sensitive value.
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleEngine On
SecRule &REQUEST_HEADERS:X-Azure-FDID \"@eq 0\" \"log,deny,id:106,status:403,msg:\'Front Door ID not present\'\"
SecRule REQUEST_HEADERS:X-Azure-FDID \"@rx ^(?!{{ .Values.azure.frontdoorid }}).*$\" \"log,deny,id:107,status:403,msg:\'Wrong Front Door ID\'\"
# ...
Potoki wdrażania pomagają upewnić się, że ten nagłówek jest poprawnie wypełniony, ale musi również pominąć to ograniczenie dla testów weryfikacyjnych kompilacji, ponieważ sondują każdy klaster bezpośrednio zamiast za pośrednictwem usługi Azure Front Door. Implementacja referencyjna używa faktu, że testy weryfikacyjne kompilacji są uruchamiane w ramach wdrożenia. Dzięki temu projektowi wartość nagłówka może być znana i dodawana do żądań HTTP testu weryfikacyjnego kompilacji.
#
# /.ado/pipelines/scripts/Run-SmokeTests.ps1
#
$header = @{
"X-Azure-FDID" = "$frontdoorHeaderId"
"TEST-DATA" = "true" # Header to indicate that posted comments and ratings are for tests and can be deleted again by the app.
}
Bezpieczne wdrożenia
Aby postępować zgodnie z podstawowymi dobrze zaprojektowanymi zasadami doskonałości operacyjnej, w pełni zautomatyzować wszystkie wdrożenia. Nie powinny wymagać żadnych ręcznych kroków, z wyjątkiem wyzwalania przebiegu lub zatwierdzania bramy.
Należy zapobiec złośliwym próbom lub przypadkowym błędom konfiguracji, które mogą wyłączyć środki zabezpieczeń. Implementacja referencyjna używa tego samego potoku zarówno dla wdrożenia infrastruktury, jak i aplikacji, co wymusza automatyczne wycofywanie wszelkich potencjalnych dryfów konfiguracji. To wycofanie pomaga zachować integralność infrastruktury i dopasować go do kodu aplikacji. Każda zmiana zostanie odrzucona w następnym wdrożeniu.
Narzędzie Terraform generuje poufne wartości wdrożenia podczas uruchamiania potoku lub usługa Azure DevOps dostarcza je jako wpisy tajne. Te wartości są chronione za pomocą ograniczeń dostępu opartych na rolach.
Uwaga
Przepływy pracy usługi GitHub zapewniają podobną koncepcję oddzielnych magazynów dla wartości wpisów tajnych. Wpisy tajne są szyfrowane, zmienne środowiskowe, których może używać funkcja GitHub Actions.
Ważne jest, aby zwrócić uwagę na wszelkie artefakty generowane przez potok, ponieważ te artefakty mogą potencjalnie zawierać wartości wpisów tajnych lub informacje o wewnętrznej pracy aplikacji. Wdrożenie usługi Azure DevOps implementacji referencyjnej generuje dwa pliki z danymi wyjściowymi narzędzia Terraform. Jeden plik dotyczy sygnatur, a jeden plik jest przeznaczony dla globalnej infrastruktury. Te pliki nie zawierają haseł, które mogą naruszyć bezpieczeństwo infrastruktury. Należy jednak wziąć pod uwagę, że te pliki powinny być poufne, ponieważ ujawniają informacje o infrastrukturze, w tym identyfikatory klastrów, adresy IP, nazwy kont magazynu, nazwy usługi Key Vault, nazwy baz danych usługi Azure Cosmos DB i identyfikatory nagłówków usługi Azure Front Door.
W przypadku obciążeń korzystających z narzędzia Terraform należy włożyć dodatkowy wysiłek w ochronę pliku stanu, ponieważ zawiera pełny kontekst wdrożenia, w tym wpisy tajne. Plik stanu jest zwykle przechowywany na koncie magazynu, które powinno mieć oddzielny cykl życia od obciążenia i powinny być dostępne tylko z potoku wdrażania. Należy zarejestrować dowolny inny dostęp do tego pliku i wysłać alerty do odpowiedniej grupy zabezpieczeń.
Aktualizacje zależności
Biblioteki, struktury i narzędzia używane przez aplikację są aktualizowane wraz z upływem czasu. Ważne jest regularne wykonywanie tych aktualizacji, ponieważ często zawierają one poprawki problemów z zabezpieczeniami, które mogą dać osobie atakującej nieautoryzowany dostęp do systemu.
Implementacja referencyjna korzysta z narzędzia Dependabot usługi GitHub dla aktualizacji zależności narzędzi NuGet, Docker, npm, Terraform i GitHub Actions. dependabot.yml
Plik konfiguracji jest generowany automatycznie za pomocą skryptu programu PowerShell ze względu na złożoność różnych części aplikacji. Na przykład każdy moduł Terraform wymaga oddzielnego wpisu.
#
# /.github/dependabot.yml
#
version: 2
updates:
- package-ecosystem: "nuget"
directory: "/src/app/AlwaysOn.HealthService"
schedule:
interval: "monthly"
target-branch: "component-updates"
- package-ecosystem: "docker"
directory: "/src/app/AlwaysOn.HealthService"
schedule:
interval: "monthly"
target-branch: "component-updates"
# ... the rest of the file...
- Aktualizacje są wyzwalane co miesiąc jako kompromis między posiadaniem najbardziej aktualnych bibliotek i utrzymaniem możliwości utrzymania nakładu pracy. Ponadto kluczowe narzędzia, takie jak Terraform, są stale monitorowane, a ważne aktualizacje są wykonywane ręcznie.
- Żądania ściągnięcia (PRs) są przeznaczone dla
component-updates
gałęzi zamiastmain
. - Biblioteki npm są skonfigurowane tak, aby sprawdzały tylko zależności, które przechodzą do skompilowanej aplikacji zamiast do narzędzi pomocniczych, takich jak
@vue-cli
.
Funkcja Dependabot tworzy oddzielne żądanie ściągnięcia dla każdej aktualizacji, co może przeciążyć zespół operacyjny. Implementacja referencyjna najpierw zbiera partię aktualizacji w component-updates
gałęzi, a następnie uruchamia testy w e2e
środowisku. Jeśli te testy zakończyły się pomyślnie, zostanie utworzone kolejne żądanie ściągnięcia, które jest przeznaczone dla main
gałęzi.
Kodowanie defensywne
Wywołania interfejsu API mogą zakończyć się niepowodzeniem z różnych powodów, takich jak błędy kodu, nieprawidłowe wdrożenia i błędy infrastruktury. Jeśli wywołanie interfejsu API zakończy się niepowodzeniem, obiekt wywołujący lub aplikacja kliencka nie powinien otrzymywać obszernych informacji debugowania, ponieważ te informacje mogą dać przeciwnikom przydatne punkty danych dotyczące aplikacji.
Implementacja referencyjna demonstruje tę zasadę, zwracając tylko identyfikator korelacji w odpowiedzi, która zakończyła się niepowodzeniem. Nie udostępnia przyczyny niepowodzenia, takiej jak komunikat o wyjątku lub ślad stosu. Korzystając z tego identyfikatora i z pomocą nagłówka Server-Location
, operator może zbadać zdarzenie przy użyciu usługi Application Insights.
//
// Example ASP.NET Core middleware, which adds the Correlation ID to every API response.
//
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
app.Use(async (context, next) =>
{
context.Response.OnStarting(o =>
{
if (o is HttpContext ctx)
{
context.Response.Headers.Add("Server-Name", Environment.MachineName);
context.Response.Headers.Add("Server-Location", sysConfig.AzureRegion);
context.Response.Headers.Add("Correlation-ID", Activity.Current?.RootId);
context.Response.Headers.Add("Requested-Api-Version", ctx.GetRequestedApiVersion()?.ToString());
}
return Task.CompletedTask;
}, context);
await next();
});
// ...
}
Następny krok
Wdróż implementację referencyjną, aby uzyskać pełną wiedzę na temat zasobów i ich konfiguracji.