Introducción al servicio DNS

per Victor Carceler darrera modificació 2024-01-28T14:08:10+02:00

Introducción

El Sistema de Nombres de Dominio (DNS - Domain Name System) permite asociar nombres de domino con direcciones IP para facilitar en gran medida el acceso a las máquinas de la red. Sin DNS referirse a una máquina implica recordar su dirección IP y trabajar directamente con direcciones IP no es cómodo porque son difíciles de recordar y porque la dirección IP de una estación puede variar por diferentes motivos. Quien utiliza el nombre de dominio no necesita preocuparse por estos cambios (aunque el servidor DNS debe conocer la IP real en cada caso).

El sistema de nombres de dominio es una base de datos distribuida y jerárquica, y aunque su función principal es asociar los nombres de dominio con direcciones IP también puede guardar otras informaciones. El servicio DNS es uno de los pilares de la red y por eso su disponibilidad debe ser absoluta. Para conseguirlo se utilizan servidores redundantes y se hace uso de cache para mejorar su rendimiento.

Conceptos relacionados con el DNS

Concepto Explicación
Cliente DNS (resolver)

Es el componente que permite consultar a los servidores DNS y todas las estaciones de red cuentan con uno.

En GNU/Linux tradicionalmente se ha utilizado el fichero /etc/resolv.conf como configuración del resolver. Hoy en día es habitual que cada estación ejecute systemd-resolved o dnsmasq para proporcionar resolución de nombres a las aplicaciones locales.

Su función es mejorar el rendimiento de las resoluciones mediante cache. Cuando una resolución provoca un fallo de cache se utilizará el DNS recursivo del cual, probablemente, se habrá obtenido la IP mediante una concesión DHCP.

Servidor DNS (name server)

Atienden a las consultas realizadas por los clientes. La consulta de un cliente a un servidor puede obligar a este a realizar otra consulta a otro servidor cuando no encuentre sus datos en un archivo de zona o en cache.

Encontramos dos tipos de servidores DNS:

  • DNS recursivo: Están pensados para atender a los hosts de los usuarios. Pueden acudir a la jerarquía DNS para resolver las consultas de los clientes sobre cualquier dominio.
  • DNS autoritativo: No son recursivos y únicamente se encargan de contestar a consultas sobre las zonas de las que son responsables. Forman parte de la jerarquía DNS manteniendo los datos de su zona de autoridad.
Zona de autoridad

Porción del espacio de nombres de dominio. Cada zona de autoridad abarca un dominio y posiblemente incluya a sus subdominios, aunque estos pueden delegarse a otros servidores de nombres.

Por ejemplo, los servidores raíz tienen autoridad sobre la zona '.'. Otros servidores tienen autoridad sobre cada uno de los TLDs y otros sobre los subdominios.

Dominio de nivel superior (Top Level Domain - TLD)
Etiqueta situada más a la derecha del nombre de dominio. Por ejemplo en elpuig.xeill.net, el TLD es .net que actúa como raíz de todos sus subdominios. Se dividen en dominios genéricos y dominios geográficos.
Subdominio Cada una de las etiquetas del nombre de dominio que están situadas a la izquierda del TLD.
Nombre de la máquina (hostname)
La etiqueta que está a la izquierda en el nombre de dominio. Por ejemplo en moodle.elpuig.xeill.net el hostname del servidor es moodle.
Nombre de dominio completamente calificado
Un nombre de dominio completo como proxy.stallman.elpuig.xeill.net. Si sólo se especifica una parte como proxy no se tiene un FQDN (Full Qualified Domain Name).
Servidores raíz (root servers)
Los servidores DNS forman una jerarquía en la que cada uno es responsable de mantener la información de sus zonas de autoridad. Los servidores raíz tienen autoridad en zona raíz (representada por '.') y son los que delegan la autoridad de los diferentes TLDs en los servidores apropiados.
Resolución directa Cuando se pregunta al servidor DNS por la dirección IP asociada con un nombre de dominio.
Resolución inversa Cuando se pregunta al servidor DNS por el nombre de dominio asociado con una dirección IP.

Resolución de nombres en el cliente

Cuando una estación quiere comunicarse con otra de la que sólo conoce su FQDN (por ejemplo moodle.elpuig.xeill.net), lo primero que debe hacer es obtener la dirección IP asociada con el nombre de dominio. Para ello, dependiendo del contenido del fichero /etc/host.conf se consulta el fichero local /etc/hosts o bien se consulta a los servidores DNS.

