NetBox DNS
Jan-Piet Mens
(JP designed the image which was then drawn by ↯⌀⌁⌂ --NOCARRIER)
November 2025
@jpmens@mastodon.social
dig @::1 +dnssec JP
$ORIGIN jan-piet.mens.
$TTL 1D
@ SOA ns _ 1 3H 1H 52W 1H
NS @
TXT "Jan-Piet Mens"
RP jp.mens.de. @
MX 0 .
A 192.0.2.53 ; RFC5737
AAAA 2001:db8:2::2025 ; RCF3849
HTTPS 0 jpmens.net.
JP CNAME @
jpmens TXT "small-time fiddler, plain text, WTF-8"
HINFO "Epson HX-20" "SomethIX OS"
LOC 38 55 18.435 N 1 25 50.418 E 10m 10m 100m 10m
jo PTR jo.jpmens.github.com.
_geo URI 0 0 "https://owntracks.org"
ansible PTR NO🐄 S
toot TXT "mastodon.social/@jpmens"
NetBox
• network source of truth
• IP address management (IPAM)
• RACK,VLAN,AS, device modeling
• VPN, IPSec policies
• virtual machines, etc., etc.
• change logs, search, events, scripts
• custom
fi
elds
NetBox DNS
do you need Netbox DNS?
it depends.
if you work alone and manage your DNS
with vi/emacs/nano or nsupdate then
possibly not ;-)
But …
NetBox DNS
• created by Peter Eckel
• not bound to speci
fi
c DNS
• we integrate with that
• CI/CD pipelines
• scripts
• con
fi
g management
• API
• UI, REST API, bits of Ansible
github.com/peteeckel/netbox-plugin-dns
NetBox DNS
• internationalized domain names (IDN)
• tenancy on objects
• optional automatic SOA serial
• RFC 2137 classless delegation
• IPAM DNSsync
adding plugin to NetBox
$ cd /opt/netbox/
$ source venv/bin/activate
(venv) $ pip install netbox-plugin-dns
(venv) $ echo netbox-plugin-dns >> local_requirements.txt
(venv) $ echo "PLUGINS=['netbox_dns']" >> netbox/netbox/configuration.py
(venv) $ /opt/netbox/netbox/manage.py migrate
$ sudo systemctl restart netbox netbox-rq
• add NetBox DNS to existing NetBox
• or do all-in-one:
playbook
- name: Install NetBox and netbox-plugin-dns
hosts: nb
vars:
nb_host: "{{ ansible_default_ipv4.address }}"
netbox_version: v4.4.2 # or latest
netbox_local_requirements:
- netbox-plugin-dns==1.4.1
netbox_config:
ALLOWED_HOSTS: [ "{{ nb_host }}" ]
PLUGINS: [ "netbox_dns", ]
PLUGINS_CONFIG:
netbox_dns:
zone_nameservers: [ "nsa.example", "usb.example" ]
zone_soa_mname : "nsa.example"
zone_soa_rname: "noc.example.org"
filter_record_types: [ "A6", "AFSDB", "APL", "AVC", "DLV" ]
netbox_setup_systemd: true
netbox_setup_web_frontend: true
roles:
# https://github.com/gmazoyer/ansible-role-netbox
- gmazoyer.netbox
preliminaries
$ echo $NETBOX_API
https://netbox.example
$ echo $NETBOX_TOKEN
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
• I use environment variables in examples
• tokens are user-speci
fi
c and
permissions apply
DNS views
• views are yuck can be practical
• BIND-style (and now Unbound and
PowerDNS have them too!)
• each zone belongs in a view
• two zones example. can exist if
they are in two distinct views (that's
the point, innit?)
create a view
• create view, assign DNSsync pre
fi
x
#!/usr/bin/env python3
import pynetbox
import os
viewname = "external"
nb = pynetbox.api(os.getenv("NETBOX_API"),
token = os.getenv("NETBOX_TOKEN"))
v = nb.plugins.netbox_dns.views.create(name=viewname,
display=viewname,
description="Outward-facing zones",
prefixes=[
{
"prefix": "192.0.2.0/24"
}
])
DNS zones
• manage in UI
• use zone templates to add common
sets of objects to zones
#!/bin/sh
jo name="$1" 
default_ttl=7200 
soa_ttl=43200 
soa_rname=noc.example.org. 
soa_refresh=7200 
soa_retry=1800 
soa_expire=4838400 
soa_minimum=900 | curl -sSf 
-H "Authorization: Token $NETBOX_TOKEN" 
-H "Content-type: application/json" 
"${NETBOX_API}/api/plugins/netbox-dns/zones/" 
--data @-
resource records
• rdata validation on input (also via API)
• record templates → zone templates
• optionally filter_record_types from form
adding an address
- name: Get next available IPv4 address
netbox.netbox.netbox_ip_address:
data:
prefix: "192.0.2.0/24"
dns_name: "{{ hostname }}.{{ zone }}"
state: "new"
• create an IP address in NetBox
• DNSsync → zone
Ansible inventory
---
plugin: netbox.netbox.nb_inventory
validate_certs: true
flatten_custom_fields: true
config_context: true
query_filters:
- cf_special: "tonic"
group_by:
- sites
- location
cache: false
rename_variables:
- pattern: "tags"
repl: "xtags"
- pattern: "serial"
repl: "xserial"
dns_name: true
• from the netbox.netbox collection
ceci n'est pas ...
NetBox DNS is not a DNS server,
however with help, it can feed DNS data into
authoritative servers, signers
BIND
Cascade
Knot DNS
NSD
PowerDNS
serving DNS
octodns
github.com/octodns/octodns
github.com/olofvndrhr/octodns-netbox-dns
• manage DNS records across providers
• many providers
• zone master
fi
les, RFC 2136, ...
• support for NetBox DNS as source
octodns providers
/etc/hosts;Akamai Edge DNS;Amazon Route 53;
AutoDNS;Azion DNS;Azure DNS; BIND,AXFR, RFC-2136;
Bunny DNS; Cloud
fl
are DNS; ClouDNS; Constellix; deSEC;
DigitalOcean; DNS Made Easy; DNSimple; easyDNS;
EdgeCenter DNS; Fastly; G-Core Labs DNS; Gandi; Google
Cloud DNS; Hetzner DNS; Infoblox; Infomaniak; Lexicon;
Mythic Beasts DNS; NetBox-DNS; NS1; OVHcloud DNS;
Pi-hole; PowerDNS; Rackspace; Scaleway; Selectel;TransIP;
UltraDNS;YAML; Zone
fi
le
octodns.readthedocs.io/en/latest/
more octodns
• Con
fi
gure
• Run
---
providers:
netbox: # pip install octodns-netbox-dns
class: octodns_netbox_dns.NetBoxDNSProvider
url: env/NETBOX_API
token: env/NETBOX_TOKEN
zonefiles: # pip install octodns-bind
class: octodns_bind.ZoneFileSource
directory: ./zonefiles
file_extension: ""
zones:
"*":
sources: [ netbox ]
targets: [ zonefiles ]
$ octodns-sync --config-file=./config/production.yml --doit --quiet
octo nits
jpmens.net/2025/02/22/notes-to-self-on-octodns-and-its-providers/
jpmens.net/2025/02/19/netbox-dns-and-a-pinch-of-octodns/
• SOA serial updated at every run
• invents SOA rname
• doesn't honour NetBox SOA timers!!
• provider code quality ?
• limited rrtype support in providers
• basic docs good, providers' so-so
• (learn to read stack traces ... :-( )
DNSSEC in NetBox
• document policies and signing keys
• e.g. KASP
• use to generate DNS server con
fi
gs
• key material is not in NetBox and
should not be (HSM?)
• signers typically manage keys
key templates
• describe desired key types
• use to automate key generation
DNSSEC policies
• describe signing parameters which can
be assigned to zones
• key types, lifetimes, etc.
• use to generate DNS server con
fi
gs
generate con
fi
gs
how else? (3)
$ pdnsutil add-zone-key example.net. KSK active published ECDSAP256SHA256
• for instance, PowerDNS
$ dnssec-keygen -a ECDSAP256SHA256 -f ksk example.net.
• for instance, BIND 9.6 tools
# How keys are generated.
[key-manager.generation]
use-csk = true
algorithm = "ECDSAP256SHA256"
• for instance, Cascade
$ ldns-keygen -a ECDSAP256SHA256 -k example.net.
• for instance, LDNS tools
NetBox scripts
• run any Python script on demand (even
trigger run of Ansible playbooks)
• ask for input
fi
elds
• captures stdout and displays it
• logging possible
jpmens.net/2020/02/28/dial-a-for-ansible-and-r-for-runner/
choose script
run script
Events on DNS
•
fi
re on any NetBox object
• create, update, delete, job start/end
• actions are webhook, script, noti
fi
cation
• trigger almost anything ...
changelogs (1)
changelogs (2)
con
fi
g contexts
jpmens.net/2025/02/21/netbox-and-con
fi
guration-contexts-templates/
further reading
• GraphQL
$ curl -sSf -H "Authorization: Token $NETBOX_TOKEN" 
-H "Content-type: application/json" 
"${NETBOX_API}/graphql/" 
--data '{"query":"query {netbox_dns_zone_list { id name }}"}'
{
"data": {
"netbox_dns_zone_list": [
{
"id": "2",
"name": "2.0.192.in-addr.arpa"
},
{
"id": "1",
"name": "example.net"
}
]
}
}
on the horizon
• DHCP parameters (not a server)
• DNS catalog zones
Fin
jpmens.net
@jpmens@mastodon.social

OSMC 2025: Using NetBox DNS by Jan-Piet Mens.pdf

  • 2.
    NetBox DNS Jan-Piet Mens (JPdesigned the image which was then drawn by ↯⌀⌁⌂ --NOCARRIER) November 2025 @[email protected]
  • 3.
    dig @::1 +dnssecJP $ORIGIN jan-piet.mens. $TTL 1D @ SOA ns _ 1 3H 1H 52W 1H NS @ TXT "Jan-Piet Mens" RP jp.mens.de. @ MX 0 . A 192.0.2.53 ; RFC5737 AAAA 2001:db8:2::2025 ; RCF3849 HTTPS 0 jpmens.net. JP CNAME @ jpmens TXT "small-time fiddler, plain text, WTF-8" HINFO "Epson HX-20" "SomethIX OS" LOC 38 55 18.435 N 1 25 50.418 E 10m 10m 100m 10m jo PTR jo.jpmens.github.com. _geo URI 0 0 "https://owntracks.org" ansible PTR NO🐄 S toot TXT "mastodon.social/@jpmens"
  • 4.
    NetBox • network sourceof truth • IP address management (IPAM) • RACK,VLAN,AS, device modeling • VPN, IPSec policies • virtual machines, etc., etc. • change logs, search, events, scripts • custom fi elds
  • 5.
    NetBox DNS do youneed Netbox DNS? it depends. if you work alone and manage your DNS with vi/emacs/nano or nsupdate then possibly not ;-) But …
  • 6.
    NetBox DNS • createdby Peter Eckel • not bound to speci fi c DNS • we integrate with that • CI/CD pipelines • scripts • con fi g management • API • UI, REST API, bits of Ansible github.com/peteeckel/netbox-plugin-dns
  • 7.
    NetBox DNS • internationalizeddomain names (IDN) • tenancy on objects • optional automatic SOA serial • RFC 2137 classless delegation • IPAM DNSsync
  • 8.
    adding plugin toNetBox $ cd /opt/netbox/ $ source venv/bin/activate (venv) $ pip install netbox-plugin-dns (venv) $ echo netbox-plugin-dns >> local_requirements.txt (venv) $ echo "PLUGINS=['netbox_dns']" >> netbox/netbox/configuration.py (venv) $ /opt/netbox/netbox/manage.py migrate $ sudo systemctl restart netbox netbox-rq • add NetBox DNS to existing NetBox • or do all-in-one:
  • 9.
    playbook - name: InstallNetBox and netbox-plugin-dns hosts: nb vars: nb_host: "{{ ansible_default_ipv4.address }}" netbox_version: v4.4.2 # or latest netbox_local_requirements: - netbox-plugin-dns==1.4.1 netbox_config: ALLOWED_HOSTS: [ "{{ nb_host }}" ] PLUGINS: [ "netbox_dns", ] PLUGINS_CONFIG: netbox_dns: zone_nameservers: [ "nsa.example", "usb.example" ] zone_soa_mname : "nsa.example" zone_soa_rname: "noc.example.org" filter_record_types: [ "A6", "AFSDB", "APL", "AVC", "DLV" ] netbox_setup_systemd: true netbox_setup_web_frontend: true roles: # https://github.com/gmazoyer/ansible-role-netbox - gmazoyer.netbox
  • 10.
    preliminaries $ echo $NETBOX_API https://netbox.example $echo $NETBOX_TOKEN xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx • I use environment variables in examples • tokens are user-speci fi c and permissions apply
  • 11.
    DNS views • viewsare yuck can be practical • BIND-style (and now Unbound and PowerDNS have them too!) • each zone belongs in a view • two zones example. can exist if they are in two distinct views (that's the point, innit?)
  • 12.
    create a view •create view, assign DNSsync pre fi x #!/usr/bin/env python3 import pynetbox import os viewname = "external" nb = pynetbox.api(os.getenv("NETBOX_API"), token = os.getenv("NETBOX_TOKEN")) v = nb.plugins.netbox_dns.views.create(name=viewname, display=viewname, description="Outward-facing zones", prefixes=[ { "prefix": "192.0.2.0/24" } ])
  • 13.
    DNS zones • managein UI • use zone templates to add common sets of objects to zones #!/bin/sh jo name="$1" default_ttl=7200 soa_ttl=43200 soa_rname=noc.example.org. soa_refresh=7200 soa_retry=1800 soa_expire=4838400 soa_minimum=900 | curl -sSf -H "Authorization: Token $NETBOX_TOKEN" -H "Content-type: application/json" "${NETBOX_API}/api/plugins/netbox-dns/zones/" --data @-
  • 14.
    resource records • rdatavalidation on input (also via API) • record templates → zone templates • optionally filter_record_types from form
  • 15.
    adding an address -name: Get next available IPv4 address netbox.netbox.netbox_ip_address: data: prefix: "192.0.2.0/24" dns_name: "{{ hostname }}.{{ zone }}" state: "new" • create an IP address in NetBox • DNSsync → zone
  • 16.
    Ansible inventory --- plugin: netbox.netbox.nb_inventory validate_certs:true flatten_custom_fields: true config_context: true query_filters: - cf_special: "tonic" group_by: - sites - location cache: false rename_variables: - pattern: "tags" repl: "xtags" - pattern: "serial" repl: "xserial" dns_name: true • from the netbox.netbox collection
  • 17.
    ceci n'est pas... NetBox DNS is not a DNS server, however with help, it can feed DNS data into authoritative servers, signers BIND Cascade Knot DNS NSD PowerDNS
  • 18.
  • 19.
    octodns github.com/octodns/octodns github.com/olofvndrhr/octodns-netbox-dns • manage DNSrecords across providers • many providers • zone master fi les, RFC 2136, ... • support for NetBox DNS as source
  • 20.
    octodns providers /etc/hosts;Akamai EdgeDNS;Amazon Route 53; AutoDNS;Azion DNS;Azure DNS; BIND,AXFR, RFC-2136; Bunny DNS; Cloud fl are DNS; ClouDNS; Constellix; deSEC; DigitalOcean; DNS Made Easy; DNSimple; easyDNS; EdgeCenter DNS; Fastly; G-Core Labs DNS; Gandi; Google Cloud DNS; Hetzner DNS; Infoblox; Infomaniak; Lexicon; Mythic Beasts DNS; NetBox-DNS; NS1; OVHcloud DNS; Pi-hole; PowerDNS; Rackspace; Scaleway; Selectel;TransIP; UltraDNS;YAML; Zone fi le octodns.readthedocs.io/en/latest/
  • 21.
    more octodns • Con fi gure •Run --- providers: netbox: # pip install octodns-netbox-dns class: octodns_netbox_dns.NetBoxDNSProvider url: env/NETBOX_API token: env/NETBOX_TOKEN zonefiles: # pip install octodns-bind class: octodns_bind.ZoneFileSource directory: ./zonefiles file_extension: "" zones: "*": sources: [ netbox ] targets: [ zonefiles ] $ octodns-sync --config-file=./config/production.yml --doit --quiet
  • 22.
    octo nits jpmens.net/2025/02/22/notes-to-self-on-octodns-and-its-providers/ jpmens.net/2025/02/19/netbox-dns-and-a-pinch-of-octodns/ • SOAserial updated at every run • invents SOA rname • doesn't honour NetBox SOA timers!! • provider code quality ? • limited rrtype support in providers • basic docs good, providers' so-so • (learn to read stack traces ... :-( )
  • 23.
    DNSSEC in NetBox •document policies and signing keys • e.g. KASP • use to generate DNS server con fi gs • key material is not in NetBox and should not be (HSM?) • signers typically manage keys
  • 24.
    key templates • describedesired key types • use to automate key generation
  • 25.
    DNSSEC policies • describesigning parameters which can be assigned to zones • key types, lifetimes, etc. • use to generate DNS server con fi gs
  • 26.
  • 27.
    how else? (3) $pdnsutil add-zone-key example.net. KSK active published ECDSAP256SHA256 • for instance, PowerDNS $ dnssec-keygen -a ECDSAP256SHA256 -f ksk example.net. • for instance, BIND 9.6 tools # How keys are generated. [key-manager.generation] use-csk = true algorithm = "ECDSAP256SHA256" • for instance, Cascade $ ldns-keygen -a ECDSAP256SHA256 -k example.net. • for instance, LDNS tools
  • 28.
    NetBox scripts • runany Python script on demand (even trigger run of Ansible playbooks) • ask for input fi elds • captures stdout and displays it • logging possible jpmens.net/2020/02/28/dial-a-for-ansible-and-r-for-runner/
  • 29.
  • 30.
  • 31.
    Events on DNS • fi reon any NetBox object • create, update, delete, job start/end • actions are webhook, script, noti fi cation • trigger almost anything ...
  • 32.
  • 33.
  • 34.
  • 35.
    further reading • GraphQL $curl -sSf -H "Authorization: Token $NETBOX_TOKEN" -H "Content-type: application/json" "${NETBOX_API}/graphql/" --data '{"query":"query {netbox_dns_zone_list { id name }}"}' { "data": { "netbox_dns_zone_list": [ { "id": "2", "name": "2.0.192.in-addr.arpa" }, { "id": "1", "name": "example.net" } ] } }
  • 36.
    on the horizon •DHCP parameters (not a server) • DNS catalog zones
  • 37.