Question
"""
This module defines a certbot plugin to automate the process of completing a
`dns-01` challenge (`~acme.challenges.DNS01`) by creating, and subsequently
removing, TXT records using the Namecheap API.
"""
import logging
import zope.interface
from certbot import errors, interfaces
from certbot.plugins import dns_common, dns_common_lexicon
from lexicon.providers import namecheap
from requests.exceptions import RequestException
import tldextract
logger = logging.getLogger(__name__)
@zope.interface.implementer(interfaces.IAuthenticator)
@zope.interface.provider(interfaces.IPluginFactory)
class Authenticator(dns_common.DNSAuthenticator):
"""DNS Authenticator for Namecheap
This Authenticator uses the Namecheap API to fulfill a dns-01 challenge.
"""
description = ('Obtain certificates using a DNS TXT record (if you are '
'using Namecheap for DNS).')
def __init__(self, *args, **kwargs):
super(Authenticator, self).__init__(*args, **kwargs)
self.credentials = None
@classmethod
def add_parser_arguments(cls, add):
super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
add('credentials', help='Namecheap credentials INI file.')
def more_info(self):
return ('This plugin configures a DNS TXT record to respond to a '
'dns-01 challenge using the Namecheap API.')
def _setup_credentials(self):
self.credentials = self._configure_credentials(
'credentials',
'namecheap credentials INI file',
{
'api_user': 'Namecheap API user',
'api_key': 'Namecheap API key',
'client_ip': 'Your client IP address',
'username': 'Namecheap username',
}
)
def _perform(self, domain, validation_name, validation):
return self.namecheap_client.add_txt_record(domain, validation_name, validation)
def _cleanup(self, domain, validation_name, validation):
return self.namecheap_client.del_txt_record(domain, validation_name, validation)
@property
def namecheap_client(self):
return _NamecheapLexiconClient(credentials=self.credentials.conf)
class _NamecheapLexiconClient(dns_common_lexicon.LexiconClient):
"""Encapsulates all communication with Namecheap via Lexicon."""
def __init__(self, credentials):
super(_NamecheapLexiconClient, self).__init__()
config = dns_common_lexicon.build_lexicon_config('namecheap', {}, {
'auth_username': credentials('api_user'),
'auth_token': credentials('api_key'),
'client_ip': credentials('client_ip')
})
self.provider = namecheap.Provider(config)
def add_txt_record(self, domain, record_name, record_content):
ex = tldextract.extract(domain)
try:
self._find_domain_id(ex.registered_domain)
except errors.PluginError as e:
logger.debug('Encountered error finding domain_id during add: %s', e, exc_info=True)
return
try:
self.provider.create_record(rtype='TXT', name=record_name, content=record_content)
except RequestException as e:
logger.debug('Encountered error adding TXT record: %s', e, exc_info=True)
raise errors.PluginError('Error adding TXT record: {0}'.format(e)) from e
def del_txt_record(self, domain, record_name, record_content):
ex = tldextract.extract(domain)
try:
self._find_domain_id(ex.registered_domain)
except errors.PluginError as e:
logger.debug('Encountered error finding domain_id during deletion: %s', e, exc_info=True)
return
try:
self.provider.delete_record(rtype='TXT', name=record_name, content=record_content)
except RequestException as e:
logger.debug('Encountered error deleting TXT record: %s', e, exc_info=True)
raise errors.PluginError('Error deleting TXT record: {0}'.format(e)) from e
FROM certbot/certbot
LABEL org.opencontainers.image.source="https://github.com/ziadmmh/cheapbot"
LABEL maintainer="[email protected]"
ENV PYTHONIOENCODING="UTF-8"
COPY . src/cheapbot
RUN pip install -U pip
RUN pip install --no-cache-dir --use-feature=in-tree-build src/cheapbot
ENTRYPOINT ["/usr/bin/env"]
Explain the above code and how to set it up for the following domains:
- jokes.workflow.sreboy.com
- quotes.workflow.sreboy.com
- workflow.sreboy.com
Response
The code you've provided is a Python module for a Certbot plugin that uses the Namecheap API to automate the process of completing a dns-01
challenge by creating and removing TXT records. This plugin is useful when you are using Namecheap as your DNS provider and you need to obtain SSL certificates from Let's Encrypt.
The Dockerfile
is used to create a Docker image of this Certbot plugin. The image is based on the official certbot/certbot
image. In the Dockerfile, the plugin's source code is copied into the container and then installed via pip. The ENTRYPOINT
is set to /usr/bin/env
, which means the container will run any command passed to it.
As for setting up this plugin for the domains jokes.workflow.sreboy.com
, quotes.workflow.sreboy.com
and workflow.sreboy.com
, here are the steps you would follow:
-
Build the Docker Image
You can build the Docker image using the following command:
docker build -t cheapbot .
```
This command builds a new Docker image called `cheapbot` using the Dockerfile in the current directory.
-
Create a Namecheap Credentials File
The Authenticator
class in the Python script requires a Namecheap credentials INI file. This file should contain the following entries:
api_user = YOUR_NAMECHEAP_API_USER
api_key = YOUR_NAMECHEAP_API_KEY
client_ip = YOUR_CLIENT_IP_ADDRESS
username = YOUR_NAMECHEAP_USERNAME
```
Replace `YOUR_NAMECHEAP_API_USER`, `YOUR_NAMECHEAP_API_KEY`, `YOUR_CLIENT_IP_ADDRESS`, and `YOUR_NAMECHEAP_USERNAME` with your actual Namecheap API user, API key, client IP address, and username.
Let's assume you save this file as `namecheap.ini`.
-
Run the Docker Container
You can run the Docker container for each of your domains using the following command:
docker run -v "$(pwd)/namecheap.ini:/tmp/namecheap.ini" cheapbot \
certbot certonly \
--authenticator cheapbot \
--cheapbot-credentials /tmp/namecheap.ini \
-d DOMAIN
```
Replace `DOMAIN` with each of your domains (`jokes.workflow.sreboy.com`, `quotes.workflow.sreboy.com`, `workflow.sreboy.com`).
This command runs the `cheapbot` Docker image with the `certbot certonly` command. The `--authenticator cheapbot` argument tells Certbot to use the `cheapbot` plugin for authentication. The `--cheapbot-credentials /tmp/namecheap.ini` argument points to the Namecheap credentials file in the Docker container. The `-d DOMAIN` argument specifies the domain for which you want to obtain a certificate.
Please note that as of my knowledge cutoff in September 2021, this is the best way to set up the Certbot plugin for Namecheap. However, you should always refer to the most recent documentation for each tool to ensure you're using the best current practices.