Gestire i segreti crittografati nelle applicazioni di Service Fabric

Questa guida descrive la procedura di gestione dei segreti in un'applicazione di Service Fabric. I segreti possono essere informazioni riservate, ad esempio le stringhe di connessione di archiviazione, le password o altri valori che non devono essere gestiti in testo normale.

Per usare i segreti crittografati in un'applicazione di Service Fabric è necessario completare tre passaggi:

  • Configurare un certificato di crittografia e crittografare i segreti.
  • Specificare i segreti crittografati in un'applicazione.
  • Decrittografare i segreti crittografati dal codice del servizio.

Configurare un certificato di crittografia e crittografare i segreti

La configurazione di un certificato di crittografia e il suo utilizzo per crittografare i segreti sono operazioni che vengono eseguite diversamente in Windows rispetto a Linux.

Specificare i segreti crittografati in un'applicazione

Il passaggio precedente illustra come crittografare un segreto con un certificato e produrre una stringa con codifica Base 64 da usare in un'applicazione. Questa stringa con codifica Base 64 può essere specificata come parametro crittografato nel file Settings.xml di un servizio o come variabile di ambiente nel file ServiceManifest.xml di un servizio.

Specificare un parametro crittografato nel file di configurazione Settings.xml del servizio con l'attributo IsEncrypted impostato su true:

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Section Name="MySettings">
    <Parameter Name="MySecret" IsEncrypted="true" Value="I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=" />
  </Section>
</Settings>

Specificare una variabile di ambiente crittografata nel file ServiceManifest.xml del servizio con l'attributo Type impostato su Encrypted:

<CodePackage Name="Code" Version="1.0.0">
  <EnvironmentVariables>
    <EnvironmentVariable Name="MyEnvVariable" Type="Encrypted" Value="I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=" />
  </EnvironmentVariables>
</CodePackage>

I segreti devono essere inclusi anche nell'applicazione di Service Fabric specificando un certificato nel manifesto dell'applicazione. Aggiungere un elemento SecretsCertificate per ApplicationManifest.xml e includere l'identificazione personale del certificato desiderato.

<ApplicationManifest … >
  ...
  <Certificates>
    <SecretsCertificate Name="MyCert" X509FindType="FindByThumbprint" X509FindValue="[YourCertThumbrint]"/>
  </Certificates>
</ApplicationManifest>

Nota

Dopo l'attivazione di un'applicazione che specifica un secretsCertificate, Service Fabric troverà il certificato corrispondente e concederà all'applicazione l'identità in esecuzione con autorizzazioni complete per la chiave privata del certificato. Service Fabric monitorerà anche il certificato per le modifiche e applicherà nuovamente le autorizzazioni di conseguenza. Per rilevare le modifiche per i certificati dichiarati dal nome comune, Service Fabric esegue un'attività periodica che trova tutti i certificati corrispondenti e la confronta con un elenco memorizzato nella cache delle identificazioni personali. Quando viene rilevata una nuova identificazione personale, significa che un certificato da tale soggetto è stato rinnovato. L'attività viene eseguita una volta al minuto in ogni nodo del cluster.

Mentre SecretsCertificate consente dichiarazioni basate su soggetto, tenere presente che le impostazioni crittografate sono associate alla coppia di chiavi usata per crittografare l'impostazione nel client. È necessario assicurarsi che il certificato di crittografia originale (o equivalente) corrisponda alla dichiarazione basata su soggetto e che sia installata, inclusa la chiave privata corrispondente, in ogni nodo del cluster che potrebbe ospitare l'applicazione. Tutti i certificati validi per il tempo corrispondenti alla dichiarazione basata su soggetto e compilati dalla stessa coppia di chiavi del certificato di crittografia originale sono considerati equivalenti.

Inserire i segreti dell'applicazione nelle istanze dell'applicazione

Idealmente, la distribuzione in ambienti diversi dovrebbe essere il più possibile automatizzata. Questo può essere ottenuto tramite l'esecuzione della crittografia dei segreti in un ambiente di compilazione e l'uso dei segreti crittografati come parametri durante la creazione delle istanze dell'applicazione.

Usare parametri sostituibili in Settings.xml

Il file di configurazione Settings.xml consente di usare parametri sostituibili che possono essere forniti al momento della creazione dell'applicazione. Usare l'attributo MustOverride invece di fornire un valore per un parametro:

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Section Name="MySettings">
    <Parameter Name="MySecret" IsEncrypted="true" Value="" MustOverride="true" />
  </Section>
</Settings>

Per sostituire i valori in Settings.xml, dichiarare un parametro di sostituzione per il servizio in ApplicationManifest.xml:

<ApplicationManifest ... >
  <Parameters>
    <Parameter Name="MySecret" DefaultValue="" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Stateful1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides>
      <ConfigOverride Name="Config">
        <Settings>
          <Section Name="MySettings">
            <Parameter Name="MySecret" Value="[MySecret]" IsEncrypted="true" />
          </Section>
        </Settings>
      </ConfigOverride>
    </ConfigOverrides>
  </ServiceManifestImport>

A questo punto, il valore può essere specificato come un parametro dell'applicazione quando si crea un'istanza dell'applicazione. La creazione di un'istanza dell'applicazione può generare uno script con PowerShell o essere scritta in C#, per semplificare l'integrazione in un processo di compilazione.

Tramite PowerShell, viene fornito il parametro del comando New-ServiceFabricApplication come tabella hash:

New-ServiceFabricApplication -ApplicationName fabric:/MyApp -ApplicationTypeName MyAppType -ApplicationTypeVersion 1.0.0 -ApplicationParameter @{"MySecret" = "I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM="}

Tramite C#, i parametri dell'applicazione vengono specificati in ApplicationDescription come NameValueCollection:

FabricClient fabricClient = new FabricClient();

NameValueCollection applicationParameters = new NameValueCollection();
applicationParameters["MySecret"] = "I6jCCAeYCAxgFhBXABFxzAt ... gNBRyeWFXl2VydmjZNwJIM=";

ApplicationDescription applicationDescription = new ApplicationDescription(
    applicationName: new Uri("fabric:/MyApp"),
    applicationTypeName: "MyAppType",
    applicationTypeVersion: "1.0.0",
    applicationParameters: applicationParameters)
);

await fabricClient.ApplicationManager.CreateApplicationAsync(applicationDescription);

Decrittografare i segreti crittografati dal codice del servizio

Le API per l'accesso a parametri e variabili di ambiente consentono di decrittografare facilmente i valori crittografati. Poiché la stringa crittografata contiene informazioni sul certificato usato per la crittografia, non è necessario specificare manualmente il certificato. Il certificato deve essere solo installato sul nodo su cui è in esecuzione il servizio.

// Access decrypted parameters from Settings.xml
ConfigurationPackage configPackage = FabricRuntime.GetActivationContext().GetConfigurationPackageObject("Config");
bool MySecretIsEncrypted = configPackage.Settings.Sections["MySettings"].Parameters["MySecret"].IsEncrypted;
if (MySecretIsEncrypted)
{
    SecureString MySecretDecryptedValue = configPackage.Settings.Sections["MySettings"].Parameters["MySecret"].DecryptValue();
}

// Access decrypted environment variables from ServiceManifest.xml
// Note: you do not have to call any explicit API to decrypt the environment variable.
string MyEnvVariable = Environment.GetEnvironmentVariable("MyEnvVariable");

Passaggi successivi