dnsmasq

dnsmasq: DNS práctico y sencillo (con DHCP opcional)

Download PDF

Simon Kelley en su sitio web, y por cuenta propia, fue quien creó -y mantiene- a dnsmasq: así, sin mayúscula inicial (excepto si está al comienzo de una línea o después de un punto). Dnsmasq es exactamente lo que su creador quiso que fuera: un programa sencillo, pero poderoso, que sirve como DNS sin mayores pretensiones, especialmente creado para redes de área local y con funciones adicionales, veamos.

Publicado el domingo 28 de abril de 2019.
Actualizado el domingo 20 de diciembre de 2020.

Tabla de contenido:

Introducción

¿Qué hace un software hecho de manera artesanal y solitario, hecho por un británico en las tierras heladas del norte, sea tan especial? Está bien hecho, es práctico, sencillo y directo, «la genialidad es la simplicidad» dicen muchas personas. No subestimen a este pequeño programa porque es ampliamente utilizado para gestionar las direcciones IP de las máquinas virtuales basadas en Docker y manejado de manera masiva por Kubernetes. También es tan pequeño que está incrustado en millones de enrutadores inalámbricos y de ser necesario dispone de muchas características adicionales que se pueden instalar posteriormente:

 

  • DHCP.
  • Arranque de red con PXE, BOOTP y TFTP (si el DHCP está instalado y configurado).
  • Acepta guiones en lenguaje LUA.
  • Soporte para IPv6.
  • Soporte para DNS seguros o DNSSEC.

Precisamente esta fama fue la que llamó la atención de los investigadores, los cuales se aplicaron a estudiarlo muy bien y en octubre de 2017 hallaron…

 

Advertencia.
Advertencia.

dnsmasq tiene serias vulnerabilidades en la versión 2.77 y anteriores. Para que podamos usarlo debemos estar seguros de usar la versión 2.78 o superior; revisen con apt show dnsmasq el número de versión que les retribuye sus repositorios, de ser necesario descarguen desde su propia página web y lo compilan o en el caso de Ubuntu descargamos el paquete .deb del repositorio.

https://blog.hyperiongray.com/pwning-dnsmasq-with-rop/
apt show dnsmasq
apt show dnsmasq

Al final, en una sección especial, colocamos todas las debilidades que adolecía dnsmasq, acá no las explicamos porque sería muy extenso. El interés de los investigadores fue robustecer, fortalecer, asegurar a Docker y Kubernetes, bueyes de carga que llevan el peso de nuestros servidores en Internet.

Esencialmente dnsmasq ofrece un DNS recursivo, es decir, si no sabe el dominio consultado entonces reenvía la consulta hacia el DNS configurado en la máquina GNU/Linux y una vez resuelto guarda en memoria cache dicha información, acelerando nuestra navegación. Además podremos colocar en el archivo /etc/hosts dominios adicionales, como por ejemplo anfitriones para servicios especiales como servidores FTP, de correo o Web. Si no queremos tocar ese archivo especial, también le podremos configurar que lea desde un archivo adicional los dominios que necesitemos declarar.

Instalando dnsmasq

Lo describiremos para Ubuntu 18.04 pero todo esto se puede extrapolar para toda distribución basada en Debian.

systemd-resolve

Este señor systemd-resolve viene por defecto instalado y funcionando y utiliza la dirección 127.0.0.53 además de apoderarse del puerto 53,  justo el que necesita dnsmasq para funcionar.

De hecho systemd-resolved tiene dos métodos principales basados en API para «resolver» los dominios de las aplicaciones locales y a pesar de que el manual de dicho programa recomienda fuertemente que se utilicen primero estos dos métodos antes de usar el puerto 53 (¿para qué entonces se adueñan de ese puerto?🤔). No explicaremos mayor cosa sobre esto, si instalamos dnsmasq por supuesto que dnsmasq será el encargado de ello. Sin embargo si quieren ver en acción a este software systemd-resolve, en una ventana de comandos ejecuten un comando especial, déjenlo abierto y naveguen, usen dig con algún dominio, lean correo con Thunderbird, hagan ping en otra terminal, etcétera. Dicho comando es:

sudo journalctl -u systemd-resolved -f

También pueden ver el estado del servicio con:

systemd-resolve --status
systemd-resolve --statistics

Siéntanse a gusto de probar todo esto, porque el siguiente paso es inhabilitar a systemd-resolve para poder instalar a dnsmasq.

Desinstalando systemd-resolve

Con la primera línea inhabilitamos su arranque y con la segunda detenemos el servicio en sí:

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved

Luego vamos a seguir el enlace simbólico del fichero resolv.confpara saber hacia donde apunta y revisamos lo que contiene su contraparte:

Enlace simbólico de resolv.conf y contenido de su contraparte
Enlace simbólico de resolv.conf y contenido de su contraparte

…y como pueden ver en la figura anterior, todo se reduce a un reenvío a la famosa dirección 127.0.0.53

En Ubuntu 20.04 el fichero es manejado por systemd, observen la siguiente figura.

Actualizado el domingo 20 de diciembre de 2020.
sudo systemctl disable systemd-resolved
sudo systemctl disable systemd-resolved

Lo siguiente que haremos será eliminar ese enlace simbólico, borrar el archivo /etc/resolv.conf y proceder a crear uno nuevo con el comando echo apuntando al DNS que ustedes prefieran (nosotros antes usábamos los DNS de Norton pero como el servicio fue eliminado pues ahora estamos usando los DNS de Google mientras encontramos un sustituto).

Hechas todas estas aclaratorias, procedemos entonces (también pueden usar su editor de textos favoritos):

ls -lh /etc/resolv.conf
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf

Google no es el único que ofrece servicios DNS «gratuitos», la mundialmente famosa empresa Cisco compró la compañía OpenDNS que también ofrecen un buen servicio. Colocamos las direcciones IP a continuación:

  • 208.67.222.222
  • 208.67.220.220
  • 208.67.222.220
  • 208.67.220.222

También Cloudflare por medio del préstamo de las siguientes direcciones IP para un servicio experimental DNS muy innovador:

  • 1.0.0.1
  • 1.1.1.1

Luego volveremos a modificar este famoso archivo resolv.conf, atentos y atentas.

Instalando dnsmasq

Como dijimos al principio,  si ya verificamos que los repositorios que tenemos configurados en nuestro sistema contienen la versión 2.78 o superior (apt show dnsmasq) simplemente:

sudo apt update
sudo apt install dnsmasq

De ser necesario el caso, podremos descargar directamente el paquete .deb e instalarlo con las siguientes instrucciones:

wget http://archive.ubuntu.com/ubuntu/pool/universe/d/dnsmasq/dnsmasq_2.79-1_all.deb
ls -la *.deb
sudo dpkg -i dnsmasq_2.79-1_all.deb

Con la primera línea descargamos la versión 2.79 (siempre revisen si hay versión nueva), con la segunda nos aseguramos de que se haya descargado (son 18 kilobytes, bien pequeño) y con la tercera lo instalamos en sí.

¿Recuerdan el fichero /etc/resolv.conf, donde colocamos nuestros DNS preferidos? Pues bien, probablemente ya tengamos instalada la librería openresolv (versión 3.3.0-1 al escribir estas líneas) que permite ejecutar los demonios que permiten configurar y administrar dicho fichero. Si no la tenemos instalada de seguro que al instalar dnsmasq se incluye.

Por otra parte la librería que siempre se instala es dnsmasq-base, imaginen ustedes que es pequeño el programa y sus librerías, más pequeñas aun, son utilizadas por otros programas… La tercera librearía básica es network-manager una potente herramienta de los sistemas operativos GNU/Linux, básicamente se encarga de mantener bajo control las diferentes tarjetas de red (recordemos que en este siglo XXI aparte de ethernet existe Wi-fi, LTE, etcétera). Para no extendernos les colocamos su descripción exacta en idioma inglés:

NetworkManager is a system network service that manages your network devices and connections, attempting to keep active network connectivity when available. It manages ethernet, WiFi, mobile broadband (WWAN), and PPPoE devices, and provides VPN integration with a variety of different VPN services.

