Dans le domaine où le certificat est automatiquement renouvelé par Let's Encrypt, si vous suivez le manuel, le certificat SSL doit être renouvelé au moment de moins de 30 jours avec le paramètre par défaut, mais le renouvellement est effectué. Je l'ai implémenté dans un script car j'avais besoin de vérifier si c'était le cas. En fait, ce qui suit est opéré en alimentant le fichier de configuration de la liste de domaines à vérifier, mais comme il n'y avait pas beaucoup d'explications sur la bibliothèque M2Crypto utilisée pour l'implémentation, je vais la transcrire en incluant l'enregistrement de l'opération réelle. .. J'aimerais pouvoir l'implémenter avec urllib, ce à quoi je suis habitué, mais je ne savais pas comment vérifier le certificat SSL, j'ai donc utilisé la bibliothèque M2Crypto.
Un environnement python3 a été créé en utilisant Pyenv comme celui-ci.
pwd
/root/python3
pyenv versions
system
* 3.5.6 (set by /root/python3/.python-version)
python -V
Python 3.5.6
Nous préparerons ce dont vous avez besoin tout en vérifiant l'état des données, etc. en utilisant le mode interactif interactif.
import ssl
import M2Crypto
import datetime
port = 443
hostname = 'www.qiita.com' # Le domaine est le vôtre.
cert = ssl.get_server_certificate((hostname, port))
x509 = M2Crypto.X509.load_cert_string(cert)
x509.get_subject().as_text() # 'CN=qiita.com'
De ce domaine, je ne sais pas grand-chose car je ne trouve pas beaucoup de documentation, je vais donc continuer en recherchant des méthodes utilisables.
dir(x509)
['__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_ptr', '_pyfree', 'add_ext', 'as_der', 'as_pem',
'as_text', 'check_ca', 'check_purpose', 'get_ext', 'get_ext_at', 'get_ext_count', 'get_fingerprint', 'get_issuer', 'get_not_after',
'get_not_before', 'get_pubkey', 'get_serial_number', 'get_subject', 'get_version', 'm2_x509_free', 'save', 'save_pem', 'set_issuer',
'set_issuer_name', 'set_not_after', 'set_not_before', 'set_pubkey', 'set_serial_number', 'set_subject', 'set_subject_name',
'set_version', 'sign', 'verify', 'x509']
J'ai trouvé get_not_after qui semble utilisable.
type(x509.get_not_after()) # <M2Crypto.ASN1.ASN1_TIME object at 0x7f26999f1940>
dir(x509.get_not_after())
['__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_ptr', '_pyfree', '_ssl_months', 'asn1_time',
'get_datetime', 'm2_asn1_time_free', 'set_datetime', 'set_string', 'set_time']
J'ai trouvé quelque chose appelé get_datetime qui pourrait être généré avec datetime.
type(x509.get_not_after().get_datetime()) # <class 'datetime.datetime'>
x509.get_not_after().get_datetime() # datetime.datetime(2020, 4, 30, 12, 0, tzinfo=<Timezone: UTC>)
Étant donné que les données ont été acquises par datetime, vous pouvez utiliser la bibliothèque datetime pour trouver le timedelta.
exp_date = x509.get_not_after().get_datetime()
now = datetime.datetime.now() # datetime.datetime(2019, 11, 29, 10, 52, 24, 89337)
exp_date - now
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't subtract offset-naive and offset-aware datetimes
Il semble que la soustraction entre datetime ne soit pas possible si les fuseaux horaires sont associés. Référence: Gestion du fuseau horaire Python Donc, j'ai réduit les informations de fuseau horaire et comparé.
remaining_time = exp_date.replace(tzinfo=None) - now # datetime.timedelta(53, 15629, 910663)
remaining_time.days
152
J'ai pu obtenir avec succès les jours restants du certificat SSL.
Le code final est ci-dessous. Il est relativement compact.
import ssl
import M2Crypto
from cryptography import x509
from cryptography.hazmat.backends import default_backend
import datetime
port = 443
hostname = 'www.qiita.com' # Veuillez réécrire comme il convient ou lire l'argument
cert = ssl.get_server_certificate((hostname, port))
x509 = M2Crypto.X509.load_cert_string(cert)
exp_date = x509.get_not_after().get_datetime()
now = datetime.datetime.now()
remaining_time = exp_date.replace(tzinfo=None) - now
print(remaining_time.days)
152
Recommended Posts