; I'm posting this one in Elisp.
;
; Someone I work with entered 200710110333 instead of
; 2007101103 for a serial number field of the SOA RR on
; our root DNS server. Once this high number propagated
; DNS updates with the correct date broke.
;
; The problem is that the following is true:
(< 2007101201 200710110333)
; so today's updates didn't propogate to our other servers.
;
; According to:
; http://www.zytrax.com/books/dns/ch9/serial.html
;
; "perhaps ritual suicide is the best option" it also says:
;
;; The SOA serial number is an unsigned 32-bit field with
;; a maximum value of 2**31, which gives a range of 0 to
;; 4294967295, but the maximum increment to such a number
;; is 2**(31 - 1) or 2147483647, incrementing the number
;; by the maximum would give the same number.
;
; Did I read that math right? I think the key word here
; is "usigned". Checking up on this:
(insert-string (expt 2 32))
(insert-string (expt 2 31))
(insert-string (expt 2 30))
; Inserts 4294967296, 2147483648 and 1073741824 into the
; buffer respectively. Also, the notation is bad, I think they
; mean (2**31) - 1 not 2**(31 - 1). More precisely one of
; the two:
(- (expt 2 31) 1)
(- (expt 2 32) 1)
; I guess I'll compute both and use this to solve my problem.
; Let's assume that the following is true:
;
;; An unsigned 32-bit field with a maximum value of 2**31
;
; Actually let's check the RFC:
;
;; http://www.faqs.org/rfcs/rfc1982.html
;
; which defines SERIAL as:
;
;; The unsigned 32 bit version number of the original copy of
;; the zone. Zone transfers preserve this value. This value
;; wraps and should be compared using sequence space arithmetic.
;
; It is "the maximum is always one less than a power of two."
; The DNS-Pro book then says:
;
;; Using the maximum increment, the serial number fix is a two-step
;; process. First, add 2147483647 to the erroneous value, for example,
;; 2008022800 + 2147483647 = 4155506447, restart BIND or reload the zone,
;; and make absolutely sure the zone has transferred to all the slave
;; servers. Second, set the SOA serial number for the zone to the correct
;; value and restart BIND or reload the zone again. The zone will
;; transfer to the slave because the serial number has wrapped through
;; zero and is greater that the previous value of 4155506447! RFC 1982
;; contains all the gruesome details of serial number comparison
;; algorithms if you are curious about such things.
;
; OK so what's the real_error value? It wrapped by 2^32:
(mod 200710110333 (expt 2 32))
; Which makes sense since
;
; me@workstation:~> dig @nameserver mta1.domain.tld
; ...
; domain.tld. 3600 IN SOA
; nameserver.domain.tld. hostmaster.domain.tld.
; 3141614717 1800 900 86400 3600
; me@workstation:~>
; So, I'm going to set my root server's SOA SN to 3141614717
(mod 200710110333 (expt 2 32))
; To get everyone back in sync. dig verified that they're
; back in sync in less than an hour:
;
;; for x in dns1 ... dnsN;
;; do dig @$x domain.tld SOA +short;
;; done
;
; I'm then free to set it to:
(let ((today 2007101201))
(- (expt 2 32)
1
(abs (- today (- (expt 2 31) 1)))))
; or greater than 0 but less than:
(let ((error_value 3141614717))
(mod
(+ (- (expt 2 31) 1) error_value)
(expt 2 32)))
; For fun my colleague and I went with 666 and then did
; an "rndc reload" and then set it to today and reload
; again.
Friday, October 12, 2007
DNS Math
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment