Cómo buscar en la caché DNS de Linux de forma eficaz utilizando un script Bash para profesionales de TI

En el panorama informático actual, gestionar las redes de forma eficaz es crucial. Un componente clave de esta gestión es el almacenamiento en caché del DNS (Sistema de Nombres de Domin io), que puede mejorar significativamente el rendimiento de la red al reducir el tiempo que se tarda en resolver los nombres de dominio.

Para los profesionales de TI, especialmente los que gestionan múltiples sistemas, es vital comprender y utilizar la información de la caché DNS. Este post explorará un script de Bash diseñado para buscar en la caché DNS de Linux, proporcionando un desglose detallado de cómo funciona, sus casos de uso y las mejores prácticas para su implementación.

Contexto

El almacenamiento en caché DNS almacena los resultados de las consultas DNS de forma local en un dispositivo, lo que permite responder más rápidamente a las solicitudes posteriores de los mismos nombres de dominio. Mientras que los servidores generalmente no tienen servicios de caché DNS habilitados por defecto, ciertos entornos de escritorio como GNOME o KDE sí suelen tener, y emplean servicios como systemd-resolved o dnsmasq.

Este script está diseñado para ayudar a los profesionales de TI y proveedores de servicios gestionados (MSP) a buscar y recuperar entradas de caché DNS en sistemas Linux. La capacidad de buscar en las entradas de caché DNS puede ser crucial para solucionar problemas de red, investigar posibles incidentes de seguridad o simplemente optimizar el rendimiento de la red.

Al proporcionar una forma sistemática de acceder a estas entradas y filtrarlas, el script ayuda a agilizar tareas que, de otro modo, requerirían métodos más complejos o lentos.

El script

#!/usr/bin/env bash

# Description: Find DNS Cache entries on a Linux system. Supports systemd-resolved and dnsmasq(requires log-facility to be configured).
#
# Servers usually do not have a DNS cache service installed by default.
# systemd-resolved is commonly installed along with most Desktop Environments, such as GNOME and KDE.
#
# Release Notes: Initial Release
#   By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://ninjastage2.wpengine.com/terms-of-use.
#   Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
#   Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
#   Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
#   Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
#   Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
#   Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
#   EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).

# A comma separated list of keywords to search for in the DNS cache. Example: "google,comcast,cloudflare"
keywords_to_search=$1
# A multiline custom field to save the DNS cache entries.
multiline_custom_field=$2

# Check if the multilineCustomField is set
if [[ -n "${multilineCustomField}" && "${multilineCustomField}" != "null" ]]; then
    multiline_custom_field=$multilineCustomField
fi

# Check if the keywordsToSearch is set
if [[ -n "${keywordsToSearch}" && "${keywordsToSearch}" != "null" ]]; then
    keywords_to_search=$keywordsToSearch
fi

# Check if the keywords_to_search is set
if [[ -z "${keywords_to_search}" ]]; then
    echo "[Info] keywords_to_search is not set."
    exit 1
else
    # Split the keywords_to_search into an array
    OLDIFS=$IFS
    IFS=',' read -r -a keywords <<<"${keywords_to_search}"
    IFS=$OLDIFS
    # Trim trailing and leading whitespace from each keyword
    keywords=("${keywords[@]/ /}")

fi

# Check if the multiline_custom_field is set
if [[ -z "${multiline_custom_field}" ]]; then
    echo "[Info] multilineCustomField is not set."
fi

# Check if ninjarmm-cli command exists in the default path
ninjarmm_cli="/opt/NinjaRMMAgent/programdata/ninjarmm-cli"
if [[ -z $ninjarmm_cli ]]; then
    echo "[Error] The ninjarmm-cli command does not exist in the default path. Please ensure the NinjaRMM agent is installed before running this script."
    exit 1
else
    # ninjarmm-cli command exists in the default path
    echo -n
fi

# Check that we are running as root
if [[ $EUID -ne 0 ]]; then
    echo "[Error] This script must be run as root."
    exit 1
fi

# Check for which dns cache service is installed
if [ "$(command -v resolvectl)" ]; then
    # resolvectl is installed
    dns_cache_service="resolvectl"
elif [ "$(command -v dnsmasq)" ]; then
    # dnsmasq is installed
    dns_cache_service="dnsmasq"
else
    # no dns cache service is installed
    echo "[Error] No DNS cache service is installed on this system that this script supports."
    echo ""
    echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
    echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
    echo "[Info] Servers usually do not have a DNS cache service installed by default."
    echo ""
    echo "[Info] Installing a DNS cache is not recommended on servers."
    exit 1
