Compare commits

...
4 Commits
Author SHA1 Message Date
Sven Luthi cfb4633006 modified: netbox_dns_bridge/__init__.py
Bump version
2026-07-20 15:21:36 +02:00
Sven Luthi b4ab5596d6 modified: netbox_dns_bridge/notify_handler.py
modified:   netbox_dns_bridge/signals/netbox_dns_zones.py
Some code cleanup
2026-07-20 15:21:14 +02:00
Sven Luthi 11ea9a6f1a modified: README.md
modified:   netbox_dns_bridge/notify_handler.py
Remove hardcoded client notify port and connect to plugin setting
instead.
2026-07-20 15:07:21 +02:00
Sven Luethi 83965817d6 Update README 2026-07-16 14:54:35 +02:00
4 changed files with 59 additions and 32 deletions

No files matched your search

+43 -13
View File
@@ -18,7 +18,8 @@ changes (RFC 1996).
<a href="https://pepy.tech/project/netbox-plugin-dns-bridge"><img src="https://static.pepy.tech/personalized-badge/netbox-plugin-dns-bridge?period=monthly&left_color=BLACK&right_color=BLUE&left_text=Downloads%2fMonth" alt="Downloads/Month"></a>
<a href="https://pepy.tech/project/netbox-plugin-dns-bridge"><img src="https://static.pepy.tech/personalized-badge/netbox-plugin-dns-bridge?period=weekly&left_color=BLACK&right_color=BLUE&left_text=Downloads%2fWeek" alt="Downloads/Week"></a>
## Plugin configuration
# Plugin configuration
While providing Zone transfers via AXFR, the Server also exposes specialized catalog zones that BIND
and other RFC9432 compliant DNS Servers use to automatically discover newly created zones and remove
deleted ones. The plugin supports views and basic DNS security via TSIG.
@@ -39,13 +40,15 @@ This process needs to be scheduled as a background service for the built-in DNS
correctly. For Linux users with Systemd (Ubuntu, etc), Matt Kollross provides a startup unit and
instructions [here](docs/install-systemd-service.md).
### Service parameters
## Service parameters
Parameter | Description
--------- | -------------------------------------------------------------------
--port | Port to listen on for requests (defaults to 5354)
--address | IP of interface to bind to (defaults to 0.0.0.0)
### Plugin settings
## Plugin settings
Plugin settings should be configured under `PLUGINS_CONFIG` in `netbox_dns_bridge`:
```
PLUGINS_CONFIG = {
@@ -56,7 +59,7 @@ PLUGINS_CONFIG = {
}
```
#### TSIG Authentication
### TSIG Authentication
Following sets the TSIG key that allows clients to query the transfer endpoint and also they key to
be used to sign NOTIFY messages to clients on zone changes. Each view should have its own unique
key to allow the plugin to identify the view the client is trying to access. Re-using the key for
@@ -71,7 +74,21 @@ multiple views yields unpredicted behavior.
}
```
#### NOTIFY
### NOTIFY
The plugin has 2 different NOTIFY mechanisms that may be turned on individually or together.
1. [Client Notify](#client-notify)
2. [NS Notify](ns-notify)
- [Per Zone](ns-notify-per-zone)
- [For all Zones](ns-notify-for-all-zones)
Note: This makes the *Per Zone* mechanism redundant. There is no point in enabling both.
#### Global NOTIFY Settings
```
'notify_over_tcp': True
```
Switch to using TCP instead of UDP. Defaults to False
#### Client NOTIFY
Clients may be notified of zone changes using the NOTIFY mechanism defined in RFC 1996.
When enabled, the zone transfer endpoint keeps track of any client that successfully queried the
endpoint. Once a zone has changed, NetBox informs each client about the zone changed so that the
@@ -81,7 +98,6 @@ Note that this feature uses NetBox's background job system to schedule the messa
In order to work, you need at least one `rq-worker` service running in the background to handle
the queued jobs.
##### NOTIFY Settings
```
'notify_clients': True
```
@@ -93,12 +109,15 @@ This enables the NOTIFY system. Defaults to False
This sets how long a client is considred "alive" after it last queried the transfer endpoint.
Once the client has failed to check in for this amout of time, it is automatically removed from the
list of clients to be notified on zone changes. Default is 24 hours.
```
'notify_over_tcp': True
```
Switch to using TCP instead of UDP. Defaults to False
#### NOTIFY to a zone's own nameservers
```
'notify_client_port': 53
```
Destination port used to send NOTIFY messages to clients. Defaults to 53.
#### NS NOTIFY
In addition to notifying clients that queried the transfer endpoint, the plugin can send a NOTIFY
directly to a zone's own nameservers whenever that zone's SOA serial number changes. This is useful
when you want nameservers to pull updates immediately, independent of the `notify_clients` mechanism.
@@ -108,7 +127,12 @@ not.
This can be enabled per zone, globally, or both. If neither of the settings below is configured, the
feature is disabled entirely.
**Per zone (custom field).** Create a boolean custom field (e.g. `dns_bridge_notify_ns`) that applies
##### NS NOTIFY per Zone
This uses a True/False custom field attached to each Zone to enable/disable NOTIFY for each
individually.
Create a boolean custom field (e.g. `dns_bridge_notify_ns`) that applies
to `netbox_dns > zone`, then point the plugin at it:
```
'notify_ns_custom_field_name': 'dns_bridge_notify_ns'
@@ -116,7 +140,8 @@ to `netbox_dns > zone`, then point the plugin at it:
A NOTIFY is then sent for any zone whose custom field is set to `True`. This lets you toggle the
behavior per zone straight from the NetBox UI, without changing the plugin config.
**Globally (all zones).**
##### NS NOTIFY for all Zones
```
'notify_ns_all_zones': True
```
@@ -124,6 +149,9 @@ When enabled, a NOTIFY is sent for every zone on serial change, regardless of th
Defaults to `False`. The two options coexist: a NOTIFY is sent if the global switch is on **or** the
zone's custom field is set.
##### NS NOTIFY Settings
The nameserver addresses are resolved from NetBox DNS itself by looking up active A/AAAA records
(within the zone's view) matching each nameserver's hostname. The NOTIFY messages are signed with the
same per-view TSIG key configured under `tsig_keys`, so the receiving nameservers must accept NOTIFY
@@ -137,12 +165,14 @@ Destination port used for these NOTIFY messages. Defaults to 53.
As with the client NOTIFY feature, this uses NetBox's background job system, so at least one
`rq-worker` service must be running.
## Plugin compatibility
This plugin extends the netbox-plugin-dns plugin. As such the versioning was changed to match the
one of netbox-plugin-dns more closely. To guarantee compatability, ensure that the major and minor
version match between both plugins. For example, when using netbox-plugin-dns `v1.5.5` install
netbox-plugin-dns-bridge `v1.5.x`.
## Installation guide
This setup provisions a BIND9 server directly with DNS data from NetBox. BIND9 can optionally run on
a separate server. If so, any reference to 127.0.0.1 in step 6 must be replaced with the IP address
+1 -1
View File
@@ -2,7 +2,7 @@ from netbox.plugins import PluginConfig
from django.conf import settings
from .logger import get_logger
__version__ = "1.5.7"
__version__ = "1.5.8"
LOGGER = get_logger(__name__)
+13 -16
View File
@@ -42,12 +42,13 @@ def _load_tsig_key(view_name: str) -> dns.tsig.Key:
return dns.tsig.Key(name=key_name, secret=secret, algorithm=algorithm)
class SendDNSNotify(JobRunner):
class SendClientDNSNotify(JobRunner):
class Meta:
name = "Send DNS NOTIFY"
def run(self, *args, **kwargs):
notify_over_tcp = SETTINGS.get("notify_over_tcp", False)
port = SETTINGS.get("notify_client_port", 53)
view_name = kwargs["view_name"]
try:
@@ -89,17 +90,17 @@ class SendDNSNotify(JobRunner):
try:
if notify_over_tcp:
LOGGER.debug("Sending NOTIFY over TCP")
dns.query.tcp(msg, client.source_ip, port=5355, timeout=2)
dns.query.tcp(msg, client.source_ip, port=port, timeout=2)
else:
LOGGER.debug("Sending NOTIFY over UDP")
dns.query.udp(msg, client.source_ip, port=5355, timeout=2)
dns.query.udp(msg, client.source_ip, port=port, timeout=2)
LOGGER.info(
f"NOTIFY sent: {client.source_ip} {view_name}/{zone_name} {soa_serial}"
)
except Exception as e:
LOGGER.error(
f"NOTIFY failed: {client.source_ip}"
f"NOTIFY failed: {client.source_ip}:{port}"
f" {view_name}/{zone_name} {soa_serial}: {e}"
)
@@ -111,10 +112,10 @@ class SendDNSNotify(JobRunner):
close_old_connections()
class SendZoneNSNotify(JobRunner):
class SendNSNotify(JobRunner):
"""Send a NOTIFY straight to a zone's own nameservers.
Unlike ``SendDNSNotify`` (which notifies clients that previously queried the
Unlike ``SendClientDNSNotify`` (which notifies clients that previously queried the
transfer endpoint), this job resolves the addresses of the zone's configured
nameservers from NetBox DNS itself and notifies each of them so they pick up
the changed zone quickly.
@@ -151,9 +152,7 @@ class SendZoneNSNotify(JobRunner):
try:
tsig_key = _load_tsig_key(view_name)
except RuntimeError as e:
LOGGER.error(
f"NS NOTIFY aborted for {view_name}/{zone_name}: {e}"
)
LOGGER.error(f"NS NOTIFY aborted for {view_name}/{zone_name}: {e}")
return
fqdn = dns.name.from_text(zone_name, dns.name.root).to_text()
@@ -178,9 +177,7 @@ class SendZoneNSNotify(JobRunner):
LOGGER.debug("Sending NS NOTIFY over UDP")
dns.query.udp(msg, ip, port=port, timeout=2)
LOGGER.info(
f"NS NOTIFY sent: {ip} {view_name}/{fqdn} {soa_serial}"
)
LOGGER.info(f"NS NOTIFY sent: {ip} {view_name}/{fqdn} {soa_serial}")
except Exception as e:
LOGGER.error(
f"NS NOTIFY failed: {ip} {view_name}/{fqdn} {soa_serial}: {e}"
@@ -241,24 +238,24 @@ def _resolve_zone_nameserver_ips(zone: Zone) -> list:
return ips
def schedule(zone: Zone):
def schedule_client_notify(zone: Zone):
soa_serial = _get_soa_serial(zone)
if soa_serial is None:
return
SendDNSNotify.enqueue(
SendClientDNSNotify.enqueue(
zone_name=zone.name,
view_name=zone.view.name,
soa_serial=soa_serial,
)
def schedule_notify_ns(zone: Zone):
def schedule_ns_notify(zone: Zone):
soa_serial = _get_soa_serial(zone)
if soa_serial is None:
return
SendZoneNSNotify.enqueue(
SendNSNotify.enqueue(
zone_id=zone.pk,
zone_name=zone.name,
view_name=zone.view.name,
@@ -52,12 +52,12 @@ def zone_post_save(sender, instance, created, **kwargs):
catzm.increment_soa_serial()
if SETTINGS.get("notify_clients", False):
notify_handler.schedule(zone)
notify_handler.schedule_client_notify(zone)
# Send a NOTIFY to the zone's own nameservers when its SOA serial changed
# and the feature is enabled — globally or per zone via a custom field.
if soa_serial_changed and _notify_ns_enabled(zone):
notify_handler.schedule_notify_ns(zone)
notify_handler.schedule_ns_notify(zone)
transaction.on_commit(_on_commit)