Cómo detectar un túnel DNS en un servidor Linux
Última actualización:
El túnel DNS (DNS tunneling) esconde datos dentro de consultas DNS. Un programa del servidor pide nombres como mzxw6ytboi4dgnzt.tunnel.example, donde el subdominio son los datos, y el servidor de nombres del atacante para tunnel.example responde con más datos en registros TXT u otros. Funciona porque casi cualquier servidor puede enviar consultas DNS, incluso uno cuyo tráfico saliente está filtrado por lo demás. El malware lo usa para recibir órdenes y sacar datos robados; herramientas como iodine y dnscat2 montan conexiones de red completas sobre él.
Ese tráfico deja huellas que el DNS normal no deja: subdominios muy largos y aleatorios, muchos nombres únicos bajo un mismo dominio, una proporción alta de consultas TXT, un ritmo constante de consultas a un único dominio. A continuación: cómo capturar y leer el tráfico DNS del servidor, revisar los logs del resolver, encontrar el programa y bloquear el túnel. Los comandos son para Debian y Ubuntu y para la familia RHEL.
Saber cómo es un túnel DNS
| Señal | Tráfico normal | Un túnel |
|---|---|---|
| Longitud del subdominio | Palabras cortas: www, mail, api | De 30 a 63 caracteres aleatorios por etiqueta, a menudo varias etiquetas |
| Nombres únicos por dominio | Unos pocos, consultados una y otra vez | Cientos o miles, cada uno consultado una sola vez |
| Tipos de consulta | Sobre todo A y AAAA | Muchas consultas TXT, NULL, CNAME o MX |
| Ritmo | Picos cuando alguien usa un servicio | Un ritmo constante, de día y de noche, hacia el mismo dominio |
| Resolver | Los de /etc/resolv.conf | A veces un servidor DNS que el sistema no tiene configurado |
Nota: Algo de tráfico legítimo se le parece: las consultas de antivirus y de reputación (codifican hashes de archivos en los nombres), las comprobaciones de listas negras que hace un servidor de correo y algunos nombres de CDN y de nube. Comprueba el dominio antes de llamarlo túnel.
Capturar el tráfico DNS del servidor con tcpdump
Instala tcpdump, y tshark para el análisis de más abajo. En Debian y Ubuntu el instalador de tshark pregunta si los usuarios sin privilegios pueden capturar: responde que no.
sudo apt install tcpdump tsharksudo dnf install tcpdump wireshark-cliGraba cinco minutos de tráfico DNS, UDP y TCP, en todas las interfaces. Con systemd-resolved, los programas preguntan al stub local en 127.0.0.53 y el stub pregunta aguas arriba: -i any ve ambas cosas.
sudo timeout 300 tcpdump -i any -nn -Z root -w /root/dns.pcap 'port 53'Después léelo. Primero la proporción de cada tipo de consulta: muchos TXT? o NULL? llaman la atención.
sudo tcpdump -nn -r /root/dns.pcap 'dst port 53' 2>/dev/null \
| grep -oE '[A-Z0-9]+\? [^ ]+' | awk '{print $1}' | sort | uniq -c | sort -rnLuego los dominios con más nombres únicos por debajo. Un túnel pone un dominio en cabeza con cientos de nombres; el tráfico normal se reparte entre muchos dominios con pocos nombres cada uno. (El recuento agrupa por las dos últimas etiquetas, así que example.co.uk aparece como co.uk.)
sudo tcpdump -nn -r /root/dns.pcap 'dst port 53' 2>/dev/null \
| grep -oE '[A-Z0-9]+\? [^ ]+' | awk '{print tolower($2)}' | sort -u \
| awk -F. '{n = NF - 1; if (n >= 2) print $(n-1) "." $n}' | sort | uniq -c | sort -rn | head -20Y los nombres con una etiqueta de 30 caracteres o más:
sudo tcpdump -nn -r /root/dns.pcap 'dst port 53' 2>/dev/null \
| grep -oE '[A-Z0-9]+\? [^ ]+' | awk '{print $2}' \
| awk -F. '{for (i = 1; i < NF; i++) if (length($i) >= 30) {print; break}}' | sort -u | head -20Lo mismo con tshark
tshark da estadísticas por tipo de consulta y el origen y el destino de cada consulta, y encuentra respuestas inusualmente grandes, que los túneles usan para traer datos de vuelta:
sudo tshark -r /root/dns.pcap -q -z dns,tree
sudo tshark -r /root/dns.pcap -Y 'dns.flags.response == 0' -T fields \
-e ip.src -e ip.dst -e dns.qry.type -e dns.qry.name | head -50
sudo tshark -r /root/dns.pcap -Y 'dns.flags.response == 1 && udp.length > 512' -T fields \
-e dns.qry.name | sort | uniq -c | sort -rn | headNota: Esto solo ve el DNS del puerto 53. Un túnel sobre DNS over HTTPS viaja como HTTPS normal por el puerto 443 y aquí es invisible; DNS over TLS usa el puerto 853, que el paso 5 bloquea.
Revisar los logs del resolver
Primero mira qué resolvers tiene configurados el servidor. Las consultas a cualquier otra dirección ya merecen una mirada por sí solas.
cat /etc/resolv.conf
resolvectl status 2>/dev/null | grep -E 'DNS Servers|Current DNS'systemd-resolved no guarda un log de consultas, pero desde systemd 252 (Debian 12, Ubuntu 24.04, RHEL 9 y posteriores) muestra cada resolución en directo. Déjalo funcionando unos minutos y busca nombres largos y aleatorios:
sudo resolvectl monitorSi el servidor tiene su propio resolver, activa su log de consultas. Para unbound, luego sudo systemctl restart unbound:
# /etc/unbound/unbound.conf (RHEL) or a file in /etc/unbound/unbound.conf.d/ (Debian, Ubuntu)
server:
log-queries: yes
log-replies: yessudo rndc querylog onLos dos escriben en el journal. Esto lista los nombres con una etiqueta de 30 caracteres o más de la última hora:
sudo journalctl --since "1 hour ago" -u unbound -u named -u bind9 \
| grep -ioE '([a-z0-9-]{30,}\.)+[a-z0-9.-]+' | sort | uniq -c | sort -rn | head -20Atención: Los logs de consultas crecen rápido en un resolver con mucho tráfico. Desactívalos cuando termines (log-queries: no, sudo rndc querylog off).
Encontrar el programa que hace las consultas
Los sockets DNS viven una fracción de segundo, así que toma muestras: esto mira una vez por segundo durante un minuto y cuenta los programas que tenían un socket DNS abierto. Los programas que preguntan al stub de systemd-resolved aparecen con su propio nombre, porque el stub también escucha en el puerto 53.
for i in $(seq 1 60); do sudo ss -unpH '( dport = :53 )'; sleep 1; done \
| grep -o 'users:(("[^"]*",pid=[0-9]*' | sort | uniq -c | sort -rnSi en cabeza aparecen systemd-resolve, unbound o named, las consultas pasan por el resolver desde otro programa: repite la captura solo en la interfaz de loopback (-i lo) y compara las horas. Para un programa que no conoces, mira su binario, su carpeta y la unidad que lo arrancó:
sudo ls -l /proc/PID/exe /proc/PID/cwd
sudo tr '\0' ' ' < /proc/PID/cmdline; echo
systemctl status PIDUn cliente de túnel es una señal de compromiso, no el compromiso en sí. Busca el resto como en Cómo encontrar y eliminar un minero de criptomonedas: persistencia en cron, systemd y claves SSH, binarios del sistema modificados, y cómo entró el atacante.
Bloquear el túnel
Detén primero el programa. Después asegúrate de que el DNS solo pueda salir por los resolvers que elegiste: esta tabla de nftables descarta el DNS hacia cualquier otra dirección, y DNS over TLS hacia todas. Sustituye 192.0.2.53 por tus resolvers del paso 3 (varios, separados por comas).
sudo nft add table inet dnsguard
sudo nft 'add chain inet dnsguard out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet dnsguard out ip daddr != { 127.0.0.0/8, 192.0.2.53 } meta l4proto { tcp, udp } th dport 53 drop
sudo nft add rule inet dnsguard out tcp dport 853 dropAtención: Con una dirección de resolver equivocada el servidor ya no puede resolver nombres: las actualizaciones, el correo y la mayoría de las aplicaciones se paran. Mantén abierta una segunda sesión, prueba con getent hosts debian.org y, si falla, elimina la tabla con sudo nft delete table inet dnsguard. Las reglas cubren IPv4; añade reglas ip6 daddr si el servidor usa resolvers IPv6. La tabla desaparece al reiniciar.
Un túnel a través de tu propio resolver sigue funcionando, porque el resolver reenvía las consultas. Si usas unbound, responde al dominio del túnel con "no existe":
# In the server: section of unbound.conf
local-zone: "tunnel.example." always_nxdomainsudo unbound-checkconf && sudo systemctl restart unboundCon systemd-resolved solo no hay bloqueo por dominio: apunta el servidor a un resolver que sí lo permita, o confía en eliminar el programa. /etc/hosts no sirve, porque no puede abarcar todos los subdominios.
Cómo detecta InfraFence el túnel DNS
Con **Inspeccionar el tráfico DNS** activado, que es el valor por defecto, el agente lee las consultas y respuestas DNS del propio servidor a nivel de paquete: puerto UDP 53, en solo lectura, con un filtro que se ejecuta en el kernel. Cada evento indica el programa que preguntó, también cuando pasó por systemd-resolved.
dns_tunneling: 60 o más subdominios distintos de un mismo dominio en 5 minutos, largos de media (24 caracteres o más), contando los subdominios de 16 caracteres o más y las consultas TXT y NULL. El evento da el dominio, el número de subdominios y su longitud media.dns_dga: 20 o más dominios de aspecto aleatorio que no existen en 5 minutos, la marca del malware que busca su servidor.dns_threat_resolver(crítico) cuando una consulta va a un servidor DNS que figura en una lista de amenazas,dns_threat_answercuando un nombre resuelve a una dirección listada, ydns_unlisted_resolvercuando un programa usa un servidor DNS distinto de los configurados.- Las consultas de antivirus y de reputación, las comprobaciones de listas negras del correo y las grandes CDN y nubes quedan fuera, y el propio servicio DNS del servidor no cuenta como programa sospechoso.
Consulta Amenazas salientes y DNS. Lo que no hace: notifica un túnel, no lo bloquea; los bloqueos salientes solo se aplican a direcciones de listas de amenazas (Puertos y bloqueo saliente), así que el bloqueo descrito arriba sigue siendo cosa tuya. No ve DNS sobre TCP, TLS ni HTTPS, y un túnel más lento que los umbrales no se notifica.
Preguntas
- Mi firewall bloquea el tráfico saliente. ¿Puede funcionar igualmente un túnel DNS?
- Sí, si el servidor puede consultar un resolver, y casi todos pueden. El resolver reenvía por ti las consultas al servidor de nombres del atacante. Por eso el resolver también debe bloquear el dominio, o el programa tiene que desaparecer.
- ¿DNSSEC o DNS over HTTPS lo impiden?
- No. DNSSEC demuestra que las respuestas son auténticas, y las respuestas del atacante son auténticas para su propio dominio. DNS over HTTPS oculta las consultas a la red, lo que hace un túnel más difícil de ver, no imposible de montar.
- ¿Qué tráfico legítimo se parece a un túnel?
- Las consultas de antivirus y de reputación que codifican hashes de archivos en los nombres, las comprobaciones de listas negras de un servidor de correo y algunos nombres de CDN, nube y telemetría. Investiga el dominio antes de actuar.
Pruébalo gratis en 1 servidor
Starter es gratuito para un servidor, con protección completa y bloqueo automático. Sin tarjeta de crédito.
Instala el agente como root, con tu token en lugar de <TOKEN>:
curl -fsSL https://github.com/infrafence/infrafence-agent/releases/latest/download/install.sh | sudo bash -s -- --token <TOKEN>El token se crea en el panel, en Servidores › Añadir servidor.
