Partilhar via


Proteger um cluster autônomo no Windows usando certificados X.509

Este artigo descreve como proteger a comunicação entre os vários nós do cluster autônomo do Windows. Ele também descreve como autenticar clientes que se conectam a esse cluster usando certificados X.509. A autenticação garante que apenas usuários autorizados possam acessar o cluster e os aplicativos implantados e executar tarefas de gerenciamento. A segurança do certificado deve ser habilitada no cluster quando ele for criado.

Para obter mais informações sobre segurança de cluster, como segurança nó a nó, segurança de cliente para nó e controle de acesso baseado em função, consulte Cenários de segurança de cluster.

De que certificados precisa?

Para começar, baixe o pacote do Service Fabric para Windows Server para um dos nós do cluster. No pacote baixado, você encontra um arquivo ClusterConfig.X509.MultiMachine.json. Abra o arquivo e revise a seção de segurança na seção de propriedades:

"security": {
    "metadata": "The Credential type X509 indicates this cluster is secured by using X509 certificates. The thumbprint format is d5 ec 42 3b 79 cb e5 07 fd 83 59 3c 56 b9 d5 31 24 25 42 64.",
    "ClusterCredentialType": "X509",
    "ServerCredentialType": "X509",
    "CertificateInformation": {
        "ClusterCertificate": {
            "Thumbprint": "[Thumbprint]",
            "ThumbprintSecondary": "[Thumbprint]",
            "X509StoreName": "My"
        },        
        "ClusterCertificateCommonNames": {
            "CommonNames": [
            {
                "CertificateCommonName": "[CertificateCommonName]",
                "CertificateIssuerThumbprint": "[Thumbprint1,Thumbprint2,Thumbprint3,...]"
            }
            ],
            "X509StoreName": "My"
        },
        "ClusterCertificateIssuerStores": [
            {
                "IssuerCommonName": "[IssuerCommonName]",
                "X509StoreNames" : "Root"
            }
        ],
        "ServerCertificate": {
            "Thumbprint": "[Thumbprint]",
            "ThumbprintSecondary": "[Thumbprint]",
            "X509StoreName": "My"
        },
        "ServerCertificateCommonNames": {
            "CommonNames": [
            {
                "CertificateCommonName": "[CertificateCommonName]",
                "CertificateIssuerThumbprint": "[Thumbprint1,Thumbprint2,Thumbprint3,...]"
            }
            ],
            "X509StoreName": "My"
        },
        "ServerCertificateIssuerStores": [
            {
                "IssuerCommonName": "[IssuerCommonName]",
                "X509StoreNames" : "Root"
            }
        ],
        "ClientCertificateThumbprints": [
            {
                "CertificateThumbprint": "[Thumbprint]",
                "IsAdmin": false
            },
            {
                "CertificateThumbprint": "[Thumbprint]",
                "IsAdmin": true
            }
        ],
        "ClientCertificateCommonNames": [
            {
                "CertificateCommonName": "[CertificateCommonName]",
                "CertificateIssuerThumbprint": "[Thumbprint1,Thumbprint2,Thumbprint3,...]",
                "IsAdmin": true
            }
        ],
        "ClientCertificateIssuerStores": [
            {
                "IssuerCommonName": "[IssuerCommonName]",
                "X509StoreNames": "Root"
            }
        ]
        "ReverseProxyCertificate": {
            "Thumbprint": "[Thumbprint]",
            "ThumbprintSecondary": "[Thumbprint]",
            "X509StoreName": "My"
        },
        "ReverseProxyCertificateCommonNames": {
            "CommonNames": [
                {
                "CertificateCommonName": "[CertificateCommonName]"
                }
            ],
            "X509StoreName": "My"
        }
    }
},

Esta seção descreve os certificados necessários para proteger seu cluster autônomo do Windows. Se você especificar um certificado de cluster, defina o valor de ClusterCredentialType como X509. Se você especificar um certificado de servidor para conexões externas, defina ServerCredentialType como X509. Embora não seja obrigatório, recomendamos que você tenha ambos os certificados para um cluster devidamente protegido. Se você definir esses valores como X509, também deverá especificar os certificados correspondentes ou o Service Fabric lançará uma exceção. Em alguns cenários, talvez você queira especificar apenas o ClientCertificateThumbprints ou o ReverseProxyCertificate. Nesses cenários, não é necessário definir ClusterCredentialType ou ServerCredentialType como X509.

Nota

