]> git.ipfire.org Git - dbl.git/commitdiff
exporters: Support customizing the DNS zones
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 2 Jan 2026 11:55:23 +0000 (11:55 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 2 Jan 2026 12:07:55 +0000 (12:07 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/dnsbl/exporters.py

index d29283c06c36841b976cfec3dcb644f9ae6b2087..ea533315ce9563e22fb4969ec90dad15189efeee 100644 (file)
@@ -168,7 +168,8 @@ class AdBlockPlusExporter(TextExporter):
 
 
 class ZoneExporter(TextExporter):
-       def export(self, f, ttl=60):
+       def export(self, f, ttl=None, primary=None, zonemaster=None,
+                       refresh=None, retry=None, expire=None, nameservers=None):
                # Write the header
                self.write_header(f, ";")
 
@@ -181,26 +182,110 @@ class ZoneExporter(TextExporter):
                # Write $ORIGIN
                f.write("$ORIGIN %s\n" % origin)
 
+               # Read the configuration
+               if self.backend.config.has_section(self.section):
+                       # Fetch the TTL
+                       if ttl is None:
+                               ttl = self.backend.config.getint(
+                                       self.section, "ttl", fallback=None,
+                               )
+
+                       # Fetch the primary
+                       if primary is None:
+                               primary = self.backend.config.get(
+                                       self.section, "primary", fallback=None,
+                               )
+
+                       # Fetch the zonemaster
+                       if zonemaster is None:
+                               zonemaster = self.backend.config.get(
+                                       self.section, "zonemaster", fallback=None,
+                               )
+
+                       # Fetch the refresh time
+                       if refresh is None:
+                               refresh = self.backend.config.getint(
+                                       self.section, "refresh", fallback=None,
+                               )
+
+                       # Fetch the retry time
+                       if retry is None:
+                               retry = self.backend.config.getint(
+                                       self.section, "retry", fallback=None,
+                               )
+
+                       # Fetch the expire time
+                       if expire is None:
+                               expire = self.backend.config.getint(
+                                       self.section, "expire", fallback=None,
+                               )
+
+                       # Fetch the nameservers
+                       if nameservers is None:
+                               nameservers = self.backend.config.get(
+                                       self.section, "nameservers", fallback=None,
+                               )
+
+                               # Split the namesevers
+                               if nameservers:
+                                       nameservers = [
+                                               nameserver.strip() for nameserver in nameservers.split(",")
+                                       ]
+
+               # Set a default TTL if none was set
+               if ttl is None:
+                       ttl = 60
+
+               # Set a default primary
+               if primary is None:
+                       primary = "primary.invalid."
+
+               # Ensure the primary ends with a dot
+               if not primary.endswith("."):
+                       primary = "%s." % primary
+
+               # Set a default for the zonemaster
+               if zonemaster is None:
+                       zonemaster = "zonemaster@invalid."
+
+               # Ensure the zonemaster ends with a dot
+               if not zonemaster.endswith("."):
+                       zonemaster = "%s." % zonemaster
+
+               # Replace any @ in the zonemaster
+               zonemaster = zonemaster.replace("@", ".")
+
+               # Set a default refresh time
+               if refresh is None:
+                       refresh = 3600
+
+               # Set a default retry time
+               if retry is None:
+                       retry = 600
+
+               # Set a default expire time
+               if expire is None:
+                       expire = 3600000
+
+               # Set a default nameserver because some DNS servers
+               # refuse to load a zone without any NS records
+               if nameservers is None:
+                       nameservers = ("nameserver.invalid.",)
+
                # Set the TTL
                f.write("$TTL %s\n" % ttl)
 
                # Write the SOA
-               f.write(" ".join((
-                       "@",
-                       "IN",
-                       "SOA",
-                       "master.lwldns.net.",
-                       "hostmaster.ipfire.org.",
-                       serial,
-                       "3600",
-                       "600",
-                       "3600000",
-                       "%s" % ttl,
-               )))
-               f.write("\n")
-
-               # XXX Add NS
-               f.write("@ IN NS master.lwldns.net.\n")
+               f.write("@ IN SOA %s %s %s %s %s %s %s\n" % (
+                       primary, zonemaster, serial, refresh, retry, expire, ttl,
+               ))
+
+               # Write all nameservers
+               for nameserver in sorted(nameservers):
+                       if not nameserver.endswith("."):
+                               nameserver = "%s." % nameserver
+
+                       f.write("@ IN NS %s\n" % nameserver)
 
                # Add the update timestamp (in human-readable format)
                if self.list.updated_at:
@@ -231,6 +316,9 @@ class BlocklistExporter(ZoneExporter):
        type = "A"
        content = "127.0.0.2"
 
+       # The section in the configuration file for additional settings
+       section = "dnsbl"
+
 
 class RPZExporter(ZoneExporter):
        """
@@ -240,6 +328,9 @@ class RPZExporter(ZoneExporter):
        type = "CNAME"
        content = "."
 
+       # The section in the configuration file for additional settings
+       section = "rpz"
+
 
 class SquidGuardExporter(Exporter):
        """