Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

jueves, 22 de diciembre de 2016

Cómo proteger el servidor DNS en Linux con DNSSEC

Hace ya tiempo hablé sobre cómo construir nuestro propio servidor DNS con bind9; un servidor que si bien era sencillo era funcional; la cuestión está en que hoy en día no basta con que un servicio funcione; también tiene que ser seguro. La seguridad es un tema que es, desgraciadamente, poco valorado en mucho ámbitos... Sí, uno se preocupa de la seguridad, pero no aplica ninguna medida, con lo que dicha "preocupación" suele ser ficticia. La cuestión es que este servicio en concreto, el DNS, es de importancia vital hoy en día y la seguridad de éste no debe de ser tomada a la ligera si no queremos sufrir sustos indeseados tales como la toma del control de este servicio para que le dirija a uno a una web fraudulenta en vez de a la original. Afortunadamente, Linux posee un recurso muy útil que, por un lado no supone ninguna molestia para el usuario final, y que por otro lado proporciona una sólida capa de seguridad para este servicio. Dicho recurso se llama DNSSEC.

DNSSEC_Portada

DNSSEC es una extensión de seguridad que se encarga de "firmar" digitalmente las transmisión de datos de forma que certifica que el sitio es válido y que no ha sido suplantado. Con esto tratamos de tener la seguridad de que realmente estamos visitando el sitio que deseamos. Es importante tener en cuenta que esta tecnología no sustituye al cifrado SSL; es decir que cada tecnología tiene su propósito. SSL, cifra las conexiones mientras que DNSSEC verifica la autenticidad del nombre de minio. Una de las virtudes de extensión de seguridad es que está incluida por defecto en el sistema, con lo que no requiere que se descarguen paquetes adicionales para hacer funcionar esta extensión, si bien obviamente habría que realizar una serie de configuraciones para que dicha extensión esté activa y que funcione correctamente; configuraciones que veremos a continuación.

Antes de nada, doy por supuesto que ya se ha creado el servidor DNS, con lo que se dará por sentado que ya se han aplicado las configuraciones mínimas para tener un DNS funcional. En caso contrario recomiendo mirar el artículo de creación de un DNS con bind9, cuyo link se encuentra al principio de este post. Comencemos entonces.

Lo primero que necesitamos hacer es habilitar el uso de la extensión DNSSEC dentro de nuestro servidor DNS; cosa que sería tan sencilla como acceder al fichero /etc/bind/named.conf.options y editarlo. Veréis que dentro de dicho fichero, todo el contenido se encuentra dentro de una sección entre {} llamada "options". En dicha sección habría añadir las siguientes líneas:

  1. dnssec-enable yes;
  2. dnssec-validation yes;
  3. dnssec-lookaside auto;

En caso de encontrarnos con líneas parecidas a éstas dentro de dicho fichero, habría que o bien comentar dichas líneas o eliminarlas. Ahora bien, no pensemos que con ésto seria suficiente para fortificar nuestro DNS; hace falta crear una serie de "claves" que serán las que se usarán para más adelante realizar la verificación de que efectivamente el nombre del dominio al que estamos accediendo, es real. Todo el proceso se realizará suponiendo que el nombre del dominio es pruebaivan.net, con lo que cualquier aplicación que se quiera hacer para otro nombre, tendrá que realizarse modificando dicho nombre. Habría que crear dos pares de claves (al decir dos pares de claves me refiero a que habría que crear dos claves públicas y privadas). Para dicha creación nos tendríamos que situar dentro del directorio /var/cache/bind/ y teclear el siguiente comando:

dnssec-keygen -a NSEC3RSASHA1 -b 4092 -n ZONE pruebaivan.net

Este proceso tardará bastante tiempo, pues nos estará creado una clave pública y privada de un tamaño de 4092 bytes usando un cifrado "NSECRSASHA1". A modo de recomendación, sería deseable abrir una terminal aparte y hacer que la CPU del equipo esté trabajando con el fin de que el proceso de creación de claves sea más rápido, ya que éste suele ser bastante lento. Yo generalmente, al crear un clave, abro una terminal aparte y escribo el siguiente comando:

i=1while [ $i > 0 ]do echo $ii=$(($i + 1));done

Tras finalizar el proceso que, dependiendo de la potencia de nuestro equipo, puede tardar desde minutos hasta horas, habría que crear otro par de claves más; par de claves que también estarían en la misma carpeta, es decir en /var/cache/bind. El comando para crear dicho nuevo par de claves, difiere bastante poco del anterior, tal y como vereis a continuación:

dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4092 -n ZONE pruebaivan.net