Uma impressão digital é a identidade principal de um certificado. Para descobrir a impressão digital dos certificados criados, consulte Recuperar uma impressão digital de um certificado.

A tabela a seguir lista os certificados necessários na configuração do cluster:

Configuração CertificateInformation Descrição
ClusterCertificate Recomendado para um ambiente de teste. Este certificado é necessário para proteger a comunicação entre os nós em um cluster. Você pode usar dois certificados diferentes, um primário e um secundário, para atualização. Defina a impressão digital do certificado primário na seção Impressão digital e a impressão digital do secundário nas variáveis ThumbprintSecundário.
ClusterCertificateCommonNames Recomendado para um ambiente de produção. Este certificado é necessário para proteger a comunicação entre os nós em um cluster. Você pode usar um ou dois nomes comuns de certificado de cluster. O CertificateIssuerThumbprint corresponde à impressão digital do emissor deste certificado. Se mais de um certificado com o mesmo nome comum for usado, você poderá especificar várias impressões digitais do emissor.
ClusterCertificateIssuerStores Recomendado para um ambiente de produção. Este certificado corresponde ao emissor do certificado de cluster. Você pode fornecer o nome comum do emissor e o nome da loja correspondente nesta seção em vez de especificar a impressão digital do emissor em ClusterCertificateCommonNames. Isso facilita a substituição de certificados de emissor de cluster. Vários emissores podem ser especificados se mais de um certificado de cluster for usado. Um IssuerCommonName vazio permite todos os certificados nos armazenamentos correspondentes especificados em X509StoreNames.
Certificado do servidor Recomendado para um ambiente de teste. Esse certificado é apresentado ao cliente quando ele tenta se conectar a esse cluster. Por conveniência, você pode optar por usar o mesmo certificado para ClusterCertificate e ServerCertificate. Você pode usar dois certificados de servidor diferentes, um primário e um secundário, para atualização. Defina a impressão digital do certificado primário na seção Impressão digital e a impressão digital do secundário nas variáveis ThumbprintSecundário.
ServerCertificateCommonNames Recomendado para um ambiente de produção. Esse certificado é apresentado ao cliente quando ele tenta se conectar a esse cluster. O CertificateIssuerThumbprint corresponde à impressão digital do emissor deste certificado. Se mais de um certificado com o mesmo nome comum for usado, você poderá especificar várias impressões digitais do emissor. Por conveniência, você pode optar por usar o mesmo certificado para ClusterCertificateCommonNames e ServerCertificateCommonNames. Você pode usar um ou dois nomes comuns de certificado de servidor.
ServerCertificateIssuerStores Recomendado para um ambiente de produção. Este certificado corresponde ao emissor do certificado do servidor. Você pode fornecer o nome comum do emissor e o nome da loja correspondente nesta seção em vez de especificar a impressão digital do emissor em ServerCertificateCommonNames. Isso facilita a substituição de certificados de emissor do servidor. Vários emissores podem ser especificados se mais de um certificado de servidor for usado. Um IssuerCommonName vazio permite todos os certificados nos armazenamentos correspondentes especificados em X509StoreNames.
ClientCertificateImpressões digitais Instale este conjunto de certificados nos clientes autenticados. Você pode ter vários certificados de cliente diferentes instalados nas máquinas que deseja permitir o acesso ao cluster. Defina a impressão digital de cada certificado na variável CertificateThumbprint. Se você definir IsAdmin como true, o cliente com esse certificado instalado nele poderá executar atividades de gerenciamento de administrador no cluster. Se IsAdmin for false, o cliente com esse certificado poderá executar as ações permitidas apenas para direitos de acesso do usuário, normalmente somente leitura. Para obter mais informações sobre funções, consulte Controle de acesso baseado em função do Service Fabric.
ClientCertificateCommonNames Defina o nome comum do primeiro certificado de cliente para o CertificateCommonName. O CertificateIssuerThumbprint é a impressão digital do emissor deste certificado. Para saber mais sobre nomes comuns e o emissor, consulte Trabalhar com certificados.
ClientCertificateIssuerStores Recomendado para um ambiente de produção. Este certificado corresponde ao emissor do certificado do cliente (funções de administrador e não administrador). Você pode fornecer o nome comum do emissor e o nome da loja correspondente nesta seção em vez de especificar a impressão digital do emissor em ClientCertificateCommonNames. Isso facilita a rolagem de certificados de emissor de cliente. Vários emissores podem ser especificados se mais de um certificado de cliente for usado. Um IssuerCommonName vazio permite todos os certificados nos armazenamentos correspondentes especificados em X509StoreNames.
ReverseProxyCertificate Recomendado para um ambiente de teste. Esse certificado opcional pode ser especificado se você quiser proteger seu proxy reverso. Certifique-se de que reverseProxyEndpointPort está definido em nodeTypes se você usar esse certificado.
ReverseProxyCertificateCommonNames Recomendado para um ambiente de produção. Esse certificado opcional pode ser especificado se você quiser proteger seu proxy reverso. Certifique-se de que reverseProxyEndpointPort está definido em nodeTypes se você usar esse certificado.

