Rate this page

Flattr this

Reset the serial number of a DNS zone

Tested on

Debian (Lenny)
Ubuntu (Lucid, Maverick)

Objective

To reset the serial number of a DNS zone

Scenario

Suppose that the zone example.com has two nameservers: ns0.example.com (198.51.100.1) which is the master and ns1.example.com (203.0.113.1) which is a slave.

You follow the convention of encoding the date in the DNS serial number, but have made a mistake: instead of 2011012400 you have set it to 2111012400. You want to correct this error without disrupting the normal operation of the zone (and in particular, without causing ns1 to lose synchronisation with ns0).

Background

Serial numbers are used by slave nameservers to determine when a zone transfer is necessary. Higher values are considered to be more recent than lower values. If the master has a more recent copy of the zone than the slave then the slave requests a transfer.

For this scheme to work the serial number of each zone must increase monotonically. However, serial numbers do not follow the normal rules of integer arithmetic. Instead they use 32-bit sequence space arithmetic:

Changing a serial number directly from 2111012400 to 2011012400 is not allowed because it would require either a subtraction, or an addition outside of the permitted range. However it is possible to achieve the same outcome by performing two separate additions.

Method

Overview

The following procedure allows any desired serial number to be reached:

  1. Calculate the total distance by which the serial number must advance to reach the desired value.
  2. Divide this distance into steps that are no larger than the permitted maximum.
  3. Add each step to the serial number of the master zone file, stopping after each one until all of the slave nameservers have resynchronised.

Steps 1 and 2 can be performed using the DNS serial number calculator provided in the tools section of this website.

Calculate the total distance by which the serial number must advance

Serial numbers wrap around modulo 232 (equal to 4294967296). To calculate the total distance you should therefore:

For the scenario considered here this would be (2011012400 − 2111012400) + 4294967296 = 4194967296.

Divide the total distance into steps

The maximum distance by which the serial number can advance in one step is 231−1 (equal to 2147483647). It is desirable that the number of steps be minimised in order to avoid unnecessary work. This can be achieved as follows:

It is usually possible to reach the desired serial number in two steps. For the scenario considered here, those steps would be:

There are only two situations that require three steps:

Add each step to the serial number of the master zone file

Each time the serial number is changed you must reload the zone into the master nameserver, then wait for it to propagate to all of the slaves.

You can check whether a zone change has propagated to a particular slave by requesting the SOA record for the zone:

dig @203.0.113.1 -t SOA example.com

The format of the answer is slightly different from the format used in a zone file, but it contains the same information (including the serial number) in the same order:

;; ANSWER SECTION:
example.com.            86400   IN      SOA     example.com. hostmaster.example.com. 2011012400 86400 900 1209600 3600

If you make a second change to the serial number when one of the slave nameservers has not registered the first one then instead of taking two steps forward the value will appear to have taken one step back. The zone will not then be transferred and the slave will lose synchronisation with the master. If this happens then you will need to repeat the entire process from the beginning.

Alternatives

Purge each slave of zone data

An alternative method is to:

It should then fetch a fresh copy of the zone, regardless of serial number. The details of this method will vary according to the nameserver software you are using. In the case of BIND 9, the location of the zone file is specified in the zone declaration:

zone "example.com" {
  type slave;
  masters { 198.51.100.1; };
  file "/var/lib/bind/db.example.com";
};

Deleting this file while the nameserver is stopped should have the desired effect, for example:

service stop bind9
rm /var/lib/bind/db.example.com
service start bind9

As above you can check which version of the zone has been loaded by inspecting the SOA record. Depending on your configuration, it may be necessary to purge some or all of the slaves simultaneously in order to prevent them from fetching the unwanted copy of the zone from each other.

Methods to avoid

Set the serial number to zero

Some nameserver software will perform a zone transfer if the serial number on the master is set to zero, regardless of the serial number on the slave. This behaviour was never RFC-compliant, and is no longer supported by BIND.

Tags: dns