Serviço Secreto Central no Azure Service Fabric

O Serviço Secreto Central (CSS), também conhecido como Arquivo Secreto Central, é um serviço de sistema do Service Fabric destinado a salvaguardar segredos dentro de um cluster. O CSS facilita a gestão de segredos para aplicações SF, eliminando a necessidade de depender de parâmetros encriptados.

O Serviço Secreto Central é uma cache secreta no cluster durável e replicada; os segredos armazenados no CSS são encriptados inativos para um certificado de encriptação fornecido pelo cliente. O CSS fornece APIs de cliente para gestão de segredos, acessíveis a entidades que se autenticam como cluster ou um utilizador administrador de cluster. O modelo de aplicação runtime do Service Fabric integra-se no CSS, permitindo a declaração dos parâmetros da aplicação como referências secretas do CSS.

O CSS também é fundamental no aprovisionamento de segredos de aplicações declarados como URIs secretos do KeyVault, em combinação com a Identidade Gerida para Aplicações do Service Fabric implementadas no Azure.

O Serviço Secreto Central não se destina a substituir um serviço de gestão de segredos externos dedicado, como o Azure Key Vault.

Nota

Ao ativar o CSS num cluster SF com uma versão anterior à 7.1. CU3, a ativação pode falhar e deixar o CSS num estado de mau estado de funcionamento permanente se o cluster estiver configurado para autenticação do Windows ou se EncryptionCertificateThumbprint for declarado incorretamente ou se o certificado correspondente não estiver instalado. Em ambos os casos, é aconselhável atualizar o cluster para uma versão de runtime SF mais recente do que 7.1. CU3 antes de prosseguir.

Ativar o Serviço de Segredos Centrais

Para ativar o Serviço Secreto Central, atualize a configuração do cluster conforme descrito abaixo. Recomendamos que utilize um certificado de encriptação diferente do certificado de cluster. Este certificado tem de ser instalado em todos os nós.

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

Nota

A definição de configuração "DeployedState", introduzida na versão 8.0 do Service Fabric, é o mecanismo preferencial para ativar ou desativar o CSS; esta função foi servida em versões anteriores pela definição de configuração "IsEnabled", que é agora considerada obsoleta.

Modelo secreto do Serviço Secreto Central

A API do Serviço Secreto Central expõe dois tipos: recurso secreto e versão secreta. O tipo de recurso secreto representa, conceptualmente, uma família de versões de um único segredo utilizado para um propósito específico; os exemplos incluem: uma cadeia de ligação, uma palavra-passe, um certificado de ponto final. Um objeto do tipo de recurso secreto contém metadados associados a esse segredo, especificamente tipo, tipo de conteúdo e descrição. O tipo de versão secreta representa uma instância específica do segredo associado e armazena o texto simples secreto (encriptado); Continuando com os exemplos acima, uma versão secreta contém o valor de palavra-passe atual, um objeto de certificado válido até ao final do mês, etc. Após a renovação destes segredos, devem ser produzidas novas versões secretas (e adicionadas ao CSS).

Formalizar o modelo, seguem-se as regras implementadas e impostas na implementação do CSS:

  • Um recurso secreto pode ter zero ou mais versões
  • Cada versão secreta é um subordinado de um recurso secreto específico; uma versão pode ter apenas um recurso principal
  • Uma versão secreta individual pode ser eliminada, sem afetar outras versões do mesmo segredo
  • Eliminar um recurso secreto causa a eliminação de todas as respetivas versões
  • O valor de uma versão secreta é imutável

Declarar um recurso secreto

Pode criar um recurso secreto com a API REST.

Nota

Se o cluster estiver a utilizar a autenticação do Windows sem um certificado HttpGateway, o pedido REST é enviado através de um canal HTTP não seguro. Para ativar o TLS para este canal, a definição do cluster deve ser atualizada para especificar um certificado de servidor http gateway.

Para criar um supersecret recurso secreto com a API REST, faça um pedido PUT para https://<clusterfqdn>:19080/Resources/Secrets/supersecret?api-version=6.4-preview. Terá de autenticar com um certificado de cluster ou um certificado de cliente de administrador para criar um recurso secreto.

$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

Definir o valor do segredo

Utilize o seguinte script para utilizar a API REST para definir o valor do segredo.

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

Examinar o valor do segredo

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

