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()

howto install

curl -fssl https://willifix.net/blog/send-email-with-new-cert-when-certbot-has-runned/certmail.txt > /usr/local/bin/certmail.py
echo -n "python3 /usr/local/bin/certmail.py" >/usr/local/bin/certmail && chmod o+x /usr/local/bin/certmail

dont forget to change the mxlist and paths in the Script (highlighted lines)

configure certbot
per certificate

add the post_hook parameter in the respective configuration file for the renewal. the configuration files are located in /etc/letsencrypt/renewal

add the following line:

 # configuration for automailing the new cert by ♞ Raffael.Willems@scheer-group.com
  post_hook = /usr/local/bin/certmail
Global Configuration

it is also possible to add a global hook for all created certificates. this can be done in /etc/letsencrypt/cli.ini

add the following line:

  # configuration for automailing the new cert by ♞ Raffael.Willems@scheer-group.com
  post-hook = /usr/local/bin/certmail

please note that the parameters in conf and cli differ. post_hook is used for conf files and post-hook for cli files

Previous Post