Centralna usługa wpisów tajnych w usłudze Azure Service Fabric

Central Secret Service (CSS), znana również jako Central Secret Store, to usługa systemowa usługi Service Fabric przeznaczona do ochrony wpisów tajnych w klastrze. Arkusz CSS ułatwia zarządzanie wpisami tajnymi dla aplikacji SF, eliminując konieczność polegania na zaszyfrowanych parametrach.

Central secret Service to trwała, replikowana w klastrze pamięć podręczna wpisów tajnych; Wpisy tajne przechowywane w arkuszu CSS są szyfrowane w spoczynku do certyfikatu szyfrowania dostarczonego przez klienta. Arkusz CSS udostępnia interfejsy API klienta do zarządzania wpisami tajnymi, dostępne dla jednostek uwierzytelniających się jako klaster lub użytkownika administratora klastra. Model aplikacji środowiska uruchomieniowego usługi Service Fabric integruje się z arkuszem CSS, umożliwiając deklarację parametrów aplikacji jako odwołania do wpisów tajnych CSS.

Arkusz CSS ma również kluczowe znaczenie w aprowizacji wpisów tajnych aplikacji zadeklarowanych jako identyfikatory URI wpisów tajnych usługi KeyVault w połączeniu z tożsamością zarządzaną dla wdrożonych aplikacji usługi Service Fabric na platformie Azure.

Central Secret Service nie jest przeznaczona do zastąpienia dedykowanej, zewnętrznej usługi zarządzania wpisami tajnymi, takiej jak Azure Key Vault.

Uwaga

Podczas aktywowania arkusza CSS w klastrze SF z uruchomioną wersją starszą niż 7.1. CU3 aktywacja może zakończyć się niepowodzeniem i pozostawić arkusz CSS w stanie trwałej złej kondycji, jeśli klaster jest skonfigurowany do uwierzytelniania systemu Windows lub jeśli EncryptionCertificateThumbprint jest zadeklarowany niepoprawnie lub odpowiedni certyfikat nie jest zainstalowany. W obu przypadkach zaleca się uaktualnienie klastra do wersji środowiska uruchomieniowego SF nowszej niż 7.1. CU3 przed kontynuowaniem.

Włączanie centralnej usługi wpisów tajnych

Aby włączyć centralną usługę wpisów tajnych, zaktualizuj konfigurację klastra zgodnie z poniższym opisem. Zalecamy użycie certyfikatu szyfrowania, który różni się od certyfikatu klastra. Ten certyfikat musi być zainstalowany na wszystkich węzłach.

{ 
    "fabricSettings": [
        {
            "name":  "CentralSecretService",
            "parameters":  [
                {
                    "name":  "DeployedState",
                    "value":  "enabled"
                },
                {
                    "name" : "EncryptionCertificateThumbprint",
                    "value": "<thumbprint>"
                },
                {
                    "name":  "MinReplicaSetSize",
                    "value":  "1"
                },
                {
                    "name":  "TargetReplicaSetSize",
                    "value":  "3"
                }
            ]
        }
    ]
}

Uwaga

Ustawienie konfiguracji "DeployedState", wprowadzone w usłudze Service Fabric w wersji 8.0, jest preferowanym mechanizmem włączania lub wyłączania css; ta funkcja była obsługiwana w poprzednich wersjach przez ustawienie konfiguracji "IsEnabled", które jest teraz uważane za przestarzałe.

Centralny model wpisów tajnych usługi wpisów tajnych

Centralny interfejs API usługi wpisów tajnych uwidacznia dwa typy: zasób tajny i wersję wpisu tajnego. Typ zasobu wpisu tajnego reprezentuje, koncepcyjnie, rodzinę wersji pojedynczego wpisu tajnego używanego do określonego celu; przykłady obejmują: parametry połączenia, hasło, certyfikat punktu końcowego. Obiekt typu zasobu wpisu tajnego zawiera metadane skojarzone z tym wpisem tajnym, w szczególności rodzajem, typem zawartości i opisem. Typ wersji wpisu tajnego reprezentuje określone wystąpienie skojarzonego wpisu tajnego i przechowuje tajny zwykły tekst (zaszyfrowany); kontynuując powyższe przykłady, wersja wpisu tajnego zawiera bieżącą wartość hasła, obiekt certyfikatu ważny do końca miesiąca itp. Po odnowieniu tych wpisów tajnych należy wygenerować nowe wersje wpisów tajnych (i dodać je do arkusza CSS).

