Mantenha a CA raiz da VPN offline e ainda assim emita certificados
Mantenha a chave raiz fora da rede, assine certificados folha com uma CA intermediária, publique uma CRL a tempo e teste a cadeia antes de o primeiro cliente se conectar.
A sua VPN responde a ligações às 3 da manhã enquanto a máquina que assina os certificados está desligada numa gaveta. Um cliente que valida o certificado do servidor nunca contacta a sua CA, por isso a CA não precisa de estar acessível para nenhuma ligação. A parte que exige planeamento é o dia em que um certificado tem de ser emitido, renovado ou revogado enquanto a chave raiz permanece trancada.
O que uma ligação valida realmente
Quando o cliente OpenVPN se liga, percorre a cadeia de assinaturas desde o certificado folha do servidor até um certificado de CA em que já confia, verifica a janela de validade e, se o perfil o indicar, consulta uma lista de revogação. Nunca procura a sua CA raiz. O servidor faz a imagem espelhada para os certificados de cliente. No momento da ligação só estão presentes a folha, o intermediário e o pacote de confiança que distribuiu antes.
O que falha realmente é uma de três coisas: a chave de assinatura não está disponível na emissão, uma lista de revogação ficou obsoleta ou o pacote de confiança do cliente é mais antigo do que a cadeia apresentada pelo servidor. A primeira é um problema de processo; as outras duas são problemas de distribuição. Nenhuma delas exige que a chave raiz esteja online, e um serviço VPN gerido que exige um certificado privado para a autenticação do túnel apenas transfere a autoridade de assinatura para o fornecedor. O Azure ponto-a-site funciona ao contrário: carrega um certificado raiz e os certificados assinados abaixo dele são considerados fidedignos, por isso pergunte quem assina, quem valida e como um certificado é retirado antecipadamente.
Construa a raiz num anfitrião que nunca recebe um endereço
Uma raiz offline usa-se raramente: para assinar o certificado da CA intermediária e, mais tarde, para o renovar ou revogar. Tudo o resto acontece um nível abaixo. Faça o trabalho da raiz numa máquina mantida fora da rede, se possível a partir de um sistema vivo, e registe quem estava na sala. Os comandos presumem OpenSSL 1.1.1 ou posterior, porque -addext não existe em compilações antigas.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
-subj "/CN=Example VPN Root CA" -out root.crt \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
Crie a intermediária no anfitrião de assinatura e leve apenas o pedido para a máquina offline. A raiz assina esse pedido com comprimento de caminho zero, pelo que a CA intermediária pode assinar certificados de ponto final mas não pode criar outra CA abaixo de si. Essa única extensão impede que um anfitrião de assinatura comprometido crie uma autoridade equivalente à raiz. Use ECDSA apenas se todos os clientes executarem OpenVPN 2.4 ou posterior; caso contrário, gere chaves RSA e mantenha o fluxo idêntico.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
-CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt
intermediate.ext contém basicConstraints=critical,CA:TRUE,pathlen:0, keyUsage=critical,keyCertSign,cRLSign e authorityKeyIdentifier=keyid:always. Devolva a chave raiz ao cofre antes de reconectar o anfitrião de assinatura. Se a raiz tiver de poder revogar a intermediária, assine-a com openssl ca -config root.cnf -extensions intermediate_ca contra um index.txt de nível raiz em vez de openssl x509 -req, para que o número de série fique registado; depois envie a lista raiz resultante dentro do perfil do cliente, onde um crl-verify baseado em ficheiro a lê no arranque. Envie aos clientes um pacote com os dois certificados de CA; uma folha sozinha não será validada contra a raiz.
Emita folhas a partir da intermediária, com uma base de dados
Assinar com openssl x509 -req funciona até precisar de revogar, porque nada registra o número de série. Use openssl ca desde o primeiro certificado para que o número de série, a validade e o estado de revogação vivam numa única base de dados. Crie os ficheiros da base de dados uma vez e depois aponte ali a configuração:
mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com
A linha de uso de chave pressupõe uma chave ECDSA; acrescente keyEncipherment para RSA. Dê a cada cliente o seu próprio nome comum, porque OpenVPN identifica uma ligação por esse campo, e dois portáteis que partilhem CN=vpn-client não se distinguem nos registos, nas regras de client-config-dir nem em qualquer envio por utilizador, e perde a atribuição que torna uma decisão de revogação defensável. Emita e valide uma folha assim:
openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt
Mantenha a chave de assinatura atrás de uma fronteira de política em vez de a copiar para o anfitrião VPN: um serviço pequeno que autentica o pedido, verifica o nome comum contra uma lista de permitidos e devolve apenas o certificado. Registe cada número de série; o registo é a única ligação entre um certificado e a pessoa que o pediu.
Publique a revogação sem acordar a raiz
Os certificados de cliente são revogados pela intermediária, nunca pela raiz. A lista raiz só importa quando uma intermediária é queimada. Aponte o servidor à lista intermediária com crl-verify. Uma CRL baseada em ficheiro é carregada no arranque do serviço, por isso recarregue-a após cada regeneração; a forma de diretório lê o estado no momento da ligação e custa um ficheiro por número de série.
Revoque e regenere com dois comandos da mesma base de dados:
openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem
Depois vigie o relógio. Uma CRL transporta um campo de próxima atualização, e quando essa data passa, um par que valida rejeita a lista em vez de a ignorar. Regenerar mensalmente com default_crl_days = 30 deixa margem; anualmente não. Tempos de vida de folha mais curtos são o controlo mais fiável, porque a revogação só se aplica onde a lista é consultada.
Teste a cadeia e depois escreva a cerimónia
Reproduza quatro falhas antes de confiar no desenho. Valide a cadeia com openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt. Ligue-se com um certificado de cliente expirado e confirme que o servidor o rejeita. Revoque um cliente de teste, recarregue e confirme que a lista produz efeito. Avance o relógio de um anfitrião num dia, porque um relógio errado pode emitir e rejeitar certificados que parecem válidos noutro lugar.
Uma raiz offline só é um controlo se existir o papel: duas pessoas nomeadas para a cerimónia, um registo de cada número de série assinado, uma cópia de segurança cifrada guardada à parte da máquina e um teste de restauro num anfitrião isolado. Assine uma intermediária de reserva durante a mesma cerimónia para que um anfitrião de assinatura morto não o obrigue a desbloquear a raiz à meia-noite.
Antes de o dar por terminado, confirme cinco coisas: a chave raiz não está num anfitrião em rede, a chave intermediária só vive no anfitrião de assinatura, o pacote do cliente transporta os dois certificados de CA, a CRL tem uma próxima atualização futura e alguém possui uma entrada de calendário para cada validade da cadeia. Se faltar uma, a configuração que parece offline está apenas indocumentada.