Taller DNS Recursivo
Taller DNS Recursivo
Taller DNS Recursivo
¡Bienvenidos!
Todos los pasos serán realizados en tiempo real conectado a una máquina virtual con
la instalación básica de paquete de Ubuntu.
Quedará disponible este guión escrito, incluyendo los comandos listos para copiar y pegar.
Comenzamos entonces.
Al finalizar, tendremos el servicio "bind9" listo para iniciar, con parámetros por defecto que
permiten una rápida configuración.
1
Para demostrar el comportamiento sin validación, cambiaremos la directiva dnssec-
validation por no. Luego la volveremos a activar.
Activaremos la recursión, pero al mismo tiempo es muy importante definir qué IPs tendrán
acceso a esto. Definimos una lista de acceso:
$ cd /etc/bind
$ sudo vi named.conf.options
acl clientes {
127.0.0.0/16;
};
$ sudo vi named.conf.options
dnssec-validation no;
recursion yes;
allow-query {
clientes;
};
Con estos cambios, iniciamos named y ya podemos comenzar a probar nuestro nuevo
recursivo
Luego de cada reinicio o reconfiguración, es conveniente estar mirando los archivos de logs.
En nuestro caso el comando siguiente nos muestra los relacionados a named:
Se ve todo bien, podemos lanzar nuestra primera consulta recursiva, dando explícitamente
la opción +rec:
2
Nuestra primera consulta tarda un poco. En mi caso la obtuve en 716 milisegundos. Esto es
porque nuestro recursivo tiene el caché vacío, y tiene que comenzar la resolución desde la
raíz. Pero si consultamos de nuevo, vemos que obtenemos respuesta en 0 milisegundos!
Nuestro caché ya tiene esta respuesta y no tarda nada en responder.
Si miramos los logs, vemos algo extraño. Tenemos mensajes de error relacionados a IPv6.
Esto es porque lamentablemente nuestro sistema de virtualización no da soporte a
conectividad IPv6, pese a que el host sí lo tiene. Para mantener nuestros logs limpios,
podemos desactivar la conectividad IPv6 en nuestro recursivo. Esto se logra con la
siguiente configuración global:
$ sudo vi named.conf.options
server ::/0 { bogus yes; };
Bind tiene soporte nativo para qname minimization. Por default se encuentra en un estado
"relajado", que es preferible en estos momentos frente a un modo estricto. Esto porque hay
muchos dominios con configuraciones incorrectas que hacen fallar qname-minimization a
menudo.
VALIDACIÓN DNSSEC
3
$ dig @localhost www.dnssec-failed.org a
Como vemos, obtuvimos dos registros A de respuesta, con status NOERROR. Esto indica
que nuestro resolver pudo ubicar el nombre, pero no verificó las firmas. Corrijamos de
inmediato este error!
$ sudo vi named.conf.options
dnssec-validation auto;
y perfecto! Nuestra consulta ahora dió status SERVFAIL, y no hay respuesta. DNSSEC nos
está protegiendo, arrojando error en vez de una respuesta ante nombres que no cumplen
con una validación correcta. Podemos confirmar que es un error DNSSEC usando la opción
+cd, que desactiva validación en forma explícita para esa consulta, y debiéramos tener
resultados:
Por otro lado, un nombre de dominio correctamente firmado vendrá con el bit "ad",
indicando que el resolver pudo validarlo correctamente:
RPZ Y FILTROS
Como vimos en los módulos teóricos, una de las funciones más recurrentes es aplicar filtros
locales a ciertos nombres que no queremos que sean resueltos, como por ejemplo filtros
parentales.
4
$ sudo vi named.conf.options
response-policy {
zone "rpz.localhost";
};
$ sudo vi named.conf.local
zone "rpz.localhost" {
type primary;
file "/var/lib/bind/rpz.localhost.zone";
};
Creamos la zona. Pondremos como demo la dirección www.lacnic.net que será bloqueado
con NXDOMAIN. La forma de lograr un NXDOMAIN en RPZ es con un alias a la raíz
(CNAME .). Otra cosa importante es que los nombres deben ser relativos y no absolutos.
$ sudo vi /var/lib/bind/rpz.localhost.zone
$ORIGIN rpz.localhost.
@ 300 IN SOA localhost. hsalgado.vulcano.cl (
2022091101
60
60
432000
60
)
300 IN NS localhost.
5
Bind tiene un comportamiento conservador respecto a la relación entre RPZ y DNSSEC. Al
modificar las respuestas la validación DNSSEC se puede romper, ya que esa es su labor.
Por eso, Bind por defecto responde con el registro real en caso de recibir una consulta
pidiendo los registros DNSSEC. Si queremos romper incluso este caso, y filtrar las
respuestas sin importar si quebramos DNSSEC, se le debe agregar a la directiva "response-
policy" del named.conf.options, el valor "break-dnssec yes".
Existen diversos servicios que entregan zonas RPZ listas con cientos de dominios con
malware y bloqueos. En ese caso se deben utilizar zonas secundarias que transfieren de un
primario que mantiene estos nombres, según la configuración de cada servicio externo.
Aprovecharemos también de configurar un archivo de logs nuevo para dejar las consultas
por dominios bloqueados con RPZ. Para ello tenemos que crear un "canal", indicándole
dónde vamos a loguear, y la categoría correspondiente.
$ sudo vi named.conf.options
logging {
channel rpzlog {
file "rpz.log" versions 10 size 1024;
print-time yes;
print-category yes;
print-severity yes;
severity info;
};
category rpz { rpzlog; };
};
El archivo de logs queda en el directorio de cache por default. Ahí podemos revisar su
contenido:
$ cat /var/cache/bind/rpz.log
6
ZONAS INTERNAS PRIVADAS
Otra situación bastante común es el uso de zonas internas de una organización, donde
puede existir un subdominio que es invisible para las redes externas, pero sí se dispone de
autoritativos internos que sí responden.
Para ello, la técnica que veremos acá es la de declarar una zona "forwarder" desde nuestro
resolver.
$ sudo vi named.conf.local
zone "intranet.curso.localhost" {
type forward;
forwarders {
127.0.20.1;
127.0.21.1;
};
forward only;
};
Además debemos desactivar la validación DNSSEC para este nombre, debido a que al ser
inexistente en la zona real "curso.localhost", tendremos un NSEC que nos indicará que el
nombre no existe. Al desactivar DNSSEC podemos llegar a resolverlo.
$ sudo vi named.conf.options
validate-except {
"intranet.curso.localhost";
};
Si ahora recargamos, cualquier consulta a este nombre interno no será resuelto usando la
recursión en el árbol DNS público, sino será "forwardeado" a los dos servidores internos
7
indicados, y la respuesta será retornada al cliente final, logrando hacer funcionar un nombre
solo para clientes internos.
Dicho esto, el mecanismo es agregar un "negative trust anchor", el concepto de Bind para
desactivar validación. Esto se hace con el comando nta de rndc:
Esta desactivación queda por 1 hora, y luego se reactiva la validación. Si el dominio persiste
con el problema, hay que volver a evaluar y repetir el comando. Además, Bind cada 5
minutos verifica si las firmas se corrigen, en cuyo caso reactiva la validación antes de la
hora.
Con el comando:
8
ERRORES DE UPSTREAM CON COOKIES Y EDNS
Existen muchos dominios que están muy mal configurados, que funcionar casi de milagro.
Es complejo hacer un catálogo de todos los errores, pero hay uno en particular que se repite
bastante frecuentemente, y sobre todo con un servicio famoso en Internet que no quiero
nombrar, pero tengan por seguro que se toparán con el.
El uso de cookies está estandarizado y en operación, pero existen ciertos DNS autoritativos
que no saben cómo reaccionar ante la utilización de cookies. Bind por defecto las utiliza en
modo recursivo cuando contacta a los DNS autoritativos upstream, así que hay que estar
atentos.
Estos errores se pueden detectar fácilmente en forma manual. Si una consulta dirigida al
autoritativo con dnssec normal:
da error, SERVFAIL, FORMERR o se queda sin respuesta, prueben enviándola sin cookies:
Si acá tienen respuesta, entonces está claro el problema. La solución es agregar una
directiva "send-cookie" especial para ese servidor, identificándolo por su dirección IP, en la
configuración global pero fuera de la sección options:
$ sudo vi named.conf.options
server 6.6.6.6 { send-cookie no; };
Si siguen teniendo errors con +nocookie, puede ser que el servidor incluso esté fallando con
EDNS. Esto es un error muy grave, en el DNS Flag Day del año 2020 se definió que este
tipo de errores serían castigados marcando el autoritativo como "dead" (muerto). Pero
sabemos que a veces es necesario hacer excepciones!
9
Si acá tienen respuesta, entonces se puede poner una excepción más radical en la
configuración global:
$ sudo vi named.conf.options
server 6.6.6.6 { edns no; };
¡Con esto damos por finalizado el taller! Ahora es tiempo que ustedes tomen manos a la
obra. En el sitio del curso podrán encontrar las instrucciones para descargar la imagen de la
máquina virtual, o bien armarla ustedes. Luego deberán repetir estos comandos y ejecutar
una serie de pruebas, que será su evaluación final. ¡Mucha suerte!
10