Servizio segreto centrale in Azure Service Fabric

Central Secret Service (CSS), noto anche come Archivio segreto centrale, è un servizio di sistema di Service Fabric progettato per proteggere i segreti all'interno di un cluster. CSS semplifica la gestione dei segreti per le applicazioni SF, eliminando la necessità di basarsi sui parametri crittografati.

Il Servizio segreto centrale è una cache segreta durevole e replicata nel cluster; i segreti archiviati in CSS vengono crittografati inattivi in un certificato di crittografia fornito dal cliente. CSS fornisce API client per la gestione dei segreti, accessibili alle entità che eseguono l'autenticazione come cluster o come utente amministratore del cluster. Il modello di applicazione di runtime di Service Fabric si integra con CSS, consentendo la dichiarazione dei parametri dell'applicazione come riferimenti ai segreti CSS.

CSS è anche fondamentale per il provisioning dei segreti dell'applicazione dichiarati come URI segreti di KeyVault, in combinazione con l'identità gestita per le applicazioni di Service Fabric distribuite in Azure.

Il servizio segreto centrale non è destinato a sostituire un servizio di gestione dei segreti esterno dedicato, ad esempio Azure Key Vault.

Nota

Quando si attiva CSS in un cluster SF che esegue una versione precedente alla 7.1. CU3, l'attivazione può non riuscire e lasciare CSS in uno stato permanentemente non integro se il cluster è configurato per autenticazione di Windows o se EncryptionCertificateThumbprint è dichiarato in modo non corretto o il certificato corrispondente non è installato. In entrambi i casi, è consigliabile aggiornare il cluster a una versione di runtime sf successiva alla versione 7.1. CU3 prima di procedere.

Abilitare il servizio segreti centrali

Per abilitare il Servizio segreto centrale, aggiornare la configurazione del cluster come descritto di seguito. È consigliabile usare un certificato di crittografia diverso dal certificato del cluster. Questo certificato deve essere installato in tutti i nodi.

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

Nota

L'impostazione di configurazione "DeployedState", introdotta in Service Fabric versione 8.0, è il meccanismo preferito per abilitare o disabilitare CSS; questa funzione è stata servita nelle versioni precedenti dall'impostazione di configurazione "IsEnabled", che ora è considerata obsoleta.

Modello segreto servizio segreto centrale

L'API Servizio segreto centrale espone due tipi: risorsa privata e versione privata. Il tipo di risorsa segreta rappresenta, concettualmente, una famiglia di versioni di un singolo segreto utilizzato per uno scopo specifico; alcuni esempi includono: una stringa di connessione, una password, un certificato endpoint. Un oggetto del tipo di risorsa segreto contiene metadati associati a tale segreto, in particolare tipo, tipo di contenuto e descrizione. Il tipo di versione del segreto rappresenta una particolare istanza del segreto associato e archivia il testo non crittografato (crittografato); continuando con gli esempi precedenti, una versione privata contiene il valore della password corrente, un oggetto certificato valido fino alla fine del mese e così via. Dopo il rinnovo di questi segreti, è necessario produrre nuove versioni segrete (e aggiungerle a CSS).

Formalizzando il modello, di seguito sono riportate le regole implementate e applicate nell'implementazione CSS:

  • Una risorsa privata può avere zero o più versioni
  • Ogni versione segreta è un figlio di una particolare risorsa segreta; Una versione può avere una sola risorsa padre
  • È possibile eliminare una singola versione del segreto, senza influire sulle altre versioni dello stesso segreto
  • L'eliminazione di una risorsa privata causa l'eliminazione di tutte le versioni
  • Il valore di una versione privata non è modificabile

Dichiarare una risorsa privata

È possibile creare una risorsa privata usando l'API REST.

Nota

Se il cluster usa autenticazione di Windows senza un certificato HttpGateway, la richiesta REST viene inviata tramite un canale HTTP non protetto. Per abilitare TLS per questo canale, è necessario aggiornare la definizione del cluster per specificare un certificato del server gateway HTTP.

Per creare una supersecret risorsa privata usando l'API REST, effettuare una richiesta PUT a https://<clusterfqdn>:19080/Resources/Secrets/supersecret?api-version=6.4-preview. Per creare una risorsa privata, è necessario eseguire l'autenticazione usando un certificato del cluster o un certificato client amministratore.

$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

Impostare il valore del segreto

Usare lo script seguente per usare l'API REST per impostare il valore del segreto.

$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>

Esaminare il valore del segreto

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

Usare il segreto nell'applicazione