Otras dependencias

  • Si programamos con el lenguaje LUA podremos hacer guiones para administrar DHCP con esta herramienta ( sudo apt install dnsmasq-base-lua ).
  • Volviendo al tema de DHCP, si lo usaremos con dnsmasq pues debemos incluir : sudo apt install dnsmasq-utils

Comprobando a dnsmasq

Su funcionamiento es sencillo de comprobar de dos maneras:

dig pandorafms.org @localhost
nslookup wikipedia.org

Como vemos en el primer caso le estamos indicando al comando que utilicen al equipo local como «resolvedor» y no a los DNS comunes que tengamos configurados. De nuevo, según lo que tengamos en /etc/resolv.conf nos redireccionará; sabemos que es como tedioso o complicado (y hasta absurdo) pero así es la programación y la computación.

Ahora bien, la comprobación correcta que nos informará de forma concreta cómo se ejecuta dnsmasq sería utilizar:

sudo systemctl status dnsmasq
 sudo systemctl status dnsmasq
 sudo systemctl status dnsmasq

Permitiendo al cortafuegos

Antes de continuar debemos permitir que el cortafuegos, en este caso ufw (Ubuntu Fire Wall) abra el puerto 53:

sudo ufw allow 22
sudo ufw allow 53

¿Pero de qué vamos, y ese puerto 22? Pues debemos asegurarnos, si nos conectamos remoto -lo más seguro- con ssh, de que ese puerto quede abierto para nosotros. Si utilizan cualquier otro número de puerto lo mejor sería sudo ufw allow ssh (esta última acción de manera análoga no lo podremos hacer con dnsmasq porque opera en otro nivel distinto).

Comprobando, de nuevo, a dnsmasq

La instrucción que nos permitirá conocer a fondo si funciona y cómo funciona dnsmasq, su estado, sería:

systemctl status dnsmasq.service
sudo service dnsmasq status

Ejemplo:

systemctl status dnsmasq.service
systemctl status dnsmasq.service

Configurando dnsmasq

Como cosa rara en GNU/Linux (sarcasmo) todo está un un fichero: /etc/dnsmasq.conf así que ya sabemos cómo editar un archivo de texto cualquiera, colocaremos ahora las secciones más relevantes y deberán usar la opción de búsqueda de palabras clave de dicho editor de texto.

/etc/dnsmasq.conf

La primera vez que se ejecuta dnsmasq lo primero que lee es este archivo de configuración. Otros lugares donde podremos encontrar el fichero dnsmaq.conf (varía de distribución en distribución):

  • /etc/default/dnsmasq
  • /etc/dnsmasq.d/
  • /etc/dnsmasq.d-available/

A su vez dnsmas.conf es capaz de leer y cargar otros archivos de configuración o directorios si dentro del mismo le colocamos la ordenes:

conf-file=/ruta/nuestro_fichero.conf
conf-dir=/ruta/nuestra_carpeta.d

En el caso de los directorios podremos, además, por la extensión del fichero agregarlo o negarlo. supongamos que queremos agregar (que procese) todos los .conf pero que descarte los .tmp.old y los .bak:

conf-dir=/etc/dnsmasq.d/,*.conf,
conf-dir=/etc/dnsmasq.d,.tmp, .old, .bak

Exacto: con asterisco los incluimos, sin asterisco (solo la extensión) los excluimos y los separamos debidamente por medio de comas.

Una vez hayamos guardado el fichero podemos verificar si tenemos todo correcto (devuelve el valor cero si todo está bien, cualquier otro valor es un error):

sudo dnsmasq --test

También debemos recordar el reiniciar el servicio dnsmasq cada vez que modifiquemos estos archivos o directorios de configuración:

sudo /etc/init.d/dnsmasq restart

Nota: todas las opciones largas de la línea de comandos pueden ser utilizadas en los ficheros de configuración. Por ejemplo –conf-dir=/etc/dnsmasq.d/,*.conf lo utilizaríamos tal cual en la línea de comandos, solo hemos antepuesto par de guiones al ejemplo dado recientemente.

Configurando DNS

Escogiendo puerto de escucha

