~/.eth0/ 

This is my code. There is a lot like it, but this is mine.

Certificate renewal script for Let's Encrypt in PythonAnywhere

/pythonanywhere/renew-letsencrypt.sh

Well, this script is now not needed, since PythonAnywhere finally added an option to the SSL settings to create and autorenew Let’s Encrypt certificates. However, this script still could be useful for something else.

This script performs the renewal of Let’s Encrypt certificates for PythonAnywhere webapps, as outlined in their knowledge base article.

You need to read the linked article to set everything up, but after that you can just use this script in a periodic task and it’ll take care of automatically renewing the certificate when its expiration date is closer than 30 days and send the corresponding email message to the PythonAnywhere staff to update the certificate.

There’s one more step that’s not referenced in the knowledge base article. Since the script must send an email message to the staff, you must set up a config file in your home directory with your GMail account details, since that’s the only SMTP server reachable from the PythonAnywhere servers.

Just create the file ~/.ssmtprc and fill the details:

root=your-address@example.com
mailhub=smtp.gmail.com:587
AuthUser=your-address@example.com
AuthPass=your_application_specific_password
UseSTARTTLS=YES

It’s highly advisable to use an application-specific password here instead of your account password, since it can be revoked at any time.

Download this script
Secondary click/Save as…

View license file

#!/usr/bin/env bash
#
# renew-letsencrypt.sh
# Copyright 2018-2019 eth0 <ethernet.zero@gmail.com>
# 
# This work is free. You can redistribute it and/or modify it under the terms of
# the ISC License. See the COPYING file for more details.
#

mail_from=your-email@example.com
mail_to=support@pythonanywhere.com

domain="$1"

expiration="$(date -d "$(openssl x509 -enddate -noout -in "${HOME}/letsencrypt/certs/${domain}/cert.pem" | cut -d= -f2)" +'%s')"
threshold="$(date -d '+30 days' +'%s')"

(( threshold < expiration )) && exit 0

~/dehydrated/dehydrated \
	--cron \
	--config "${HOME}/letsencrypt/config/${domain}.conf" \
	--domain "$domain" \
	--out "${HOME}/letsencrypt/certs" \
	--challenge http-01

if (($? == 0)); then
	ssmtp -C ~/.ssmtprc "${mail_to}" <<-EOF
	From: ${mail_from}
	Subject: Please update the SSL certificate for ${domain}

	Hi!

	Could you please update the SSL certificate for my webapp?

	This is the data you need:

	    User name: ${USER}
	    Domain: ${domain}
	    Path to certificates: ${HOME}/letsencrypt/certs/${domain}
	EOF
fi