Clustering¶
Nota
Esta funcionalidade é atualmente uma pré-visualização técnica com as seguintes limitações temporárias:
Se um cluster for perdido (o quorum é perdido), o único meio de recuperação é a reposição de fábrica + restauração. Certifique-se de fazer backups com frequência. Versões futuras incluirão meios de recuperação de dados no disco.
A configuração ativa/passiva para suportar clusters de dois nós, utilizando o etcd Learner ou Mirror, ainda não está disponível.
Por enquanto, a hora do sistema entre os nós deve ser sincronizada manualmente. Uma versão futura incluirá a sincronização automática do relógio.
O NetHSM 4.0 em diante suporta o agrupamento para sincronizar dados entre vários NetHSMs diretamente. Isto suporta uma elevada frequência de gerações de chaves, permite uma elevada disponibilidade e um equilíbrio de carga. Um cluster NetHSM baseia-se em etcd que utiliza o algoritmo de consenso Raft para uma consistência forte. Isto garante que os dados (por exemplo, chaves) estão sempre corretos em todos os NetHSMs.
Antes de configurar um cluster NetHSM, familiarize-se com esta tecnologia e com as suas restrições para evitar interrupções acidentais e perda de dados. Para além deste documento, poderá querer consultar também a documentação do etcd.
Operational Redundancy¶
Chamaremos «nó» a um NetHSM que se espera que faça parte de um cluster. Um cluster de N nós continuará a operar desde que pelo menos (N/2)+1 nós estejam saudáveis e acessíveis. Essa quantidade mínima de nós saudáveis e acessíveis é chamada de quorum.
Isto implica os seguintes cenários.
Um nó fica inoperante e o quorum ainda é alcançado¶
Num cluster de 3 nós, se um nó falhar (avariar ou ficar inacessível devido a condições de rede), os outros dois nós continuarão a trabalhar e a servir pedidos.
Se o nó que falhou ainda estiver saudável (por exemplo, foi apenas um problema de rede), ficará inoperacional enquanto estiver isolado (nem sequer só de leitura).
No entanto, se o nó recuperar, será ressincronizado de forma limpa com o resto do cluster e voltará a estar operacional, sem perder dados.
Se nunca recuperar, tem de ser removido do cluster (ver secção seguinte), fazer uma reposição de fábrica e passar novamente pelo processo de junção a partir do zero.
Ocorre uma partição de rede e o quorum ainda é atingido¶
Esta é apenas uma generalização do cenário anterior. Num cluster de 5 nós em que, por exemplo, 3 nós estão numa localização física A e 2 nós estão noutra localização B, um problema de rede que isole A e B significaria o seguinte:
Os 3 nós da localização A estão a cumprir o quórum (3, neste caso), pelo que continuam a funcionar.
Os 2 nós na localização B são não satisfazem o quórum (ainda 3), pelo que deixarão de funcionar (mesmo só de leitura).
Se o problema da rede for resolvido, os 2 nós voltarão a juntar-se aos outros 3.
O Quorum está perdido de forma duradoura¶
Uma falha que cause a perda de quorum em todos os subconjuntos do cluster fará com que o cluster e seus dados sejam completamente perdidos, a menos que a falha seja resolvida. Neste caso, os nós devem ser repostos de fábrica e deve ser restaurada uma cópia de segurança.
Isso pode acontecer, por exemplo, se um único nó falhar em um cluster de 2 nós (onde o quorum é 2). Nesta situação, o nó falhado não pode ser removido do cluster após o facto, porque o nó saudável restante já está inoperacional uma vez que perdeu o quórum.
Por isso, é aconselhável ter sempre um número ímpar de nós num cluster e fazer cópias de segurança com frequência.
Para ser claro, temporariamente perder o quorum (por exemplo, se estiver a reiniciar todos os nós de um cluster em conjunto, ou se uma falha de rede temporária isolar os nós) não é um problema: assim que um número suficiente de nós for reconectado (sem ter de se voltar a juntar manualmente) para atingir o quorum, o cluster retomará o seu funcionamento normal. Apenas as falhas permanentes, como partições de rede, configurações incorrectas de rede, problemas de autenticação ou falhas de hardware, exigirão uma ação manual.
Para mais informações, consulte etcd’s FAQ.
Cluster de 2 nós¶
Um cluster ativo/passivo de dois nós ainda não é suportado e será adicionado numa versão futura. Recomendamos a introdução de um terceiro nó, seja um terceiro NetHSM ou uma «testemunha» etcd que pode ser operada em qualquer hospedeiro. Veja a próxima secção «Testemunha».
Testemunha¶
A natureza do clustering com etcd torna-o mais confiável quanto mais nós houver no cluster. Como explicado na secção Redundância Operacional, os clusters devem idealmente ter pelo menos 3 nós para ter espaço para falhar, uma vez que um cluster de 2 nós irá falhar completamente se apenas um falhar.
No entanto, o design do recurso é tal que não é necessário adicionar um dispositivo NetHSM completo e real ao cluster para atingir um número estável de nós. Em vez disso, pode implementar e adicionar um nó «testemunha». Tal nó é apenas uma instância do etcd rodando na máquina de sua escolha (ou em um container), e conectado ao cluster. Ele será reconhecido como um nó normal dos dispositivos reais no cluster e receberá todos os dados e atualizações dos dispositivos (mas é claro que não será possível executar nenhuma operação do HSM com ele - ele apenas armazena dados).
Security Considerations¶
O nó testemunha (ou qualquer pessoa com acesso a ele) tem acesso direto ao backend de armazenamento de todos os nós do cluster (por exemplo, pode descarregar todas as entradas e valores correspondentes com etcdctl get "/" "0").
No entanto, com exceção da versão de configuração (/config/version, que deve ser sempre «1»), todos os valores são estritamente encriptados (com uma chave de dispositivo para valores específicos de nós ou com as chaves de domínio para outros), garantindo a confidencialidade de dados sensíveis.
Note-se, no entanto, que um nó malicioso pode:
escrever lixo como o valor de qualquer entrada no repositório, o que fará com que os nós não consigam desencriptá-lo (o que pode levar a falhas em algumas entradas do sistema).
listar nomes de entradas, tais como utilizadores, espaços de nomes e chaves, que podem ser considerados sensíveis.
Creating a Cluster¶
Qualquer cluster começará inicialmente com um único nó. Os novos nós juntar-se-ão ao cluster um a um.
Preparing Nodes¶
O tráfego de rede entre os nós é encriptado e autenticado utilizando o seu certificado TLS.
Todos os nós que se espera que façam parte do mesmo cluster devem primeiro instalar uma Autoridade de Certificação (CA) comum que lhes permita verificar se os outros nós são legítimos.
A seguir, partimos do princípio de que todos os nós estão recém-provisionados e operacionais.
Networking¶
Nodes must first be reconfigured with their expected final network configuration using the /config/network endpoint (refer to the API documentation).
Criação e instalação de uma CA¶
Os utilizadores devem criar uma AC pelos seus próprios meios e de acordo com as suas próprias restrições operacionais, certificando-se de que permite, pelo menos, a utilização da chave keyCertSign.
Por exemplo, uma CA mínima pode ser criada com openssl:
$ openssl genrsa -out CA.key 2048 # create a key
$ openssl req -x509 -new -nodes -key CA.key -sha256 -days 1825 -out CA.pem -addext keyUsage=critical,keyCertSign
Esta CA tem agora de ser instalada em todos os nós.
To do this, first generate a Certificate Signing Request (CSR) from the node with the /config/tls/csr.pem endpoint (refer to the API documentation).
Nota
Para autenticar corretamente os nós, o backend de clustering (etcd) espera que cada nó tenha um certificado com um campo Subject Alt Names (SAN) corretamente preenchido. Em particular, os nós que se espera que sejam alcançados apenas através do seu IP precisam de ter um SAN de IP correto no seu certificado. Os SANs de IP podem ser solicitados para o CSR prefixando «IP:» aos nomes, como em openssl:
"subjectAltNames": [ "normalname.org", "IP:192.168.1.1" ]
Dado o CSR obtido (vamos chamá-lo de nethsm.csr), podemos então gerar um certificado para ele, pronto para ser instalado. Por exemplo, com openssl:
$ openssl x509 -req -days 1825 -in nethsm.csr -CA CA.pem -copy_extensions copy \
-CAkey CA.key -out new_cert.pem -set_serial 01 -sha256
Then install the obtained new_cert.pem with the /config/tls/cert.pem endpoint (refer to the API documentation).
Finalmente, a CA (CA.pem) pode agora ser instalada com o ponto de extremidade /config/tls/cluster-ca.pem (consulte a documentação da API ` <https://nethsmdemo.nitrokey.com/api_docs/index.html>` __). Isto só é possível quando o certificado TLS instalado é assinado por ela. Caso contrário, a operação será rejeitada.
Nota
Este processo tem de ser repetido para cada nó.
Sincronização do relógio¶
Certifique-se de que cada nó tenha sido provisionado com uma hora de sistema precisa. Caso contrário, ajuste os relógios com o ponto de extremidade /config/time.
Adding a New Node¶
A adição de um nó a um cluster é efectuada em duas etapas:
registar a adição ao cluster (através de qualquer um dos seus membros)
dizer ao novo nó para se juntar
Configure a Backup Passphrase¶
Primeiro, certifique-se de que está configurada uma frase-chave de backup no nó que será utilizado para registar um novo membro (consulte a documentação da API do ponto de extremidade /config/backup-passphrase).
Registar um novo nó¶
Aviso
O registo de um nó introduz imediatamente um novo nó no cluster, modificando o limiar de quorum, mesmo que o nó ainda não se tenha juntado. Isto pode tornar os nós existentes inoperacionais até que o novo nó tenha efetivamente entrado. Consulte a documentação da API ` <https://nethsmdemo.nitrokey.com/api_docs/index.html>` __ e a secção Redundância operacional deste documento.
Ter em mãos o IP do nó que irá aderir. O URL completo ** (também chamado peer URL na terminologia etcd) desse nó será https://<IP_of_node>:2380 (por exemplo, https://192.168.1.1:2380). A porta deve ser 2380, portanto, certifique-se de que qualquer firewall entre os nós permita o tráfego TCP nessa porta.
Você pode verificar se a URL está correta chamando GET /cluster/members no nó que se espera juntar. Isso deve listar apenas um membro: ele mesmo.
Em seguida, registe esse URL esperado em qualquer nó existente do cluster (se ainda não tiver um cluster, faça isso no NetHSM que servirá como o nó inicial do cluster). Isso é feito usando o endpoint POST /cluster/members (consulte a documentação da API ` <https://nethsmdemo.nitrokey.com/api_docs/index.html>` __), passando-lhe um corpo JSON contendo o URL.
Se for bem sucedido, devolve um corpo JSON do formulário:
{
"members": [
{
"name": "",
"urls": [
"https://172.22.1.3:2380"
]
},
{
"name": "9ZVNM2MNWP",
"urls": [
"https://172.22.1.2:2380"
]
}
],
"joinerKit": "eyJiYWNrdXBfc2FsdCI6IkVlUzNPOEhHSEc5NnlNRktrdG1NZmc9PSIsInVubG9ja19zYWx0IjoiU3phMkEvYW13NlhxVWsrdHZMMmFubm5SZFlWd2ZQUjdpZ3IxK1RSdTdVaU14dmh3d0x2NWIvYVNkY2c9IiwibG9ja2VkX2RvbWFpbl9rZXkiOiIyMnNGVlkyelhQUVZ6S1pQenI3MmkwTk1WM3lmQ2k5dGwzeDhUbGtuOXM0WjFOd3JoZkRQTFZIVHp1WVl0YkQxaVZCMlovV3JHUHJlMXlwN0t4U0w4WkxjY2ZUTmUzcFg0WXE4YXNlY0wwREhXNGlIaXlPMlZnPT0ifQ=="
}
que contém a informação necessária para que o novo nó se junte ao cluster. Em particular, lista todos os membros do cluster (onde o membro com um nome vazio é o novo membro). Também contém a chave de domínio encriptada pelas frases-chave de desbloqueio e de backup - portanto, uma frase-chave de backup deve ter sido configurada anteriormente.
Guarde essa resposta para o passo seguinte.
Entrada efectiva no cluster¶
Pegue na resposta do último passo e acrescente-lhe um campo backupPassphrase que contém a frase-chave de backup do nó no qual o novo membro foi registado, e passe esses dados para uma chamada a POST /cluster/join (consulte a documentação da API ` <https://nethsmdemo.nitrokey.com/api_docs/index.html>` __) no nó que se espera que se junte.
Partindo do princípio que tanto o cluster como o nó se conseguem contactar, isto irá efetuar a junção real, limpando os dados do novo membro para sincronizar o seu estado com o do cluster.
Dependendo da rede e das condições do cluster, esta operação pode demorar algumas dezenas de segundos. Se esta operação falhar imediatamente (por exemplo, o cluster não estava acessível ou a autenticação falhou), o estado deste nó não será apagado e a junção será revertida. No entanto, assim que uma primeira junção for bem sucedida, esta operação é definitiva e só pode ser revertida através de uma reposição de fábrica.
Se esta junção for bem sucedida, o nó irá acabar num estado Locked, e tem de ser desbloqueado com a frase-chave de desbloqueio do nó que foi utilizado para o registo. Posteriormente, a frase-chave de desbloqueio pode ser alterada (as frases-chave de desbloqueio permanecem específicas do nó e não são partilhadas entre nós).
Nota
Mesmo depois de a junção ter sido bem sucedida, se a base de dados do cluster for grande ou se o cluster estiver ocupado, pode demorar algum tempo até que o novo membro sincronize totalmente o seu estado. Durante esse tempo, todos os nós (incluindo, em particular, o novo participante) podem ser menos reactivos ou não reactivos. O novo marceneiro, em particular, pode inicialmente retornar erros ao tentar desbloqueá-lo, por exemplo. Nesse caso, dê algum tempo e tente novamente.
Adding a Witness Node¶
Prepare a Witness¶
Você precisará de um ambiente com etcd v3.6 disponível, com um endereço IPv4 (pelo menos) acessível aos outros membros do seu cluster. O tráfego TCP de e para a porta 2380 precisa ser permitido.
Crie um diretório vazio onde etcd irá armazenar os seus dados, e escreva o seu caminho (utilizaremos /var/etcd/data). Certifique-se de que o utilizador que irá lançar o processo tem permissão para ler e escrever no diretório.
Transfira para a máquina o certificado da CA que está sendo usado para autenticar os nós no cluster. Você deve ter criado um na seção Criando e instalando uma CA. Nós o armazenaremos em /var/etcd/CA.pem.
Em seguida, será necessário criar um certificado para a testemunha e assiná-lo com a CA para que ela possa se comunicar com seus pares. Isto pode ser feito, por exemplo, através de openssl:
# Create a key
$ openssl genrsa -out witness.key 2048
# Create a CSR with a SAN that corresponds to the witness's IP or hostname
$ openssl req -new -sha256 -key own.key -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=witness" \
-addext "subjectAltName=IP:172.22.1.3" --out witness.csr
# Sign it
$ openssl x509 -req -days 1825 -in witness.csr -CA CA.pem -copy_extensions copy \
-CAkey CA.key -out witness.pem -set_serial 01 -sha256
Armazene os resultados witness.key e witness.pem em /var/etcd também.
Register Witness to Cluster¶
Siga as instruções normais da secção Registering a New Node para sinalizar ao cluster existente a adição de um novo membro com o(s) URL(s) fornecido(s).
Anote a resposta do cluster: deve conter a lista dos membros do cluster e um kit de aderente (não vai precisar desta parte).
Configure etcd¶
Ao contrário dos NetHSMs que escolhem automaticamente um nome de nó para si próprios (utilizando o ID do dispositivo), é necessário escolher um nome para cada testemunha que adicionar, certificando-se de que os nomes são únicos. Usaremos «witness1» nos exemplos a seguir.
Com a resposta do NetHSM ao registo da testemunha, preparar variáveis do formulário:
export ETCD_NAME="witness1"
export ETCD_DATA_DIR="/var/etcd/data"
export ETCD_INITIAL_CLUSTER="peer1=url1,peer1=url2,peer2=url1,peer2=url2,..."
export ETCD_INITIAL_ADVERTISE_PEER_URLS="my_url1,my_url2,..."
Assumindo que a resposta do NetHSM está armazenada num ficheiro response.json, é possível gerar estas duas últimas variáveis automaticamente com as seguintes expressões jq:
export ETCD_INITIAL_CLUSTER=$(jq --raw-output '[.members[] | ["\(if .name == "" then "witness1" else .name end)=\(.urls[])"]] | flatten | join(",")' < response.json)
export ETCD_INITIAL_ADVERTISE_PEER_URLS=$(jq --raw-output '.members[] | select(.name=="") | .urls | join(",")' < response.json)
Por exemplo, com a resposta de exemplo fornecida na secção Registar um novo nó, terá:
ETCD_NAME="witness1"
ETCD_DATA_DIR="/var/etcd/data"
ETCD_INITIAL_CLUSTER="witness1=https://172.22.1.3:2380,9ZVNM2MNWP=https://172.22.1.2:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.22.1.3:2380"
Finalmente, crie um ficheiro etcd.conf.yml utilizando o ficheiro modelo fornecido em docs/etcd_witness.conf.template:
$ envsubst < NETHSM_ROOT/docs/etcd_witness.conf.template > /var/etcd/witness.conf.yml
$ cat witness.conf.yml
Isto deve fornecer-lhe um ficheiro do formulário:
name: witness1
data-dir: /var/etcd/data
log-level: warn
log-format: console
listen-peer-urls: https://0.0.0.0:2380
listen-client-urls: http://localhost:2379
initial-advertise-peer-urls: https://172.22.1.3:2380
advertise-client-urls: http://localhost:2379
initial-cluster: witness1=https://172.22.1.3:2380,9ZVNM2MNWP=https://172.22.1.2:2380
initial-cluster-state: 'existing'
peer-transport-security:
cert-file: witness.pem
key-file: witness.key
client-cert-auth: true
trusted-ca-file: CA.pem
skip-client-san-verification: true
Start etcd¶
Inicie etcd da forma que preferir (manualmente, systemd serviço, contentor, etc.), apontando-o para o ficheiro de configuração criado no passo anterior:
$ cd /var/etcd
$ etcd --config-file witness.conf.yml
Deverá vê-lo a iniciar, a juntar-se ao cluster e a apanhar os dados. Depois de algum tempo, você deve ser capaz de verificar se ele está saudável com o cliente etcdctl:
etcdctl get /config/version
Esta chave deve existir e conter «1».
Certifique-se de que este processo continua a ser executado, uma vez que é agora um membro adequado do seu cluster. Se for necessário desativá-lo, primeiro remova-o corretamente do cluster (consulte a seção dedicada). Se o IP acessível for alterado, actualize o URL do cluster.
Operating a Cluster¶
Cópia de Segurança e Restauração¶
A operação de backup funciona da mesma forma que sem um cluster e pode ser solicitada a partir de qualquer nó do cluster. Fará o backup dos dados de todo o cluster, incluindo os campos específicos do nó (embora estes sejam ignorados, a menos que o backup seja restaurado num nó não provisionado).
Um backup feito num cluster pode ser restaurado no mesmo cluster, mesmo que alguns nós tenham sido adicionados ou removidos desde então. Esses restauros efectuados em clusters operacionais não afectarão os valores de configuração (apenas chaves, utilizadores, espaços de nomes), como qualquer outro restauro parcial.
O restauro de uma cópia de segurança num nó não provisionado irá restaurar os campos específicos do nó (como a configuração de rede, certificados, etc.) do nó que foi utilizado para criar a cópia de segurança.
O restauro de uma cópia de segurança grande pode sobrecarregar o cluster durante algum tempo, enquanto o nó que aplica o restauro encaminha as alterações para os outros.
Esta operação permanece compatível com as cópias de segurança efectuadas em versões anteriores do NetHSM.
Nota
Restaurar num nó A uma cópia de segurança efectuada noutro nó Z com uma chave de domínio diferente reescreverá corretamente a chave de domínio de A, como anteriormente. No entanto, se A estiver num cluster com o nó B, B ficará inoperacional, uma vez que a chave de domínio de Z não será restaurada em B.
Por outras palavras, apenas execute um restauro num cluster com backups efectuados no mesmo cluster (embora, mais uma vez, os nós possam ter sido removidos ou adicionados desde então). Se pretender restaurar uma cópia de segurança externa num nó, primeiro remova-o com segurança do respetivo cluster e, em seguida, proceda à reposição de fábrica e restaure a cópia de segurança.
Removendo um nó de forma limpa¶
Desde que alguma parte do cluster ainda esteja a cumprir o quórum, qualquer um dos seus membros pode ser utilizado para remover outro nó do cluster, quer este nó já esteja inacessível ou se espere que esteja.
Em primeiro lugar, é necessário saber o ID do nó que se pretende remover, listando todos os nós através de GET /cluster/members e procurando o nó correto.
Então ele pode ser removido chamando DELETE /cluster/members/<id>. Se o nó em questão ainda estava saudável, isso irá isolá-lo do resto do cluster e torná-lo inoperável.
Software Updates in Clusters¶
As futuras actualizações serão marcadas como «cluster-safe» (deve ser a maioria) ou «cluster-unsafe».
As actualizações à prova de cluster podem ser aplicadas a nós que fazem parte de um cluster sem removê-los do cluster primeiro. No entanto, tal como acontece com todas as operações, deve certificar-se de que o faz num nó de cada vez e num cluster em que a remoção de um nó não fique abaixo do quórum (por exemplo, se a atualização falhar).
As actualizações não seguras para o cluster devem ser aplicadas a nós isolados. Deve desmantelar o cluster (removendo os nós um a um), fazer a reposição de fábrica de todos os nós exceto um, aplicar a atualização a todos os nós e, em seguida, fazer com que todos os nós repostos se juntem ao nó restante.
Certifique-se de que efectua uma cópia de segurança antes destas operações.
Reconfiguração de um cluster existente¶
Changing the Cluster CA¶
Um cluster existente (com dois ou mais nós) não pode alterar sua CA de cluster enquanto estiver em operação. Se precisar de alterar este certificado: escolha um nó, remova todos os outros nós, actualize a CA e, em seguida, faça com que os outros membros se juntem novamente.
Changing the Network Configuration of Nodes¶
Modificar a configuração de rede de um nó (por exemplo, alterar o seu IP) informará automaticamente os outros nós sobre a atualização. No entanto, deve certificar-se de que apenas efectua essas actualizações num único nó de cada vez e num cluster em que a perda desse nó não perca o quórum.