fi

# Check if the dns_cache_service is resolvectl
if [[ "${dns_cache_service}" == "resolvectl" ]]; then
    systemdVersion=$(systemctl --version | head -1 | awk '{ print $2}')
    if [ "$systemdVersion" -lt 254 ]; then
        echo "[Error] The version of systemd is less than 254. The resolvectl show-cache command is not available. Currently system version is ${systemdVersion}."
        exit 1
    fi
    # Get the DNS cache entries from resolvectl
    # https://github.com/systemd/systemd/pull/28012
    if ! dns_cache=$(resolvectl show-cache 2>/dev/null); then
        # Check if the systemd-resolved service is active
        if [[ $(systemctl is-active systemd-resolved) != "active" ]]; then
            echo "[Warn] The systemd-resolved service is not active."
        # Check /etc/resolv.conf that the nameserver is set to the default IP address 127.0.0.53 for systemd-resolved to work
        elif ! grep -q "^nameserver 127.0.0.53" /etc/resolv.conf; then
            echo "[Warn] The nameserver in /etc/resolv.conf is not set to an IP address 127.0.0.53 ."
            echo "[Info] The nameserver in /etc/resolv.conf should be set to an IP address 127.0.0.53 for systemd-resolved to work."
        else
            echo "[Warn] Failed to get the DNS cache entries. Is systemd-resolved installed, configured, and running?"
        fi
        echo ""
        echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
        echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
        echo "[Info] Servers usually do not have a DNS cache service installed by default."
        echo ""
        echo "[Info] Installing a DNS cache is not recommended on servers."
        exit 0
    fi

    dns_cache_entries=""
    # Get the DNS cache entries from resolvectl based on the keywords provided
    for keyword in "${keywords[@]}"; do
        # Example DNS cache entry:
        # consto.com IN A 123.123.123.123
        # consto.com IN AAAA 2001:0db8:85a3:0000:0000:8a2e:0370:7334
        dns_cache_entries+="DNS Cache Records Matching: ${keyword}"
        dns_cache_entries+=$'\n' # newline
        dns_cache_entries+=$(echo "$dns_cache" | grep -i -E "${keyword}")
        dns_cache_entries+=$'\n' # newline
    done
    # Print the DNS cache entries
    echo "" # newline
    echo "$dns_cache_entries"
# Check if the dns_cache_service is dnsmasq
elif [[ "${dns_cache_service}" == "dnsmasq" ]]; then
    if [ -f "/etc/dnsmasq.conf" ]; then
        echo "[Info] dnsmasq configuration file exists."
    else
        echo "[Warn] The dnsmasq configuration file does not exist and is likely not installed or configured."
        echo ""
        echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
        echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
        echo "[Info] Servers usually do not have a DNS cache service installed by default."
        echo ""
        echo "[Info] Installing a DNS cache is not recommended on servers."
        exit 0
    fi
    # Check that log-queries is enabled in the dnsmasq configuration file
    if ! grep -q "log-queries" /etc/dnsmasq.conf; then
        echo "[Warn] The 'log-queries' option is not enabled in the dnsmasq configuration file."
        echo ""
        echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
        echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
        echo "[Info] Servers usually do not have a DNS cache service installed by default."
        echo ""
        echo "[Info] Installing a DNS cache is not recommended on servers."
        exit 0
    fi
    # Get the log-facility from the dnsmasq configuration file
    log_facility=$(grep -E "^log-facility" /etc/dnsmasq.conf | awk '{print $2}')
    if [[ -z "${log_facility}" ]]; then
        echo "[Warn] The 'log-facility' option is not set in the dnsmasq configuration file."
        echo ""
        echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
        echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
        echo "[Info] Servers usually do not have a DNS cache service installed by default."
        echo ""
        echo "[Info] Installing a DNS cache is not recommended on servers."
        exit 0
    fi
    # Check that log_facility is a valid file
    if [[ ! -f "${log_facility}" ]]; then
        echo "[Error] The log facility file '${log_facility}' does not exist."
        echo ""
        echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
        echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
        echo "[Info] Servers usually do not have a DNS cache service installed by default."
        echo ""
        echo "[Info] Installing a DNS cache is not recommended on servers."
        exit 1
    fi
    # Get the DNS cache entries from log_facility
    # Example log_facility file:
    # Jan  1 00:00:00 dnsmasq[12345]: query[A] example.com from
    for keyword in "${keywords[@]}"; do
        # Get the DNS cache entries from the log_facility file
        # The awk command parses the log_facility file and extracts the time, query, and host
        if ! dns_cache_entries=$(grep -i -E "${keyword}" "${log_facility}" | awk 'BEGIN {OFS = ",";}$5 == "query[A]" {time = mktime(sprintf("%04d %02d %02d %s\n",strftime("%Y", systime()),(match("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3,$2,gensub(":", " ", "g", $3)));query = $6;host = $8;print time, host, query;}'); then
            echo "[Error] Failed to get the DNS cache entries."
            echo "$dns_cache_entries"
            echo ""
            echo "[Info] Supported DNS cache services: systemd-resolved, dnsmasq"
            echo "[Info] systemd-resolved commonly installed along with a Desktop Environment."
            echo "[Info] Servers usually do not have a DNS cache service installed by default."
            echo ""
            echo "[Info] Installing a DNS cache is not recommended on servers."
            exit 1
        fi
    done
    echo "$dns_cache_entries"