Aqui está um exemplo de configuração de cluster onde os certificados de cluster, servidor e cliente foram fornecidos. Para certificados cluster/server/reverseProxy, a impressão digital e o nome comum não podem ser configurados juntos para o mesmo tipo de certificado.

{
   "name": "SampleCluster",
   "clusterConfigurationVersion": "1.0.0",
   "apiVersion": "10-2017",
   "nodes": [{
       "nodeName": "vm0",
       "metadata": "Replace the localhost below with valid IP address or FQDN",
       "iPAddress": "10.7.0.5",
       "nodeTypeRef": "NodeType0",
       "faultDomain": "fd:/dc1/r0",
       "upgradeDomain": "UD0"
   }, {
       "nodeName": "vm1",
       "metadata": "Replace the localhost with valid IP address or FQDN",
       "iPAddress": "10.7.0.4",
       "nodeTypeRef": "NodeType0",
       "faultDomain": "fd:/dc1/r1",
       "upgradeDomain": "UD1"
   }, {
       "nodeName": "vm2",
       "iPAddress": "10.7.0.6",
       "metadata": "Replace the localhost with valid IP address or FQDN",
       "nodeTypeRef": "NodeType0",
       "faultDomain": "fd:/dc1/r2",
       "upgradeDomain": "UD2"
   }],
   "properties": {
       "diagnosticsStore": {
       "metadata":  "Please replace the diagnostics store with an actual file share accessible from all cluster machines.",
       "dataDeletionAgeInDays": "7",
       "storeType": "FileShare",
       "IsEncrypted": "false",
       "connectionstring": "c:\\ProgramData\\SF\\DiagnosticsStore"
       },
       "security": {
           "metadata": "The Credential type X509 indicates this cluster is secured by using X509 certificates. The thumbprint format is d5 ec 42 3b 79 cb e5 07 fd 83 59 3c 56 b9 d5 31 24 25 42 64.",
           "ClusterCredentialType": "X509",
           "ServerCredentialType": "X509",
           "CertificateInformation": {
               "ClusterCertificateCommonNames": {
                 "CommonNames": [
                   {
                     "CertificateCommonName": "myClusterCertCommonName"
                   }
                 ],
                 "X509StoreName": "My"
               },
               "ClusterCertificateIssuerStores": [
                   {
                       "IssuerCommonName": "ClusterIssuer1",
                       "X509StoreNames" : "Root"
                   },
                   {
                       "IssuerCommonName": "ClusterIssuer2",
                       "X509StoreNames" : "Root"
                   }
               ],
               "ServerCertificateCommonNames": {
                 "CommonNames": [
                   {
                     "CertificateCommonName": "myServerCertCommonName",
                     "CertificateIssuerThumbprint": "7c fc 91 97 13 16 8d ff a8 ee 71 2b a2 f4 62 62 00 03 49 0d"
                   }
                 ],
                 "X509StoreName": "My"
               },
               "ClientCertificateThumbprints": [{
                   "CertificateThumbprint": "c4 c18 8e aa a8 58 77 98 65 f8 61 4a 0d da 4c 13 c5 a1 37 6e",
                   "IsAdmin": false
               }, {
                   "CertificateThumbprint": "71 de 04 46 7c 9e d0 54 4d 02 10 98 bc d4 4c 71 e1 83 41 4e",
                   "IsAdmin": true
               }]
           }
       },
       "reliabilityLevel": "Bronze",
       "nodeTypes": [{
           "name": "NodeType0",
           "clientConnectionEndpointPort": "19000",
           "clusterConnectionEndpointPort": "19001",
           "leaseDriverEndpointPort": "19002",
           "serviceConnectionEndpointPort": "19003",
           "httpGatewayEndpointPort": "19080",
           "applicationPorts": {
               "startPort": "20001",
               "endPort": "20031"
           },
           "ephemeralPorts": {
               "startPort": "20032",
               "endPort": "20062"
           },
           "isPrimary": true
       }
        ],
       "fabricSettings": [{
           "name": "Setup",
           "parameters": [{
               "name": "FabricDataRoot",
               "value": "C:\\ProgramData\\SF"
           }, {
               "name": "FabricLogRoot",
               "value": "C:\\ProgramData\\SF\\Log"
           }]
       }]
   }
}