Que ya dijimos que es el 53, pero si queremos usar uno distinto, por ejemplo el 5353 que no está en la lista de puertos comunes, pues colocamos:

port=5353

O el puerto deseado. Si no vamos a usar a dnsmasq como DNS (sí, eso se escucha ilógico y hasta contraproducente) podemos colocar:

port=0

Por si lo preguntan, el escenario anterior se daría únicamente si dnsmasq solo cumple funciones de DHCP y/o TFTP.

Escogiendo la tarjeta de red

Obvio, por defecto si tenemos una sola pues… Pero es común que los servidores tengas dos o más tarjetas de red (eth0 y eth1, generalmente) o incluso si es un ordenador portátil tenga una tarjeta de red inalámbrica (wlan0), etc. Para «escuchar» en eth1:-

Por favor, lea también   D-Bus: aplicaciones que "hablan" entre sí

interface=eth1

Filtrando errores de tipeo y direcciones IP locales

Sí, que muchos usuarios fueron mal acostumbrados por los navegadores web a realizar búsquedas desde la barra de direcciones e incluso en Firefox ocultan el cuadro de texto para las búsquedas normales, comunes y corrientes:

Pantalla de inicio de Firefox Quantum 66.0.3
Pantalla de inicio de Firefox Quantum 66.0.3

Por eso debemos filtrar la cadena de texto que envía el navegador web (supuesto dominio solicitado) y verificar que tiene puntos y que cumple con las normas de nombrado de un dominio web.

domain-needed

