; 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