Sformalizacja modelu to reguły zaimplementowane i wymuszone w implementacji CSS:

  • Zasób tajny może mieć zero lub więcej wersji
  • Każda wersja wpisu tajnego jest elementem podrzędnym określonego zasobu tajnego; wersja może mieć tylko jeden zasób nadrzędny
  • Pojedyncza wersja wpisu tajnego może zostać usunięta bez wpływu na inne wersje tego samego wpisu tajnego
  • Usunięcie zasobu tajnego powoduje usunięcie wszystkich jego wersji
  • Wartość wersji wpisu tajnego jest niezmienna

Deklarowanie zasobu wpisu tajnego

Za pomocą interfejsu API REST można utworzyć zasób tajny.

Uwaga

Jeśli klaster korzysta z uwierzytelniania systemu Windows bez certyfikatu HttpGateway, żądanie REST jest wysyłane za pośrednictwem niezabezpieczonego kanału HTTP. Aby włączyć protokół TLS dla tego kanału, definicja klastra powinna zostać zaktualizowana w celu określenia certyfikatu serwera bramy http.

Aby utworzyć zasób wpisu tajnego supersecret przy użyciu interfejsu API REST, utwórz żądanie PUT na https://<clusterfqdn>:19080/Resources/Secrets/supersecret?api-version=6.4-previewadres . Aby utworzyć zasób tajny, należy uwierzytelnić się przy użyciu certyfikatu klastra lub certyfikatu klienta administratora.

$json = '{"properties": {"kind": "inlinedValue", "contentType": "text/plain", "description": "supersecret"}}'
Invoke-WebRequest  -Uri https://<clusterfqdn>:19080/Resources/Secrets/supersecret?api-version=6.4-preview -Method PUT -CertificateThumbprint <CertThumbprint> -Body $json

Ustawianie wartości wpisu tajnego

Użyj następującego skryptu, aby ustawić wartość wpisu tajnego przy użyciu interfejsu API REST.

$Params = '{"properties": {"value": "mysecretpassword"}}'
Invoke-WebRequest -Uri https://<clusterfqdn>:19080/Resources/Secrets/supersecret/values/ver1?api-version=6.4-preview -Method PUT -Body $Params -CertificateThumbprint <ClusterCertThumbprint>

Sprawdzanie wartości wpisu tajnego

Invoke-WebRequest -CertificateThumbprint <ClusterCertThumbprint> -Method POST -Uri "https:<clusterfqdn>/Resources/Secrets/supersecret/values/ver1/list_value?api-version=6.4-preview"

Używanie wpisu tajnego w aplikacji

Aplikacja może używać wpisu tajnego z arkusza CSS, deklarując go jako zmienną środowiskową lub określając ścieżkę, w której tajny zwykły tekst jest serializowany. Wykonaj następujące kroki, aby odwołać się do wpisu tajnego CSS:

  1. Dodaj sekcję w pliku settings.xml z następującym fragmentem kodu. Zwróć uwagę, że wartość jest w formacie {secretname:version}.
     <Section Name="testsecrets">
      <Parameter Name="TopSecret" Type="SecretsStoreRef" Value="supersecret:ver1"/
     </Section>
  1. Zaimportuj sekcję w ApplicationManifest.xml.
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="testservicePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<Policies>
 <ConfigPackagePolicies CodePackageRef="Code">
   <ConfigPackage Name="Config" SectionName="testsecrets" EnvironmentVariableName="SecretPath" />
   </ConfigPackagePolicies>
</Policies>
</ServiceManifestImport>

Przykład 1. Instalowanie wpisów tajnych w kontenerze. Jedyną zmianą wymaganą do udostępnienia wpisów tajnych wewnątrz kontenera jest specify punkt instalacji w programie <ConfigPackage>. Poniższy fragment kodu to zmodyfikowany ApplicationManifest.xml.

   <ServiceManifestImport>
       <ServiceManifestRef ServiceManifestName="testservicePkg" ServiceManifestVersion="1.0.0" />
       <ConfigOverrides />
       <Policies>
         <ConfigPackagePolicies CodePackageRef="Code">
           <ConfigPackage Name="Config" SectionName="testsecrets" MountPoint="C:\secrets" EnvironmentVariableName="SecretPath" />
           <!-- Linux Container
            <ConfigPackage Name="Config" SectionName="testsecrets" MountPoint="/mnt/secrets" EnvironmentVariableName="SecretPath" />
           -->
         </ConfigPackagePolicies>
       </Policies>
     </ServiceManifestImport>

Wpisy tajne są dostępne w punkcie instalacji wewnątrz kontenera.