El fichero /etc/hosts puede contener una lista de direcciones (una por línea) con sus respectivos nombres. De este modo no es necesaria ninguna petición a través de la red para obtener la dirección de uno de los nombres de dominio contenidos en el fichero. La limitación evidente de este sistema es que el fichero no puede contener todos los nombres de dominio con los que potencialmente la estación se va a querer comunicar.

Ejemplo de fichero /etc/host.conf

order hosts,bind
multi on
nospoof on
spoofalert on

Ejemplo de fichero /etc/hosts

127.0.0.1               localhost
82.151.203.129 iespuigcastellar.xeill.net
145.97.39.155 es.wikipedia.org

Mediante el fichero de configuración /etc/hosts es posible asignar nuevos nombres de dominio a algunas direcciones o bien enmascarar otras.

Cuando se utiliza el cliente DNS para obtener la dirección IP de un nombre de dominio es preciso examinar el fichero de configuración /etc/resolv.conf para obtener:

  • La lista de servidores DNS  a utilizar (uno por línea precedido por la directiva nameserver)
  • El dominio a utilizar para las consultas que no son un FQDN indicado por la directiva search

Ejemplo de fichero /etc/resolv.conf

search dominiox.example
nameserver 62.81.16.132
nameserver 62.81.0.36

Servicio systemd-resolved y comando resolvectl

La mayoría de las distribuciones actuales de GNU/Linux utilizan systemd así que suelen ejecutar el servicio systemd-resolved como stub DNS local de la máquina. La ventaja de utilizar systemd-resolved es que las aplicaciones encontrarán un mejor rendimiento gracias a su cache.

Un stub DNS reenvía todas las consultas que no tiene en cache a un servidor DNS recursivo. Pero no es capaz de funcionar como DNS recursivo acudiendo directamente a la jerarquía DNS para resolver la consulta con los servidores autoritativos.

En estos casos el fichero /etc/resolv.conf puede ser:

usuario@laika:~$ cat /etc/resolv.conf 
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0
usuario@laika:~$

Aquí se puede observar:

  • El comentario advierte de que se trata de un fichero generado por systemd-resolved.
  • Como servidor DNS se ha configurado la dirección 127.0.0.53 que únicamente es accesible desde el propio equipo.

El comando resolvectl permite:

  • Mostrar información sobre la configuración: resolvectl status
  • Mostrar estadísticas sobre los aciertos de cache: resolvectl statistics
  • Mostrar los DNS utilizados: resolvectl dns
  • Hacer resoluciones DNS: resolvectl query ru.wikipedia.org

Otros comandos para realizar resoluciones

El comando host es muy sencillo

usuario@laika:~$ host wikipedia.org
wikipedia.org has address 91.198.174.192
wikipedia.org has IPv6 address 2620:0:862:ed1a::1
wikipedia.org mail is handled by 10 mx1001.wikimedia.org.
wikipedia.org mail is handled by 50 mx2001.wikimedia.org.
usuario@laika:~$

Y permite especificar el servidor DNS al que se pregunta:

usuario@laika:~$ host wikipedia.org 1.1.1.1
Using domain server:
Name: 1.1.1.1
Address: 1.1.1.1#53
Aliases: 

wikipedia.org has address 91.198.174.192
wikipedia.org has IPv6 address 2620:0:862:ed1a::1
wikipedia.org mail is handled by 10 mx1001.wikimedia.org.
wikipedia.org mail is handled by 50 mx2001.wikimedia.org.
usuario@laika:~$

Otros comandos que permiten realizar consultas al DNS son nslookup y dig.

Dnsmasq

Dnsmasq es una herramienta libre que proporciona una versión ligera de los servicios: DNS, DHCP y TFTP. Está disponible en GNU/Linux y en otros sistemas operativos teniendo mucho éxito tanto en las distribuciones generales como en sistemas empotrados en los que los recursos están muy limitados.

Antes de la aparición de systemd-resolved la mayoría de distribuciones de GNU/Linux utilizaban dnsmasq como stub DNS, pudiendo hacer cache de las resoluciones y mejorando el rendimiento. En esos casos se veía en el fichero /etc/resolv.conf la IP de loopback como nameserver.

Instalación del servidor DNS

