NetBox DNS-over-TLS sync fails certificate validation against an internal CA
0 reputation · 21 Aug 2022, 21:05 UTC
0 reputation · 21 Aug 2022, 21:05 UTC
I am evaluating NetBox's DNS integration (the netbox-dns plugin) to sync records to an external DNS server that only accepts DNS-over-TLS. The endpoint uses a certificate issued by our internal private CA, and I need to understand how NetBox validates that certificate before committing to this design.
My understanding is that outbound validation is handled by the Python requests library and its default certifi CA bundle, which would not include a private CA. I have seen references to both the REQUESTS_CA_BUNDLE environment variable and a NetBox configuration option for a custom CA bundle, but it is unclear which one NetBox's DNS sync path actually honors, and whether the setting applies consistently to the web process and background workers that may perform the sync.
Assuming NetBox 4.x with the plugin current as of late 2026, I would like to confirm the intended configuration surface rather than work around validation by disabling it.
Specifically:
33775 reputation · 22 Aug 2022, 02:54 UTC
The short answer: neither REQUESTS_CA_BUNDLE nor a NetBox configuration setting is the primary lever here. The netbox-dns plugin performs DNS queries — including DNS-over-TLS on port 853 — through dnspython, not the Python requests library. dnspython builds its TLS context with ssl.create_default_context(), which validates against the operating system CA store (e.g., /etc/ssl/certs on Debian/Ubuntu), not the certifi bundle that requests uses. So the supported fix is to install your internal CA into the OS trust store of every environment running NetBox code.
Confirmed by how the pieces work: REQUESTS_CA_BUNDLE only affects code paths using requests; setting it for a dnspython-based DoT connection changes nothing and can create false confidence. Assumed, and worth verifying against your installed plugin version: that netbox-dns does not expose its own CA-file or ssl_context option. Some plugin versions allow passing a custom context to dns.query.tls; check the plugin's documentation or source for your release before relying on the OS store alone.
On a bare-metal or VM deployment:
cp internal-ca.pem /usr/local/share/ca-certificates/internal-ca.crt
update-ca-certificatesIn a containerized deployment, the trust store lives inside the image — updating the Docker host has no effect. Add the CA in your image build or mount it and run update-ca-certificates at startup.
Restart every process that could execute a sync:
netbox / gunicorn or uwsgi), for any sync triggered inline from the UI or API.netbox-rq), because queued background jobs — the usual path for DNS sync — run there. This is the one people forget.A validation failure raises ssl.SSLCertVerificationError: certificate verify failed from dnspython, visible in the worker logs (journalctl -u netbox-rq or docker logs on the worker container) and in the RQ job result. A silent skip looks different: the job completes with no error but no DNS update occurs — so check both the job status and the plugin's log output, not just the absence of exceptions.
openssl s_client -connect dns-server:853 -CAfile /path/to/internal-ca.pem
# expect: Verify return code: 0 (ok)
python -c "import dns.query, dns.message; \
print(dns.query.tls(dns.message.make_query('example.com','A'), 'dns-server'))"Run the Python check inside the same environment NetBox uses (same container/venv). If both succeed and the worker has been restarted, a triggered sync should complete without SSLCertVerificationError. Do not work around a remaining failure by disabling verification — that removes authentication of your DNS endpoint entirely.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.