Temos mais de 700 certificados, gerados para uso OpenVPN pelo Easy-RSA 2. Não sei como isso aconteceu (suspeito de exclusão uma vez por alguém index.txt
, serial
ou ambos), mas mais da metade dos certificados gerados têm números de série idênticos. Além disso, o original index.txt
contém apenas metade de todos os certificados (última metade), sem incluir os anteriores.
Então, novos certificados podem ser feitos, está tudo bem. Mas quando tento revogar um certificado que não está em index.txt
, recebo um erro.
Tentei recriar index.txt
por script:
for cert in *.crt
do
echo "-> $cert"
enddate=`openssl x509 -enddate -noout -in $cert | sed 's/notAfter=//' | awk '\
{ year=$4-2000;
months="JanFebMarAprMayJunJulAugSepOctNovDec" ;
month=1+index(months, $1)/3 ;
day=$2;
hour=substr($3,1,2) ;
minutes=substr($3,4,2);
seconds=substr($3,7,2);
printf "%02d%02d%02d%02d%02d%02dZ", year, month, day, hour, minutes, seconds}'`
serial=`openssl x509 -serial -noout -in $cert |sed 's/serial=//'`
subject=`openssl x509 -subject -noout -in $cert |sed 's/subject= //'`
echo -e "V\t$enddate\t\t$serial\tunknown\t$subject" >>index.txt
done
Ele lê os certificados um por um, obtém seus dados e preenche novos arquivos index.txt
. Tudo parece bem.
Mas, de acordo com o texto superior, o script o preenche por certificados, que possuem números de série iguais. Então, com esse recém-criado index.txt
não posso fazer nada com certificados (criar, revogar, etc...)
A questão é: existe alguma possibilidade de reparar index.txt
a base se eu tiver todos os certificados? Ou, talvez, alterar de alguma forma o número de série de um certificado (uma simples alteração no cabeçalho do *.crt
arquivo não faz nada - a série permanece antiga quando consultada por openssl
)
Caso contrário, só preciso revogar os certificados que não estão em index.txt
, posso fazer isso sem index.txt
base?
Responder1
Temos mais de 700 certificados... mais da metade dos certificados gerados possuem número de série idêntico... o index.txt original contém apenas metade de todos os certificados (última metade), sem incluir os anteriores.
Vou tentar apontar a direção certa, mas provavelmente não conseguirei levar isso até o fim porque não configurei um equipamento de teste e dupliquei o problema. Minhas desculpas antecipadamente.
Se você quiser uma visão geral de nível superior sobre a emissão de um certificado em uma PKI privada, consulteComo você assina a Solicitação de Assinatura de Certificado com sua Autoridade de Certificação?Explica como você faria as coisas manualmente se o Easy-RSA não estivesse fazendo isso por você.
Outro documento importante éRFC 4158, Infraestrutura de Chave Pública Internet X.509: Construção do Caminho de Certificação. Isso é__o__documento que explica o que são correspondências e como você pode usar tuplas como {Issuer Distinguished Name,Serial Number}
ou {Subject Distinguished Name,Public Key Identifier}
para comparar dois certificados quanto à equivalência. OpenSSL usa este documento para correspondência. Consulte também a Seção 3.5.15,"Correspondência de nome distinto (DN) do endpoint"e Seção 3.5.12,"Identificadores de chave correspondentes (KIDs)".
Os números de série devem ser exclusivos. Este é o problema a superar.Nomes Distintos do Assunto (DN)são uma história diferente. Se o seu openssl.cnf
tiver unique_subject=yes
, eles não poderão ser duplicados. Se unique_subject=no
, os DNs poderão ser duplicados.
Acho que você precisa fazer algumas coisas. Primeiro, use uma versão moderna ou atualizada dos utilitários OpenSSL. Aqui, "moderno" significa um dos 1.0.2 ou 1.1.0 posteriores. As versões anteriores do utilitário apresentavam problemas sutis na correspondência de nomes e números de série.
Segundo, examine seu arquivo de configuração (normalmente, openssl.cnf
mas você pode usar um arquivo diferente, talvez copiado, com -config filename
) e anote as configurações relevantes, como serial.txt
e unique_subject=no
. Acredito que estes sejam os relevantes [CA_Default]
de openssl.cnf
:
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number
unique_subject = no # Allow reuse of subjects
Terceiro, faça backup de tudo, especialmente das coisas importantes como index.txt
e serial.txt
.
Quarto, crie uma lista dos certificados que deseja revogar. A lista pode ter entradas como nomes de arquivos - john-doe-vpn.pem
. Mova-os para sua própria pasta, se desejar. De preferência, cada um deve ter um número de série exclusivo e todos DEVEM ter o mesmo nome de Emissor; as funções openssl ca
e ocsp
não podem lidar com mais de um Emissor por vez, embora para OCSP o protocolo pudesse.
Quinto, crie um novo index.txt
contendo uma linha para cada serial. Uma abordagem é extrair o assunto, a série e a expiração de cada arquivo de certificado como no script que você postou, embora você possa agrupar a maior parte do trabalho do shell em um openssl e um awk por certificado:
for f in *files*; do
openssl x509 -noout -enddate -serial -subject -in $f \
| awk 'BEGIN{FS="=";OFS="\t"} /^serial/{num=$2} /^subject/{sub=$2}
/^notAfter/{split($2,a,/ /);mon=index(months,a[1])/3+1;day=a[2]...exp=sprintf(...)}
END{print "V",exp,"",num,sub}' >>index.txt
done
Se for difícil remover (de forma confiável) números de série duplicados com antecedência, você pode colocar tudo e descartar duplicatas com awk -F'\t' '!already[$4]++'
ou sort -t$'\t' -k4,4 -u
similar.
Outra abordagem disponível na versão 1.0.2, mas documentada apenas na versão 1.1.0, é usar openssl ca [-config conffile] -valid certfile
para fazer essa extração automaticamente. Mas -valid
carrega desnecessariamente a chave privada da CA todas as vezes, portanto, se sua chave privada estiver criptografada por senha, como é uma boa prática, isso significará digitar sua senha repetidamente; para economizar tempo, substitua temporariamente a chave CA real e o certificado por uma chave não criptografada e um certificado correspondente, mas falso (provavelmente autoassinado). -valid
não escreverá uma entrada serial duplicada, então você não precisa se preocupar em excluí-las ou removê-las.
Coloque no serial
arquivo um valor que sejapelo menoso valor mais alto de qualquer certificado emitido anteriormente; se você quiser pular para o próximo 10000
ou 1000000
o que quer que seja para ficar seguro e talvez também mais claro, tudo bem. Você pode precisar definir unique_subject=no
neste ponto.
Sexto, marque cada certificado (série) no index
arquivo como revogado. Você pode percorrer os arquivos cert usando openssl ca -revoke
cada um, mas é mais fácil usar o awk como:
awk -F'\t' -vOFS='\t' '{$1="R"; $3="161101000000Z"}' <index.txt >temp && mv temp index.txt
# if you want, you can add a comma and a reason, see man ca or
# online at https://www.openssl.org/docs/manmaster/man1/ca.html
# under -crl_reason. But there isn't a code for 'CA stupid', and
# in practice the reason doesn't really matter to reliers except
# you should't use hold or remove (latter noted in the man)
Sétimo, gere uma CRL a partir disso index
e openssl ca -gencrl [-crldays n] [-out file]
/ou configure um respondedor OCSP usando-o se (qualquer um dos) certificados antigos especificasse a extensão OCSP.
Oitavo, depois de distribuir a CRL e/ou começar a executar o (novo) respondedor OCSP,todoscertificados com as séries afetadas são revogados e causarão falha na comunicação se usados (e verificados corretamente). Sequalquerdos números de série duplicados estão em certificados que seus sistemas ainda estão usando, eles devem ser substituídos primeiro. Se você ainda tiver os arquivos de solicitação (CSRs) dos sistemas que usam os certificados afetados, basta reemitir openssl ca [-config conffile] [-in reqfile | -infiles reqfile...]
e enviar os novos certificados aos sistemas em questão e fazer com que os operadores desses sistemas os instalem. Caso contrário, você precisa primeiro fazer com que o operador de cada sistema lhe envie um CSR, que pode ser aquele que ele usou anteriormente (e salvou) ou um novo que ele gerou.
Finalmente, restaure quaisquer entradas 'boas' (números de série que você não revogou) do index
arquivo antigo, combinando com quaisquer novas entradas para certificados de substituição emitidos no item 8 acima. Se estiver executando um respondente OCSP (veja acima), você também deverá manter as entradas revogadas; não, não importa, mas provavelmente é mais fácil. Fazernãorestaurar o valor antigo para serial
se for menor que o certificado antigo mais altoouo novo certificado de substituição mais alto, em vez disso, deixe-o continuar a incrementar a partir do novo valor.
Em relação às for-loop
datas de impressão:
hour=substr($3,1,2) ;
minutes=substr($3,4,2);
seconds=substr($3,7,2);
printf "%02d%02d%02d%02d%02d%02dZ", year, month, day, hour, minutes, seconds}'`
Nem se preocupe com as datas. Se expirarem, não poderão ser usados se sua PKI estiver funcionando corretamente. Se isso faz você se sentir melhor, exclua a chave privada associada ao certificado e à chave pública.
Tudo o que importa é a lista de certificados a serem revogados, seu número de série e nome distinto. Aqui, sua lista seria composta por certificados como (1) funcionário que está saindo e que possui um certificado não expirado e uma chave privada (ou seja, o funcionário está se aposentando ou foi demitido); (2) um funcionário que perdeu um dispositivo (ou seja, a chave privada está à solta); etc.
Outra opção que você tem... Queime a PKI existente e comece de novo. Nesse caso, a etapa (1) é revogar a CA raiz e todas as CAs intermediárias/subordinadas. Então, jogue fora a chave privada. A etapa (2) é criar uma nova CA raiz, emitir novas CAs intermediárias/subordinadas e, finalmente, emitir novos certificados de entidade final. Para a etapa (2), você pode até fazer a dança da festa de autógrafos.
Acredite ou não, o OpenStack usa essa estratégia (ou estava pensando em usá-la). É uma espécie de “PKI efêmera” que deve durar tempo suficiente para atender às suas necessidades; e então ser descartado quando as coisas dão errado.
Para rir, você pode querer dar uma olhada no livro de Peter GutmannSegurança de Engenharia. Ele é implacável quando se trata de PKIs e CAs públicas.