Un'applicazione può utilizzare un segreto da CSS dichiarandolo come variabile di ambiente o specificando un percorso in cui deve essere serializzato il testo non crittografato del segreto. Seguire questa procedura per fare riferimento a un segreto CSS:

  1. Aggiungere una sezione nel file settings.xml con il frammento di codice seguente. Si noti che il valore è nel formato {secretname:version}.
     <Section Name="testsecrets">
      <Parameter Name="TopSecret" Type="SecretsStoreRef" Value="supersecret:ver1"/
     </Section>
  1. Importare la sezione in 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>

Esempio 1: montare i segreti in un contenitore. L'unica modifica necessaria per rendere disponibili i segreti all'interno del contenitore è un specify punto di montaggio in <ConfigPackage>. Il frammento di codice seguente è il ApplicationManifest.xmlmodificato.

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

I segreti sono disponibili nel punto di montaggio all'interno del contenitore.

Esempio 2: Associare un segreto a una variabile di ambiente del processo specificando Type='SecretsStoreRef. Il frammento di codice seguente è un esempio di come associare la supersecret versione ver1 alla variabile MySuperSecret di ambiente in ServiceManifest.xml.

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

La variabile SecretPath di ambiente punterà alla directory in cui sono archiviati tutti i segreti. Ogni parametro elencato nella testsecrets sezione viene archiviato in un file separato. L'applicazione può ora usare il segreto come segue:

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

Rotazione del certificato di crittografia del servizio segreto centrale

È importante notare che i certificati rimangono validi per la decrittografia oltre la scadenza. In questo momento, è consigliabile continuare a effettuare il provisioning dei certificati di crittografia precedenti dopo la rotazione, per ridurre la probabilità di un blocco. La rotazione del certificato di crittografia CSS richiede i passaggi seguenti:

  1. Effettuare il provisioning del nuovo certificato in ogni nodo del cluster. Al momento, non rimuovere o continuare il provisioning del certificato di crittografia precedente.
  2. Avviare un aggiornamento della configurazione del cluster per modificare il valore di EncryptionCertificateThumbprint impostando l'identificazione personale SHA-1 del nuovo certificato. Al termine dell'aggiornamento, CSS inizierà a crittografare nuovamente il contenuto esistente nel nuovo certificato di crittografia. Tutti i segreti aggiunti a CSS dopo questo punto verranno crittografati direttamente nel nuovo certificato di crittografia. Poiché la convergenza di tutti i segreti protetti dal nuovo certificato è asincrona, è importante che il certificato di crittografia precedente rimanga installato in tutti i nodi e disponibile per CSS.

Rimozione del servizio segreto centrale dal cluster

La rimozione sicura del servizio segreto centrale da un cluster richiede due aggiornamenti. Il primo aggiornamento disabilita dal punto di vista funzionale CSS, mentre il secondo aggiornamento rimuove il servizio dalla definizione del cluster, che include l'eliminazione permanente del relativo contenuto. Questo processo in due fasi impedisce l'eliminazione accidentale del servizio e consente di garantire che non vi siano dipendenze orfane in CSS durante il processo di rimozione. Questa funzionalità è disponibile a partire dalla versione 8.0 di SF.

Passaggio 1: Aggiornare CSS DeployedState alla rimozione

Aggiornare la definizione del cluster da "IsEnabled" = "true" o da "DeployedState" = "enabled" a

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

Quando il servizio segreto centrale entra nello stato Removingdistribuito, rifiuterà tutte le chiamate API segrete in ingresso, sia chiamate REST dirette che tramite attivazioni di servizi che includono SecretStoreRefs o KeyVaultReferences. Tutte le applicazioni o i componenti nel cluster che dipendono ancora da CSS a questo punto passeranno allo stato avviso. In questo caso, è necessario eseguire il rollback dell'aggiornamento allo stato Removing distribuito. Se l'aggiornamento è già stato completato, è necessario avviare un nuovo aggiornamento per ripristinare CSS in DeployedState = Enabled. Se il Servizio segreto centrale riceve una richiesta nello stato Removingdistribuito, restituirà codice HTTP 401 (non autorizzato) e si troverà in uno stato di integrità di avviso.

Passaggio 2: Aggiornare CSS DeployedState in disabilitato

Aggiornare la definizione del cluster da "DeployedState" = "removing" a

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

Il servizio segreto centrale non deve più essere in esecuzione nel cluster e non sarà presente nell'elenco dei servizi di sistema. Il contenuto di CSS è inarrestabilemente perso.

Passaggi successivi