Proteger um cluster autónomo no Windows com certificados X.509

Este artigo descreve como proteger a comunicação entre os vários nós do seu cluster autónomo do Windows. Também descreve como autenticar clientes que se ligam a este cluster com certificados X.509. A autenticação garante que apenas os utilizadores autorizados podem aceder ao cluster e às aplicações implementadas e executar tarefas de gestão. A segurança do certificado deve ser ativada no cluster quando o cluster é criado.

Para obter mais informações sobre a segurança do cluster, como a segurança entre nós, a segurança cliente a nó e o controlo de acesso baseado em funções, veja Cenários de segurança de cluster.

De que certificados precisa?

Para começar, transfira o pacote do Service Fabric para Windows Server para um dos nós no cluster. No pacote transferido, encontrará um ficheiro ClusterConfig.X509.MultiMachine.json. Abra o ficheiro e reveja a secção para obter segurança na secçã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 secção descreve os certificados de que precisa para proteger o cluster autónomo do Windows. Se especificar um certificado de cluster, defina o valor de ClusterCredentialType como X509. Se especificar um certificado de servidor para ligações externas, defina ServerCredentialType como X509. Embora não seja obrigatório, recomendamos que tenha ambos estes certificados para um cluster devidamente protegido. Se definir estes valores como X509, também tem de especificar os certificados correspondentes ou o Service Fabric gera uma exceção. Em alguns cenários, poderá querer especificar apenas os ClientCertificateThumbprints ou o ReverseProxyCertificate. Nesses cenários, não precisa de definir ClusterCredentialType ou ServerCredentialType como X509.

Nota

Um thumbprint é a identidade primária de um certificado. Para descobrir o thumbprint dos certificados que cria, veja Obter um thumbprint de um certificado.

A tabela seguinte lista os certificados de que precisa na configuração do cluster:

