Skip to content

Receive DNS NOTIFYs, extract the SERIAL, write it into a DB and calculate zone propagation delay statistics

License

Notifications You must be signed in to change notification settings

nic-at/serial-logger

Repository files navigation

serial-logger

serial-logger logs the times at which a specific serial of a DNS zone becomes active on various name servers within a DNS infrastructure. To achieve this, all name server are configured to send NOTIFYs to the serial-logger. This enables accurate measurement of DNS propagation delay and helps assess compliance with SLA (Service Level Agreement) targets.

The logger tracks zone propagation across multiple stages: from the customer's hidden primary name server, through the incoming and distribution layers, up to the public (anycast) name servers.

✅ This script is actively used by RcodeZero DNS, a professional DNS service provider, to monitor DNS zone propagation across its global infrastructure.

🧭 Overview

Name servers can be configured to send NOTIFYs to other name servers to inform them about a new version of a zone. The sending of the NOTIFYs is usually done immediately after loading the new zone version.

The zone propagation delay is defined as the time difference between when a new zone becomes active on a primary name server and when the same zone version becomes active on a secondary name server. When sending of notifications are enabled, the time difference of receiving NOTIFYs from the primary name server and the secondary name server is a good indicator of the zone propagation delay.

The architecture supports four name server roles:

  • Customer: The hidden primary name server of the customer. It sends NOTIFY messages and serves as the primary name server for zone transfers.
  • Incoming: Internal name servers in the DNS infrastructure that receive zone transfers directly from the customer’s hidden primary.
  • Distribution: Internal servers responsible for distributing zones to the public-facing (anycast) name servers.
  • Secondary: Public anycast name servers that serve the zones to the world.

The software includes a daemon that listens for and processes incoming NOTIFY messages, logging the time each serial is observed.

The DNS server code is inspired by this Gist: https://gist.github.com/pklaus/b5a7876d4d2cf7271873

The idea of sending NOTIFYs from all the name servers to a central collector was coming from Jake Zack's presentation "Embracing SLA's: How Customer Requirements Drive Innovation" held at "OARC 39 & 47th CENTR Technical Workshop": https://indico.dns-oarc.net/event/44/contributions/960/attachments/915/1715/JakeZack-OARCCENTR-Embracing-SLAs.pdf (slide 10)

🌐 Zone Propagation Flow

Customer      Incoming      Distribution     Secondary  
+---+          +---+          +---+              +---+
| C | -------> | I | -------> | D | -----------> | S |
+---+          +---+          +---+              +---+
  |      Δ1      |                                 |
  | <----------- |                                 |  
  |              |       Δ2     |                  |  
  |              | <----------- |                  |  
  |                             |         Δ3       |  
  |                             | <--------------- |  
  • Δ1: Delay from Customer to Incoming
  • Δ2: Delay from Incoming to Distribution
  • Δ3: Delay from Distribution to Secondary
  • Customer-Lag: From the customer to the public facing name server: Δ1 + Δ2 + Δ3
  • Incoming-Lag: From the time the zone was received by the DNS provider to the public facing name server: Δ2 + Δ3. This is the 'delay' inside the DNS provider
  • Distribution-Lag: Δ3. Between the incoming and distribution name server, the DNS provider may perform certain checks on the zone which take time. After that checks, the zone will be distributed.

🗄️ Database Structure

This project uses a PostgreSQL schema named tlddns to manage and analyze DNS NOTIFY traffic and SLA compliance. Below is a breakdown of the schema and its components:

tlddns.serials:

Stores information about received DNS NOTIFY messages and the propagation delays to various name server types.

  • srcip: Source IP address of the NOTIFY
  • zone: Zone name (e.g. 'at')
  • received_at: Timestamp when the NOTIFY was received at the serial-logger (generated by the serial-logger)
  • serial: Zone serial number
  • ns_type: ENUM indicating the type of name server (customer, incoming, distribution, secondary)
  • distribution_lag, incoming_lag, customer_lag: Propagation delay indicators

Purpose: Track how long it takes a zone update to propagate to various types of name servers.

tlddns.nameservers

Stores metadata for each RcodeZero anycast name server.

  • ip4, ip6: IPv4/IPv6 addresses
  • hostname: DNS name
  • loc: Physical/data center location (in our case a 3 letter code), e.g. "mad"
  • dsc_name: Long/nice name of the location, e.g. "Madrid"
  • ns_type: ENUM (same as above)
  • status: ENUM showing if the server is in production, maintenance, or disabled

Purpose: Define the DNS server fleet used for monitoring and SLA calculations.

tlddns.customer_nameservers

Stores customer name server information.

  • ip: IP address of customer's name server
  • zone: Customer’s zone for which above IP address is allowed to send NOTIFYs (e.g., 'at' for customer nic.at)
  • accountname: Customer/account label

Purpose: Track where customers send NOTIFYs from and how they're associated with zones.

tlddns.slas

Stores SLA metrics per zone and serial.

  • zone: Zone name
  • serial: Serial number
  • min_lag, max_lag, avg_lag, median_lag, percentile_90_lag: Propagation delay statistics
  • ns_count: Number of name servers used in calculations
  • calculated_at: When the metrics were computed or time of last update

Purpose: Evaluate SLA compliance of zone propagation.

🔧 Features

  • Logs the timestamp when a serial number becomes active.
  • Detects and records propagation delays between DNS layers.
  • Processes IPv4 and IPv6 NOTIFYs.
  • Integrates with PostgreSQL for structured logging.
  • Logs data in three customizable environments: prod, test, and dev.
  • Designed for anycast and distributed DNS architectures.

🚀 Installation

  1. Clone the repository:
git clone https://github.com/nic-at/serial-logger
cd serial-logger
  1. Install the required dependencies:
sudo apt update
sudo apt install python3 python3-pip
pip install -r requirements.txt
  1. Set up the database user: Create a PostgreSQL user 'serial_logger': CREATE USER serial_logger WITH ENCRYPTED PASSWORD 'HEREYOURPASSWORD';

    Then add the user to pg_hba.conf.

  2. Configure database credentials: Copy the sample credential file and edit it:

cp credentials.yaml.sample credentials.yaml

Edit credentials.yaml to match your environment.

  1. Set up the database: Run the provided python3 init_all_dbs.py file on your PostgreSQL server to create the required schema and tables. This will also GRANT proper permissions to the serial_logger user.

▶️ Usage

Run the daemon to start listening for NOTIFY messages:

python3 serial_logger.py

Make sure the daemon has access to:

  • The PostgreSQL database
  • Proper network ports (for receiving NOTIFYs)
  • Logging paths

📜 License

This project is licensed under the Apache License 2.0. See LICENSE for details.

About

Receive DNS NOTIFYs, extract the SERIAL, write it into a DB and calculate zone propagation delay statistics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages