DNSroboCert: Let's Encrypt certificates over DNS challenges
Orchestrate Certbot and Lexicon together to provide Let's Encrypt TLS certificates validated by DNS challenges
At a glance
- What is it?
- DNSroboCert orchestrates Certbot and the Lexicon library so that Let's Encrypt certificates, including wildcards, are validated with DNS challenges and then propagated to the services that need them. It ships as a Python application and as a container image with a single YAML configuration file, and it targets the cases where HTTP and TLS challenges cannot work, such as firewalled hosts and non-web protocols.
- Who is it for?
- DNSroboCert fits an operator who needs wildcard certificates, or who runs services such as LDAP, IMAP and POP that have no web endpoint to validate, or whose inbound ports are closed to the internet, and who would rather drive one YAML file than glue Certbot and a DNS provider API together by hand.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One tool to place a challenge record and collect the certificate
DNSroboCert is built around a specific gap in the usual certificate tooling. Certbot is the component that talks to Let's Encrypt and produces the certificate, and Lexicon is the library that abstracts DNS providers so that a text record can be created through a provider's API. DNSroboCert orchestrates the two, and adds the part that the ecosystem around them tends to leave to the reader: getting the resulting certificate to the service that needs it, and restarting that service when the certificate changes.
The feature list is explicit. It generates Let's Encrypt wildcard and regular certificates with Certbot using DNS challenges. It renews certificates that are close to expiry. It offers a standardized API through Lexicon to insert the DNS challenge across various DNS providers. It keeps a centralized YAML configuration file that can hold several certificates and several DNS providers, with configuration validity control. It allows modification of container configuration without a restart. It provides hooks on certificate creation and renewal, including container restarts, commands run inside containers and custom hooks. It supports DNS alias mode through the follow_cnames option in the certificate section. It runs on Linux, Mac OS X and Windows, with particular attention to Docker services.
The delivery is a standalone application and a Docker image, and the documentation site is at dnsrobocert.readthedocs.io with a user guide and a configuration reference, plus a Lexicon provider configuration page for the provider side.
The three cases where a DNS challenge is the only option
The project explains its own scope by listing three situations that push you away from the HTTP and TLS challenges used by the popular reverse proxy tools.
The first is a firewalled network. An ACME server has to reach your site over HTTP or HTTPS in order to validate, so if ports 80 and 443 are not open to the outside world, neither of those challenges works and you have to ask for a DNS challenge instead. The second is securing a service that is not a web service at all, such as LDAP, IMAP or POP, where there is no website for a challenge to point at. The third is a wildcard certificate, valid for any subdomain of a domain, for which a DNS challenge is mandatory. The certificate propagation problem that follows from a DNS challenge is the same in the second and third case.
The comparison the project draws is with stacks such as Traefik, or nginx-proxy together with letsencrypt-nginx-proxy-companion. Those tools automate certificate generation and renewal on top of a reverse proxy, using TLS or HTTP challenges. That approach is the right one when the proxy is publicly reachable, and DNSroboCert is positioned as the dedicated alternative when it is not. The project's own note is that Traefik does embed DNS challenges, but only for a few DNS providers, which is a narrower position than routing every provider through Lexicon.
One YAML file for certificates, providers and validation
The configuration model is the part of the tool that most affects day to day use. Instead of running a command per domain, a single YAML file holds several certificates and several DNS providers, and the project describes that as centralized configuration with configuration validity control, which is backed by a jsonschema dependency and a schema that can be checked before anything is issued.
Each certificate entry carries the settings that decide how it is obtained and where it goes, including the follow_cnames option that turns on DNS alias mode, a mechanism for pointing validation at a domain you do not serve directly. The certificate section of the configuration reference is where that option is documented, and the user guide and the Lexicon provider configuration page are the two references the project points a new user to first.
Hooks are the other half of the model, and they exist because of a specific operational fact. A certificate renewed by DNS challenge does not automatically reach the service that is using it, and the documentation is blunt that most non-web services will need to be restarted each time the certificate is renewed. The hooks cover three shapes: restarting containers, running commands inside containers, and custom hooks for anything else. The container configuration can also be changed without a restart, which matters when the thing being reconfigured is a proxy that reads its configuration on the fly.
The project treats Lexicon as the provider abstraction, so the set of DNS providers you can use is the set Lexicon supports, and the provider specific credentials and endpoints are documented on the Lexicon site rather than here.
The container image pins constraints and carves out armv7l
The image is built in two stages from a Python 3.13.13 slim base. The first stage is named constraints, and its job is to produce a reproducible set of pinned versions: it copies the source, the uv lock file and the project metadata into a temporary directory, installs uv, exports the lock file without hashes into constraints.txt, and then builds the wheel.
The armv7l handling is the part that is unusual. On that architecture, the cryptography and lxml pins are rewritten with sed to specific versions, 49.0.0 and 6.1.1 respectively, taking the newest compatible releases available from piwheels, and the later install step points pip at the piwheels extra index. The reason is stated in a comment in the Dockerfile itself: some packages are pinned on armv7l to the latest available and compatible versions. This is a Raspberry Pi class problem, and solving it inside the image is better than leaving every Pi user to rediscover it.
The runtime stage installs curl, bash, libxslt1.1 and podman, then installs the built wheel with the exported constraints, and creates the two configuration directories. Two environment variables define the contract with the host: CONFIG_PATH points at /etc/dnsrobocert/config.yml and CERTS_PATH at /etc/letsencrypt, so the configuration file and the certificate store are mounted from outside the container rather than baked in. A symlink at /opt/dnsrobocert/bin/python is created for retro-compatibility, and the container runs docker/run.sh as its command.
A hatchling package with a wide dependency set and a plain CLI
The Python packaging is modern and conventional. The build backend is hatchling, the project name is dnsrobocert, the licence is MIT, and the version in the project metadata is 3.27.1. The minimum supported Python is 3.10, and the classifiers list 3.10 through 3.14 on CPython, with Unix, POSIX and Windows operating systems listed.
The dependency list explains the architecture. acme and certbot are the ACME client and the certificate client, dns-lexicon with the full extra pulls in every provider integration, and cryptography, cffi and pyopenssl handle the certificate and key material, with pem and lxml supporting the certificate formats and XML parsing. dnspython handles DNS resolution, jsonschema the configuration validation, pyyaml the configuration file itself, and tldextract the domain parsing. schedule and coloredlogs with colorama provide the renewal loop and the console output. The command line entry point is dnsrobocert, bound to dnsrobocert.core.main:main.
The development tooling is grouped separately and is a sensible list for a project of this size: black and isort for formatting, flake8 with flake8-pyproject for linting, mypy with type stubs for PyYAML and pyOpenSSL for typing, and pytest with pytest-cov and pytest-sugar for tests. The repository uses uv for dependency management with a uv.lock file, pins the interpreter in .python-version, and carries a snapcraft.yaml alongside a compose/ directory and a Dockerfile, which confirms that the container, the Compose and the snap are three supported shapes of the same application.
Alpha status, a year between releases and the version in the metadata
The project classifies itself as Development Status :: 3 - Alpha in its own metadata, and that is the first thing to weigh. The release history is not continuous: version 3.27.0 was published on 2026-04-28, and before it version 3.26.1 and version 3.26.0 both arrived on 2025-04-13. The last push to the repository was on 2026-10-01, so the code is moving, but the packaging metadata carries version 3.27.1, which is ahead of the most recent tagged release, so what you install from PyPI and what is in the tree are not necessarily the same thing.
The dependency coupling is the other upgrade cost. DNSroboCert pins lower bounds rather than exact versions for most libraries, with certbot at 2 and above, dns-lexicon at 3.14.0 and above, and acme at 2 and above. That means a Certbot or Lexicon major release can change behaviour underneath you, and the alpha classification means the project may not absorb that quickly.
The MIT licence, which the LICENSE file and the project metadata both state, leaves you free to run and modify it. The practical exposure is not the licence but the coupling: an unattended renewal that fails after a dependency change is exactly the failure that matters for a certificate tool, and the hooks and logs are where you would see it.
Standalone, container or snap, and when a reverse proxy is simpler
There are three ways to run the same application, and the choice follows from what else has to see the certificates. A reverse proxy in the same container or the same network can read a certificate file from a shared volume and reload itself, which is the simplest arrangement and the one the hook support is built for, since a hook can restart a container by name. The standalone application suits a host where the services are not containers at all, which is the case the project calls out for things like LDAP, IMAP and POP servers. The snap and the image cover the case where the tool should be a fixed, self contained unit on a small machine.
The alternative that deserves a serious look is the reverse proxy route rather than another DNS challenge tool. If your services are all HTTP and your ingress is publicly reachable, Traefik, or nginx-proxy with the letsencrypt-nginx-proxy-companion, will renew certificates with HTTP or TLS challenges on top of the reverse proxy. That removes an entire class of moving parts: no DNS API credentials, no extra propagation delay, no hook that restarts a service on a schedule.
DNSroboCert earns its place in the other direction. Wildcards need it, closed ports need it, non-web protocols need it, and a multi-provider environment where you want one YAML file beats several provider specific integrations. Choose it when the certificate has to reach services that never see HTTP, and choose the proxy stack when it does not.
Editorial conclusion
DNSroboCert fits an operator who needs wildcard certificates, or who runs services such as LDAP, IMAP and POP that have no web endpoint to validate, or whose inbound ports are closed to the internet, and who would rather drive one YAML file than glue Certbot and a DNS provider API together by hand. It is the wrong tool when ports 80 and 443 are reachable and a reverse proxy stack already handles certificates for you, and the wrong tool if you need a maturity guarantee, since the project still classifies itself as an alpha. Before deploying, confirm the DNS provider you use is supported by Lexicon, check that the container can reach the DNS API and the ACME servers, and read the section on the follow_cnames option in the certificate section of the configuration reference if your domain sits behind a CNAME.
Frequently asked questions
What is DNSroboCert and how does it issue certificates?
DNSroboCert orchestrates Certbot and the Lexicon library to obtain Let's Encrypt certificates using DNS challenges, which lets it issue both regular and wildcard certificates. It also handles automated renewal of certificates that are close to expiry.
When do I need DNSroboCert instead of a reverse proxy certificate tool?
The documentation points to three cases: a firewalled network where ports 80 and 443 are closed, non-web services such as LDAP, IMAP and POP that have no website to validate, and wildcard certificates, which always require a DNS challenge. Where your ingress is reachable, a stack such as Traefik or nginx-proxy with its companion handles renewal more simply.
How is DNSroboCert configured and what are its hooks for?
A single centralized YAML file holds several certificates and several DNS providers, with configuration validity control, and the follow_cnames option in the certificate section enables DNS alias mode. Hooks run on certificate creation and renewal and can restart containers, run commands inside containers or run custom hooks, which matters because services using a renewed certificate usually need a restart.
How do I run DNSroboCert in a container?
The image is built from a Python 3.13.13 slim base and runs docker/run.sh, with CONFIG_PATH set to /etc/dnsrobocert/config.yml and CERTS_PATH to /etc/letsencrypt so both can be mounted from the host. On armv7l the cryptography and lxml pins are rewritten to versions available from piwheels.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/adferrand-dnsrobocert)Was this useful?