
Tuneliza datos IPv4 a través de servidores DNS para evadir las restricciones del firewall y proporcionar acceso de red encubierto para pruebas de penetración.
Este es un software que te permite tunelizar datos IPv4 a través de un servidor DNS. Puede ser útil en diferentes situaciones donde el acceso a internet está bloqueado por un firewall, pero las consultas DNS están permitidas.
Iodine no tiene script de configuración. Hay dos características opcionales
para Linux (soporte para SELinux y systemd) que se habilitarán
automáticamente si los archivos de cabecera relevantes se encuentran en
/usr/include. (Consulta el script en ./src/osflags)
Ejecuta make para compilar los binarios del servidor y del cliente.
Ejecuta make install para copiar los binarios y la página man al directorio
de destino.
Ejecuta make test para compilar y ejecutar las pruebas unitarias. (Requiere
la librería check)
¡Pruébalo en tu propia LAN! Sigue estos sencillos pasos:
./iodined -f 10.0.0.1 test.com.
Si ya usas la red 10.0.0.0, utiliza otra red interna como
172.16.0.0../iodine -f -r 192.168.0.1 test.com.
Reemplaza 192.168.0.1 con la dirección IP de tu servidor.10.0.0.2 y el servidor tiene
10.0.0.1.Para usarlo realmente a través de un servidor de nombres intermediario, mira más abajo.
Nota: el servidor y el cliente deben hablar exactamente el mismo protocolo. En la mayoría de los casos, esto significa ejecutar la misma versión de iodine. Desafortunadamente, implementar compatibilidad de protocolo hacia atrás y hacia adelante generalmente no es factible.
Para usar este túnel, necesitas control sobre un dominio real (como
mydomain.com) y un servidor con una dirección IP pública para ejecutar
iodined. Si este servidor ya ejecuta un programa DNS, cambia su puerto de
escucha y luego usa la opción -b de iodined para permitir que iodined
reenvíe las consultas DNS. (Ten en cuenta que este procedimiento no se
recomienda en entornos de producción, porque el reenvío DNS de iodined no
es completamente transparente; por ejemplo, las transferencias de zona no
funcionarán). Alternativamente, puedes reenviar el subdominio desde tu
servidor DNS a iodined, que debe entonces ejecutarse en un puerto diferente
(-p).
Luego, delega un subdominio (por ejemplo, t1.mydomain.com) al servidor
iodined. Si usas BIND para tu dominio, añade dos líneas como estas al archivo
de zona:
t1 IN NS t1ns.mydomain.com. ; note the dot!
t1ns IN A 10.15.213.99
La línea NS es todo lo que se necesita para enrutar las consultas del
subdominio t1 al servidor t1ns. Usamos un nombre corto para el
subdominio, para mantener disponible el mayor espacio posible para el tráfico
de datos. Al final de la línea NS está el nombre de tu servidor iodined.
Este puede ser cualquier nombre, apuntando a cualquier lugar, pero en este
caso es fácil mantenerlo en el mismo archivo de zona. Debe ser un nombre (no
una dirección IP), y ese nombre debe tener un registro A (no un CNAME).
Si tu servidor iodined tiene una IP dinámica, usa un proveedor de DNS
dinámico. Simplemente apunta la línea NS a él y omite la línea A:
t1 IN NS myname.mydyndnsprovider.com. ; note the dot!
Luego recarga o reinicia tu programa de servidor de nombres. Ahora cualquier
consulta DNS para dominios que terminen en t1.mydomain.com se enviará a tu
servidor iodined.
Finalmente, inicia iodined en tu servidor. El primer argumento es la
dirección IP dentro del túnel, que puede ser de cualquier rango que aún no
uses (por ejemplo 192.168.99.1), y el segundo argumento es el dominio
asignado (en este caso t1.mydomain.com). Usar la opción -f mantendrá
iodined ejecutándose en primer plano, lo que ayuda al probar. iodined abrirá
una interfaz virtual ("dispositivo tun") y también comenzará a escuchar
consultas DNS en el puerto UDP 53. Introduce una contraseña en la línea de
comandos (-P pass) o después de que el servidor haya iniciado. Ahora todo
está listo para el cliente.
Si existe la posibilidad de que uses un túnel iodine desde entornos
inesperados, inicia iodined con la opción -c.
Línea de comandos resultante en esta situación de ejemplo:
./iodined -f -c -P secretpassword 192.168.99.1 t1.mydomain.com
Todo el proceso de configuración está hecho; solo inicia iodine. Acepta uno
o dos argumentos: el primero es el servidor DNS intermediario local
(opcional) y el segundo es el dominio que usaste (t1.mydomain.com). Si no
especificas el primer argumento, se consultará la configuración DNS actual
del sistema.
Si las consultas DNS están permitidas hacia cualquier equipo, puedes dar
directamente la dirección del servidor iodined como primer argumento (en el
ejemplo: t1ns.mydomain.com o 10.15.213.99). En ese caso, también puede
suceder que se permita cualquier tráfico hacia el puerto DNS (53 UDP) de
cualquier equipo. Iodine detectará esto y cambiará a tunelización UDP pura si
es posible. Para forzar la tunelización DNS en cualquier caso, usa la opción
-r (especialmente útil al probar dentro de tu propia red).
La interfaz de túnel del cliente obtendrá una IP cercana a la del servidor
(en este caso 192.168.99.2 o .3, etc.) y una MTU adecuada. Introduce la
misma contraseña que en el servidor, ya sea como opción de línea de comandos
o después de que el cliente haya iniciado. Usar la opción -f mantendrá el
cliente iodine ejecutándose en primer plano.
Línea de comandos resultante en esta situación de ejemplo; añadir -r fuerza
la tunelización DNS incluso si la tunelización UDP pura sería posible:
./iodine -f -P secretpassword t1.mydomain.com
Desde cualquiera de los dos lados, ahora deberías poder hacer ping a la
dirección IP del otro extremo del túnel. En este caso, ping 192.168.99.1
desde el cliente iodine y 192.168.99.2 desde el servidor iodine.
Los datos dentro del túnel son solo IPv4.
Por defecto, el servidor escucha tanto IPv4 como IPv6 para las solicitudes
entrantes. Usa las opciones -4 o -6 para escuchar solo en un protocolo.
El modo raw se intentará en el mismo protocolo utilizado para el inicio de
sesión.
El cliente puede usar servidores de nombres IPv4 o IPv6 para conectarse a
iodined. Los servidores de nombres intermediarios traducirán entre protocolos
automáticamente si es necesario. Usa las opciones -4 o -6 para forzar al
cliente a usar una versión de IP específica para sus consultas DNS.
Si tu servidor está escuchando en IPv6 y es accesible, añade un registro AAAA para él en tu configuración DNS. Extender el ejemplo anterior se vería así:
t1 IN NS t1ns.mydomain.com. ; note the dot!
t1ns IN A 10.15.213.99
t1ns IN AAAA 2001:db8::1001:99
Es posible enrutar todo el tráfico a través del túnel DNS. Para hacer esto, primero añade una ruta de host hacia el servidor de nombres usado por iodine a través de la interfaz cableada/inalámbrica, con la puerta de enlace predeterminada como gateway. Luego reemplaza la puerta de enlace predeterminada con la dirección IP del servidor iodined dentro del túnel DNS y configura el servidor para hacer NAT.
Sin embargo, ten en cuenta que el tráfico de datos tunelizado no está cifrado en absoluto y puede ser leído y modificado por terceros con relativa facilidad. Para máxima seguridad, ejecuta una VPN a través del túnel DNS (=doble tunelización), o usa acceso mediante shell seguro (SSH), posiblemente con reenvío de puertos. Esto último también se puede usar para navegación web, si ejecutas un proxy web (por ejemplo Privoxy) en tu servidor.
El servidor iodined responde a las solicitudes NS enviadas para
subdominios del dominio del túnel. Si tu subdominio iodined es
t1.mydomain.com, envía una solicitud NS para foo123.t1.mydomain.com
para ver si la delegación funciona. dig es una buena herramienta para esto:
% dig -t NS foo123.t1.mydomain.com
ns.io.citronna.de.
Además, el servidor iodined responderá a las solicitudes que comiencen con 'z' para cualquiera de los tipos de solicitud soportados, por ejemplo:
dig -t TXT z456.t1.mydomain.com
dig -t SRV z456.t1.mydomain.com
dig -t CNAME z456.t1.mydomain.com
La respuesta debería verse como texto ilegible en todos estos casos.
En Mac OS X 10.6 y posteriores, iodine soporta los dispositivos utun nativos
integrados en el sistema operativo: usa -d utunX.
El tamaño de fragmento de las respuestas DNS normalmente se autodetecta para
obtener el máximo ancho de banda. Para forzar un valor específico (y acelerar
las cosas), usa la opción -m.
Los nombres de host DNS normalmente se usan hasta su longitud máxima, 255
caracteres. Se ha encontrado que algunos relays DNS responden a consultas de
longitud completa de manera bastante poco fiable, dando resultados muy
variables (y en su mayoría muy malos) de la autodetección del tamaño de
fragmento en intentos repetidos. En estos casos, usa la opción -M para
reducir la longitud del nombre de host DNS a, por ejemplo, 200 caracteres, lo
que hace que estos relays DNS sean mucho más estables. Esto también es útil
en algunos relays DNS "desoptimizadores" que rellenan la respuesta con dos
copias completas de la consulta, dejando muy poco espacio para los datos de
bajada (tampoco son capaces de usar EDNS0). La opción -M puede intercambiar
algo de ancho de banda de subida por ancho de banda de bajada. Ten en cuenta
que el valor mínimo de -M es alrededor de 100, ya que el protocolo puede
dividir paquetes (máximo 1200 bytes) en solo 16 fragmentos, requiriendo al
menos 75 bytes de datos reales por fragmento.
Los datos de subida se envían comprimidos con gzip y codificados con Base32;
o Base64 si el servidor de relevo soporta mayúsculas y minúsculas mezcladas y
+ en los nombres de dominio; o Base64u si se soporta _ en su lugar; o
Base128 si se soportan caracteres de alto valor de byte. Esta codificación de
subida se autodetecta. El protocolo DNS permite una consulta por paquete, y
una consulta puede tener un máximo de 256 caracteres. Cada parte del nombre de
dominio puede tener un máximo de 63 caracteres. Por lo tanto, tu nombre de
dominio y subdominio deben ser lo más cortos posible para permitir el máximo
rendimiento de subida.
Se soportan varios tipos de solicitud DNS, esperándose que los tipos NULL y
PRIVATE proporcionen el mayor ancho de banda de bajada. El tipo PRIVATE
usa el valor 65399 en el rango de uso privado. Otros tipos disponibles son
TXT, SRV, MX, CNAME y A (que devuelve CNAME), en orden decreciente
de ancho de banda. Normalmente, el tipo de solicitud "mejor" se autodetecta y
se usa. Sin embargo, los relays DNS pueden imponer límites, por ejemplo en
NULL y TXT, haciendo que SRV o MX sean en realidad la mejor opción. Esto no
se autodetecta, pero se puede forzar usando la opción -T. Es aconsejable
probar varias alternativas, especialmente cuando el tipo de solicitud
autodetectado proporciona un tamaño de fragmento de bajada de menos de 200
bytes.
Ten en cuenta que las consultas SRV, MX y A (que devuelven CNAME)
pueden/causarán búsquedas adicionales por parte de servidores de nombres con
caché "inteligentes" para obtener una dirección IP real, lo que puede
ralentizar el proceso o hacerlo fallar por completo.
Las respuestas DNS para consultas que no son NULL/PRIVATE se pueden codificar
con el mismo conjunto de códecs que los datos de subida. Esto normalmente
también se autodetecta, pero no se realizan pruebas totalmente exhaustivas,
por lo que algunos problemas pueden no notarse al seleccionar códecs más
avanzados. En ese caso, verás fallos/corrupción en la autodetección del tamaño
de fragmento. En particular, se ha encontrado que varios relays DNS cambian a
minúsculas las respuestas que devuelven nombres de host (SRV, MX, CNAME,
A) solo cuando ese nombre de host supera aprox. 180 caracteres. En estos
casos y similares, usa la opción -O para probar otros códecs de bajada;
Base32 debería funcionar siempre.
El funcionamiento normal ahora es que el servidor no responda a una
solicitud DNS hasta que haya llegado la siguiente solicitud DNS, es decir,
ser "perezoso". De esta manera, el servidor siempre tendrá una solicitud DNS
a mano cuando haya que enviar nuevos datos de bajada. Esto mejora enormemente
el rendimiento (interactivo) y la latencia, y permite ralentizar las
solicitudes de ping en reposo a intervalos de 4 segundos por defecto, y
posiblemente mucho más lentos. De hecho, el propósito principal de los pings
ahora es forzar una respuesta al ping anterior y prevenir los tiempos de
espera del servidor DNS (generalmente al menos 5-10 segundos según RFC1035).
Algunos servidores DNS son más impacientes y darán errores SERVFAIL (tiempos
de espera) en períodos sin tráfico de datos tunelizado. Todos los datos
deberían pasar de todos modos en estos casos, pero iodine reducirá el
intervalo de ping a 1 segundo de todos modos (-I1) para reducir el número de
mensajes de error. Esto puede no ayudar para relays DNS muy impacientes como
dnsadvantage.com (ultradns), que agotan el tiempo de espera en 1 segundo o
incluso menos. Aun así, los datos seguirán pasando, y puedes ignorar los
errores SERVFAIL.
Si estás ejecutando en una red local sin ningún servidor DNS en medio, prueba
-I 50 (iodine e iodined cierran la conexión después de 60 segundos de
silencio). La única vez que notarás una ralentización es cuando los paquetes
de respuesta DNS se pierden; el servidor iodined tiene entonces que esperar
un nuevo ping para reenviar los datos. Puedes acelerar esto generando algo de
tráfico de subida (pulsación de tecla, ping). Si esto sucede a menudo, revisa
tu red en busca de cuellos de botella y/o ejecuta con -I1.
La respuesta retardada en modo perezoso hará que algunos relays DNS
comerciales de "grado carrier" reenvíen repetidamente la misma consulta DNS
al servidor iodined. Si el relay DNS está realmente implementado como un grupo
de servidores paralelos, las solicitudes duplicadas pueden incluso llegar
desde múltiples fuentes. Este efecto solo será visible en el tráfico de red
en el servidor iodined y no afectará la conexión del cliente. Iodined
notará estos duplicados y enviará la misma respuesta (cuando llegue su
momento) tanto a la consulta original como al último duplicado. Después de
eso, la respuesta completa se almacena en caché por un corto tiempo. Los
duplicados retardados que llegan al servidor incluso más tarde reciben una
respuesta que el cliente iodine ignorará (si es que alguna vez llega allí).
Si tienes problemas, intenta inspeccionar el tráfico con herramientas de
monitoreo de red como tcpdump o ethereal/wireshark, y asegúrate de que el
servidor DNS intermediario no haya almacenado en caché la respuesta. Un
mensaje de error en caché podría significar que iniciaste el cliente antes que
el servidor. La opción -D (y -DD) en el servidor también puede mostrar las
consultas recibidas y enviadas.
Si tu puerto 53 está ocupado en una interfaz específica por una aplicación
que no lo usa, usa -p en iodined para especificar un puerto alternativo
(como -p 5353) y usa por ejemplo iptables (en Linux) para reenviar el
tráfico:
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to :5353
(Enviado por Tom Schouten)
Iodined rechazará datos de clientes que no hayan estado activos (datos/pings) durante más de 60 segundos. De manera similar, iodine se cerrará cuando no se haya recibido datos de bajada durante 60 segundos. En caso de una interrupción de red prolongada o similar, simplemente reinicia iodine (vuelve a iniciar sesión), posiblemente varias veces hasta que recuperes tu antigua dirección IP. Una vez hecho esto, solo espera un rato y eventualmente verás que el tráfico TCP tunelizado continúa fluyendo desde donde se detuvo antes de la interrupción.
Con la introducción de la cola de paquetes de bajada en el servidor, su uso de memoria ha aumentado en varios megabytes en la configuración predeterminada. Para usar en entornos con poca memoria (por ejemplo, ejecutándose en tu router DSL), puedes disminuir USERS y anular la definición de OUTPACKETQ_LEN en user.h sin ninguna consecuencia negativa, asumiendo que como máximo un cliente estará conectado en cualquier momento. Todavía se recomienda un DNSCACHE_LEN pequeño, preferiblemente 2 o más; sin embargo, también puedes anular su definición para ahorrar unos kilobytes más.
Un servidor iodine puede manejar múltiples dominios. Configura diferentes
registros NS en el mismo dominio apuntando todos al mismo host, y usa un
comodín al inicio del argumento del dominio superior (ejemplo
*.mydomain.com). iodine aceptará tráfico de túnel para todos los dominios
que coincidan con ese patrón. El comodín debe estar al inicio del argumento
del dominio superior y ser seguido por un punto.
Esta sección tabula algunas mediciones de rendimiento. Para verlas correctamente, usa una fuente de ancho fijo como Courier.
Las mediciones se realizaron con el protocolo 00000502 en modo perezoso;
codificación de subida siempre Base128; iodine -M255; iodined -m1130. Las
condiciones de red no fueron extremadamente favorables; los resultados no son
benchmarks sino una indicación realista del rendimiento en el mundo real que
se puede esperar en situaciones similares.
El rendimiento de subida/bajada se midió haciendo scp de un archivo
previamente leído de /dev/urandom (es decir, incompresible) y midiendo el
tamaño con ls -l ; sleep 30 ; ls -l en una conexión separada no tunelizada.
Dado el gran tamaño de bloque de scp de 16 kB, esto da una resolución de
4.3 kbit/s, lo que explica por qué algunos valores son exactamente iguales.
Los tiempos de ida y vuelta de ping se midieron con ping -c100; se
presentan el rtt promedio y la desviación media (que indica la dispersión
alrededor del promedio), en milisegundos.
Laptop -> Wifi AP -> Home server -> DSL provider -> Datacenter iodine DNS "relay" bind9 DNS cache iodined
downstr. upstream downstr. ping-up ping-down
fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev
-----------------------------------------------------------------------------
iodine -> Wifi AP :53
-Tnull (= -Oraw) 982 43.6 131.0 28.0 4.6 26.8 3.4
iodine -> Home server :53
-Tnull (= -Oraw) 1174 48.0 305.8 26.6 5.0 26.9 8.4
iodine -> DSL provider :53
-Tnull (= -Oraw) 1174 56.7 367.0 20.6 3.1 21.2 4.4
-Ttxt -Obase32 730 56.7 174.7*
-Ttxt -Obase64 874 56.7 174.7
-Ttxt -Obase128 1018 56.7 174.7
-Ttxt -Oraw 1162 56.7 358.2
-Tsrv -Obase128 910 56.7 174.7
-Tcname -Obase32 151 56.7 43.6
-Tcname -Obase128 212 56.7 52.4
iodine -> DSL provider :53
wired (no Wifi) -Tnull 1174 74.2 585.4 20.2 5.6 19.6 3.4
[174.7* : these all have 2frag/packet]
Laptop -> Wifi+vpn / wired -> Home server iodine iodined
downstr. upstream downstr. ping-up ping-down
fragsize kbit/s kbit/s avg +/-mdev avg +/-mdev
-----------------------------------------------------------------------------
wifi + openvpn -Tnull 1186 166.0 1022.3 6.3 1.3 6.6 1.6
wired -Tnull 1186 677.2 2464.1 1.3 0.2 1.3 0.1
El rendimiento está fuertemente ligado a tiempos de ping bajos, ya que iodine requiere confirmación para cada fragmento de datos antes de pasar al siguiente. Permitir múltiples fragmentos en vuelo como TCP posiblemente podría aumentar el rendimiento, pero probablemente causaría una sobrecarga grave para los servidores DNS intermediarios. El protocolo actual escala el rendimiento con la capacidad de respuesta del DNS, ya que los servidores DNS manejan en promedio como máximo una solicitud DNS por cliente.
iodine ha sido probado en Linux (arm, ia64, x86, AMD64 y SPARC64), FreeBSD (ia64, x86), OpenBSD (x86), NetBSD (x86), MacOS X (ppc y x86, con http://tuntaposx.sourceforge.net/) y Windows (con el driver OpenVPN TAP32, consulta el archivo readme de win32). Debería ser fácil portarlo a otros sistemas tipo Unix que tengan soporte de tunelización TUN/TAP. Haznos saber si consigues ejecutarlo en otras plataformas.
El nombre iodine fue elegido porque comienza con IOD (IP Over DNS) y porque el yodo tiene número atómico 53, que resulta ser el número de puerto de DNS.
Copyright (c) 2006-2014 Erik Ekman [email protected], 2006-2009 Bjorn Andersson [email protected]. También con contribuciones importantes de Anne Bezemer.
Se concede permiso para usar, copiar, modificar y/o distribuir este software para cualquier propósito, con o sin cargo, siempre que el aviso de copyright anterior y este aviso de permiso aparezcan en todas las copias.
EL SOFTWARE SE PROPORCIONA "TAL CUAL" Y EL AUTOR RENUNCIA A TODAS LAS GARANTÍAS CON RESPECTO A ESTE SOFTWARE, INCLUYENDO TODAS LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD. EN NINGÚN CASO EL AUTOR SERÁ RESPONSABLE POR DAÑOS ESPECIALES, DIRECTOS, INDIRECTOS O CONSECUENTES, NI POR CUALQUIER OTRO DAÑO QUE RESULTE DE LA PÉRDIDA DE USO, DATOS O BENEFICIOS, YA SEA POR UNA ACCIÓN CONTRACTUAL, NEGLIGENCIA U OTRA ACCIÓN PERJUDICIAL, QUE SURJA DE O EN CONEXIÓN CON EL USO O RENDIMIENTO DE ESTE SOFTWARE.
Implementación de MD5 por L. Peter Deutsch (licencia y fuente en
src/md5.[ch])
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. Todos los derechos
reservados.