I have a dns zone, which has serial number: 2015040500

Today I am going to add some CNAME records there, so I am interested in how to increment serial number, I mean should I change it based on today's date, e.g it will be: 2015042200 or just increment it with one, so it will be 2015040501 ?

up vote 6 down vote accepted

You can do however you please, the only thing you must make sure is that the new serial number is greater than the old one.

Having said that, I would recommend a timestamp based approach following a scheme like:

 YYYYMMDDxx

where xx starts at 00 and is incremented for all edits on that specific day (when editing on another day, you reset xx to 00)

The main advantage of this scheme is, that you also know the date of the last modification of your zone-file at first glance.

It also makes the serial number incrementing more robust.

The alternative is to start with 1 and just increment whenever you edit the file.

If the serial number is already timestamp based (and 2015040500 looks very much like that), you shold probably stick with that decision (even if not made by you), and use the logical successor 2015042200

  • DNS mode for emacs automatically increments serial numbers using the above model. – BillThor Apr 23 '15 at 2:47

i decided to use unix time for serial

- name: "{{ role_path|basename }} | get unix time"
  shell: echo $(date +%s)
  register: unix_time_stamp
  delegate_to: localhost
  run_once: true
  become: no

#
- name: "{{ role_path|basename }} setting execution facts"
  set_fact:
    __bind9_zone_serial: "{{ unix_time_stamp.stdout }}"
  run_once: true
  become: no
  • The idea is interesting, however following the date convention makes life easier for humans. – Rui F Ribeiro Feb 13 at 12:35
  • @RuiFRibeiro, $ date +%s 1518530553 $ date -d \@1518530553 вівторок, 13 лютого 2018 16:02:33 +0200 – shcherbak Feb 13 at 14:03
  • I am afraid I do not read Russian. I am not discussing the lack of merit of your technical solution, it is just that the format YYYYMMDDxx is more convenient for human operators when debugging problems, and is a more or less de facto unofficial standard. – Rui F Ribeiro Feb 13 at 14:07
  • 1
    @RuiFRibeiro it is not trivial to be conform with YYYYMMDDxx standard in case of the Ansible (to much workarounds needed). by the way, it was ukrainian output (also cyrillic), not russian :) I'v just pointed the date -d @TIMESTAMP for converting to humanreadable date – shcherbak Feb 13 at 19:35

A bash script searching for:

   12345 ; Serial

in directory /etc/bind/zones. It should match any number before ; Serial (case sensitive). And replace it with format YYYYMMDDxx.

#!/bin/bash

ZONES_PATH="/etc/bind/zones"
DATE=$(date +%Y%m%d)
# we're searching for line containing this comment
NEEDLE="Serial"
for ZONE in $(ls -1 $ZONES_PATH) ; do
    curr=$(/bin/grep -e "${NEEDLE}$" $ZONES_PATH/${ZONE} | /bin/sed -n "s/^\s*\([0-9]*\)\s*;\s*${NEEDLE}\s*/\1/p")
    # replace if current date is shorter (possibly using different format)
    if [ ${#curr} -lt ${#DATE} ]; then
      serial="${DATE}00"
    else
      prefix=${curr::-2}
      if [ "$DATE" -eq "$prefix" ]; then # same day
        num=${curr: -2} # last two digits from serial number
        num=$((10#$num + 1)) # force decimal representation, increment
        serial="${DATE}$(printf '%02d' $num )" # format for 2 digits
      else
        serial="${DATE}00" # just update date
      fi
    fi
    /bin/sed -i -e "s/^\(\s*\)[0-9]\{0,\}\(\s*;\s*${NEEDLE}\)$/\1${serial}\2/" ${ZONES_PATH}/${ZONE}
    echo "${ZONE}: "
    grep "; ${NEEDLE}$" $ZONES_PATH/${ZONE}
done

Modified version for bind configuration managed in a git repository, that update serial only for modified zone file:

#!/bin/bash
ZONES_PATH="$(pwd)/zones"
REPO_PATH="$(git rev-parse --show-toplevel)"
DATE=$(date +%Y%m%d)
NEEDLE="Serial"
for ZONE in $(git diff --name-only --diff-filter=AM `git merge-base origin/master HEAD` $ZONES_PATH) ; do
    curr=$(/bin/grep -e "${NEEDLE}$" ${REPO_PATH}/${ZONE} | /bin/sed -n "s/^\s*\([0-9]*\)\s*;\s*${NEEDLE}\s*/\1/p")
    if [ ${#curr} -lt ${#DATE} ]; then
      serial="${DATE}00"
    else
      prefix=${curr::-2}
      if [ "$DATE" -eq "$prefix" ]; then # same day
        num=${curr: -2} # last two digits from serial number
        num=$((10#$num + 1)) # force decimal representation, increment
        serial="${DATE}$(printf '%02d' $num )" # format for 2 digits
      else
        serial="${DATE}00" # just update date
      fi
    fi
    /bin/sed -i -e "s/^\(\s*\)[0-9]\{0,\}\(\s*;\s*${NEEDLE}\)$/\1${serial}\2/" ${REPO_PATH}/${ZONE}
    echo "${ZONE}: "
    grep "; ${NEEDLE}$" ${REPO_PATH}/${ZONE}
done

Note: you shouldn't make more than 99 modification during single day :)

  • The only problem with this script is updating all serials. In servers with many zones, you might only want to update the zones that were modified since the last time you ran it. – Rui F Ribeiro Feb 13 at 14:15
  • 1
    @RuiFRibeiro If you're versioning your configuration files with git you could replace ls -1 with something like git diff that would find only changed files. – Tombart Feb 14 at 7:15
  • @RuiFRibeiro I've added an example with git diff as it was hard to fit it into a single comment. – Tombart Feb 14 at 12:56

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.