Substituição de certificados

Quando você usa um nome comum de certificado em vez de uma impressão digital, a substituição de certificado não requer uma atualização de configuração de cluster. Para atualizações de impressão digital do emissor, certifique-se de que a nova lista de impressão digital se cruza com a lista antiga. Primeiro, você precisa fazer uma atualização de configuração com as impressões digitais do novo emissor e, em seguida, instalar os novos certificados (certificados de cluster/servidor e certificados de emissor) no armazenamento. Mantenha o certificado de emissor antigo no armazenamento de certificados por pelo menos duas horas após a instalação do novo certificado de emissor. Se você estiver usando repositórios de emissores, nenhuma atualização de configuração precisará ser executada para a substituição de certificados do emissor. Instale o novo certificado de emissor com uma última data de expiração no armazenamento de certificados correspondente e remova o certificado de emissor antigo após algumas horas.

Adquira os certificados X.509

Para proteger a comunicação dentro do cluster, primeiro você precisa obter certificados X.509 para os nós do cluster. Além disso, para limitar a conexão a esse cluster a máquinas/usuários autorizados, você precisa obter e instalar certificados para as máquinas cliente.

Para clusters que executam cargas de trabalho de produção, use um certificado X.509 assinado pela autoridade de certificação (CA) para proteger o cluster. Para obter mais informações sobre como obter esses certificados, consulte Como obter um certificado.

Há uma série de propriedades que o certificado deve ter para funcionar corretamente:

  • O provedor do certificado deve ser o Microsoft Enhanced RSA e o AES Cryptographic Provider

  • Ao criar uma chave RSA, certifique-se de que a chave tem 2048 bits.

  • A extensão Uso de Chave tem um valor de Assinatura Digital, Codificação de Chave (a0)

  • A extensão de Uso Avançado de Chave tem valores de Autenticação de Servidor (OID: 1.3.6.1.5.5.7.3.1) e Autenticação de Cliente (OID: 1.3.6.1.5.5.7.3.2)

Para clusters que você usa para fins de teste, você pode optar por usar um certificado autoassinado.

Para perguntas adicionais, consulte as perguntas frequentes sobre certificados.

Opcional: Criar um certificado autoassinado

Uma maneira de criar um certificado autoassinado que pode ser protegido corretamente é usar o script CertSetup.ps1 na pasta SDK do Service Fabric no diretório C:\Program Files\Microsoft SDKs\Service Fabric\ClusterSetup\Secure. Edite este arquivo para alterar o nome padrão do certificado. (Procure o valor CN=ServiceFabricDevClusterCert.) Execute este script como .\CertSetup.ps1 -Install.

Agora exporte o certificado para um arquivo .pfx com uma senha protegida. Primeiro, obtenha a impressão digital do certificado.

  1. No menu Iniciar, execute Gerenciar certificados de computador.

  2. Vá para a pasta Computador Local\Pessoal e localize o certificado que você criou.

  3. Clique duas vezes no certificado para abri-lo, selecione a guia Detalhes e role para baixo até o campo Impressão digital.

  4. Remova os espaços e copie o valor da impressão digital para o seguinte comando do PowerShell.

  5. Altere o String valor para uma senha segura adequada para protegê-lo e execute o seguinte no PowerShell:

    $pswd = ConvertTo-SecureString -String "1234" -Force –AsPlainText
    Get-ChildItem -Path cert:\localMachine\my\<Thumbprint> | Export-PfxCertificate -FilePath C:\mypfx.pfx -Password $pswd
    
  6. Para ver os detalhes de um certificado instalado na máquina, execute o seguinte comando do PowerShell:

    $cert = Get-Item Cert:\LocalMachine\My\<Thumbprint>
    Write-Host $cert.ToString($true)
    

Como alternativa, se você tiver uma assinatura do Azure, siga as etapas em Criar um cluster do Service Fabric usando o Gerenciador de Recursos do Azure.

Instalar os certificados