Ahora vamos a crear un fichero de "zonas" que, por un lado incluya la configuración referente al hostname, y que por otro lado tenga en su interior referencias a las claves que acabamos de crear; en concreto a las claves públicas que acabamos de crear cuya extensión sea .key. El fichero en cuestión  se llamará nombre_dominio.zone y estará ubicado en el mismo directorio que las claves que hemos creado; mi caso el dominio se llamaría pruebaivan.net.zone. En dicho fichero habría que volarle primero desde la consola las siguientes líneas; en vuestro caso, tendríais que sustituir "pruebaivan.net "por vuestro nombre de dominio:

echo \$TTL 3600 > ; for key in `ls Kpruebaivan.net*.key`do echo "\$INCLUDE $key" >> pruebaivan.net.zone; done

Con este volcado en el fichero, el aspecto de éste tendría que ser algo medianamente parecido a lo siguiente:

  1. $TTL 3600
  2. $INCLUDE Kpruebaivan.net.+007+45422.key
  3. $INCLUDE Kpruebaivan.net.+007+63606.key

Pero con esto de por sí no es suficiente; tenemos que añadir una serie de configuraciones extra para que el fichero sea válido; en concreto el fichero final sería el siguiente, donde pruebaivan.net sería el nombre de dominio y 192.168.1.6 sería la IP de dominio:

  1. $TTL 3600
  2. $INCLUDE Kpruebaivan.net.+007+45422.key
  3. $INCLUDE Kpruebaivan.net.+007+63606.key
  4. @       IN      SOA     pruebaivan.net. root.pruebaivan.net. (
  5.                               2         ; Serial
  6.                          604800         ; Refresh
  7.                           86400         ; Retry
  8.                         2419200         ; Expire
  9.                          604800 )       ; Negative Cache TTL
  10. ;
  11. @       IN      NS      pruebaivan.net.
  12. @       IN      A       192.168.1.6
  13. @       IN      MX 0    pruebaivan.net.
  14. www     IN      A       192.168.1.6
  15. uah     IN      CNAME   pruebaivan.net.

Ya casi estaría, ahora habría "firmar" este fichero de zonas mediante el comando dnssec-signzone para que las zonas que aparecen en éste se consideren "seguras", Esto se logra mediante el comando de a continuación:

dnssec-signzone -A -3 $(head -c 1000 /dev/urandom | sha1sum | cut -b 1-16) -N INCREMENT -o pruebaivan.net -t pruebaivan.net.zone

Este proceso de firma crearía un fichero de zonas firmado llamado nombre_dominio.zone.signed que sería el fichero de zonas firmado mediante nuestro último comando... Ahora obviamente habría que usarlo, pues en caso contrario el proceso realizado hasta ahora no habría valido para nada. Esto es tan sencillo como editar el fichero /etc/bind/named.conf.local y cambiar la ruta del parámetro file de la zona por la ruta del nuevo fichero de zonas... Véase el siguiente ejemplo para tener una idea más clara:

Antes:

  1. zone "pruebaivan.net" {
  2.         type master;
  3.         file "/etc/bind/db.pruebaivan";
  4. };

Despues:

  1. zone "pruebaivan.net" {
  2.         type master;
  3.         file "/var/cache/bind/pruebaivan.net.zone.signed";
  4. };

Ahora únicamente habría que reiniciar el servidor DNS para aplicar los cambios, que sería tan sencillo como escribir:

/etc/init.d/bind9 restart

Ahora bien. ¿Cómo podemos saber si efectivamente nuestro host está usando esta extensión? A nivel de usuario final no notaremos nada, pero si "sondeamos" el host mediante el comando dig, veremos que efectivamente estamos usando dicha extensión de seguridad y que efectivamente, el hostname es el que debe ser:

dig DNSKEY pruebaivan.net. +multiline

dig_resultado

Como veis, si bien el proceso de añadir la capa de seguridad de DNSSEC es algo tedioso, se trata de una medida de seguridad que muy interesante que podemos usar en combinación con otras medidas tales como el cifrado SSL o el uso de cortafuegos.

Espero que os haya resultado útil.

Saludos.

2 comentarios :

  1. Te agradezco muchísimo tu manual.Yo tenía un problema con los chrome de mi red que se basaba en despreciar, a priori, los DNS no encriptados. Había dos soluciones, o el cambiar la configuración de los chrome o utilizar DNS encriptado

    Que sepas que me ha servido y me ha salvado de un atolladero.

    ResponderEliminar
  2. Por cierto, hay una errata en esa especie de guión

    echo \$TTL 3600 > ; for key in `ls Kpruebaivan.net*.key`; do echo "\$INCLUDE $key" >> pruebaivan.net.zone; done

    después del echo \$TTL 3600 > ; falta el destino, que en tu caso sería pruebaivan.net.zone

    quedaría así cho \$TTL 3600 >pruebaivan.net.zone ; BLABLABLA

    ResponderEliminar