today, I'll show you how to use certbot and a small python script I wrote to receive the newly created certificates as email attachments.
Why
A few weeks ago, a webserver certificate expired. This is usually not a problem, as certbot takes care of it. If certbot fails, we also receive information about our existing icinga monitoring. We also monitor the HTTP status, but this page was not covered by this check. However, in this case, things were a little different. The web application provided was protected by a WAF (Web Application Firewall).
My first thought was a script that uses az Shell to exchange the corresponding certificate on the WAF as well. Unfortunately, the WAF is not within my scope. This resulted in the script provided here.
the script
# certmail Version 1.0 by ♞ Raffael.Willems@scheer-group.com
# This Script send the new Cert to imc Hosting Team for WAF Update.
# It can be full automated with az Shell but is not wished by imc hosting.
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.application import MIMEApplication
mxlist = [
['MTA', 'user', 'password']
]
for record in mxlist:
print(" Send Message over: " + record[0])
msg = MIMEMultipart('related')
msg['Subject'] = "Certificate Update on Server"
msg['From'] = record[1]
msg['To'] = "someone@somewhere.com"
html = """\
<html>
<head></head>
<body>
<p><center><h4 style="font-size:15px;"> Certificate Update!</h4></center></p>
The Certificate on Server has been updated with certbot. Please update the WAF Certificate with the attached Certificate Chain and Key! </br></br>Thank you</br></br></br>
<hr>
<table border="0">
<tr>
<td><img src="cid:Emma" alt="Logo" style="width:90px;height:90px;"></td>
<td valign="top">
Contact: Raffael.Willems@scheer-group.com</br>
Adress: Uni-Campus Nord, 66123 Saarbrücken, Germany</br>
Phone: +49 162 4197862</br>
Web: <a href="https://www.willifix.net">willifix.net</a>
</td>
</body>
</head>
</html>
"""
part2 = MIMEText(html, 'html')
msg.attach(part2)
fp = open('/usr/local/bin/commanderkeen.gif', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', '<Emma>')
msg.attach(msgImage)
fp = open('/etc/letsencrypt/live/server/fullchain.pem')
filename = os.path.basename(fp.name)
msgcert = MIMEApplication(fp.read())
fp.close()
msgcert.add_header(
"Content-Disposition",
"attachment",
filename=filename,
Content_Type="application/x-pem-file",
Content_Disposition=f"attachment; filename={filename}",
)
msg.attach(msgcert)
fp = open('/etc/letsencrypt/live/server/privkey.pem')
filename = os.path.basename(fp.name)
msgcertkey = MIMEApplication(fp.read())
fp.close()
msgcertkey.add_header(
"Content-Disposition",
"attachment",
filename=filename,
Content_Type="application/x-pem-file",
Content_Disposition=f"attachment; filename={filename}",
)
msg.attach(msgcertkey)
server = smtplib.SMTP(record[0], 587)
server.starttls()
server.login(record[1], record[2])
server.send_message(msg)
server.quit()