Depois de ter certificados, você pode instalá-los nos nós do cluster. Seus nós precisam ter o Windows PowerShell 3.x mais recente instalado neles. Repita essas etapas em cada nó para certificados de cluster e servidor e quaisquer certificados secundários.

  1. Copie o arquivo ou arquivos .pfx para o nó.

  2. Abra uma janela do PowerShell como administrador e insira os seguintes comandos. Substitua $pswd pela senha que você usou para criar este certificado. Substitua $PfxFilePath pelo caminho completo do .pfx copiado para este nó.

    $pswd = "1234"
    $PfxFilePath ="C:\mypfx.pfx"
    Import-PfxCertificate -Exportable -CertStoreLocation Cert:\LocalMachine\My -FilePath $PfxFilePath -Password (ConvertTo-SecureString -String $pswd -AsPlainText -Force)
    
  3. Agora, defina o controle de acesso nesse certificado para que o processo do Service Fabric, que é executado sob a conta do Serviço de Rede, possa usá-lo executando o script a seguir. Forneça a impressão digital do certificado e do SERVIÇO DE REDE para a conta de serviço. Você pode verificar se as ACLs no certificado estão corretas abrindo o certificado em Iniciar>Gerenciar certificados de computador e examinando Todas as tarefas>Gerenciar chaves privadas.

    param
    (
    [Parameter(Position=1, Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$pfxThumbPrint,
    
    [Parameter(Position=2, Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$serviceAccount
    )
    
    $cert = Get-ChildItem -Path cert:\LocalMachine\My | Where-Object -FilterScript { $PSItem.ThumbPrint -eq $pfxThumbPrint; }
    
    # Specify the user, the permissions, and the permission type
    $permission = "$($serviceAccount)","FullControl","Allow" # "NT AUTHORITY\NetworkService" is the service account
    $accessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission
    
    # Location of the machine-related keys
    $keyPath = Join-Path -Path $env:ProgramData -ChildPath "\Microsoft\Crypto\RSA\MachineKeys"
    $keyName = $cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
    $keyFullPath = Join-Path -Path $keyPath -ChildPath $keyName
    
    # Get the current ACL of the private key
    $acl = (Get-Item $keyFullPath).GetAccessControl('Access')
    
    # Add the new ACE to the ACL of the private key
    $acl.SetAccessRule($accessRule)
    
    # Write back the new ACL
    Set-Acl -Path $keyFullPath -AclObject $acl -ErrorAction Stop
    
    # Observe the access rights currently assigned to this certificate
    get-acl $keyFullPath| fl
    
  4. Repita as etapas anteriores para cada certificado de servidor. Você também pode usar essas etapas para instalar os certificados de cliente nas máquinas que deseja permitir o acesso ao cluster.

Criar o cluster seguro

Depois de configurar a seção de segurança do arquivo ClusterConfig.X509.MultiMachine.json, você pode prosseguir para a seção Criar o cluster para configurar os nós e criar o cluster autônomo. Lembre-se de usar o arquivo ClusterConfig.X509.MultiMachine.json enquanto cria o cluster. Por exemplo, seu comando pode ter a seguinte aparência:

.\CreateServiceFabricCluster.ps1 -ClusterConfigFilePath .\ClusterConfig.X509.MultiMachine.json

Depois de executar com êxito o cluster autônomo seguro do Windows e configurar os clientes autenticados para se conectarem a ele, siga as etapas na seção Conectar-se a um cluster usando o PowerShell para se conectar a ele. Por exemplo:

$ConnectArgs = @{  ConnectionEndpoint = '10.7.0.5:19000';  X509Credential = $True;  StoreLocation = 'LocalMachine';  StoreName = "MY";  ServerCertThumbprint = "057b9544a6f2733e0c8d3a60013a58948213f551";  FindType = 'FindByThumbprint';  FindValue = "057b9544a6f2733e0c8d3a60013a58948213f551"   }
Connect-ServiceFabricCluster $ConnectArgs

Em seguida, você pode executar outros comandos do PowerShell para trabalhar com esse cluster. Por exemplo, você pode executar Get-ServiceFabricNode para mostrar uma lista de nós nesse cluster seguro.

Para remover o cluster, conecte-se ao nó no cluster onde você baixou o pacote do Service Fabric, abra uma linha de comando e vá para a pasta do pacote. Agora execute o seguinte comando:

.\RemoveServiceFabricCluster.ps1 -ClusterConfigFilePath .\ClusterConfig.X509.MultiMachine.json

Nota

A configuração incorreta do certificado pode impedir que o cluster apareça durante a implantação. Para autodiagnosticar problemas de segurança, procure no grupo Visualizador de Eventos Logs de Aplicativos e Serviços do>Microsoft-Service Fabric.