July 27, 2009, 5:55 PM — Serial numbers in zone files help your DNS service determine whether it should re-ingest your zone files or ignore them. But there's more to these pseudo timestamps than meets the eye. In fact, the number that you put in your file and the one that DNS extracts from it might be as different as 200907270001 and 3338774385.
Serial numbers in DNS zone files provide a way for the server to verify that the contents of a particular zone file are up-to-date. If the serial number in a zone file hasn't changed since that zone was last loaded, named figures that it can ignore the file. This means that sysadmins have to remember to update the serial number every time they make a change to a zone file -- otherwise, their changes won't be picked up and published.
The format of the serial number is fairly flexible. Some sysadmins like to use a sequential number, incrementing it for every change they make. Others find it easier to base the sequence number on the current date. If so, they need to put the year first, followed by the month and day of the month to be sure that the serial numbers become larger each time a zone file is edited. They might have 20090729 in the zone file if they made changes on July 29th or they might prefer using 2009072901 for the first such change and 2009072902 when they make a second change the same day. Some sysadmins prefer, instead, to use four digits after the date so that they can associate the hour and minutes with their changes. Whatever method reminds you prefer is fine as long as each serial number you use is larger than the one preceding it and you don't forget to update it each time you make a change.
Your DNS service pays careful attention to your zone serial numbers, but it may not assign them the same value that you do. If your zone file assigns 200907270001 as your serial number, for example, your server will claim the serial number is 3338774385. You can use nslookup like this to verify the value that your DNS server assigns:
abns:/var/named # nslookup Default Server: localhost Address: 127.0.0.1 > set querytype=SOA > ns.particles.org Server: localhost Address: 127.0.0.1 particles.org origin = ns.particles.org mail addr = root.labns.annlab.telecomsys.com serial = 3338774385 <== look here refresh = 10800 (3H) retry = 3600 (1H) expire = 604800 (1W) minimum ttl = 86400 (1D) particles.org nameserver = ns.particles.org ns.particles.org internet address = 10.1.2.3 > exit
Hey, what happened?
What happened is that DNS reduces the serial number that you use if it's larger than the magical value of 4,294,967,296. If this number looks familiar to you, that's likely because it's the number of IP addresses available in IPv4 -- a nice big more-than-four-billion number that once was considered as many IP addresses as the world would ever need. It's also the number of different values that can be stored in 32 bits -- one more than the maximum value you caexpr n store in four bytes.
So, not surprisingly, the designers of DNS figured you wouldn't need more than four billion plus different serial numbers to manage your zone files. Still, they didn't want to cramp your style. So, if you exceed the big four billion plus number as I did in my example above, named will run one of those mod (modulo) operations on it, basically removing as many increments of 4294967296 as it can and then leaving you with the remainder. You can compute the serial number that DNS will use in bash like this:
# expr 200907270001 % 4294967296 3338774385
That's your serial number modulo 2^32 (two to the 32nd power).
This scheme works fine unless you, in a strangely perverse mood, decide to change the serial number in a zone file from 4294967295 (5) to 85899345944 (4). Considering how most sysadmins format their serial numbers, a change which inadvertently makes the serial number smaller is exceedingly unlikely.
If you forget to update your serial number before sending a hangup to (or restarting) named, you will likely find messages such as this one in your messages file:
master zone "ns.particles.org" (IN) rejected due to errors (serial 3338774384)
Plus, if you consider the math involved, the internal serial number in messages like this will at least make sense.