viernes, 10 de mayo de 2013

servidor OpenVPN en tu Raspberry Pi

Desde hace ya un tiempo tuve la necesidad de montar una VPN. Me decanté por OpenVPN ya que siempre he pensado que era de lo más completo, en lo referente a la seguridad pudiendo acceder mediante user/pass + fichero.
Bueno pues... si haceis una simple busqueda en Google encontraremos manuales, algunos muy bien detallados y otros ... no tanto pero lo sorprendente que a todos ellos les funciona su servidor cosa que a mi nunca ha sido así. Siempre con problemas "una de las interfaces no hace MASQUERADE", "el paquete llega pero no pasa...", "me he confundido de puerto, AIS!!", "se conecta pero no navega..." Bueno un sin fin de problemas y ninguna solución. Y me he encontrado en varias ocasiones en las que ni calcando el ejemplo del propio manual he conseguido resultados. 

Pues bien! hace unos días después de insistir en mil intentos inútiles me puse manos a la obra, pasando de manuales que ya me he leído muchos y creo que ya se perfectamente que tengo que hacer. El problema que nunca conseguí resultados. Solo espero que esto no sea un manual más donde solo a mi me funciona y al resto del mundo no. Así que intentaré ser lo más claro en los detalles.

Un resumen de mi red.
(Equipo externo)=> {INTERNET} <=> [RouterWifi] <=> |Raspberry Pi| <= (Equipo local)
Por supuesto no falta decir que los equipos local y externo se conectan a la wifi. El local a la propia del router y el externo en la de un.... Starbucks para que sea molón el ejemplo. Y detalle importante OJO AL DATO la Raspberry Pi para el que no tenga una sólo tiene UNA interface FÍSICA de red ETH0. Ni una más ni una menos. Por supuesto en el router wifi tiene que estar abierto el puerto UDP 1194 o el que se configure en el servidor.

Como todos los manuales comenzamos.
apt-get install openvpn openssl
posteriormente copiamos y nos movemos de directorio
cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
cd /etc/openvpn/easy-rsa/2.0
Y comenzamos a crear los ficheros clave y certificados
. ./vars
./clean-all
./build-ca
./build-key-server server
Ahora generamos tantas claves de clientes cómo usuarios queramos
./build-key client-movil
./build-key client-movilPapa
./build-key client-pcMio
./build-key client-pcPapa
./build-key client-invitado
Cuando tengamos todas las claves de clientes que queramos lanzamos lo siguiente
./build-dh
BUFFF esto tarda mucho. Si has generado muchas claves, vete a tomar un café o a sacar al perro.

Cuando termine si aun sigues despierto, copiamos las claves necesarias en el servidor
cd /etc/openvpn/easy-rsa/2.0/keys
cp ca.crt ca.key dh1024.pem server.crt server.key /etc/openvpn
Copiamos los ficheros clave de cada cliente.
Lo guardamos en nuestra propia carpeta. Así que en mi caso me creo una carpeta
mkdir /home/endika/MisClavesVPN
y copio en ella
cp client*.crt, client*.key ca.crt /home/endika/MisClavesVPN
Recodar donde lo hemos copiado que necesitaremos los ficheros para conectar los clientes

Ahora copiamos el fichero de configuración del servidor que tiene openvpn por defecto
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn
gunzip /etc/openvpn/server.conf.gz
y lo editamos para que concuerde con nuestra configuración
nano /etc/openvpn/server.conf
De ese fichero solo he modificado lo siguiente modificar la IP local del servidor Raspberry Pi
local 192.168.1.33 
El puerto si queremos modificarlo
port 1194
El protocolo si queremos cambiar UDP por TCP
proto UDP
La interface virtual si queremos modificar el nombre de TUN por TAP
dev tun
La Red virtual de la VPN
server 10.8.0.0 255.255.255.0
La Red local de nuestra wifi
push "route 192.168.1.0 255.255.255.0"
Los servidores DNS si queremos poner alguno, por ejemplo los DNS de google
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
Si os dais cuenta no tiene # ni un ; delante de la instrucción. Todo lo que lo tenga estará comentado y no surgirá efecto. Así es como queda mi fichero server.conf
local 192.168.1.33
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
client-to-client
keepalive 10 120
comp-lzo
user nobody
user nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
Últimos detalles, vamos a permitir que nuestra máquina actúe como un router
echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
Y lo más importante las reglas del IPTABLES
#!/bin/bash
echo "Limpiando IPTables"
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

echo "Configurando las interfaces eth0 y tun0"
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT
iptables -I FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -I FORWARD -i tun0 -o eth0 -j ACCEPT

iptables -A OUTPUT -m state --state NEW -o eth0 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

echo "para el resto de los casos aceptamos el tráfico"
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
Revisar las reglas por si el nombre de las interfaces cambia o en el caso del masquerade por si la red no es la misma. Por otro lado las normas están echas para solo una ÚNICA interface de entrada y salida eth0. Ya solo queda lanzar el servidor
/etc/init.d/openvpn start
Para evitar que sea muy largo este post en la segunda parte configuraremos los clientes para que se conecten al servidor

lunes, 6 de mayo de 2013

modificar el valor del HASH en un fichero binario

Cada vez que modificamos un fichero su HASH obtiene un valor distinto. Pero que ocurre si el fichero es un binario? pues exactamente lo mismo. Aquí tenéis un pequeño script donde podemos indicar el nombre de nuestro binario y nos crea uno nuevo con 100 caracteres aleatorios añadidos al final del mismo. Esto no altera el funcionamiento pero si el valor de su hash.
import sys,os,random

def bytes_aleatorio(n):
    return "".join(chr(random.randrange(0,256)) for i in xrange(n))

nombre=str(sys.argv[1])
fichero=open(nombre,'rb').read()
fichero_nuevo=fichero+bytes_aleatorio(100)
open(nombre+str("_new"),'wb').write(fichero_nuevo)
os.system("md5sum "+nombre)
os.system("md5sum "+nombre+"_new")
y su uso:
python modificarHash.py NombreFicheroBinario
y PUM!! el "mismo" fichero con un hash diferente.