Debido a la noticia de los ataques prácticos a SHA-1, se está haciendo cada vez más necesario realizar rotaciones de algoritmo en DNSSEC, que es el mecanismo ordenado para pasar desde una llave vulnerable que utiliza SHA-1, hacia una superior.
Hacer una rotación de algoritmo de una llave tiene sus sutilezas, y es un poco más complicado que la rotación normal de llaves -aquella donde solo se reemplaza una por otra nueva, manteniendo su algoritmo-.
Acá procedo a contar mi experiencia en realizar esta rotación de algoritmo, siguiendo las últimas recomendaciones.
Si usted considera esto muy complejo, no se preocupe. Los actuales sistemas de firma DNSSEC automatizan todo este procedimiento. Lo que demostraré ahora es la forma “hacker” de hacerlo. Y aunque usted no esté tan loco para hacerlo así, de todas formas es conveniente conocer los detalles de los pasos, para además ser capaz de monitorear su sistema automático y estar confiado en el proceso.
Lo más importante a tener en cuenta es que el DNS es un sistema altamente distribuido, con caches intermedios, y que por lo tanto, hay que tener siempre presente respetar los tiempos de cada paso. No es posible acelerar cada etapa. Después de cada paso es necesario esperar el tiempo que el mismo protocolo define por medio de los campos “TTL” de cada registro.
Es decir, tenga calma, y todo estará bien.
Utilizaremos las herramientas de firmado “en crudo” de Bind, pero sin el manejo ni publicación automática de llaves que tiene internamente. Además los ejemplos se refieren a una zona hipotética “ejemplo.cl”. Recuerde reemplazar este valor para su propio caso.
Los pasos son básicamente 7.
Comenzamos con una zona firmada con DNSSEC, con su KSK1 y ZSK1; y además el padre tiene correctamente configurado el registro DS1, apuntando a la KSK de nuestra zona.
En esta etapa creamos una nueva ZSK2 con el nuevo algoritmo. En este caso pasaremos de una RSASHA1 a una RSASHA256:
$ dnssec-keygen -a RSASHA256 -3 -b 1024 -n ZONE -c IN -r /dev/urandom ejemplo.cl
Esta nueva llave debe ponerse en la zona, mediante un INCLUDE o directamente en el archivo.
Luego, damos la instrucción de firma con las dos ZSK. Es importante agregar la opción “-P” en este paso, para evitar que el comando falle por no encontrar la KSK correspondiente a la nueva ZSK:
$ dnssec-signzone -u -Q -3 - -g -N increment -k <archivo_ksk_1> -o ejemplo.cl -e now+2592000 -f ejemplo.cl.signed -P ejemplo.cl <archivo_zsk_1> <archivo_zsk_2>
Con esto ya podemos publicar la nueva zona en el DNS.
Es necesario esperar un tiempo prudente antes del siguiente paso, el que es dependiente de los parámetros específicos de cada zona, y del padre de la zona. Existe toda una ciencia del “timing” en DNSSEC (ver RFC7583: “DNSSEC Key Rollover Timing Considerations“), pero para nuestro caso podemos simplificarlo en:
tiempo de espera = tiempo de sincronización y propagación nueva zona + TTL del DNSKEY
En mi caso en particular, el “tiempo de sincronización y propagación nueva zona“ representa lo que demora desde que cargo la zona en el primario, y ya está en todos los secundarios. Para mí eso es muy pequeño, generalmente algunas decenas de segundos. Todo depende de la velocidad de sincronización de sus secundarios.
El segundo es más simple: miren el campo TTL de la zona para el registro DNSKEY. O bien pueden obtenerlo con una consulta a un autoritativo de su zona:
$ dig @ns1.ejemplo.cl ejemplo.cl DNSKEY
[ ... salida del comando... ]
;; ANSWER SECTION:
ejemplo.cl. *7200* IN DNSKEY 256 3 8 AwEAAb+TgVyeaGob...
ejemplo.cl. *7200* IN DNSKEY 257 3 8 AwEAAfEG/xIgexdUN...
En este caso el número “7200″ es el TTL en segundos: 2 horas.
Por lo tanto, podemos decir que luego de cualquier cambio con mis llaves, debo esperar 2 horas y algunas decenas de segundos.
En lo personal, espero 3 horas.
Sigamos con los pasos entonces.
Luego de esperar 3 horas luego del paso 2, seguimos adelante.
Esta etapa es muy similar a la 2, pero creando una KSK. También pasaremos de una RSASHA1 a una RSASHA256:
$ dnssec-keygen -a RSASHA256 -3 -b 2048 -n ZONE -c IN -r /dev/urandom -f KSK ejemplo.cl
Esta nueva llave también debe ponerse en la zona, mediante un INCLUDE o directamente en el archivo.
Luego, damos la instrucción de firma con las dos ZSK y las dos KSK:
$ dnssec-signzone -u -Q -3 - -g -N increment -k <archivo_ksk_1> -k <archivo_ksk_2> -o ejemplo.cl -e now+2592000 -f ejemplo.cl.signed ejemplo.cl <archivo_zsk_1> <archivo_zsk_2>
Y con esto ya podemos volver publicar la nueva zona en el DNS.
Comenzamos esperando las 3 horas de publicación de la zona del paso anterior.
Luego ya podemos enviar a nuestro padre el nuevo DS2, correspondiente a nuestra nueva KSK2. Es importante que se agregue el nuevo DS, y se mantenga el existente DS1. Deben quedar ambos publicados.
El método de envío y publicación depende de cada padre. En mi caso se usa el panel de control de NIC Chile. También el tiempo de espera acá es distinto al de las llaves, porque el TTL es definido por el padre. Se puede hacer la misma consulta “dig” del cálculo del TTL del DNSKEY, pero reemplazando al autoritativo por algún autoritativo de la zona padre, y poniendo DS en vez de DNSKEY. En el caso de CL es 3600, es decir, 1 hora.
Luego de esperar las 2 horas correspondientes (recuerden que el TTL del padre es 1 hora, no 2 como el de nuestro DNSKEY), pasamos a la siguiente etapa.
Nuevamente vamos al padre, y esta vez eliminamos DS1, dejando sólo activo el nuevo DS2.
Luego de esperar las 2 horas desde realizado el paso 5, eliminamos KSK1 de nuestra zona.
Para ello la quitamos del INCLUDE o del archivo de zona, y luego refirmamos sólo usando la KSK2:
$ dnssec-signzone -u -Q -3 - -g -N increment -k <archivo_ksk_2> -o ejemplo.cl -e now+2592000 -f ejemplo.cl.signed -P ejemplo.cl <archivo_zsk_1> <archivo_zsk_2>
Acá al igual que el paso 2, es importante dar la opción -P para evitar errores en el proceso.
Publicamos esta nueva zona en el DNS, y esperamos el tiempo correspondiente (esta vez son 3 horas!).
Luego de esperar las 3 horas de rigor de publicación de la zona anterior, pasamos a la última etapa: eliminar la ZSK1.
Para ello, primero eliminamos ZSK1 del INCLUDE de la zona, o del mismo archivo.
Luego, procedemos a la firma solo con KSK2 y ZSK2:
$ dnssec-signzone -u -Q -3 - -g -N increment -k <archivo_ksk_2> -o ejemplo.cl -e now+2592000 -f ejemplo.cl.signed ejemplo.cl <archivo_zsk_2>
Publicamos, ¡y ya podemos dar por terminada la rotación de algoritmo de nuestras llaves!
Recomiendo ir revisando paso a paso con herramientas de diagnóstico como “dig”, o sitios externos tales como DNSViz o zonemaster.
También por seguridad es recomendable consultar a los resolutores públicos más famosos, para estar seguros que después de cada paso tienen la información correcta. Por ejemplo, un comando como
$ dig @8.8.8.8 ejemplo.cl dnskey +dnssec
debiera mostrar las llaves correctas luego de las 3 horas de espera. Se pueden usar otros como 9.9.9.9, 1.1.1.1, etc; para mayor seguridad.