Writing your Certbot Plugin for Let’s Encrypt

Dilan Tharaka
4 min readJul 15, 2019

--

Image by Gerd Altmann from Pixabay

You may have used Let’s Encrypt to enable HTTPS on your website. Let’s Encrypt is a free and open Certificate Authority. You can generate an SSL certificate for free from Let’s Encrypt.

Certbot is a tool to obtain certificates from Let’s Encrypt. It comes with several plugins to simplify the certificate generation and installation process. Among those plugins, Apache, Nginx, Manual are popular ones. if you are using an Apache server, you can use Apache plugin to generate and install certificates into an Apache server. And other plugins are for their relevant web server or hosting platform. But what if your hosting solution doesn’t have a supporting plugin. Then obviously you have to go with the Manual plugin.

Using The Manual plugin you can download the certificate to your PC and then install them manually. The manual plugin provides a challenge to the user to prove that he owns that domain. Those challenges are HTTP or DNS challenge.

The HTTP challenge will ask you to place a file with a specific name and specific content in the directory /.well-known/acme-challenge/ directory. When using the DNS challenge, Certbot will ask you to place a TXT DNS record with specific contents under the domain name consisting of the hostname for which you want a certificate issued. If you pass any of the challenges, then Certbot would generate certificates on a local folder of your PC.

Usually, Let’s Encrypt certificates are expiring after 3 months. Suppose you have multiple domain names which use Let’s Encrypt to enable HTTPS. Then you have to do the above process every three months multiple times.

In my workplace, we were using Kubernetes on Oracle Cloud where there’s no standard plugin to generate certificates. Then I decided to write my Certbot plugin.

Let’s start writing our Certbot plugin

Step 1

Fork and clone Certbot repo — https://github.com/certbot/certbot

Step 2

We can install dependencies and setup virtual environment using following commands (this works only in Linux environments. If you are using Windows, use the Ubuntu app or Docker. And I’m using Python version 2.7)

cd certbot
./certbot-auto --debug --os-packages-only
python tools/venv.py

Then, to activate virtual environment use following command,

. venv/bin/activate

Step 3

In /examples/plugins/ directory of the project they have provided an example plugin. This is a good starting point for our new plugin.

This example plugin is ready to install and run. To test if everything is good we can install this plugin.

Run the following command to install our plugin,

pip install -e examples/plugins/

Then, you can check whether the plugin is properly installed using the following command,

certbot plugins

If everything went okay, you can see new plugin in the console,

Step 4

Now we can start the development of our plugin. Before that, we need to get a brief idea of the plugin architecture of Certbot.

In a Certbot plugin, there are two parts

  • Authenticator — Solve challenges and obtain certificates
  • Installer — Install obtained certificates in the server

Any Certbot plugin can have one or both of these parts. For simplicity, I’m considering only the Authenticator. Which means our plugin is only capable of obtaining certificates. It can’t install them on a server.

In /example/plugins/certbot_example_plugins.py the file you can see an example Authenticator and Installer.

The class Authenticator is implemented from IAuthenticator. What you have to do is implementing IAuthenticator class methods in your Authenticator.

Most important methods are,

  • Prepare — Prepare your plugin. Do any additional installation or configurations if you need to
  • Perform — Perform the given challenge
  • Cleanup — Cleaning up stuff. Revert any changes you did and do any cleaning stuff

prepare and cleanup is easy to understand and easy to implement. Complex one is the performmethod.

Perform method has a parameter called ‘achalls’. These are the challenges given to your plugin. These are subclasses of KeyAuthorizationChallenge class. ( Eg: DNS01, HTTP01 .. )

As an example, HTTP01 challenge is to create a file on the server with specific content and make it available on a given URL (this is the Http challenge I described in the beginning). Let’s think our plugin supports only the HTTP01 challenge. Then our preform function would look something like following,

In the above code using get_chall_pref function, we can specify what challenges our plugin supports.

Above code shows how to get command-line arguments to your plugin. The code adds server-url parameter to your plugin and using it in the perform function.

Step 5

If everything is fine. Then as step 2, you can install your plugin. You can run your plugin using below command,

certbot certonly --authenticator certbot-example-plugins:example_authenticator —-certbot-example-plugins:example_authenticator-server-url myserver.com -d mydomain.com

Later, if your plugin works fine, you can create a PyPI package and add it to PyPI repository to allow others to install it via PIP and use it.

Following is a GitHub repository of a plugin I developed to generate certificates for Oracle Cloud Kubernetes.

Following is the PyPI URL of the plugin,

When you’re developing your plugin, if you meet with a difficulty, feel free to leave a comment 😃

--

--

Dilan Tharaka
Dilan Tharaka

Written by Dilan Tharaka

Software engineer curious about how things actually work

Responses (1)