17 años en Internet

07 mayo 2011

Dante para lerdos

¿Qué es Dante? Un proxy de sockets (socks v5), es decir, un servicio que permite que ordenadores de nuestra red interna puedan abrir sockets a través de un cortafuegos para acceder al exterior. La diferencia con otros proxys, como Squid, es que no está orientado a hacer de webcache, si no de monitorización y gestión de todo tipo de tráfico.

¿Quieres controlar las conexiones ssh de tu red local hacia tus clientes? ¿Ver su hora de conexión, desconexión, puerto empleado, ip local e ip destino? Pues por ejemplo esto no lo puedes hacer con un proxy http, te hace falta un proxy de sockets como pudiera ser Dante. Y quien dice ssh dice http o conexiones de chat o edonkey. Puedes monitorizar cualquier clase de puerto o tipo de conexión (tanto UDP como TCP).

Ok, ¿cómo instalamos un Dante? Pues en Ubuntu y Debian es tan simple como teclear "sudo apt-get install dante-server".

Sólo 147Kb de descarga =)


Ahora pasamos a configurar el servicio: "sudo nano /etc/danted.conf":


Vale, cosas que debemos saber. Por defecto no se crea ningún archivo de log pero podemos definir uno. Para ello vamos a reemplazar la línea:
lougoutput: stderr
Por la siguiente:
logoutput: /var/log/danted.log
También es importante definir la interfaz ethernet que atiende las peticiones de proxy y la que accede al exterior. Puedes editar la misma interfaz para las dos cosas. Por ejemplo, mi configuración de casa quedaría así (siendo 1080 el puerto que usaré para atender las peticiones):
internal: eth1 port = 1080
external: eth1

Si no sabes cuales son tus interfaces, puedes ejecutar el comando ifconfig desde una shell:


Sigamos con el danted.conf. Por defecto no hay métodos de autenticación, pero puedes definir username (nombre de usuario), none (ninguno), pam (autenticación del sistema en GNU/Linux, un usuario existente en esta máquina) y rfc931 (un protocolo de autenticación). Si no quieres autenticación puedes dejar comentada esta línea o bien insertar el parámetro none:
method: none
Si por ejemplo escribiera "method: pam none" daríamos a entender que la autenticación pam es optativa, pero no obligatoria para poder utilizar el proxy.

También puedes definir el tiempo máximo que invertirá el proxy en intentar abrir un socket (el tiempo máximo que tarda en levantar una conexión):
connecttimeout: 30

E incluso definir que los sockets mueran por por falta de uso (por no recibir señales de entrada o salida):
iotimeout: 30000

Vale, ya hemos definido los parámetros básicos. Ahora, como si se tratara de un cortafuegos, vamos a definir los parámetros necesarios para filtrar las conexiones. Por ejemplo, nos interesa sólo que se conecten a este proxy equipos que pertenezcan a nuestra red local:


 #Los equipos de nuestra red interna podrán usar el proxy
