Introducción

 

El numero serial de una zona DNS es uno de los campos del registro SOA (Start of Authority). El mismo indica un versionado del contenido de la zona y es utilizado en particular por los servidores secundarios para decidir si deben copiarse nuevamente una zona o no.

 

Cuando realizamos modificaciones a una zona DNS debemos incrementar el serial ya que de esa forma los secundarios saben que deben transferirse la zona nuevamente para replicar los cambios que hayamos introducido.

 

Ahora bien, supongamos que por error al modificar el archivo de zona introducimos un numero serial menor que el original. Los secundarios no van a transferirse la zona ya que consideran que la copia que tienen es mas actual que la que el master les ofrece.

 

¿Como podemos solucionar este problema? Hay dos caminos:

  • Si también tenemos derechos de administración sobre los secundarios podemos reiniciarlos para de esa forma forzar a que se transfieran la misma nuevamente
  • Si NO tenemos estos derechos entonces nos enfrentamos a que debemos realizar una rotación de numero serial

Aritmética modular

El serial es un entero de 32 bits sin signo (el rango es [0...2^32-1] o [0..4294967295]). La RFC 1982 define las propiedades aritméticas de estos números y en particular menciona que el máximo incremento que se le puede aplicar de una vez a un serial es de 2^31-1.

 

Como solo podemos incrementar el numero serial para forzar transferencias debemos entonces incrementarlo de tal manera que al "pasar" por 2^32-1 vuelva a 0. Esto ocurre debido a que las operaciones definidas en la 1982 son operaciones de aritmética modular.

 

En la aritmética 'módulo N' se define la adición de la siguiente manera:

 

C = (A + B) mod N

 

El operador 'mod N' indica que luego de realizar la adición tradicional debe tomarse el resto de la división entera entre el cociente N. 

 

Algunos ejemplos:

 

(1 + 4) mod 7 = 5

(5 + 3) mod 7 = 1

 

 

Rotación de número serial

Para entonces rotar el número serial de una zona lo que debemos es incrementarlo módulo 2^32 hasta llegar al número serial deseado. El algoritmo sería:

  • S = Numero de serie actual
  • N = Incremento
  • Calcular S = (S + N) mod 2^32
  • Notificar secundarios y esperar a que todos se transfieran la nueva zona
  • Repetir hasta llegar al S deseado

Si bien el incremento N podría ser cualquier número positivo es interesante elegir el N mas grande posible a los efectos de minimizar la cantidad de pasos y de transferencias de zona que hay que forzar.

 

Nuevamente citando la RFC 1982 vemos que el máximo incremento permitido en este caso es (2^32-1)

 

Ejemplo: Supongamos que tenemos como serial activo 2013012507 y deseamos rotarlo a 2013012411. Entonces podemos usar la siguiente secuencia de seriales:

 

  • Paso 0: 20122507
  • Paso 1: 4160496153 [ (20122507 + 2^32 - 1) mod 2^32, uso incremento máximo]
  • Paso 2: 20132411 [uso incremento menor al máximo, me sobran 92]

 

Si bien los cálculos no son difíciles al final del artículo se adjunta un pequeño script en Python que automatiza los mismos. El uso es muy sencillo, acepta dos parámetros que son el serial inicial y el final y produce la lista de pasos:

 

 

python adjust_soa_serial.py 2013012507 2013012411

MaxInc 2147483646: 

Step 0: 2013012507

INTER Step 1: 4160496153 (vfinal: 2013012411, diff: -2147483742)

FINAL Step 2: 2013012411 (vfinal: 2013012411, diff: -92)