Resolver fallas del servicio de nombres resueltas por systemd con Ansible
Resolución de nombres y el panorama de redes en constante cambio.
La mayoría de la gente tiende a dar por sentado los servicios de nombres. Son necesarios para convertir nombres legibles por humanos, como www.example.com
, en direcciones IP, como 93.184.216.34
. Es más fácil para los humanos reconocer y recordar nombres que direcciones IP, y los servicios de nombres nos permiten usar nombres y también los convierten en direcciones IP.
El Sistema de nombres de dominio (DNS) es la base de datos distribuida global que mantiene los datos necesarios para realizar estas búsquedas y búsquedas inversas, en las que se conoce la dirección IP y se necesita el nombre de dominio.
Instalé Fedora 33 el primer día que estuvo disponible en octubre de 2020. Uno de los cambios más importantes fue una migración del antiguo solucionador Name Service Switch (NSS) a systemd-resolved. Desafortunadamente, después de que todo estuvo en funcionamiento, no pude conectarme ni hacer ping a ninguno de los hosts de mi red por su nombre, aunque el uso de direcciones IP funcionó.
El problema
Ejecuto mi propio servidor de nombres usando BIND en mi servidor de red y todo ha ido bien durante más de 20 años. He configurado mi servidor DHCP para proporcionar la dirección IP de mi servidor de nombres a cada estación de trabajo conectada a mi red, y eso (junto con un par de servidores de nombres de respaldo) se almacena en /etc/resolv.conf
.
Michael Catanzaro describe cómo se supone que funciona systemd-resolved, pero la introducción de systemd-resolved causó varios problemas de resolución extraños en los hosts de mi red. Los síntomas variaban según el propósito del huésped. El problema se presentaba principalmente como una incapacidad para encontrar direcciones IP para hosts dentro de la red en la mayoría de los sistemas. En otros sistemas, no pudo resolver ningún nombre. Por ejemplo, aunque nslookup a veces devolvía las direcciones IP correctas para los hosts dentro y fuera de las redes, el ping no contactaba al host designado, ni yo podía conectarme mediante SSH a ese mismo host. La mayoría de las veces, ni la búsqueda, ni el ping ni SSH funcionarían a menos que usara la dirección IP en el comando.
El nuevo solucionador supuestamente tiene cuatro modos operativos, descritos en este artículo de la revista Fedora. Ninguna de las opciones parece funcionar correctamente cuando la red tiene su propio servidor de nombres diseñado para realizar búsquedas de hosts internos y externos.
En teoría, se supone que systemd-resolved soluciona algunos problemas relacionados con el solucionador NSS que no utiliza el servidor de nombres correcto cuando un host está conectado a una VPN, lo que se ha convertido en un problema común con tantas personas trabajando desde casa.
Se supone que el nuevo solucionador utiliza el hecho de que /etc/resolv.conf
ahora es un enlace simbólico para determinar cómo se supone que funciona según el archivo de resolución al que está vinculado. La página de manual de systemd-resolved incluye detalles sobre este comportamiento. La página de manual dice que configurar /etc/resolv.conf
como un enlace simbólico a /run/systemd/resolve/resolv.conf
debería hacer que el nuevo solucionador funcione de la misma manera el anterior sí, pero eso no funcionó para mí.
mi solución
He visto muchas opciones en Internet para resolver este problema, pero lo único que me funciona de manera confiable es detener y desactivar el nuevo solucionador. Primero, eliminé el enlace existente para resolv.conf
, copié mi archivo resolv.conf
preferido en /run/NetworkManager/resolv.conf
, y agregó un nuevo enlace a ese archivo en /etc
:
# rm -f /etc/resolv.conf
# ln -s /run/NetworkManager/resolv.conf /etc/resolv.conf
Estos comandos detienen y deshabilitan el servicio resuelto por systemd:
# systemctl stop systemd-resolved.service ; systemctl disable systemd-resolved.service
Removed /etc/systemd/system/multi-user.target.wants/systemd-resolved.service.
Removed /etc/systemd/system/dbus-org.freedesktop.resolve1.service.
No es necesario reiniciar. El antiguo solucionador toma el control y los servicios de nombres funcionan como se esperaba.
Hazlo fácil con Ansible
Configuré este manual de Ansible para realizar los cambios necesarios si instalo un nuevo host o una actualización que revierte el solucionador a systemd-resolved, o si una actualización a la próxima versión de Fedora revierte el solucionador. El archivo resolv.conf
que desea para su red debe estar ubicado en /root/ansible/resolver/files/
:
################################################################################
# fixResolver.yml #
#------------------------------------------------------------------------------#
# #
# This playbook configures the old nss resolver on systems that have the new #
# systemd-resolved service installed. It copies the resolv.conf file for my #
# network to /run/NetworkManager/resolv.conf and places a link to that file #
# as /etc/resolv.conf. It then stops and disables systemd-resolved which #
# activates the old nss resolver. #
# #
#------------------------------------------------------------------------------#
# #
# Change History #
# Date Name Version Description #
# 2020/11/07 David Both 00.00 Started new code #
# 2021/03/26 David Both 00.50 Tested OK on multiple hosts. #
# #
################################################################################
---
- name: Revert to old NSS resolver and disable the systemd-resolved service
hosts: all_by_IP
################################################################################
tasks:
- name: Copy resolv.conf for my network
copy:
src: /root/ansible/resolver/files/resolv.conf
dest: /run/NetworkManager/resolv.conf
mode: 0644
owner: root
group: root
- name: Delete existing /etc/resolv.conf file or link
file:
path: /etc/resolv.conf
state: absent
- name: Create link from /etc/resolv.conf to /run/NetworkManager/resolv.conf
file:
src: /run/NetworkManager/resolv.conf
dest: /etc/resolv.conf
state: link
- name: Stop and disable systemd-resolved
systemd:
name: systemd-resolved
state: stopped
enabled: no
Cualquier inventario de Ansible que utilice debe tener un grupo que utilice direcciones IP en lugar de nombres de host. Este comando ejecuta el libro de jugadas y especifica el nombre del archivo de inventario que uso para los hosts por dirección IP:
# ansible-playbook -i /etc/ansible/hosts_by_IP fixResolver.yml
Pensamientos finales
A veces, la mejor respuesta a un problema tecnológico es recurrir a lo que sabes. Cuando systemd-resolved sea más sólido, probablemente lo intentaré de nuevo, pero por ahora me alegro de que la infraestructura de código abierto me permita identificar y resolver rápidamente problemas de red. Usar Ansible para automatizar el proceso es una ventaja muy apreciada. La lección importante aquí es investigar al solucionar problemas y nunca tener miedo de anular la garantía.