DynDNS en casa con Bind9 y nsupdate
Friday, 23 de November de 2007Con los cambios de servidores de últimamente, nos encontramos que el servidor de correo no funcionaba bien, debido a la resolución DNS. Como uno de los servidores tiene IP fija y tiene instalado bind con las zonas configuradas, decidimos (gracias a marcos que es el que da ideas) montar un “dyndns” con ese servidor, de manera que el servidor de correo (que tiene IP dinámica) pudiera actualizar la IP y de esa manera hacer que el registro MX del dominio apuntara a un registro A directamente (y no a un CNAME como hasta ahora).
Por lo tanto, estas premisas son válidas si el escenario viene siendo este:
- Servidor BIND con IP pública fija y configurado con los ficheros de zona correspondientes.
- Servidor de XX (lo que sea) con IP dinámica.
- En nuestro caso, los SO eran debian y ubuntu respectivamente, pero entiendo que no es algo que vaya a afectar mucho al tema.
Lo primero es crear las keys que se usarán para autentificar a los clientes (como un login). Para eso, desde el servidor (hablo de servidor del que tiene instalado el BIND):
$ dnssec-keygen -a hmac-md5 -b 512 -r /dev/urandom -n USER foo22.bar44.com.
El “foo22.bar44.com.” es como un nombre de usuario, o sea que lo podeis canviar como gustéis. Esto nos crea dos ficheros, Kfoo22.bar44.com.+157+12505.key y Kfoo22.bar44.com.+157+12505.private que son las keys pública y privada respectivamente. Vamos a configurar el servidor.
Creamos un fichero llamado “keys.conf” (o lo que queráis, pero así es más descriptivo) y en su interior ponemos lo siguiente:
key foo22.bar44.com.
{
algorithm hmac-md5;
secret "YrVW9yP6gNMA7VbcU/r2mSIwYnFj/XkCDd6QuqOHE26/ipnrPy+eXrKr UyaFhB2XWNdVLUX7QCUkfhg4zN5YiA==";
};
Os explico. “key foo22.bar44.com.es” es el nombre de la key, que not iene por que ser el mismo que hemos puesto antes, simplemente es el nombre que pondremos más adelante en la configuración de BIND. Luego tenemos la definición de la key, con el algoritmo (en algun momento creo que algún comando me devolvió un error tal que BIND sólo soporta hmac-md5, no se si por mi configuración o es general) y la linia de secret. El carro de caracteres que hay ahí es el que encontraremos en el fichero .private que hemos generado antes (cuidado con ponerlo en una una sola línea y “calcadito” del fichero .private).
Ahora en el named.conf (en ubuntu/debian es mejor ponerlo en el named.conf.local), en la definición de la zona que queramos actualizar añadimos la cláusula:
allow-update {
key foo22.bar44.com.;
};
Con esto permitimos a quien se identifique con la calve pública que concuerde con la privada foo22.bar44.com. que es la que hemos definido anteriormente. Está bien configurar BIND para que haga log de los update de zona por que cuando la cosa empieza a fallar no sabes de donde vienen los palos.
logging {
channel “debug” {
file “/var/log/named.log” versions 3 size 5m;
print-time yes;
print-category yes;
};
category “update” { “debug”; };
};
Dos cositas más. Aseguraos que tanto en /var/log/named.log y en el directorio de configuración de bind, el propio bind pueda escribir, por que si no “cagada pasturet” como se dice en mi tierra (cagada pastorcito). En el directorio de configuración creara un fichero llamado $fichero_zona.jnl, que es un journal de los cambios de la zona, con lo que en cuanto pongáis esto en marcha, no editéis manualmente el dichero de zona por que no sirve de nada. En su lugar, “rndc freeze $ZONE” para parar el journaling de esa zona, editáis, y cuando acabe, “rndc thaw $ZONE”.
Bien. Vamos a por el cliente. Lo primero es copiar el fichero .key generado anteriormente al cliente. A partir de ahi, con el comando nsupdate, parametrizado, conseguiremos hacer un “borrar/crear” del registro que queramos, ya que no se puede hacer un “update”. Yo me hecho un picolo script con php que se conecta a checkip.dyndns.org y actualiza la IP en el servidor con lo que diga esa página (es del estilo de cual-es-mi-ip.net, pero sin formato para poderla tratar bien).
Queda pendiente que os ponga el script y su explicación, pero ahora no puedo conectarme con lo que será más adelante.
Pués ahí viene el script (botón derecho y guardar destino como). Básicament, usa curl para hacer la petición a checkip.dyndns.org guarda la salida (el html de la respuesta) en un string que luego se parsea para buscar la IP. Si ésta no ha cambiado desde la última vez, duerme 15 minutos (se puede cambiar modificando el número que multiplica al 60 en el parámetro de sleep()) y si es diferente de la última, envia la actualización al servidor. Hay unos cuantos parámtros configurados como variables, al principio, para que los podáis modificar más facilmente.
Notas: Las actualizaciones se hacen por TCP al contrario que las requests DNS que van por UDP. Es lógico por que no nos gustaría que se actualizara el registro DNS con ves a saber qué. Por esto tendréis que abrir el puerto 53 TCP para el servidor Bind. Otra cosa son los relojes. Si los relojes de los servidores no están minimamente sincronizados (entiendo que no es requerimiento que vayan sincronizados al segundo, pero ya os aviso que 10 minutos si son demasiados) el proceso falla. Entiendo que es un mecanismo de seguridad del servidor.
A disfrutarlo!


