Actualizar DNS con DHCP

En la entrada anterior vimos como montar un servidor bind y un server dhcp en linux para bloquear la resolución de algunas webs en nuestra red de área local. (Suplantando nuestros dns en la red local). Ya que tenemos el laboratorio montado en casa, podemos mejorar sus funcionalidades haciendo que todos los dispositivos que reciban una dirección DHCP de nuestro servidor queden registrados en el DNS con una entrada dinámica. Hacerlo a mano sería bastante laborioso y en breves tendríamos la zona dns desactualizada.

Para ello me he creado una zona a la que llamaré “canostra.local”, esta zona engloba mi red local. Siguiendo con el ejemplo anterior, tendremos 3 dispositivos en la red:

	192.168.22.1  --> Gateway
	192.168.22.2  --> Equipo Windows con reserva de DHCP
	192.168.22.11 --> DNS + DHCP.

Para poder crear el dynamic dns, el primer paso es editar el archivo para crear las nuevas zonas:

sudo vi /etc/bind/named.conf.local

Sigue leyendo

Suplantando nuestros DNS en la red local

Desde hace un tiempo, es muy común que la gente utilice su teléfono indiscriminadamente a todas horas. Esta mañana cuando desperté me dirigí a la cocina a saludar a mis padres y como es costumbre tras varios minutos apareció mi hermana escuchando un servicio de streaming de audio a todo volumen, le pedí por favor que lo desconectara y como es pasó de mi, así que esto basto para encender mi creatividad. Como no tengo el hardware necesario para montar un Firewall + Squid para que me aplique control parental, he decidido montar un aproximación con mi Raspberry (Ya os aviso de que es muy rudimentario, pero de momento efectivo). La finalidad de este post es poder bloquear el acceso a una serie de dominios en determinadas horas del día.

Evidentemente, para alguien que sepa algo de redes este procedimiento no sirve de nada, bastaría con forzar los dns de la máquina en la que se está trabajando a los de nuestro ips/google/opendns para que nos sirviera las entradas reales, pero creo que para mi propósito me sirve sobrado.

Antes de empezar supondremos que tenemos una RED de área local que corresponde con el rango 192.168.22.0/24 dónde

	192.168.22.1  --> Gateway
	192.168.22.2  --> Equipo Windows con reserva de DHCP
	192.168.22.11 --> DNS + DHCP.

En la siguiente imagen os presento una aproximación (en este caso no sería ROGUE DNS porque nosotros lo permitimos con nuestro servidor DHCP, ya que es nuestra red, pero si montáramos este escenario intentando suplantar el DHCP real se podría considerar un ataque) de lo que realizaremos:

Rogue DNS

En mi caso el Router del ISP no me permite configurar que servidores DNS serán servidos con este protocolo por lo que tendré que instalar un servidor de DHCP en la Raspberry y desactivar el propio del router.

Sigue leyendo

Let’s Encrypt la CA Open Source

Para todos aquellos que no conozcáis Let’s Encrypt os invito a que visitéis su Web . Esta entidad certificadora es Open Source y expide certificados gratuitamente siempre que podamos verificar la propiedad del sitio web mediante el protocolo ACME (automatic certificate management environment). Este protocolo nos permite administrar y expedir certificados de manera automática.

La única pega de esta entidad es que la validez de los certificados es de 90 días. Por lo que cada 3 meses hay que renovarlos en el servidor. Existen varios mecanismos de autenticación de un dominio, el más sencillo es la comprobación web donde la entidad certificadora nos solicita que creemos un .html con un contenido específico en nuestro dominio. Para automatizar el uso de ACME se creó un proyecto que se llama dehydrated en el que se gestionan en bash las llamadas a letsencrypt. Este proyecto es modular y permite parametrizar fácilmente las opciones de despliege de los certificados:

https://github.com/lukas2511/dehydrated

Este tipo de autenticación vía http presenta un problema, no puedes autenticar subdominios no publicados en Internet ya que la CA no podría conectarse a comprobar el challenge. Para este tipo de escenarios podemos utilizar la autenticación DNS01, donde se publica la información en un registro TXT del DNS que nos gestiona el dominio. Para usar este tipo de challenge, hay que especificar un “hook” a dehydrated para indicarle como tiene que interactuar con nuestro DNS.

