Como determinar a data de validade do certificado SSL a partir de um certificado codificado PEM?

327

Se eu tiver o arquivo real e um shell Bash no Mac ou Linux, como posso consultar o arquivo cert para saber quando ele expirará? Não é um site, mas, na verdade, o próprio arquivo de certificado, assumindo que eu tenho os arquivos csr, key, pem e chain.

GL2014
fonte

Respostas:

630

Com openssl:

openssl x509 -enddate -noout -in file.pem

A saída está no formulário:

notAfter=Nov  3 22:23:50 2014 GMT

Consulte também a resposta do MikeW para saber como verificar facilmente se o certificado expirou ou não, ou se dentro de um determinado período de tempo, sem precisar analisar a data acima.

aquele outro cara
fonte
19
Você também tem as opções -startdatee -enddateincorporadas ao x509utilitário. Eles vão te salvar grep.
JWW
2
isso também funciona se o arquivo não estiver no formato pem. funciona bem para server.crt
procure
163

Se você quiser apenas saber se o certificado expirou (ou o fará nos próximos N segundos), a -checkend <seconds>opção para openssl x509informar:

if openssl x509 -checkend 86400 -noout -in file.pem
then
  echo "Certificate is good for another day!"
else
  echo "Certificate has expired or will do so within 24 hours!"
  echo "(or is invalid/not found)"
fi

Isso economiza a necessidade de fazer comparações de data / hora.

opensslretornará um código de saída de 0(zero) se o certificado não tiver expirado e não o fará pelos próximos 86400 segundos, no exemplo acima. Se o certificado expirou ou já o fez - ou algum outro erro como um arquivo inválido / inexistente - o código de retorno é 1.

(Obviamente, assume que a hora / data está definida corretamente)

MikeW
fonte
8
Para determinar se um certificado expirou no momento, use uma duração de zero segundos. Omita a -nooutopção de ver uma mensagem útil usando um único comando sem lógica extra. Por exemplo, openssl x509 -checkend 0 -in file.pemfornecerá a saída "O certificado expirará" ou "O certificado não expirará" indicando se o certificado expirará em zero segundos.
LS
1
Obrigado! Isso é exatamente o que eu precisava! Com os códigos de saída, será um programa muito menor / mais limpo.
Lon Kaut
24

Aqui está minha linha de comando do bash para listar vários certificados em ordem de vencimento, vencendo mais recentemente primeiro.

for pem in /etc/ssl/certs/*.pem; do 
   printf '%s: %s\n' \
      "$(date --date="$(openssl x509 -enddate -noout -in "$pem"|cut -d= -f 2)" --iso-8601)" \
      "$pem"
done | sort

Saída de amostra:

2015-12-16: /etc/ssl/certs/Staat_der_Nederlanden_Root_CA.pem
2016-03-22: /etc/ssl/certs/CA_Disig.pem
2016-08-14: /etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_S.pem
Nicholas Sushkin
fonte
Muito agradável! Era isso que eu procurava. Agora tenho uma visão geral dos certificados que preciso renovar em breve. Salvei como checkcerts.sh na minha pasta pessoal para que eu possa ver regularmente. A próxima coisa seria ter um trabalho CRON para verificar todos os meses e enviar por e-mail os certificados que precisam de renovação.
Pete
3
Muito útil obrigado. Eu uso esse cronjob0 7 * * 1 /path/to/cert.sh | mail -s "certbot" [email protected]
Matthieu
10

Aqui está uma função bash que verifica todos os seus servidores, supondo que você esteja usando o round-robin do DNS. Observe que isso requer data GNU e não funcionará no Mac OS

function check_certs () {
  if [ -z "$1" ]
  then
    echo "domain name missing"
    exit 1
  fi
  name="$1"
  shift

  now_epoch=$( date +%s )

  dig +noall +answer $name | while read _ _ _ _ ip;
  do
    echo -n "$ip:"
    expiry_date=$( echo | openssl s_client -showcerts -servername $name -connect $ip:443 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2 )
    echo -n " $expiry_date";
    expiry_epoch=$( date -d "$expiry_date" +%s )
    expiry_days="$(( ($expiry_epoch - $now_epoch) / (3600 * 24) ))"
    echo "    $expiry_days days"
  done
}

Exemplo de saída:

$ check_certs stackoverflow.com
151.101.1.69: Aug 14 12:00:00 2019 GMT    603 days
151.101.65.69: Aug 14 12:00:00 2019 GMT    603 days
151.101.129.69: Aug 14 12:00:00 2019 GMT    603 days
151.101.193.69: Aug 14 12:00:00 2019 GMT    603 days
Andrew
fonte
surpreendentemente OSX 10.13.4 executa o shell OK (não me julgue Sou apenas no OSX hoje para empurrar um app para app store ... a inicialização de volta para linux pouco ;-)
Scott Stensland
1
@ScottStensland Estamos julgando :-P. Eu uso muito o Mac, mas o Linux é realmente muito melhor.
Mike Q
Muito obrigado por esse trecho de código! Que tarefa chata :), eu gostaria que houvesse um sinalizador de data e hora unixtime para openssl.
user1279741
1
Para aqueles em um contêiner de linux alpino, seu expiry_datevalor precisará ter o nome do fuso horário removido do final dele. Adicione um adicional cutao final do pipe para fazer isso:| cut -d ' ' -f 1-4
Droogans
5

Uma linha verificando verdadeiro / falso se o certificado do domínio expirará algum tempo depois (ex. 15 dias):

if openssl x509 -checkend $(( 24*3600*15 )) -noout -in <(openssl s_client -showcerts -connect may.domain.com:443 </dev/null 2>/dev/null | openssl x509 -outform PEM)
then
  echo 'good'
else
  echo 'bad'
fi
Alexey
fonte
2

Para MAC OSX (El Capitan) Essa modificação do exemplo de Nicholas funcionou para mim.

for pem in /path/to/certs/*.pem; do
    printf '%s: %s\n' \
        "$(date -jf "%b %e %H:%M:%S %Y %Z" "$(openssl x509 -enddate -noout -in "$pem"|cut -d= -f 2)" +"%Y-%m-%d")" \
    "$pem";
done | sort

Saída de amostra:

2014-12-19: /path/to/certs/MDM_Certificate.pem
2015-11-13: /path/to/certs/MDM_AirWatch_Certificate.pem

O macOS não gostou das bandeiras --date=ou --iso-8601no meu sistema.

Donald.M
fonte
Como você faria isso se não tivesse criado os arquivos .pem, mas tinha apenas .ceralguns documentos que acabou de criar e fazer download no site Apple Dev?
Alex Zavatone
1

O mesmo que a resposta aceita, mas observe que ele funciona mesmo com o .crtarquivo e não apenas com o .pemarquivo, caso você não consiga encontrar .pemo local do arquivo.

openssl x509 -enddate -noout -in e71c8ea7fa97ad6c.crt

Resultado:

notAfter=Mar 29 06:15:00 2020 GMT
Srihari Karanth
fonte
0

Se (por algum motivo) você quiser usar um aplicativo GUI no Linux, use gcr-viewer(na maioria das distribuições ele é instalado pelo pacote gcr(caso contrário, no pacote gcr-viewer))

gcr-viewer file.pem
# or
gcr-viewer file.crt
Attila123
fonte