Przykład 2. Powiązanie wpisu tajnego ze zmienną środowiskową procesu przez określenie .Type='SecretsStoreRef Poniższy fragment kodu to przykład powiązania wersji ver1 ze supersecret zmienną MySuperSecret środowiskową w ServiceManifest.xml.

   <EnvironmentVariables>
     <EnvironmentVariable Name="MySuperSecret" Type="SecretsStoreRef" Value="supersecret:ver1"/>
   </EnvironmentVariables>

Zmienna środowiskowa SecretPath wskaże katalog, w którym są przechowywane wszystkie wpisy tajne. Każdy parametr wymieniony w testsecrets sekcji jest przechowywany w osobnym pliku. Aplikacja może teraz używać wpisu tajnego w następujący sposób:

secretValue = IO.ReadFile(Path.Join(Environment.GetEnvironmentVariable("SecretPath"),  "TopSecret"))

Obracanie centralnego certyfikatu szyfrowania usługi wpisów tajnych

Należy pamiętać, że certyfikaty pozostają prawidłowe do odszyfrowywania poza ich wygaśnięciem. W tej chwili zalecamy kontynuowanie aprowizacji wcześniejszych certyfikatów szyfrowania po rotacji, aby zmniejszyć prawdopodobieństwo blokady. Rotacja certyfikatu szyfrowania CSS wymaga następujących kroków:

  1. Aprowizuj nowy certyfikat w każdym węźle klastra. Obecnie nie usuwaj/kontynuuj aprowizacji poprzedniego certyfikatu szyfrowania.
  2. Uruchom uaktualnienie konfiguracji klastra, aby zmienić wartość EncryptionCertificateThumbprint na odcisk palca SHA-1 nowego certyfikatu. Po zakończeniu uaktualniania arkusz CSS rozpocznie ponowne szyfrowanie istniejącej zawartości do nowego certyfikatu szyfrowania. Wszystkie wpisy tajne dodane do arkusza CSS po tym punkcie będą szyfrowane bezpośrednio do nowego certyfikatu szyfrowania. Ponieważ zbieżność wszystkich wpisów tajnych chronionych przez nowy certyfikat jest asynchroniczna, ważne jest, aby poprzedni certyfikat szyfrowania pozostał zainstalowany na wszystkich węzłach i dostępny dla arkuszy CSS.

Usuwanie centralnej usługi tajnej z klastra

Bezpieczne usunięcie centralnej usługi tajnej z klastra wymaga dwóch uaktualnień. Pierwsze uaktualnienie funkcjonalnie wyłącza arkusz CSS, podczas gdy drugie uaktualnienie usuwa usługę z definicji klastra, która obejmuje trwałe usunięcie jego zawartości. Ten dwuetapowy proces zapobiega przypadkowemu usunięciu usługi i pomaga zapewnić, że podczas procesu usuwania nie ma oddzielonych zależności od css. Ta funkcja jest dostępna od wersji SF w wersji 8.0.

Krok 1. Aktualizowanie elementu CSS DeployedState w celu usunięcia

Uaktualnianie definicji klastra z "IsEnabled" = "true" lub do "DeployedState" = "enabled"

{
    "name":  "DeployedState",
    "value":  "removing"
}

Gdy centralna usługa wpisów tajnych wejdzie w stan Removingwdrożony, odrzuci wszystkie przychodzące wywołania interfejsu API wpisów tajnych, niezależnie od tego, czy bezpośrednie wywołania REST, czy za pośrednictwem aktywacji usług, które obejmują SecretStoreRefs lub KeyVaultReferences. Wszystkie aplikacje lub składniki w klastrze, które nadal zależą od css w tym momencie, zostaną wyświetlone w stanie Ostrzeżenie. Jeśli tak się stanie, uaktualnienie do wdrożonego stanu Removing powinno zostać wycofane. Jeśli uaktualnienie zakończyło się już pomyślnie, należy zainicjować nowe uaktualnienie, aby zmienić arkusz CSS z powrotem na DeployedState = Enabled. Jeśli centralna usługa wpisów tajnych odbiera żądanie w stanie Removingwdrożonym, zwróci kod HTTP 401 (nieautoryzowany) i umieści się w stanie kondycji Ostrzeżenie.

Krok 2. Aktualizacja elementu CSS DeployedState do wyłączonego

Uaktualnianie definicji klastra z "DeployedState" = "removing" do

{
    "name":  "DeployedState",
    "value":  "disabled"
}

Centralna usługa wpisów tajnych nie powinna być już uruchomiona w klastrze i nie będzie obecna na liście usług systemowych. Zawartość css jest nieodwracalnie utracona.

Następne kroki