En mi caso dispongo de una solución DNS de EfficientIP solid server, he creado un hook para usar dehydrated con SolidServer. Se puede encontrar en github:

https://github.com/berni69/solidserver-challenge

Para usarlo bastaría con descargarlo junto con dehydrated:

$ cd ~
$ git clone https://github.com/lukas2511/dehydrated
$ cd dehydrated
$ mkdir hooks
$ git clone https://github.com/berni69/solidserver-challenge.git hooks
$ chmod +x dehydrated
$ ./dehydrated --challenge dns-01  --cron --domain "test.example.com" --hook "hooks/solid-hook.py"

Saludos!

Liberado código SWifi Keygen y Airwin 2

Buenos días,

Tras varios meses sin tiempo para actualizar estos softwares he decidido liberar el código para que la comunicad me ayude a mantenerlo.

El proyecto Swifi se encuentra en medio de una refactorización para poder segmentar los generadores de claves.

https://github.com/berni69/SwifiKeygen

El proyecto de Airwin2 tiene algunos cambios gráficos a medio crear, además de haber añadido algunas opciones que no están publicadas actualmente:

https://github.com/berni69/Airwin2

Saludos,

Creando shells inversas

Hace unos días en la casa de campo me instalaron un router 4G al que no tengo acceso de administrador, para realizar cualquier cambio sobre el dispositvo tengo que llamar a la operadora de internet y que me lo hagan remotamente (incluso un cambio de password del WIFI, IBRED atenta contra la LOPD…). Mi intención era dejar una raspberry pi realizando algunas tareas domóticas y de monitorización sencillas, al parecerme un engorro tener que estar haciendo llamadas para que me abran distintos puertos, me reserven una entrda en el dhcp,… decidí buscar una solución alternativa. Esto funcionaría también estando detrás de un firewall con los puertos capados, o en una red NAT sin forwarding de puertos.

En este post se tratará el tema: levantar un túnel inverso y hacer forward de un puerto local a un puerto remoto a través del protocolo SSH. Para ello, es necesario tener un segundo equipo en el que poder hacer login SSH sin credenciales (con claves RSA). Para los que no sepáis que es un túnel SSH, os recomiendo la entrada que publicqué hace un tiempo sobre ello ( Túnel SSH Raspberry )

El siguiente paso es configurar el demonio SSH de la máquina remota para que permita hacer keepaliving de la conexión (permitir alargar el tiempo máximo de conexión sin intercambiar información). Para ello debemos modificar el archivo

/etc/ssh/sshd_config

Añadir/modificar las siguientes líneas:

TCPKeepAlive yes
ClientAliveInterval 30
ClientAliveCountMax 99999
GatewayPorts yes

Y reniciar el servicio SSH

Una vez tenemos configurado el demonio SSH y haber intercambiado las claves públicas entre los equipos es lo único que hay que hacer es ejecutar:

ssh -f -N -R 10000:localhost:22 @ -p 22

Este comando redigirá el puerto 22 local, al puerto 10000 de la máquina remota. Si quisiéramos hacer login en la Raspberry podríamos hacer un SSH user@equipo_remoto -p 10000, en realidad esto estaría redirigiendo el tráfico a través de un túnel al puerto 22 de la raspberry. Se podría usar con cualquier otro puerto 80,443,…

Como mi idea era dejar la Raspberry encendida sin preocuparme si se reinicia y quiero acceder monté un pequeño script en Bash para que lo ejecutara cron:

#!/bin/bash

REMOTE_PORT="10000"
LOCAL_FORWARDED_PORT="22"
REMOTE_SSH_PORT="22"
REMOTE_HOST="host_remoto"
REMOTE_USER="user"

PID=$(ps -ef | grep "${REMOTE_HOST}" | grep -v grep | awk '{print $2}')

if [ "" == "$PID" ]; then
    echo "[+] Excecuting reverse ssh connection"
    ssh -f -N -R "${REMOTE_PORT}:localhost:${LOCAL_FORWARDED_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" -p "${REMOTE_SSH_PORT}"
