Comment déterminer la date d'expiration du certificat SSL à partir d'un certificat codé PEM?

327

Si j'ai le fichier réel et un shell Bash sous Mac ou Linux, comment puis-je interroger le fichier cert pour savoir quand il expirera? Pas un site Web, mais en fait le fichier de certificat lui-même, en supposant que j'ai les fichiers csr, key, pem et chain.

GL2014
la source

Réponses:

630

Avec openssl:

openssl x509 -enddate -noout -in file.pem

La sortie est sur le formulaire:

notAfter=Nov  3 22:23:50 2014 GMT

Voir également la réponse de MikeW pour savoir comment vérifier facilement si le certificat a expiré ou non, ou s'il le sera dans un certain délai, sans avoir à analyser la date ci-dessus.

cet autre gars
la source
19
Vous disposez également des options -startdateet -enddateintégrées à l' x509utilitaire. Ils vous sauveront le grep.
JWW
2
cela fonctionne également si le fichier n'est pas au format pem. fonctionne bien pour server.crt
regardez le
163

Si vous voulez simplement savoir si le certificat a expiré (ou le fera dans les N secondes suivantes), l' -checkend <seconds>option pour openssl x509vous indiquera:

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

Cela vous évite d'avoir à faire vous-même des comparaisons date / heure.

opensslrenverra un code de sortie de 0(zéro) si le certificat n'a pas expiré et ne le fera pas pendant les 86400 secondes suivantes, dans l'exemple ci-dessus. Si le certificat a expiré ou l'a déjà fait - ou une autre erreur comme un fichier invalide / inexistant - le code de retour est 1.

(Bien sûr, cela suppose que l'heure / la date est réglée correctement)

MikeW
la source
8
Pour déterminer si un certificat est actuellement expiré, utilisez une durée de zéro seconde. Omettez l' -nooutoption pour voir un message utile en utilisant une seule commande sans logique supplémentaire. Par exemple, openssl x509 -checkend 0 -in file.pemdonnera la sortie "Le certificat expirera" ou "Le certificat n'expirera pas" indiquant si le certificat expirera dans zéro seconde.
LS
1
Merci! C'est exactement ce dont j'avais besoin! Avec les codes de sortie, cela fera un programme beaucoup plus petit / plus propre.
Lon Kaut
24

Voici ma ligne de commande bash pour répertorier plusieurs certificats par ordre d'expiration, le plus récent expirant en premier.

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

Exemple de sortie:

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
la source
Très agréable! C'est ce que je cherchais. J'ai maintenant un aperçu des certificats que je dois renouveler bientôt. Enregistré sous checkcerts.sh dans mon dossier personnel afin que je puisse le vérifier régulièrement. La prochaine chose serait d'avoir un travail CRON pour vérifier chaque mois et envoyer les certificats qui doivent être renouvelés.
Pete
3
Merci très utile. J'utilise ce cronjob0 7 * * 1 /path/to/cert.sh | mail -s "certbot" [email protected]
Matthieu
10

Voici une fonction bash qui vérifie tous vos serveurs, en supposant que vous utilisez DNS round-robin. Notez que cela nécessite une date GNU et ne fonctionnera pas sur 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
}

Exemple de sortie:

$ 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
la source
étonnamment osx 10.13.4 exécute votre shell OK (ne me jugez pas que je suis uniquement sur osx aujourd'hui pour pousser une application vers l'App Store ... redémarrage sous linux sous peu ;-)
Scott Stensland
1
@ScottStensland Nous jugeons :-P. J'utilise beaucoup Mac mais Linux est vraiment beaucoup mieux.
Mike Q
Merci beaucoup pour cet extrait de code! Quelle tâche ennuyeuse :), je souhaite qu'il y ait un indicateur d'horodatage unixtime pour openssl.
user1279741
1
Pour ceux d'entre vous sur un conteneur Linux alpin, votre expiry_datevaleur devra avoir le nom du fuseau horaire supprimé à la fin de celui-ci. Ajoutez un supplémentaire cutà la fin du tuyau pour ce faire:| cut -d ' ' -f 1-4
Droogans
5

Une ligne vérifiant vrai / faux si le certificat de domaine expirera dans un certain temps plus tard (ex. 15 jours):

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
la source
2

Pour MAC OSX (El Capitan) Cette modification de l'exemple de Nicholas a fonctionné pour moi.

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

Exemple de sortie:

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

macOS n'aimait pas les indicateurs --date=ou --iso-8601sur mon système.

Donald.M
la source
Comment feriez-vous si vous n'aviez pas créé les fichiers .pem, mais que .cervous aviez simplement des certificats que vous venez de créer et de télécharger à partir du site Apple Dev?
Alex Zavatone
1

Identique à la réponse acceptée, mais notez que cela fonctionne même avec un .crtfichier et pas seulement avec un .pemfichier, juste au cas où vous ne pourriez pas trouver l' .pememplacement du fichier.

openssl x509 -enddate -noout -in e71c8ea7fa97ad6c.crt

Résultat:

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

Si (pour une raison quelconque) vous souhaitez utiliser une application graphique sous Linux, utilisez gcr-viewer(dans la plupart des distributions, elle est installée par le package gcr(sinon dans le package gcr-viewer))

gcr-viewer file.pem
# or
gcr-viewer file.crt
Attila123
la source