client pass {
       from: 192.168.0.0/8 port 1-65535 to: 0.0.0.0/0
       log: connect disconnect error
#Los equipos externos no pueden usar nuestro proxy
client block {
      from: 0.0.0.0/0 to: 0.0.0.0/0
       log: connect disconnect error
}
Como veis la sintaxis no es complicada. 192.168.0.0/8 representa nuestra red local y 0.0.0.0/0 representa "todo el rango posible de IPs". Si os fijáis usamos /8 en vez de /24. ¿Por qué? Porque en Dante no se configuran las redes según su máscara de subred, si no por su máscara wildcard. Esta máscara es la inversa de la máscara de subred. Es decir, en vez de utilizar 255.255.255.0 (el /24), se utiliza el 0.0.0.255 (el /8). De igual forma, para definir una IP concreta hay que marcar un /0 y no un /32. También observamos que podemos permitir o bloquear tráfico partiendo de un rango de puertos. Si no se define ningún puerto pues no pasa nada, entiende que se permite (o bloquea) cualquier tipo de conexión.

Si se desea crear más de una regla de acceso o de bloqueo, se debe crear una instancia por norma:
# Permitimos el acceso al cliente externo A
client pass {
       from: 192.168.0.0/8 port 1-65535 to: 10.40.0.0/16
       log: connect disconnect error
}  
# Permitimos el acceso al cliente externo B por ssh
client pass {
       from: 192.168.0.0/8  to: 10.50.2.2/0 port = 22
       log: connect disconnect error

Vale, ya hemos definido la clase de equipos que se pueden conectar al proxy. Pero aún así también nos interesa que sea el proxy quien no pueda conectarse a otros sitios. Para ello aplicaremos las normas pass y block (sin la palabra client) e incluso podemos definirle una serie de comandos predefinidos. Estas normas se aplican de forma genérica a todos los clientes conectados en nuestro proxy:


# Bloqueamos que "hackers" puedan acceder a nuestros recursos a través del loopbak
block { 
       from: 0.0.0.0/0 to: 127.0.0.0/8
       log: connect error disconnect
}


También podemos bloquear páginas webs y dominios:
# Bloqueamos el acceso web a marca.com
block {
       from: 0.0.0.0/0 to: marca.com
       log: connect error disconnect
#Bloqueamos el acceso al dominio facebook.com
block {
       from: 0.0.0.0/0 to: facebook.com
       command: bind connect udpassociate
       log: connect error disconnect
}
Puedes solicitar que todo el tráfico web sea aceptado para cualquier web:

pass { 
       from: 0.0.0.0/0 to: 0.0.0.0/0 port = http
       log: connect error disconnect 
}


pass { 
       from: 0.0.0.0/0 to: 0.0.0.0/0 port = https
       log: connect error disconnect 
}

También puedes habilitar otra clase de puertos conocidos:

pass { 
       from: 0.0.0.0/0 to: 0.0.0.0/0 port = pop3
       log: connect error disconnect 
}


pass { 
       from: 0.0.0.0/0 to: 0.0.0.0/0 port = imap
       log: connect error disconnect 
}


pass { 
       from: 0.0.0.0/0 to: 0.0.0.0/0 port = smtp
       log: connect error disconnect 
}


Por descontado, tendremos que avisar que el resto de tráfico lo denegamos:
block { 
       from: 0.0.0.0/0 to: 0.0.0.0/0 
       log: connect error disconnect 
}
Consideraciones a tener en cuenta: Los bloqueos deben ir antes de las aceptaciones. Si en una norma permites todo el tráfico http y acto seguido bloqueas el acceso a marca.com, tus usuarios entrarán sin problemas en marca.com. Es decir: primero debes indicar las webs que bloqueas y luego habilitar todo el tráfico web. Si por el contrario te interesa tener una lista muy selecta (como la lista de ip's de tus clientes para conectarte sólo a esas máquinas), puedes hacer la inversa. Defines sólo los dominios/ip/redes que das acceso para un puerto determinado (o todos) y al finalizar defines que bloqueas el resto de conexiones para ese puerto (el famoso "from: 0.0.0.0/0 to: 0.0.0.0/0").

Verás que además he puesto como logs las opciones de "connect", "error" y "disconnect". Esto indica que el servicio Dante debe de escribir en el log siempre que salte una conexión, error, o desconexión referente a esa norma. Si te interesa, por ejemplo, que Dante simule ser un sniffer, además deberías de añadir las opciones "data" e "iooperation". No te recomiendo usarlas a no ser que te interese tener un archivo de log gigantesco o violar la privacidad de tus compañeros. Si aún así quieres disponer de aún más información, puedes editar el /etc/init.d/danted para que Dante arranque con el parámetro -d (no confundir con -D). Esto hará que Dante vuelque a los logs toda su información de debug. En caso de tocar el /etc/init.d/danted, acuerdate de que no basta con tocar el método start, también deberás de ponerlo en el restart.

Bueno, ya tenemos un buen servidor Dante montadito. Recuerda que los cambios no son dinámicos, siempre que modifiques el archivo de configuración tendrás que relanzar el servicio para aplicar los cambios:
sudo /etc/init.d/danted restart
Si Dante no estaba en ejecución, el restart fallará y deberás de reiniciar manualmente:
sudo /etc/init.d/danted stop 
sudo /etc/init.d/danted start

Haz un "ps -ef | grep dante" para verificar que el servicio está levantado:



Vale, ya tienes tu proxy Dante levantado. ¿Ahora cómo configuramos los equipos? Fácil, cada sistema operativo suele traer en su configuración de red la opción de añadir un proxy socks. En el caso de Ubuntu basta con buscar la aplicación "Proxy de la red" e insertar la IP y el puerto de nuestro servidor:


Muy importante, Dante es proxy socks. ¡Nunca lo configures como proxy http!

Si en una shell haces un "tail -f /var/log/danted.log" verás en tiempo real todo el tráfico de los equipos que acceden al proxy: Sus conexiones, desconexiones y bloqueos:



¿Es posible monitorizar también el tráfico ssh? Sí, pero para ello debes de usar el comando "ProxyCommand" y bajarte y compilar el binario connect.c:


Una vez tengáis el binario lo guardáis en algún path, por ejemplo en /usr/local/bin. A partir de ahora siempre que tengamos que conectarnos por ssh haremos uso del Proxycommand, facilitando nuestro binario, ip del proxy y puerto de conexión:
ssh -o "ProxyCommand connect sebas@192.168.1.11:1080 %h %p" usuario@equipo
Si os fijáis he puesto "sebas" como usuario de la máquina proxy. Esto no lo he hecho por capricho. En el código fuente del connect.c veréis que no está soportado la conexión a proxys "socks v5" sin autenticación. Si en vuestro Dante teníais configurado el "method: none" deberéis de habilitar el de pam (usuario existente en esa máquina GNU/Linux).

No temas, ambos métodos ("autenticación" y "no autenticación") pueden coexistir escribiendo símplemente "method: pam none" en el /etc/danted.conf. De este modo te garantizas no tener que autenticarte a nivel de conexiones web y sí a nivel de ssh. De todas formas, si deseas un nivel de seguridad básico lo ideal sería que definieras de forma obligatoria el uso de un método de autenticación.

4 comentarios:

  1. Mandale este tutorial en calidad de urgente a Sony jeje.

    ResponderEliminar
  2. Jajaja, que bueno el comentario Cidroq!! =)

    ResponderEliminar
  3. Muy interesante. Gracias! Para PYMES es algo a tener en cuenta si se desea más control.

    ResponderEliminar
  4. puedo instalar SQUID como proxy http y dante como server para pop3?

    ResponderEliminar

Si te ha gustado la entrada o consideras que algún dato es erróneo o símplemente deseas dar algún consejo, no dudes en dejar un comentario. Todo feedback es bienvenido siempre que sea respetuoso. También puedes contactarme vía Twitter @Hamster_ruso si lo consideras necesario.