Definição de CertificateInformation Descrição
ClusterCertificate Recomendado para um ambiente de teste. Este certificado é necessário para proteger a comunicação entre os nós num cluster. Pode utilizar dois certificados diferentes, um primário e um secundário, para a atualização. Defina o thumbprint do certificado primário na secção Thumbprint e o do secundário nas variáveis ThumbprintSecondary.
ClusterCertificateCommonNames Recomendado para um ambiente de produção. Este certificado é necessário para proteger a comunicação entre os nós num cluster. Pode utilizar um ou dois nomes comuns de certificados de cluster. O CertificateIssuerThumbprint corresponde ao thumbprint do emissor deste certificado. Se for utilizado mais do que um certificado com o mesmo nome comum, pode especificar vários thumbprints do emissor.
ClusterCertificateIssuerStores Recomendado para um ambiente de produção. Este certificado corresponde ao emissor do certificado de cluster. Pode indicar o nome comum do emissor e o nome de arquivo correspondente nesta secção em vez de especificar o thumbprint do emissor em ClusterCertificateCommonNames. Isto facilita o rollover de certificados de emissores de clusters. Podem ser especificados vários emissores se for utilizado mais do que um certificado de cluster. Um IssuerCommonName vazio permite todos os certificados nos arquivos correspondentes especificados em X509StoreNames.
ServerCertificate Recomendado para um ambiente de teste. Este certificado é apresentado ao cliente quando tenta ligar a este cluster. Para sua comodidade, pode optar por utilizar o mesmo certificado para ClusterCertificate e ServerCertificate. Pode utilizar dois certificados de servidor diferentes, um primário e um secundário, para a atualização. Defina o thumbprint do certificado primário na secção Thumbprint e o do secundário nas variáveis ThumbprintSecondary.
ServerCertificateCommonNames Recomendado para um ambiente de produção. Este certificado é apresentado ao cliente quando tenta ligar a este cluster. O CertificateIssuerThumbprint corresponde ao thumbprint do emissor deste certificado. Se for utilizado mais do que um certificado com o mesmo nome comum, pode especificar vários thumbprints do emissor. Para sua comodidade, pode optar por utilizar o mesmo certificado para ClusterCertificateCommonNames e ServerCertificateCommonNames. Pode utilizar um ou dois nomes comuns de certificados de servidor.
ServerCertificateIssuerStores Recomendado para um ambiente de produção. Este certificado corresponde ao emissor do certificado de servidor. Pode indicar o nome comum do emissor e o nome de arquivo correspondente nesta secção em vez de especificar o thumbprint do emissor em ServerCertificateCommonNames. Isto facilita o rollover de certificados de emissor do servidor. Podem ser especificados vários emissores se for utilizado mais do que um certificado de servidor. Um IssuerCommonName vazio permite todos os certificados nos arquivos correspondentes especificados em X509StoreNames.
ClientCertificateThumbprints Instale este conjunto de certificados nos clientes autenticados. Pode ter vários certificados de cliente diferentes instalados nos computadores que pretende permitir o acesso ao cluster. Defina o thumbprint de cada certificado na variável CertificateThumbprint. Se definir IsAdmin como verdadeiro, o cliente com este certificado instalado pode realizar atividades de gestão de administrador no cluster. Se IsAdmin for falso, o cliente com este certificado só pode executar as ações permitidas para direitos de acesso de utilizador, normalmente só de leitura. Para obter mais informações sobre funções, veja Controlo de acesso baseado em funções do Service Fabric.
ClientCertificateCommonNames Defina o nome comum do primeiro certificado de cliente para o CertificateCommonName. O CertificateIssuerThumbprint é o thumbprint do emissor deste certificado. Para saber mais sobre os nomes comuns e o emissor, veja Trabalhar com certificados.
ClientCertificateIssuerStores Recomendado para um ambiente de produção. Este certificado corresponde ao emissor do certificado de cliente (funções de administrador e não administrador). Pode indicar o nome comum do emissor e o nome de arquivo correspondente nesta secção em vez de especificar o thumbprint do emissor em ClientCertificateCommonNames. Isto facilita o rollover de certificados de emissor de cliente. Podem ser especificados vários emissores se for utilizado mais do que um certificado de cliente. Um IssuerCommonName vazio permite todos os certificados nos arquivos correspondentes especificados em X509StoreNames.
ReverseProxyCertificate Recomendado para um ambiente de teste. Este certificado opcional pode ser especificado se quiser proteger o proxy inverso. Certifique-se de que reverseProxyEndpointPort está definido em nodeTypes se utilizar este certificado.
ReverseProxyCertificateCommonNames Recomendado para um ambiente de produção. Este certificado opcional pode ser especificado se quiser proteger o proxy inverso. Certifique-se de que reverseProxyEndpointPort está definido em nodeTypes se utilizar este certificado.

Eis um exemplo de configuração do cluster onde foram fornecidos os certificados de cluster, servidor e cliente. Para certificados de cluster/servidor/reverseProxy, o thumbprint e o nome comum não podem ser configurados em conjunto 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"
           }]
       }]
   }
}

Rollover de certificados

Quando utiliza um nome comum de certificado em vez de um thumbprint, o rollover de certificado não requer uma atualização da configuração do cluster. Para atualizações de thumbprint do emissor, certifique-se de que a nova lista de thumbprints se cruza com a lista antiga. Primeiro, tem de fazer uma atualização de configuração com os novos thumbprints do emissor e, em seguida, instalar os novos certificados (certificados de cluster/servidor e certificados de emissor) no arquivo. Mantenha o certificado do emissor antigo no arquivo de certificados durante, pelo menos, duas horas após instalar o novo certificado do emissor. Se estiver a utilizar arquivos de emissores, não é necessário efetuar qualquer atualização de configuração para o rollover do certificado do emissor. Instale o novo certificado do emissor com uma última data de expiração no arquivo de certificados correspondente e remova o certificado do emissor antigo após algumas horas.