fi

# Set the multiline_custom_field
if [[ -n "$multiline_custom_field" ]]; then
    if [[ -x "$ninjarmm_cli" ]]; then
        if hideOutput=$(echo "$dns_cache_entries" | "$ninjarmm_cli" set --stdin "$multiline_custom_field" 2>&1); then
            echo "[Info] Successfully set custom field: $multiline_custom_field"
        else
            echo "[Error] Failed to set custom field: $multiline_custom_field. Custom Field does not exist or does not have write permissions."
            exit 1
        fi
    else
        echo "[Error] NinjaRMM CLI not found or not executable"
        exit 1
    fi
fi

 

Accede a más de 300 scripts en el Dojo de NinjaOne

Obtén acceso

Análisis detallado

El script está estructurado para manejar diferentes servicios de caché DNS (systemd-resolved y dnsmasq) que pueden estar presentes en un sistema Linux. Aquí tienes una explicación paso a paso de cómo funciona el script:

1. Configuración de parámetros:

  • El script comienza aceptando dos parámetros: keywords_to_search y multiline_custom_field.
  • keywords_to_search es una lista separada por comas de palabras clave que el script utilizará para buscar en las entradas de la caché DNS. El script comprueba si estos parámetros están configurados y los inicializa en consecuencia.

2. Verificación del entorno:

  • Comprueba si está disponible el comando ninjarmm-cli, necesario para que el script interactúe con la plataforma NinjaOne RMM.
  • Verifica si el script se ejecuta con privilegios de root, ya que el acceso de root es necesario para consultar las cachés DNS.

3. Detección del servicio de caché DNS:

  • El script detecta si systemd-resolved o dnsmasq están instalados y activos en el sistema. Si no se encuentra ninguno de los dos servicios, el script finaliza con un mensaje de error apropiado, informando al usuario de que no hay instalado ningún servicio de caché DNS compatible.

4. Gestionar systemd-resolved:

  • Si se detecta systemd-resolved, el script comprueba la versión de systemd para asegurarse de que soporta el comando show-cache (introducido en la versión 254).
  • A continuación, el script consulta la caché DNS mediante resolvectl show-cache y filtra los resultados en función de las palabras clave proporcionadas.

5. Gestión de dnsmasq:

  • Si dnsmasq es detectado, el script verifica la presencia y configuración del archivo dnsmasq.conf, asegurando que el registro de consultas DNS esté habilitado.
  • A continuación, busca en el archivo de registro especificado en dnsmasq.conf las consultas DNS que coinciden con las palabras clave proporcionadas.

6. Gestión del output:

  • El script recopila y formatea las entradas de la caché DNS que coinciden con las palabras clave.
  • Si se proporciona el parámetro multiline_custom_field, el script intenta establecer este campo en NinjaOne RMM utilizando el comando ninjarmm-cli.

Posibles casos de uso

Imagina un escenario en el que un profesional de TI tiene la tarea de investigar una actividad sospechosa en la red. Observa patrones de tráfico inusuales y sospecha que ciertos dominios se consultan con frecuencia.

Con este script, puede buscar rápidamente en la caché DNS palabras clave específicas (por ejemplo, nombres de dominio sospechosos) y recuperar las entradas pertinentes. Esta información puede utilizarse para bloquear estos dominios, ajustar la configuración del firewall o investigar más a fondo.

Otro escenario podría implicar la optimización del rendimiento de la red. Un MSP que gestione redes de múltiples clientes podría utilizar este script para identificar los dominios de acceso frecuente almacenados en caché en varios sistemas.

