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
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.