Solamente escriban eso (quitando el «#» al principio de la línea) para no fatigar a otros DNS con solicitudes basura. Noten que no necesita el signo de igualdad y mucho menos un valor específico.

Tampoco nuestro dnsmasq enviar direcciones IP de nuestra red de área local:

bogus-priv

Archivo /etc/hosts

Como iniciamos este artículo, podremos colocar nuestros dominios personalizados en /etc/hosts sin embargo es una muy buena idea cargar un fichero aparte para que dnsmasq lo lea. Esto permite la flexibilidad de que otra aplicación controle ese archivo mientras dejamos sin tocar a /etc/hosts

addn-hosts=/etc/mi_fichero_hosts

Dicho archivo deberá tener la misma estructura de /etc/hosts: una línea para cada dominio, comenzando con una dirección IP, luego un espacio y a continuación el dominio. Se pueden agregar tantos archivos como se necesiten, si son muchos es mejor crear un directorio, guardar allí los archivos y especificar dicho directorio en la configuración.

addn-hosts=/etc/mi_directorio_hosts.d

Importante: noten que no hemos colocado una barra derecha «/» al final de la línea ya que dnsmasq lo agrega automáticamente sin revisar previamente si lo tiene. De todas maneras revisar con la orden dnsmasq –test para depurar cualquier problema con esto. Otra cosa: en GNU/Linux para denotar las carpetas o directorios se acostumbra el colocar la extensión «.d«, hasta donde sabemos es una norma no escrita pero aceptada y sumamente utilizada. También debemos recordar que dnsmasq fue pensado para redes de área local privadas y generalmente muy pocas veces cambian las direcciones IP fijas en nuestra red que guardemos en add-hosts o /etc/hosts: si queremos algo dinámico debemos activar el DHCP con dnsmasq (más adelante detalles sobre esto). Esto quiere decir que dnsmasq leerá estos ficheros o directorios una sola vez al iniciar, que leerá periódicamente «resolv.conf» (más adelante también detalles sobre esto). Para «cambiar» dominios y direcciones IP por medio de cualquier otro programa de manera frecuente o inesperada debemos usar otra opción de configuración.


Hagamos una pequeña pausa en este punto:

Imaginemos por un instante que tenemos en nuestra red de área local una implementación azul-verde: necesitaremos que cuando hayamos implementado el nuevo servidor el «dominio» que usemos en nuestra red local se derive hacia el nuevo servidor. Ahora bien, necesitamos además que dicho proceso de cambio en el DNS se realice cuando hayamos compilado y puesto a punto el nuevo esquema de manera automática. Pues dnsmasq también tiene un parámetro de configuración para ello, para que cargue -y recargue si cambia- nuestra lista de dominios y direcciones IP personalizada:

hostsdir=/etc/mi_directorio_hosts.d

Fíjense bien que lo que hemos hemos hecho es sustituir addn-hosts por  hostsdir con la particularidad, como su nombre lo indica, que debemos especificar un directorio sin colocar de último una barra derecha.


Dado el caso también podremos indicarle a dnsmasq que no lea el archivo /etc/hosts con la directiva no-hosts.

¿Recuerdan que hablamos sobre modificar /etc/resolv.conf? Pues lo podemos editar cuando queramos, el problema es que cuando la máquina reinicie -o pasado cierto tiempo también- el servicio NetworkManager sobreescribirá nuestros cambios., por ello debemos:

  • Editar /etc/NetworkManager/NetworkManager.conf y justo debajo de la etiqueta [Main] agregar o editar lo siguiente: dns=none
  • Luego reiniciaremos el servicio: sudo systemctl restart NetworkManager.service
  • A continuación editaremos  a /etc/resolv.conf solamente con esta línea:
nameserver 127.0.0.1

Esto para que todas las consultas en nuestra máquina sean hechas a dnsmasq; ahora le escribimos los nombres de los DNS a quienes les queremos reenviar las consultas; vamos a usar OpenDNS, Google y CANTV, en ese orden, en el fichero /etc/dnsmasq.conf agregando lo siguiente:

server=208.67.222.222
server=8.8.8.8
server=200.109.78.12
no-resolv

También le colocamos en la última línea la instrucción a dnsmasq para que no lea /etc/resolv.conf, principalmente para que no perdamos tiempo en ello; de todas maneras si no lo hacemos entonces dnsmasq está programado para obviar esa primera línea que hace referencia a 127.0.0.1 y evitar así el círculo vicioso.

Habilitando la función de caché DNS en dnsmasq

Anteriormente hicimos una descripción breve de network-manager, pues resulta que la mejor manera de activar el caché DNS es modificar el archivo /etc/NetworkManager/NetworkManager.conf así que, de nuevo, volvemos a editar:

[main]
dns=dnsmasq

… y luego reiniciamos el servicio:

sudo /etc/init.d/network-manager restart

También podemos agregar el número máximo de nombres a retener en el caché (si colocamos cero inactivamos el caché):

cache-size=7000
dns-forward-max=10000

De ser necesario agregamos esta última linea (ver Bug 1560489) : si tenemos una cantidad exagerada de dispositivos y realizamos operaciones de inventario de los mismos (o incluso auditoria) debemos preparar a dnsmasq para tal cantidad de datos y obetner una rápida respuesta. Aunque para la mayoría de los usuarios este panorama es lejano, para nosotros con máquinas virtuales Docker y su administrador Kubernetes se ha vuelto ya común.

Resolviendo problemas o inconvenientes

Siempre recomendamos instalar un programa, configurar y luego probar, en ese orden. Sin embargo en el mundo del software libre cada quien hace sus cosas a su manera y dnsmasq tiene una opción para ser ejecutado no como servicio. Como dnsmasq no tiene un registro de eventos propio también podemos establecer temporalmente que guarde los registros de nuestras pruebas en una ubicación particular.

sudo dnsmasq --no-daemon --log-queries --log-facility=/var/log/dnsmasq.log

Configurando DHCP

Si ya tienen un servidor DHCP no intenten configurar otro, solo con uno en cada red de área local es más que suficiente. A futuro cuando llegue el IPv6 suponemos que cada ISP tendrá disponibles tantas direcciones IP que cada dispositivo en nuestros trabajos y hogares se conectarán directamente al DHCP del ISP. Mientras tengamos IPv4 seguiremos trabajando de esta manera. De todas formas y maneras dnsmasq ofrece total y completo soporte a las direcciones IPv6.

Debido a lo anterior dnsmasq viene con el DHCP desactivado. Si queremos, por ejemplo, otorgar direcciones en nuestra LAN desde 192.168.1.200 hasta 192.168.1.254 por 7 horas (tras lo cual se vuelve a otorgar bien sea la misma dirección IP u otra diferente) debemos escribir:

dhcp-range=192.168.1.200,192.168.1.254,7h

¿Recuerdan que el DNS lo colocamos sobre eth2? Pues igual debemos hacer con el DHCP:

dhcp-range=eth2,192.168.1.200,192.168.1.254,7h

Nota: excluir al propio servidor que ejecuta dnsmasq del rango DHCP.

Caso práctico con Ubuntu Server 18

Veamos entonces un ejemplo con Ubuntu 18 en VirtualBox: una vez tengamos corriendo la máquina nos conectamos por medio de SSH y actualizamos los repositorios.

sudo apt update && sudo apt upgrade -y && cat /var/run/reboot-required

Para variar colocamos en una sola línea, indicamos como sí («–yes» o su equivalente coro «-y«) y finalizamos consultando con el comando cat si es encesario reiniciar el equipo ya sea virtual o real (de no ser así mostrará que no existe el fichero).

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf

Con lo anterior deshabilitamos systemd-resolved y en la segunda línea detenemos el servicio; luego eliminamos el fichero resolv.conf

# /etc/resolv.conf
port=53
domain-needed
bogus-priv
hostsdir=/etc/myhosts.d
server=208.67.222.222
server=208.67.220.220
server=8.8.8.8
server=200.109.78.12
no-resolv
cache-size=7000

Confirmamos, por si acaso, el puerto 53 (línea 2), filtramos las consultas insulsas o indebidas (línea 3-4), definimos nuestros propios dominios y direcciones IP (línea 5) y establecemos los DNS para redirigir las consultas que no atañen a nuestra red de área local (líneas 6-9). En la penúltima le indicamos que no lea resolv.conf y en la última línea establecemos caché para siete mil dominios, cantidas exageradamente grande pero por si acaso. A continuación reiniciamos el servicio dnsmasq y luego lo consultamos:

sudo /etc/init.d/dnsmasq restart
sudo systemctl status dnsmasq
sudo systemctl status dnsmasq

El programa systemctl permite colorear los mensajes que revisten importancia, tal como el que leemos sobre utilizar –bind-dynamic en vez de -bind-interfaces (que de paso lo escribe en mayúsculas, ver imagen anterior).

Aunque es bastante difícil de explicar estas «nuevas» opciones (versión 2.63 en adelante) podemos explicar el asunto de la siguiente manera -y que nos perdonen los licenciados en computación-:

De manera predeterminada dnsmasq asume que está trabajando en solitario en un servidor. Recordemos que dnsmasq es un programa pequeño, sin mayores pretensiones, hecho para servidores «pequeños»…

Pero resulta ser que dnsmasq se ha ido imponiendo cada vez más y ahora es común verlo trabajando en grandes servidores ¿y a qué llamamos «grandes servidores»? A los servidores que tienen dos o más fuentes de poder, con varios procesadores -y múltiples núcleos cada uno-, cantidades obscenas de memoria RAM y dos o muchas más tarjetas de red (ethernet de manera demasiado frecuente, aunque ahora hasta traen conexiones LTE).

Por ello dnsmasq tiene tres modos de funcionamiento:

  1. «wildcard»: por defecto, trabaja tomando todo el control.
  2. «bind-interfaces»: cuando inicia dnsmasq hace una revisión completa de la interfaz de redes presentes, configura las direcciones IP con el kernel.
  3. «bind-dynamic»: lleva un control estricto que ata la interfaz de redes, las direcciones IP, así como revisar constantemente nuevas interfaces de red o direcciones IP. Este modo permite colocar varios servidores, cada uno con su interfaz de red propia sin molestarse entre ellos.

Para mayor información, en inglés, en este enlace está explicado de buena manera. Si solamente tenemos una sola interfaz de red pues no tenderemos mayor problema en este aspecto.

Fuentes Consultadas

En idioma castellano

En idioma inglés

Vulnerabilidades

Repositorios

Conceptos

En idioma alemán

En idioma japonés

Download PDF

Un comentario en «dnsmasq: DNS práctico y sencillo (con DHCP opcional)»

Los comentarios están cerrados.