Sven Luthi 91562ae538 new file: README.md
new file:   certbot_dns_netbox/__init__.py
new file:   certbot_dns_netbox/dns_netbox.py
new file:   certbot_dns_netbox/nbapi.py
new file:   pyproject.toml
2026-10-26 17:47:10 +01:00
2026-10-26 17:47:10 +01:00
2026-10-26 17:47:10 +01:00
2026-10-26 17:47:10 +01:00

certbot-dns-netbox

Certbot DNS-01 authenticator plugin that updates the challenge TXT record in NetBox DNS (the netbox-dns NetBox plugin) via the bundled nbapi.py API helper.

How it works

For every domain in the certificate request certbot asks this plugin to set an _acme-challenge.<domain> TXT record. The plugin works exclusively through the netbox-dns record API endpoint — the zone endpoint is never queried, and the plugin never creates or deletes records:

  1. looks up the existing TXT records for the FQDN (records can be filtered by fqdn, zone and view by name),
  2. writes the challenge token into the existing record. If the record does not exist yet, certbot aborts with an error: create the record once beforehand (in the NetBox UI or your tooling) and rerun,
  3. leaves the record in place after validation so it can be updated again on the next renewal.

Because a single record holds a single token, a certificate request must not combine a domain and its wildcard (-d example.com -d '*.example.com'): both map to the same _acme-challenge.example.com record, and the second token would overwrite the first. Issue those as separate certificates.

Connection settings are taken from the environment, exactly as nbapi.py expects them:

Variable Purpose
NETBOX_URL Base URL of the NetBox instance
NETBOX_BEARER NetBox API token (Authorization: Bearer)
NETBOX_TOKEN NetBox API token (Authorization: Token)
DEBUG Optional: verbose nbapi.py logging

One of NETBOX_BEARER / NETBOX_TOKEN is required. The token's user needs NetBox object permissions to view and change netbox-dns records only — no zone or view permissions are required.

Installation

Install into the same Python environment as certbot:

pip install ./certbot-dns-netbox

Usage

export NETBOX_URL=https://netbox.example.com
export NETBOX_BEARER=<token>

certbot certonly \
    --authenticator dns-netbox \
    --dns-netbox-propagation-seconds 60 \
    -d example.com -d '*.example.com'

Options

Option Default Description
--dns-netbox-propagation-seconds 30 Seconds to wait for DNS propagation
--dns-netbox-ttl keep current TTL of the challenge TXT record (s)
--dns-netbox-insecure off Skip TLS verification towards NetBox

The netbox-dns view to search is configured in code: search_view at the top of certbot_dns_netbox/dns_netbox.py.

Renewal configuration

certbot stores the authenticator in the renewal configuration, so renewals need no extra flags:

# /etc/letsencrypt/renewal/example.com.conf
[renewalparams]
authenticator = dns-netbox
dns_netbox_ttl = 120

When certbot runs unattended (cron or systemd timer), make sure the NETBOX_* environment variables are set, e.g. via a systemd EnvironmentFile= or a wrapper script.

Verification

certbot plugins --init dns-netbox     # plugin is discovered and loads
certbot certonly --dry-run \
    --authenticator dns-netbox \
    -d sub.example.com                # end-to-end against the staging ACME API

Watch the _acme-challenge TXT record in the global view: its value changes to the challenge token during the run and remains in place afterwards. The next renewal updates the same record again.

S
Description
No description provided
Readme MIT
81 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 100%