Adquirir os certificados X.509

Para proteger a comunicação dentro do cluster, primeiro tem de obter certificados X.509 para os nós de cluster. Além disso, para limitar a ligação a este cluster a máquinas/utilizadores autorizados, tem de obter e instalar certificados para as máquinas cliente.

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

Existem várias propriedades que o certificado tem de ter para funcionar corretamente:

  • O fornecedor do certificado tem de ser Microsoft Enhanced RSA e AES Cryptographic Provider

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

  • A extensão Utilização da Chave tem um valor de Assinatura Digital, Encifração de Chave (a0)

  • A extensão utilização de chave avançada tem valores de Autenticação do 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 utiliza para fins de teste, pode optar por utilizar um certificado autoassinado.

Para obter perguntas adicionais, consulte as perguntas mais frequentes sobre o certificado.

Opcional: Criar um certificado autoassinado

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

Agora, exporte o certificado para um ficheiro .pfx com uma palavra-passe protegida. Primeiro, obtenha o thumbprint do certificado.

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

  2. Aceda à pasta Computador Local\Pessoal e localize o certificado que criou.

  3. Faça duplo clique no certificado para o abrir, selecione o separador Detalhes e desloque-se para baixo até ao campo Thumbprint .

  4. Remova os espaços e copie o valor thumbprint para o seguinte comando do PowerShell.

  5. Altere o String valor para uma palavra-passe 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 no computador, execute o seguinte comando do PowerShell:

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

Em alternativa, se tiver uma subscrição do Azure, siga os passos em Criar um cluster do Service Fabric com o Azure Resource Manager.

Instalar os certificados

Depois de ter certificados, pode instalá-los nos nós do cluster. Os nós têm de ter os Windows PowerShell 3.x mais recentes instalados nos mesmos. Repita estes passos em cada nó para certificados de cluster e servidor e quaisquer certificados secundários.

  1. Copie o ficheiro ou ficheiros .pfx para o nó.

  2. Abra uma janela do PowerShell como administrador e introduza os seguintes comandos. Substitua $pswd pela palavra-passe que utilizou 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 controlo de acesso neste certificado para que o processo do Service Fabric, que é executado na conta do Serviço de Rede, possa utilizá-lo ao executar o seguinte script. Forneça o thumbprint do certificado e SERVIÇO DE REDE para a conta de serviço. Pode verificar se as ACLs no certificado estão corretas ao abrir o certificado em Iniciar>Gerir certificados de computador e ver Todas as TarefasGerir 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 os passos anteriores para cada certificado de servidor. Também pode utilizar estes passos para instalar os certificados de cliente nos computadores que pretende permitir o acesso ao cluster.

Criar o cluster seguro

Depois de configurar a secção de segurança do ficheiro ClusterConfig.X509.MultiMachine.json, pode avançar para a secção Criar o cluster para configurar os nós e criar o cluster autónomo. Lembre-se de utilizar o ficheiro ClusterConfig.X509.MultiMachine.json enquanto cria o cluster. Por exemplo, o comando poderá ter o seguinte aspeto:

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

Depois de ter o cluster autónomo seguro do Windows em execução com êxito e de ter configurado os clientes autenticados para se ligarem ao mesmo, siga os passos na secção Ligar a um cluster com o PowerShell para ligar ao mesmo. 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, pode executar outros comandos do PowerShell para trabalhar com este cluster. Por exemplo, pode executar Get-ServiceFabricNode para mostrar uma lista de nós neste cluster seguro.

Para remover o cluster, ligue-se ao nó no cluster onde transferiu o pacote do Service Fabric, abra uma linha de comandos e aceda à 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 seja apresentado durante a implementação. Para autodiagnásticos problemas de segurança, consulte o grupo de Visualizador de Eventos Aplicações e Registos de Serviços>Microsoft-Service Fabric.