BIND es el software más utilizado como servidor DNS en Internet, como así lo demuestra que lo estén ejecutando la mayoría de los servidores raíz.

Este servicio se puede instalar mediante:

apt install bind9

Una vez instalado sus ficheros de configuración se encontrarán en el directorio /etc/bind

root@luna:/etc/bind# ll
total 56
drwxr-sr-x 2 root bind 4096 oct 28 16:18 ./
drwxr-xr-x 96 root root 4096 oct 28 16:18 ../
-rw-r--r-- 1 root root 1991 sep 28 12:30 bind.keys
-rw-r--r-- 1 root root 237 dic 17 2019 db.0
-rw-r--r-- 1 root root 271 dic 17 2019 db.127
-rw-r--r-- 1 root root 237 dic 17 2019 db.255
-rw-r--r-- 1 root root 353 dic 17 2019 db.empty
-rw-r--r-- 1 root root 270 dic 17 2019 db.local
-rw-r--r-- 1 root bind 463 dic 17 2019 named.conf
-rw-r--r-- 1 root bind 498 dic 17 2019 named.conf.default-zones
-rw-r--r-- 1 root bind 165 dic 17 2019 named.conf.local
-rw-r--r-- 1 root bind 846 dic 17 2019 named.conf.options
-rw-r----- 1 bind bind 100 oct 28 16:18 rndc.key
-rw-r--r-- 1 root root 1317 dic 17 2019 zones.rfc1918
root@luna:/etc/bind#

Entre estos ficheros destaca el fichero de configuración principalnamed.conf que únicamente sirve para incluír a: named.conf.options, named.conf.local y named.conf.default-zones.

Fichero: /etc/bind/named.conf.options

Este fichero contiene:

options {
	directory "/var/cache/bind";

	// If there is a firewall between you and nameservers you want
	// to talk to, you may need to fix the firewall to allow multiple
	// ports to talk.  See http://www.kb.cert.org/vuls/id/800113

	// If your ISP provided one or more IP addresses for stable 
	// nameservers, you probably want to use them as forwarders.  
	// Uncomment the following block, and insert the addresses replacing 
	// the all-0's placeholder.

	// forwarders {
	// 	0.0.0.0;
	// };

	//========================================================================
	// If BIND logs error messages about the root key being expired,
	// you will need to update your keys.  See https://www.isc.org/bind-keys
	//========================================================================
	dnssec-validation auto;

	listen-on-v6 { any; };
};
  1. La declaración del directorio en el que se guardarán los archivos de zona: /var/cache/bind
  2. La declaración, por defecto desactivada, de los servidores de reenvío: sección forwarders {...}

Si no se utilizan forwarders el servidor DNS acudirá a los servidores raíz para iniciar las resoluciones de las consultas que no estén en cache ni en ninguna de sus zonas. Cuando se utilizan servidores de reenvío se consultará a estos servidores.

Fichero: /etc/bind/named.conf.local

Este fichero inicialmente contiene un comentario y es el lugar en el que podemos declarar nuestras zonas.

zone "torvalds.elpuig.xeill.net" IN {
	type master;
	file "torvalds.elpuig.xeill.net.hosts";
	};
zone "10.168.192.in-addr.arpa" IN { type master; file "10.168.192.in-addr.arpa"; }; zone "stallman.elpuig.xeill.net" IN { type master; file "stallman.elpuig.xeill.net.hosts"; };
zone "11.168.192.in-addr.arpa" IN { type master; file "11.168.192.in-addr.arpa"; };

Cada zona (directa o inversa) tendrá:

  • La declaración con la directiva zone en la que se indica el dominio o la dirección de red en las zonas inversas.
  • Una directiva type indicando si es una zona maestra (escrita por el administrador) o esclava (descargada automáticamente de un servidor maestro).
  • Una directiva file indicando el fichero de respaldo (que se encontrará en /var/cache/bind)

Archivo de datos para una zona directa

Cada zona necesita un archivo de datos en el que guardar los registros de la zona. Para una zona directa como torvalds.elpuig.xeill.net el archivo de zona puede ser /var/cache/bind/torvalds.elpuig.xeill.net.hosts y contener:

$TTL 300
@	IN      SOA     proxy admin.elpuig.xeill.net. (
                        1      ; Serial
                        10800  ; Refresh
                        3600   ; Retry
                        604800 ; Expire
                        60     ; Minimum TTL
) @ IN NS proxy proxy IN A 192.168.10.10

