VPN con IPSEC (freeswan) para dos nodos con IP dinamicos: ==================================================== Queremos unir dos redes a traves de internet y las conexiones de estas redes a internet es por medio de dos ADSL, o sea que tienen ips dinamicas... A continuacion mostraremos como configurar los servidores (debian woody) utilizando freeswan.* *Deben ser dos subredes diferentes. Tenemos que: ============ Vamos a crear un nombre dinamico en dyndns (por ejemplo) para cada servidor y que se actualize cada vez que cambie la ip de conexion, en nuestro caso usamos el script ipcheck hecho en python. RED 10.1.1.0/24 ---- servidor debian1 ==== INTERNET ==== servidor debian2 ----- RED 192.168.1.1/24 lado1.dyndns.org lado2.dyndns.org 1.- Debemos emparchar el kernel, en debian ejecutamos: # apt-get install kernel-patch-freeswan y aceptamos las depencias que nos pide. 2.- Suponiendo que tenemos el sources del kernel (en este caso 2.4.23) en /usr/src/linux, ingresamos en ese directorio y ejecutamos: # /usr/src/kernel-patches/all/apply/freeswan 3.- Debemos compilar el kernel para habilitar ipsec, en mi caso lo he usado como modulo, la parte del .config del kernel donde dice de IPSEC deberia quedar como algo similar a esto: CONFIG_IPSEC=m CONFIG_IPSEC_IPIP=y CONFIG_IPSEC_AH=y CONFIG_IPSEC_AUTH_HMAC_MD5=y CONFIG_IPSEC_AUTH_HMAC_SHA1=y CONFIG_IPSEC_ESP=y CONFIG_IPSEC_ENC_3DES=y CONFIG_IPSEC_EXT=y CONFIG_IPSEC_EXT_MD5=m CONFIG_IPSEC_EXT_RIPEMD=m CONFIG_IPSEC_EXT_SHA1=m CONFIG_IPSEC_EXT_SHA2=m CONFIG_IPSEC_EXT_3DES=m CONFIG_IPSEC_EXT_AES_OPT=m CONFIG_IPSEC_EXT_AES=m CONFIG_IPSEC_EXT_BLOWFISH=m CONFIG_IPSEC_EXT_CAST=m CONFIG_IPSEC_EXT_NULL=m CONFIG_IPSEC_EXT_SERPENT=m CONFIG_IPSEC_EXT_TWOFISH=m CONFIG_IPSEC_IPCOMP=y CONFIG_IPSEC_DEBUG=y compilamos y booteamos con el nuevo kernel. 4.- Instalamos freeswan de la siguiente forma: # apt-get install freeswan en la instalacion nos pregunta sobre las llaves, usamos RSA de 2048 bits, que si no queremos crearla en ese momento podemos hacerlo de la siguiente manera: # ipsec newhostkey --output /etc/ipsec.secrets --bits 2048 --hostname 5.- Debemos identificar las llaves publicas de cada extremo, supongamos que en este caso el lado1 es el extremo izquierdo y el lado2 es el derecho. para el lado1, ejecutamos: # ipsec showhostkey –-left y para el derecho: # ipsec showhostkey –-right (es obvio que debe ejecutarse el left en el server izquierdo, y el right en el derecho, no?) estos comandos no sacan por pantalla la llave publica que debemos guardar para mas adelante. 6.- Configuracion de la vpn: editamos el archivo /etc/ipsec.conf que en mi caso solamente le agregue al final la siguiente linea # include ipsec.vpn.conf (esto se pone en los dos servers por igual) editamos el archivo ipsec.vpn.conf.base en el server de la izquierda (debian1): (aqui es donde usamos las llaves publicas mencionadas con anterioridad) vi /etc/ipsec.vpn.conf.base: #========================================= conn debian1-debian2net rightsubnet=192.168.0.0/24 also=debian1-debian2 conn debian1net-debian2net leftsubnet=10.1.1.0/24 rightsubnet=192.168.0.0/24 also=debian1-debian2 conn debian1net-debian2 leftsubnet=10.1.1.0/24 also=debian1-debian2 conn debian1-debian2 leftid=@lado1.dyndns.org rightid=@lado2.dyndns.org left=-IPL- leftnexthop=%defaultroute right=-IPR- #rightnexthop=%defaultroute auto=start # RSA 2048 bits debian1 Thu May 29 13:35:58 2003 leftrsasigkey=0sAQOzWg+36UDIU/z8QekV5n........ # RSA 2048 bits debian2 Sun Jun 8 16:21:52 2003 rightrsasigkey=0sAQNn47z4Yec/KKmwv3......... #========================================== luego en el server de la derecha (debian2) usamos este mismo archivo pero comentamos la linea leftnexthop=%defaultroute y descomentamos rightnexthop=..... Luego para que la vpn sepa cuando alguno de los extremos cambian de ip, usamos el siguiente script hecho en perl por Andres Gironacci (Gracias Andy!!!!!!) #===================SCRIPT======================================= #!/usr/bin/perl # actualizacion de los archivos de configuracion ipsec # Por Andres Gironacci $arch_est="/var/state/ips.ipsec"; $conf_base="/etc/ipsec.vpn.conf.base"; $conf="/etc/ipsec.vpn.conf"; # Obtengo las ips actuales utilizando como nombre dns los ids de los extremos. open(CONF,$conf_base); while() { chomp; $leftip=gethostbyname($1) if(/^\tleftid\=\@(.*)$/); $rightip=gethostbyname($1) if(/^\trightid\=\@(.*)$/); } close(CONF); #print "$leftip $rightip\n"; die if !defined($leftip) or !defined($rightip); # Desempaco las direcciones de 32 bit binario a decimal con puntos ($d1,$d2,$d3,$d4)=unpack('C4',$leftip); $leftip="$d1.$d2.$d3.$d4"; ($d1,$d2,$d3,$d4)=unpack('C4',$rightip); $rightip="$d1.$d2.$d3.$d4"; # Comparo con el estado actual open(EST,$arch_est); $leftact=; $rightact=; close(EST); chomp $leftact; chomp $rightact; exit 0 if $leftact=~/^$leftip$/ and $rightact=~/^$rightip$/; # Alguno es diferente, actualizo el estado, escribo el nuevo archivo ipsec y reinicio el ipsec. open(EST,">$arch_est"); print EST "$leftip\n$rightip\n"; close(EST); open(CONF,">$conf"); open(CONFB,$conf_base); while() { s/\-IPL\-/$leftip/; s/\-IPR\-/$rightip/; print CONF $_; } close(CONFB); close(CONF); system("/etc/init.d/ipsec restart"); exit 0; #====================FIN SCRIPT=================================== Este script se encarga de actualizar el archivo ipsec.vpn.conf comparandolo con /var/state/ips.ipsec que es donde guarda las ip de los dos extremos en el momento, si detecta que las ips cambiaron actualiza y le hace un restart a la vpn este script lo metemos en /usr/local/bin/actualiza-ipsec_host.pl y metemos en el crontab: */5 * * * * root /usr/local/bin/actualiza-ipsec_host.pl Por ultimo nos queda modificar el firewall Debemos agregar las siguientes reglas: iptables -A INPUT -p udp --dport 500 -i ppp+ -j ACCEPT iptables -A INPUT -p 50 -i ppp+ -j ACCEPT iptables -A FORWARD -o ipsec+ -j ACCEPT iptables -A FORWARD -i ipsec+ -j ACCEPT (de esta forma queda todo habilitado para conexion de un lado a otro de la vpn, podriamos hacerlo limitando puertos, destinos, etc, pero queda a gusto y uso de c/u) Eso es todo, espero que les sirva, y cualquier mejora es bienvenida :D Autores: Diego D'Angelo Andres Gironacci