Analizando estas entradas de caché, el MSP podría recomendar la configuración de servidores DNS locales o políticas de almacenamiento en caché para reducir la latencia y mejorar la experiencia del usuario.

Comparaciones

Aunque existen otros métodos para buscar entradas de caché DNS en sistemas Linux, como inspeccionar manualmente los archivos de registro o utilizar herramientas como grep en combinación con los registros del sistema, este script ofrece un enfoque más racionalizado y automatizado.

No sólo detecta el servicio de caché DNS adecuado, sino que también se encarga de los posibles problemas de configuración, lo que lo convierte en una opción más fácil de usar, especialmente para quienes gestionan varios sistemas.

FAQ

  • ¿Qué ocurre si no hay instalado ningún servicio de caché DNS? El script finalizará y mostrará un mensaje indicando que no hay instalado ningún servicio de caché DNS compatible, recomendando no instalar ninguno en los servidores.
  • ¿Se puede utilizar este script en servidores? Aunque técnicamente es posible, en general no se recomienda ejecutar servicios de caché DNS en servidores, como ponen de manifiesto los mensajes de salida del script.
  • ¿Por qué necesito privilegios de root para ejecutar este script? El acceso a las entradas de la caché DNS suele requerir permisos elevados, por lo que el script comprueba si se dispone de acceso de root.

Implicaciones

La capacidad de buscar y analizar entradas de caché DNS tiene implicaciones significativas para la seguridad y el rendimiento de la red. Al identificar y reaccionar rápidamente ante consultas de dominio inusuales o maliciosas, los profesionales de TI pueden mitigar las amenazas potenciales antes de que se agraven. Además, el análisis periódico de la caché DNS puede ayudar a optimizar las configuraciones de red, lo que se traduce en una mayor eficacia general.

Recomendaciones

Cuando utilice este script, asegúrate de:

  • Ejecutarlo con privilegios de root para evitar problemas de permisos.
  • Comprobar que systemd-resolved o dnsmasq están correctamente configurados en tu sistema.
  • Actualiza regularmente tu sistema para garantizar la compatibilidad con las últimas funciones (por ejemplo, systemd versión 254 o superior).
  • Utilizar palabras clave significativas y relevantes para filtrar eficazmente las entradas de la caché DNS.

Reflexiones finales

Este script de búsqueda de caché DNS es una poderosa herramienta para los profesionales de TI, especialmente cuando se integra con la plataforma de gestión de NinjaOne. Al automatizar el proceso de recuperación y análisis de las entradas de caché DNS, permite una gestión de la red y una supervisión de la seguridad más eficaces. El sólido conjunto de herramientas de NinjaOne puede mejorar aún más la utilidad de este script, proporcionando soluciones integrales para las tareas de gestión de TI.

Categorías:

Quizá también te interese…

×

¡Vean a NinjaOne en acción!

Al enviar este formulario, acepto la política de privacidad de NinjaOne.

Términos y condiciones de NinjaOne

Al hacer clic en el botón “Acepto” que aparece a continuación, estás aceptando los siguientes términos legales, así como nuestras Condiciones de uso:

  • Derechos de propiedad: NinjaOne posee y seguirá poseyendo todos los derechos, títulos e intereses sobre el script (incluidos los derechos de autor). NinjaOne concede al usuario una licencia limitada para utilizar el script de acuerdo con estos términos legales.
  • Limitación de uso: solo podrás utilizar el script para tus legítimos fines personales o comerciales internos, y no podrás compartirlo con terceros.
  • Prohibición de republicación: bajo ninguna circunstancia está permitido volver a publicar el script en ninguna biblioteca de scripts que pertenezca o esté bajo el control de cualquier otro proveedor de software.
  • Exclusión de garantía: el script se proporciona “tal cual” y “según disponibilidad”, sin garantía de ningún tipo. NinjaOne no promete ni garantiza que el script esté libre de defectos o que satisfaga las necesidades o expectativas específicas del usuario.
  • Asunción de riesgos: el uso que el usuario haga del script corre por su cuenta y riesgo. El usuario reconoce que existen ciertos riesgos inherentes al uso del script, y entiende y asume cada uno de esos riesgos.
  • Renuncia y exención: el usuario no hará responsable a NinjaOne de cualquier consecuencia adversa o no deseada que resulte del uso del script y renuncia a cualquier derecho o recurso legal o equitativo que pueda tener contra NinjaOne en relación con su uso del script.
  • CLUF: si el usuario es cliente de NinjaOne, su uso del script está sujeto al Contrato de Licencia para el Usuario Final (CLUF).