En este archivo de zona hay que notar:

  • El carácter @equivale al dominio que se esté definiendo acabado en punto. Aquí torvalds.elpuig.xeill.net.
  • El campo admin.elpuig.xeill.net. corresponde al correo de contacto para indicar errores en la zona y se interpreta como admin@elpuig.xeill.net
  • Es importante incrementar el valor Serial cada vez que se hace una modificación.
  • Cuando se escribe un nombre como proxy sin acabar en . se entenderá que hay que añadir la zona que se está definiendo al nombre. En este caso escribir proxy equivale a proxy.torvalds.elpuig.xeill.net.

Archivo de datos para una zona inversa

El archivo de datos para la zona inversa del dominio torvalds.elpuig.xeill.net será /var/cache/bind/10.168.192.in-addr.arpa y podrá contener:

$TTL 300
@	IN	SOA     proxy.torvalds.elpuig.xeill.net. admin.elpuig.xeill.net. (
                        1
                        10800
                        3600
                        604800
                        60 )

@	IN      NS	proxy.torvalds.elpuig.xeill.net.
10	IN	PTR     proxy.torvalds.elpuig.xeill.net. 

En este caso:

  • La @ substituye a 10.168.192.in-addr.arpa.
  • Se asocian las IPs con nombres de dominio.
  • Las direcciones que no terminan en punto como 10 se interpretan como 10.10.168.192.in-addr.arpa.

Cabeceras de los archivos de zona

Se trate de una zona directa o de una zona inversa, el archivo ha de comenzar con una cabecera que especifica algunos parámetros de configuración.

$TTL 300
tierramedia.puigcastellar. IN SOA ns0.tierramedia.puigcastellar. hostmaster.tierramedia.puigcastellar. (
200203194
10800
3600
604800
60 )
  1. TTL (Time To Live) periodo de validez para la información contenida en la zona, pasado el tiempo debe refrescarse o actualizarse.
  2. Registro SOA (Start Of Authority)
    tierramedia.puigcastellar.      IN      SOA     ns0.tierramedia.puigcastellar. hostmaster.tierramedia.puigcastellar.
    Puede utilizarse el carácter @ para substituir al dominio al que corresponde la zona. Un esquema de la cabecera de archivo de zona puede ser: 
    @ IN SOA <servidor DNS primario> <correo del administrador (cambiando la arroba por . )> (
    <serial-number>
    <time-to-refresh>
    <time-to-retry>
    <time-to-expire>
    <minimun-TTL>
    )

Campo Función
serial-number Debe incrementarse con cada modificación del archivo de zona, de este modo los servidores esclavos pueden detectar los cambios en los archivos de zona.
time-to-refresh Tiempo que los servidores esclavos (o secundarios) dejan pasar antes de consultar al servidor maestro (o principal) si ha ocurrido algún cambio en la zona.
time-to-retry Tiempo que el esclavo deja pasar antes de reintentar una transferencia de zona.
time-to-expire Si un servidor esclavo no consigue actualizar sus zonas mediante la correspondiente transferencia de zona, pasado este tiempo debe dejar de considerar válida la información de la zona.

Tipos de registros DNS

En los archivos de zona se utilizan registros para declarar los recursos que conoce el servidor DNS. Estos registros están especializados de manera que hay un tipo de registro DNS diferente para cada recurso.

Algunos de los tipos de registro básicos son:

Registro Función
A IPV4, traducción directa de nombre a dirección
AAAA IPV6, traducción directa de nombre a dirección
PTR Puntero, traducción inversa de dirección a nombre
MX Mail eXchanger, intercambiador de correo para un dominio
NS Name Server, identifica a los servidores de una zona, permite delegar subdominios
CNAME Canonical Name, permite definir nombres alternativos
SRV
Service, permite declarar servicios. De esta manera un cliente puede descubrir de manera automática los servicios que están disponibles en un dominio.
TXT Texto, permite asociar un texto arbitrario con un nombre de dominio.

Réplicas maestro - esclavo

Puesto que el servicio DNS debe estar disponible de manera permanente es conveniente montar varias máquinas con autoridad para mantener una zona. En este caso el administrador configurará manualmente el archivo de zona en una de ellas (el servidor maestro) y los servidores esclavos realizarán una transferencia de zona descargando los datos desde el maestro.