else
    echo "[-] The connection was stablished before"
fi

La entrada de crontab debe tener la siguiente forma:

* * * * * [ -x /root/reverse_ssh.sh ] &&  /root/reverse_ssh.sh &> /tmp/reverse_ssh.log

Si vamos al servidor remoto deberíamos poder ver

user@host_remoto:~$ netstat -an | grep -i 10000
tcp        0      0 0.0.0.0:10000           0.0.0.0:*               LISTEN     
tcp6       0      0 :::10000                :::*                    LISTEN     

Si queremos usar el servicio al que estamos haciendo forwarding (en este caso SSH) podríamos abrir una shell contra el puerto 10000:

user@host_remoto:~$ ssh root@127.0.0.1 -p 10000
The authenticity of host '[127.0.0.1]:10000 ([127.0.0.1]:10000)' can't be established.
ECDSA key fingerprint is XX:XX:XX:XX:XX:XX:XX:XX:XX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:10000' (ECDSA) to the list of known hosts.

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Apr  8 11:25:42 2017 from ::1
root@raspberry:~# 

En este caso veríamos que la shell está funcionando.

WebSockets – Dashboard colaborativa

Desde hace unos años, se han puesto de moda la tecnología WebSocket.
Esta tecnología es una extensión del protocolo HTTP para simular un socket. Comunmente un sócket de comunicación es un recurso que se utiliza para poder transferir datos entre aplicaciones/máquinas. Existen varios tipos de sockets: UDP,TCP,RAW,UNIX,… cada uno se utiliza para una determinada función.

Por ejemplo, UDP se va muy bien para transferir grandes cantidades de datos ya que reduce el overhead introducido por cabeceras, Los sockets TCP se usan para las aplicaciones que no toleran errores en transmisión ya que posee un buen sistema de control de flujo y errores. En ambos casos existe un evidente problema: se necesitan abrir puertos específicos en los firewalls para poder establecer la conexión. Por defecto, el puerto 80/443 que utiliza el servidor de WebSocket suele estar abierto ya que son los puertos estándares de cualquier servidor HTTP.

Diagrama de Websockets

Este diagrama muestra la negociación y uso del protocolo de websockets

Este tipo de socket se utiliza en los navegadores para poder mantener un flujo de comunicación constante por lo facilita la operativa a los programadores web para tener el contenido actualizado en sus páginas. El clásico ejemplo de uso de websockets es construir una sala de chat en la que en tiempo real se reciben y envían mensajes (Hangouts utiliza websockets), las notificaciones de Facebook utilizan websockets.

Ejemplo básico de uso de Webcoskets con node JS
Servidor:

var server = require('websocket').server, http = require('http');

var socket = new server({
    httpServer: http.createServer().listen(1337)
});

socket.on('request', function(request) {
    var connection = request.accept(null, request.origin);

    connection.on('message', function(message) {
        console.log(message.utf8Data);
        connection.sendUTF('pong');
        setTimeout(function() {
            connection.sendUTF('[!] Server Event happended');
        }, 1000);
    });

    connection.on('close', function(connection) {
        console.log('connection closed');
    });
}); 

Cliente:

<div id="content"></div>

<script type="text/javascript">
    var content = document.getElementById('content');
    var socket = new WebSocket('ws://localhost:1337');
    socket.onopen = function () {
        setTimeout(function() {
                socket.send('ping');
        }, 1000);
    };
    socket.onmessage = function (message) {
        content.innerHTML += message.data +'<br />';
    };

    socket.onerror = function (error) {
        console.log('WebSocket error: ' + error);
    };
</script>

Fuente: http://hawkee.com/snippet/16051/

Para los que trabajamos en grupo en determinadas ocasiones necesitamos sincronizar determinadas tareas, como el reinicio y arranque de determinados servidores. Por ello poder avisar a los compañeros de que has iniciado la tarea y que lo reciban en tiempo real es importante, en esto nos ayudan los websockets. Si alguien quiere ver la potencia que ofrece este tipo de tecnología recomiendo ver una dashboard de ejemplo colaborativa que he diseñado para este fin. El código es libre y susceptible de aceptar mejoras:

https://github.com/berni69/ws-dashboard