Package: certbot-py
Current Status: Very Alpha, Proof of ConceptUse at your own peril, until there’s some shakedown.OverviewThis library is a wrapper around thecertbot/certbot-autocommand line tool operatingcertonlyin manual, non-interactive
mode. It does this via Python’ssubprocess.Popen().This allows Python developers to automate the creation of certificates
in a web app (ie. Flask or Django). Let’s Encrypt’s certificate
generation process, simplified:certbotsends a certificate request for a domain (or multiple
domains in the case of SAN/UCC)Let’s Encrypt responds with validation instructions for each
requested domainFor each set of validation instructions, << developer/operations team
member needs to manually perform some action - DNS record addition or
web server file creation >>Let’s Encrypt attempts to validate each domainUpon successful validation, a certificate is provided (either single
domain or SAN/UCC)Step 3 is where this library allows the developer to customize andautomatetheir process of setting up validation (seeauth_scriptbelow). This library currently only supports web server validation (ie
http-01).An example scenario where this library becomes useful: > You have a
blogging platform (ie. blog-platform.io) where your customers can sign
up and create their own blog (ie. customer1.blog-platform.io). > >The
Customer would like to host their new blog on their own sub-domain (ie.
blog.customer-site.com) for SEO purposes - obviously they want to make
sure it’s HTTPS enabled. They can easily do this by adding a CNAME from
blog.customer-site.com to customer1.blog-platform.io. > > So your
blogging platform needs to automatically provision HTTPS certificates as
your customers create new blogs and set up CNAMEs for them.certbot_pyto the rescue.Please note that there isNOmechanism for renewal included;using
``certbot renew`via a cron job is the recommended
way <https://certbot.eff.org/docs/using.html#renewing-certificates>`__.InstallationYou must installcertbotorcertbot-autoas you will need to
specify the full path to it. It does all the heavy lifting.The user running your Python project code must have access to runsudo certbotorsudocertbot-autowithout a password, which
is largely dependent on how you configure yourgunicorn,uwsgi, etc to run (if in a web environment).This likely means runningsudo visudoor adding an entry to/etc/sudoers.d/.For security, it is highly recommended to only allow ``sudo``
access to just the one command (``certbot`` or
``certbot-auto``).Register an account with Let’s Encrypt’s servers (if you haven’t
already). Note thatcertbot_py(this library) defaults to using
Let’s Encrypt staging servers, whilecertbotandcertbot-autodefault to production servers. An example of registration for staging
servers:certbot register--staging# ORcertbot-autoregister--stagingIn your Python project’s virtual environment, installcertbot_py:pip install certbot_pyUsageEnsure you register an account with Let’s Encrypt, as mentioned above.There is a singlegenerate_certificatemethod which requires 3
parameters:domains,certbot_command, andauth_script. There
are many other optional parameters which mostly map to correspondingcertbotarguments.from certbot_py import client

command = '/my/path/to/certbot'
script = '/my/other/path/to/auth-hook-script.sh'
my_domains = ['example1.com', 'example2.com', 'example3.com']
results = client.generate_certificate(
    domains=my_domains,
    certbot_command=command,
    auth_script=script
)If you wanted to generate a SAN (ie. UCC) certificate instead, usesan_ucc=True. As withcertbot, the first domain indomainswill be the common name listed on the resulting cert.results = client.generate_certificate(
    domains=my_domains,
    certbot_command=command,
    auth_script=script,
    san_ucc=True
)There are many more options, most of the pertinent ones are listed
below. Skip further down for more information onauth_script.Option ListFull list ofgenerate_certificateparameters (order is unimportant
as they must be passed as keyword arguments):account = None
allow_domain_subset = False
allow_self_upgrade = False
auth_script = None
certbot_command = None
domains = None
hsts = False
must_staple = False
production = False
redirect = False
rsa_key_size = None
san_ucc = False
staple_ocsp = False
uir = FalseThese mostly map tocorresponding ``certbot`arguments <https://certbot.eff.org/docs/using.html#certbot-command-line-options>`__,
with a few exceptions:productionwill enable the live generation of certificates from
Let’s Encrypt’s production servers. By default (and safely),certbot_pyuses staging servers.san_uccindicates that a SAN/UCC certificate is wanted, otherwise
an individual cert will be requested for each domain passed in.certbot_commandis the full path the the installedcertbotorcertbot-autocommand line executable.auth_scriptis the full path to a script which will use thecertbot-provided$CERTBOT_DOMAIN,$CERTBOT_VALIDATION,
and$CERTBOT_TOKENenvironment variables to perform some
developer-specific action (ie. add$CERTBOT_VALIDATIONand$CERTBOT_TOKENto a database) so that the subsequent validation
request from Let’s Encrypt’s servers can succeed.allow_self_upgradewould allow auto-upgrading (certbot-autoonly), which has been disabled by default to prevent breakage due to
tool upgradesExampleauth_script(Django example), just a single bash script:#~/bin/bash
/home/webuser/.virtualenvs/bin/python /home/webuser/my_project/manage.py set_domain_validation "$CERTBOT_DOMAIN" "$CERTBOT_VALIDATION" "$CERTBOT_TOKEN"Command LineThere is a command line alias configured uponpip installthat you
can use to test with. Simply usecertbot_pyon the command line,
full help is available.Notescertbotversion 0.10.0 is the first version to expose the
necessary command line arguments - prior versions will fail.This library should be updated for security and bug fixes (obviously)
but also may require updating if the underlying arguments tocertbotchange or features are added.FutureGee, I should mock in some tests…Longer term, I look forward to having this library change (and improve!)
so that it no longer needs Python’ssubprocess.Popen()or acertbotinstallation. This is technically possible using Let’s
Encrypt’s`acmelibrary <https://github.com/certbot/certbot/tree/master/acme>`__;
however creating a client aroundacmeinvolves much more than
something simple likeacme.generate_certificate(...). Much in this
ACME/Let’s Encrypt world seems in flux at the moment, so implementing
this wrapper felt like the easiest path forward for the time being - and
retains full compatibility with the standard Let’s Encrypt command line
tools.Feedback is encouraged and appreciated.File issues on
Github. Feel free to
fork and suggest improvements.