Por ejemplo, en el servidor maestro se puede declarar una zona tal que:

        zone "dominio.prueba" {
             type master;
             file "dominio.prueba.hosts";
             allow-transfer { <IPs de los servidores esclavos>; };
        };

Y en los servidores esclavos:

        zone "dominio.prueba" {
             type slave;
             file "dominio.prueba.hosts";
             masters { <IP de Servidor-A>; };
masterfile-format text; };

La directiva masterfile-format text es opcional pero recomendable pues utilizar un archivo de zona en formato texto en el esclavo facilita comprobar los datos descargados.

Por supesto en el archivo de zona convendrá declarar con registros NS todos los servidores (sean maestros o esclavos):

$TTL 5
dominio.prueba. IN SOA ns0.dominio.prueba. hostmaster.dominio.prueba. (
1
10800
3600
604800
60 )
dominio.prueba. IN NS ns0
dominio.prueba. IN NS ns1
ns0.dominio.prueba. IN A 192.168.0.10
ns1.dominio.prueba. IN A 192.168.0.20

Desactivar los forwarders en una zona

En ocasiones, en las prácticas que se realizan en el aula el profesor monta un servidor DNS con autoridad en un TLD inventado (como .prueba), y se delega la autoridad en diferentes servidores DNS que montan los alumnos para sus subdominios (por ejemplo .<login>.prueba). En este caso, si está activo el reenvío de forma global, será necesario desactivarlo para la zona.

        zone "dominio.prueba" {
             type master;
             file "dominio.prueba.hosts";
forwarders { };
};

Transportes DNS

En 1983 el protocolo DNS apareció utilizando el protocolo de transporte UDPy el puerto 53. Aún hoy en día la mayoría de las consultas al DNS se realizan utilizando UDP pero existen otros transportes alternativos. El principal de ellos es TCP  que también utiliza el puerto 53.

Estas dos versiones clásicas de DNS no incorporan ninguna medida de seguridad ni cifrado. Por esta razón han aparecido otras alternativas que cifran el protocolo DNS para ofrecer seguridad.

De estas dos opciones DoH está ganando rápidamente soporte entre los navegadores. Por ejemplo Firefox hoy en día utiliza por defecto DoH con el servidor de Cloudflare 1.1.1.1 aunque es posible configurar otro servidor.

El comando dig nos permitirá hacer consultas DoH desde el shell:

root@test:~# dig +https @1.1.1.1 elpuig.xeill.net

; <<>> DiG 9.18.18-0ubuntu2-Ubuntu <<>> +https @1.1.1.1 elpuig.xeill.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40196
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;elpuig.xeill.net.		IN	A

;; ANSWER SECTION:
elpuig.xeill.net.	600	IN	A	136.243.80.28

;; Query time: 110 msec
;; SERVER: 1.1.1.1#443(1.1.1.1) (HTTPS)
;; WHEN: Sun Oct 22 13:06:27 UTC 2023
;; MSG SIZE  rcvd: 61

root@test:~#

DNS over HTTPS (DoH) con BIND

Para activar el soporte DoH en BIND necesitaremos un certificado. Normalmente se utilizará un certificado de una autoridad de certificación reconocida (como Let's Encrypt) para que los clientes lo acepten sin problemas. Pero también se podrá utilizar un certificado autofirmado si en el navegador (o cliente utilizado) se añade la excepción de seguridad correspondiente.

Podemos crear un certificado autofirmado:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/bind/bind-selfsigned.key -out /etc/bind/bind-selfsigned.crt

Cambiar la propiedad de los ficheros para que BIND los pueda leer:

chown bind /etc/bind/bind-selfsigned.*

Editar el fichero de configuración named.conf.options para añadir el bloque tls antes del bloque options.

tls local-tls {
key-file "/etc/bind/bind-selfsigned.key";
cert-file "/etc/bind/bind-selfsigned.crt";
};

Y añadir en el interior del bloque options las líneas:

// Queremos la IP de los clientes que hacen consultas
querylog yes;
// Configuramos el acceso DoH
listen-on port 443 tls local-tls http default {any;};

Antes de configurar el DNS en el navegador será conveniente visitar la dirección https://<dirección ip>/ para encontrar la advertencia de que se utiliza un certificado autofirmado y aceptarlo.

Finalmente se podrá configurar en el navegador el DoH utilizando la URL: https://<dirección ip>/dns-query

firefox-doh.webp

Más información