Utilizar o segredo na sua aplicação

Uma aplicação pode consumir um segredo do CSS ao declará-lo como uma variável de ambiente ou ao especificar um caminho onde o texto simples secreto deve ser serializado. Siga estes passos para referenciar um segredo do CSS:

  1. Adicione uma secção no ficheiro settings.xml com o seguinte fragmento. Tenha em atenção que o valor está no formato {secretname:version}.
     <Section Name="testsecrets">
      <Parameter Name="TopSecret" Type="SecretsStoreRef" Value="supersecret:ver1"/
     </Section>
  1. Importe a secção no 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>

Exemplo 1: montar os segredos num contentor. A única alteração necessária para disponibilizar os segredos dentro do contentor é num specify ponto de montagem em <ConfigPackage>. O fragmento seguinte é o ApplicationManifest.xmlmodificado .

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

Os segredos estão disponíveis no ponto de montagem dentro do contentor.

Exemplo 2: Vincular um segredo a uma variável de ambiente de processo ao especificar Type='SecretsStoreRef. O fragmento seguinte é um exemplo de como vincular a supersecret versão ver1 à variável MySuperSecret de ambiente no ServiceManifest.xml.

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

A variável SecretPath de ambiente irá apontar para o diretório onde todos os segredos são armazenados. Cada parâmetro listado na testsecrets secção é armazenado num ficheiro separado. A aplicação pode agora utilizar o segredo da seguinte forma:

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

Rodar o Certificado de Encriptação do Serviço Secreto Central

É importante ter em atenção que os certificados permanecem válidos para desencriptação para além da expiração. Neste momento, recomendamos que continue a aprovisionar certificados de encriptação passados após a rotação, para reduzir a probabilidade de um bloqueio. Rodar o certificado de encriptação CSS requer os seguintes passos:

  1. Aprovisione o novo certificado para cada nó do cluster. Neste momento, não remova/continue a aprovisionar o certificado de encriptação anterior.
  2. Inicie uma atualização de configuração do cluster para alterar o valor de EncryptionCertificateThumbprint para o thumbprint SHA-1 do novo certificado. Após a conclusão da atualização, o CSS começará a encriptar novamente o respetivo conteúdo existente para o novo certificado de encriptação. Todos os segredos adicionados ao CSS após este ponto serão encriptados diretamente para o novo certificado de encriptação. Uma vez que a convergência para ter todos os segredos protegidos pelo novo certificado é assíncrona, é importante que o certificado de encriptação anterior permaneça instalado em todos os nós e disponível para CSS.

Remover o Serviço Secreto Central do cluster

A remoção segura do Serviço Secreto Central de um cluster requer duas atualizações. A primeira atualização desativa funcionalmente o CSS, enquanto a segunda atualização remove o serviço da definição do cluster, que inclui a eliminação permanente do respetivo conteúdo. Este processo de duas fases impede a eliminação acidental do serviço e ajuda a garantir que não existem dependências órfãs no CSS durante o processo de remoção. Esta funcionalidade está disponível a partir da versão 8.0 do SF.

Passo 1: Atualizar o CSS DeployedState para remover

Atualizar a definição do cluster de "IsEnabled" = "true" ou de "DeployedState" = "enabled" para

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

Assim que o Serviço Secreto Central entrar no estado Removingimplementado, rejeitará todas as chamadas de API secretas recebidas, sejam chamadas REST diretas ou através de ativações de serviços que incluam SecretStoreRefs ou KeyVaultReferences. Todas as aplicações ou componentes no cluster que ainda dependam do CSS neste momento entrarão em Estado de aviso. Caso tal ocorra, a atualização para o estado Removing implementado deve ser revertida; se essa atualização já tiver sido bem-sucedida, deverá ser iniciada uma nova atualização para alterar o CSS de volta para DeployedState = Enabled. Se o Serviço Secreto Central receber um pedido no estado Removingimplementado, devolverá o Código HTTP 401 (não autorizado) e colocar-se-á num estado de funcionamento de aviso.

Passo 2: Atualizar o CSS DeployedState para desativado

Atualizar a definição do cluster de "DeployedState" = "removing" para

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

O Serviço Secreto Central já não deve estar em execução no cluster e não estará presente na lista de serviços do sistema. O conteúdo do CSS é irremediavelmente perdido.

Passos seguintes