Open VPN mini-como OpenVPN es una implementacion de VPN SSL la cual usa las extenciones OSI layer 2 o 3 para asegurar redes la cual usa los protocolos SSL/TLS, soporta diferentes medios de autenticacion como certificados, smart cards, y/o usuarios/contraseñas, y permite politicas de control de acceso para usaurios o grupos usando reglas de firewall aplicadas a las interfaces virtuales de la VPN. OpenVPN 2.0 permite multiples clientes conectar a un solo servidor (proceso) OpenVPN sobre un simple puerto TCP o UDP. Para seguir este documento se requieren conocimientos basicos de redes TCP/IP como , direcciones IP, DNS, netmasks, subnets, IP routing, routers, interfaces de red, LANs, gateways, y reglas de firewall. La implementacion de la VPN en este documento se centra en la distrubucion GNU/Linux Slackware, por lo que la instalacion de el programa OpenVPN sera con un paquete de Slackware .tgz que yo construi. Antes de seguir con la instalacion es recomendable instalar primero los paquetes: iproute2 lzo openssl tcpip iproute2, openssl y tcpip son paquetes oficiales de Slackware, por lo que los puedes encontrar en tus CD's o en un mirror de Slackware. Despues sigue la biblioteca lzo que es requerida para la compresion de el tunel VPN, el paquete binario lo puedes encontrar en: Paquete binario de lzo 1.08: http://tuxjm.net/downloads/packages/slackware-10.2/lzo/ Claro siempre puedes ver el SlackBuild y ver como se contruyo y/o construirlo tu mismo para optimizarlo para la arquitectura de tu computadora. Builds de lzo 1.08: http://tuxjm.net/downloads/source/slackware-10.1/lzo/ Una vez que se tengan instalados los requerimientos antes mencionados es hora de instalar OpenVPN, el paquete para Slackware se encuentra aqui: Builds de OpenVPN 2.0.6: http://www.tuxjm.net/downloads/source/slackware-10.2/openvpn/ Paquete binario de OpenVPN 2.0.6: http://tuxjm.net/downloads/source/slackware-10.2/openvpn/ En este documento el tipo de VPN sera tipo "routed VPN" . Configuraciones de subnets. Subnet Offina. La subnet de la officina esta en el segmento 10.0.0.0/24 el gateway/proxy/VPNs server tiene la direccion IP 10.0.0.107. Subnet Casa. La subnet de la casa esta en el segmento 10.0.20.0/24 y el gateway/proxy/VPN server tiene la direccion IP IP 10.0.20.1 La subnet de el tunel VPN sera 10.8.0.0/24, esto se usara asi ya que en los archivos de configuracion proporcionados por OpenVPN usan esa subnet. Configurando tu propia Autoridad Certificadora (CA - Certificate Authority) y generacion de certificados y par de llaves para el Servidor OpenVPN y un cliente VPN. El primer paso al construir una VPN con OpenVPN 2.0 es establecer una PKI (Infraestructura de LLave Publica - Public Key Ingrastructure), esta PKI consiste de: * Un certificado aparte (tambien conocido como llave publica) y una llave privada para el servidor y cada cliente. * Un Certificado Mastro para la Autoridad Certificadora (CA) y su llave la cual es usada para firmar cada certificado de el servidor y el cliente. En esta seccion se generaran los certificados/llaves para la CA, el server y el cliente. Para la administracion de la PKI usaremos los scripts que vienen con OpenVPN. Estos scripts estan en: /usr/doc/openvpn-2.0.6/easy-rsa, Se recomienda copiar dicho directorio por ejemplo a /etc/openvpn/. Entonces haremos: # cp -r /usr/doc/openvpn-2.0.6/easy-rsa/ /etc/openvpn/ # cd /etc/openvpn/easy-rsa/ Ahora editaremos el archivo "vars" y configuraremos los parametros KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG y KEY_MAIL, no hay que dejar ninguno de estos parametros vacios. Los valores pueden ser algo asi: export KEY_COUNTRY=MX export KEY_PROVINCE=BC export KEY_CITY=Tijuana export KEY_ORG="Calcom" export KEY_EMAIL="jmedina@calcom.com.mx" Lo siguiente es inicializar la PKI, asi: # . ./vars NOTE: when you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys Si se editaron los parametros correctamente veras algo como lo que salio arriba. Ahora configuraremos un entorno nuevo. # ./clean-all Y construiremos el certificado/key para la CA: Veremos algo asi: # ./build-ca Generating a 1024 bit RSA private key ...............++++++ ...++++++ writing new private key to 'ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [MX]: State or Province Name (full name) [BC]: Locality Name (eg, city) [Tijuana]: Organization Name (eg, company) [Calcom]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:Calcom-CA Email Address [jmedina@calcom.com.mx]: Esto fue hecho con los scripts que a la vez usan a "openssl" en modo interactivo. Notar que en el comando anterior la mayoria de los parametros se usaron los default puestos en "vars" El unico parametro que debe de ser especificado es el "Comman Name" In este ejemplo, use "Calcom-CA". - Generacion de certificado y llaves para el servidor. Lo siguiente es generar el certiicado y la llave privada par el servidor: ./build-key-server server Generating a 1024 bit RSA private key .........................++++++ .....................++++++ writing new private key to 'server.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [MX]: State or Province Name (full name) [BC]: Locality Name (eg, city) [Tijuana]: Organization Name (eg, company) [Calcom]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:server Email Address [jmedina@calcom.com.mx]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'MX' stateOrProvinceName :PRINTABLE:'BC'http://www.linuxzona.net/images/DSCN3528.jpg localityName :PRINTABLE:'Tijuana' organizationName :PRINTABLE:'Calcom' commonName :PRINTABLE:'server' emailAddress :IA5STRING:'jmedina@calcom.com.mx' Certificate is to be certified until Aug 24 06:14:08 2015 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Como en el paso previo la mayoria de los parametros se dejaron los predeterminados que estan en "vars" Cuando el valor para el parametro "Common Name" pusimos "server".Las siguientes dos preguntas requieren una respuesta positiva: Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y - Generacion de certificado y llave privada para un cliente. Esto es muy similar a los pasos previos ./build-key cliente1 Generating a 1024 bit RSA private key ..................++++++ .............++++++ writing new private key to 'cliente1.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [MX]: State or Province Name (full name) [BC]: Locality Name (eg, city) [Tijuana]: Organization Name (eg, company) [Calcom]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:cliente1 Email Address [jmedina@calcom.com.mx]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl.cnf DEBUG[load_index]: unique_subject = "yes" Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'MX' stateOrProvinceName :PRINTABLE:'BC' localityName :PRINTABLE:'Tijuana' organizationName :PRINTABLE:'Calcom' commonName :PRINTABLE:'cliente1' emailAddress :IA5STRING:'jmedina@calcom.com.mx' Certificate is to be certified until Aug 24 06:15:25 2015 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Como pudimos ver lo unico que pusimos fue el "Common Name" en este caso fue "cliente1". - Generando Parametros Diffie Hellman. Los parametros Diffie Hellman deben de ser generados para el Servidor OpenVPN: # ./build-dh Generating DH parameters, 1024 bit long safe prime, generator 2 This is going to take a long time .............................................................................+.. ..............................................................+................. ..................+........................+.................................... +................................. # - Archivos claves. Ahora podremos encontrar nuestros nuevos certificados y llaves en el subdirectorio "keys", esta es una explicacion de los archivos relevantes: Nombre de Archivo Necesario para Proposito Secreto ca.crt server + all clients Root CA certificate NO ca.key key signing machine only Root CA key YES dh{n}.pem server only Diffie Hellman parameters NO server.crt server only Server Certificate NO server.key server only Server Key YES cliente1.crt client1 only Client1 Certificate NO cliente1.key client1 only Client1 Key YES En este documento se explica la generacion de los archivos anteriores en el mismo server, aunque se puede tener una maquina dedicada para la CA, asi los archivos marcados como secretos se mantienen aparte, los clientes pueden generar su propio "Certificate Signing Request (CSR)) y que la CA lo firme. Bien, ahora lo que sigue es copiar los archivos necesarios a su lugar respectivo, en el caso de: ca.crt, dh1024.pem, server.crt y server.key van en el servidor, el ca.crt, client1.crt y client1.key se tendran que pasar a el cliente, esto tiene que ser por un medio seguro se puede usar ssh para pasarlos a la maquina cliente. Yo hago algo asi: # mkdir archivos-cliente1 # cd keys; cp -v ca.crt cliente1.crt cliente1.key ../archivos-cliente1/ Y luego: # cd .. # chmod -R 755 archivos-cliente1 $ scp -r archivos-cliente1 usuario@cliente-vpn:. - Creando archivos de configuracion para el servidor y el cliente. - Consiguendo los archivos de configuracion de ejemplo. Es recomendable usar los archivos de configuracion de ejemplo de OpenVPN como un punto inicial para tu propia configuracion. estos pueden ser encontrados en: /usr/doc/openvpn-2.0.6/sample-config-files/ Los archivos que necesitaremos son: server.conf y client.conf - Editando el archivo de configuracion de el servidor. El archivo de configuracion de ejemplo para el servidor es un punto de inicio ideal para la configuracion de un servidor OpenVPN. Creara una VPN usando una interfaz de red virtual TUN (para routed mode), escuchara conexiones de clientes en el puerto UDP 1194 (El numero de puerto oficial de OpenVPN), y distribuira direcciones virtuales de la subred 10.8.0.0/24 para los clientes que se conecten. Antes de usar el archivo de configuracion de ejemplo, primero debes de editar los parametros para ca, cert, key y dh para que apunten a los archivos generados en la seccion anterior. Por ejemplo copiamos: # cd keys; cp -v ca.crt server.crt server.key dh1024.pem ../../ `ca.crt' -> `../../ca.crt' `server.crt' -> `../../server.crt' `server.key' -> `../../server.key' `dh1024.pem' -> `../../dh1024.pem' Y copiamos el archivo de configuracion de el servidor: # cd ../../ # cp /usr/doc/openvpn-2.0.6/sample-config-files/server.conf . entonces ya tendremos en /etc/openvpn estos archivos: # ls ca.crt dh1024.pem easy-rsa/ server.conf server.crt server.key Editando el archivo de configuracion de el cliente. En el cliente VPN tambien se deben de seguir los procedimientos de instalacion que se dieron al inicio, una vez que este todo instalado es hora de copiar los archivos que se generaron en el servidor y se copiaron por un medio seguro (ssh/scp), dichos archivos son: ca.crt cliente1.crt cliente1.key Y hay que copiarlos de donde esten a /etc/openvpn/ y ponerles los permisos adecuados: # chmod 644 ca.crt # chmod 644 cliente1.crt # chmod 600 cliente1.key Ahora lo que sigue es usar un archivo de configuracion para el cliente de ejemplo: # pwd /etc/openvpn # cp /usr/doc/openvpn-2.0.6/sample-config-files/client.conf . Entonces en el cliente tendremos: # pwd /etc/openvpn # ls ca.crt client.conf cliente1.crt cliente1.key Teniendo estos archivos, lo que sigue es editar los parametros de ca, cert y key para que apunten a los nombres de archivos que acabamos de copiar, en este caso el valor de "ca" se deja como esta, y se cambia el valor de "cert" de client.crt a cliente1.crt y el valor de "key" de client.key a cliente1.key, hay que recordar que el archivo ca.crt es universal tanto para los clientes y los servidores. Ahora hay que editar el parametro de "remote" para puntarlo a el nombre de host o direccion IP y puerto de el servidor OpenVPN. Bien una vez editado el parametro guardar el archivo. - Inicializacion de la VPN y pruebas iniciales de conectividad. Iniciando el Servidor. Primero hay que asegurarse que el servidor OpenVPN es accesible desde el Internet, esto quiere decir: * Abrir el puerto UDP 1194 en el firewall o configurar una regla de redireccionamiento de puerto (port forwarding) de el puerto UDP 1194 desde el gateway/firewall a la maquina servidor OpenVPN. Lo siguiete es asegurarse que la interfaz TUN no esta firewalleada. Por simplicidad y para hacer pruebas iniciales, es recomendable iniciar el servidor OpenVPN desde la linea de comando, en lugar de iniciarlo como un servicio (daemon). # cd /etc/openvpn/ # openvpn server.conf Thu Aug 25 23:40:59 2005 OpenVPN 2.0.2 i686-pc-linux [SSL] [LZO] built on Aug 26 2005 Thu Aug 25 23:40:59 2005 Diffie-Hellman initialized with 1024 bit key Thu Aug 25 23:40:59 2005 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ] Thu Aug 25 23:40:59 2005 TUN/TAP device tun0 opened Thu Aug 25 23:40:59 2005 /sbin/ip link set dev tun0 up mtu 1500 Thu Aug 25 23:40:59 2005 /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2 Thu Aug 25 23:40:59 2005 /sbin/ip route add 10.8.0.0/24 via 10.8.0.2 Thu Aug 25 23:40:59 2005 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ] Thu Aug 25 23:40:59 2005 UDPv4 link local (bound): [undef]:1194 Thu Aug 25 23:40:59 2005 UDPv4 link remote: [undef] Thu Aug 25 23:40:59 2005 MULTI: multi_init called, r=256 v=256 Thu Aug 25 23:40:59 2005 IFCONFIG POOL: base=10.8.0.4 size=62 Thu Aug 25 23:40:59 2005 IFCONFIG POOL LIST Thu Aug 25 23:40:59 2005 Initialization Sequence Completed Si muestra algo similar a lo de arriba significa que en el servidor todo fue bien. Iniciando el Cliente. Como en la configuracion de el servidor, es mejor inicializar el cliente desde la linea de comandos. # cd /etc/openvpn/ # openvpn client.conf bla bla bla Si muestra algo similar a lo de arriba significa que en el cliente todo fue bien. Ahora, intenta hacer ping a traves de la VPN desde el cliente. Si estas usando openvpn en modo routed ( usando dev tun en el archivo de configuracion de el server), intenta: # ping 10.8.0.1 Si el ping se hace con exito, Felicitaciones! ahora ya tienes una VPN funcional. Solucion de errores: Si el ping fallo o la inicializacion de el cliente OpenVPN para completar, aqui hay un checklist de sintomas comunes y sus soluciones: * Obtienes el mensaje de error: TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity). Este error indica que el cleinte no fue capaz de establecer una conexion de red con el servidor. Soluciones: - Asegurate de que el ciente esta usando la direccion correcta de el hostname/IP y el numero de puerto que le permitira alcanzar a el servidor OpenVPN. - Si la maquina que corre el servidor OpenVPN es una maquina con una sola interfaz de red dentro de una red LAN protegida, asegurate de que estas usando un regla de redireccion de puerto en el firewall gateway de el servidor OpenVPN. For ejemplo, supongamos que tu servidor OpenVPN esta en la direccion 10.0.0.105 dentro de el firewall, escuchando por conexiones de clientes en el puerto UDP 1194. El dispositivo que hace NAT para la subred 10.0.0.x deberia una regla de reenvio de puerto que diga: reenviar el puerto UDP 1194 desde cuaqluier direccion IP publca a el host 10.0.0.105. - Abre el firewalll de el servidor OpenVPN para permitir conexiones a el puerto UDP 1194 ( o cualquier puerto TCP/UPD que hayas configurado en el archivo de configuracion de el servidor. * Obtienes el mensaje de error: Initialization Sequence Completado con errores -- Este error puede ocurrir en Windows si (a) No tienes el servicio DHCP client corriendo, o (b) Estas usando ciertos personal firewall de terceras personas en XP SP2. Solucion: - Inicia el servicio DHCP client y asegurate que esats usando un firewall personal que trabaje correctamente con XP SP2. * Obtienes el mensaje Initialization Sequence Complete pero el test de ping falla -- Esto usualmente indica que el firewall ya sea en el servidor o el cliente esta bloqueando trafico de red VPN porque esta filtrando la interfaz TUN/TAP. Solucion: - Desactiva el firewall en el cliente ( si es que existe alguno) para que no haga filtrado en la interfaz TUN/TAP en el cliente. Por ejemplo en Windows XP SP2, puedes hacer esto llendo a Windwows Security Center -> Windows Firewall -> Advanced y desactiva la casilla la cual corresponde a el adaptador TAP-Win32 (desactivando el firewall de el cliente para que no haga filtrado en el adaptador TUN/TAP es generalmente rasonable desde la perspectiva de la seguridad, ya que escencialmente le estas diciendo al firewall que no bloquee el trafico en la VPN autenticada). Tambien asegurate que la interfaz TUN/TAP en el servidor no este filtrada por un firewall (habiendo dicho esto, note que haciendo filtrado selectivo en la interfaz TUN/TAP en el servidor puede ofrecer ciertos beneficios en cuanto a seguridad. Vee la seccion "access policy" abajo). * La conexion "stalls" al inicio cuando se usa la configuracion proto udp, el archivo de log de el servidor muestra la linea: TLS: Initial packet from x.x.x.x:x, sid=xxxxxxxx xxxxxxxx Sin embargo el log de el cliente no muestra una linea equivalente. Solucion: - Tienes una conexion en un solo sentido de el cliente a el servidor. La direccion de el servidor hacia el cliente esta bloqueada por un firewall, usualmente en el lado e el cliente. El firewall puede ser (a) un software de firewall personal corriendo en el cliente, o (b) el gateway (router)_ que hace NAT para el cliente. Modifica el firewall para permitir conexiones de regreso a paquetes UDP de el servidor para alcanzar el cliente. Ver el FAQ para informacion adicional para la resolucion de problemas. Configurando OpenVPN para correr automaticamente al inicio de el sistema. La carencia de estandars en esta area significa que la mayoria de OSes tienen una diferente manera para configurar demonios/servicios para autoiniciar al arranque de el sistema. La mejor manera para tener esta funcionalidad configurada de manera predeterminada es instalar OpenVPN como un paquete, como puede ser via RPM on Linux o usando un installador de Windows. NOTA: En este caso el paquete openvpn-2.0.6-i486-1jm.tgz provee el script /etc/rc.d/rc.openvpn Si instalaste OpenVPN via un paquete TGZ en Slackware Linux, el paquete creara un rc script (/etc/rc.d/rc.openvpn). Cuando es ejecutado, el rc script escaneara por archivos de configuracion .conf en el directorio /etc/openvpn, y si encuentra alguno, iniciara un demonio separado de OpenVPN por cada archivo. Controlando un proceso de OpenVPN que ya este corriendo. Corriendo en Linux OpenVPN acepta varias señales: * SIGUSR1 -- Reinicio condicional, diseñado para reiniciar sin privilegios de root. * SIGHUP -- Hard Restart. * SIGUSR2 -- Saca las estadisticas de conexino a un archivo de log o a syslog. * SIGTERM, SIGINT -- Termina. Usa la directiva writepid para escribir el PID de el demonio OpenVPN a un archivo, asi sabras a donde enviar la señal ( si estas iniciando el script con un rc script, el script puede que ya este pasando la directiva --wirtepid en la linea de comandos). Modificando una configuracion de un servidor en vivo. Mientras que la mayoria de las configuraciones requiren que reinicies el servidor, hay dos directivas in particular que se refieren a archivos que pueden ser dinamicamente actaulizados "al vuelo", y los cuales tomaran efecto de inmediato en el servidor sin necesidad de reiniciar el proceso de el servidor. client-config-dir -- Esta directiva configuracion el directorio de configuracion, el cual el servidor OpenVPN escaneara en cada conexion entrante, en busca de un archivo de configuracion especifico para el cliente que inicia la conexion ( ver la pagina de el manual para mayor informacion). Los archivos en este directorio pueden ser actualizados "al vuelo", sin reiniciar el servidor. Note que los cambios en este directorio solo tomaran efecto para nuevas conexiones, y no para conexiones ya existentes. Si quisieras que el cambio un archivo de configuracion especifico para un clente tome efecto inmediato en un cliente actualmente conectado (o en uno el cual se ha desconectado, pero cuando el server no dado tiempo fuera a su instancia), mata la instancia de el cliente usando la interfaz de administracion ( descrita abajo). Esto causara el cliente para reconectarse y usar el nuevo archivo en client-config-dir. crl-verify -- Esta directiva nombra el archivo con la Lista de Revocacion de Certificados de el ingles (Certificate Revocation List), descrito en la seccion "Revocando Certificados. El archivo CRL puede ser modificado "al vuelo", y los cambios tomaran efecto inmediato para nuevas conexiones, o conexiones existentes que estan renegociando su canal SSL/TLS (Ocurre una vez por hora de manera predeterminada). Si quisieras matar una conexion de un cliente actualmente conectada que su certificado ha sido agregado a la CRL, usa la interfaz de administracion (descrita abajo). Status File El archivo default server.conf tiene una linea: status openvpn-status.log El cual mandara la salida de una lista de conexiones de clientes actuales a el archivo openvpn-status.log una vez por minuto. Expandiendo el ambito de la VPN para incluir maquinas adicionales en la subred de el cliente o el servidor. Incluyendo multiples maquinas en el lado de el servidor cuando se usa una VPN ruteada (dev tun). Una vez que la VPN es operacional con una capacidad punto-a-punto entre el cliente y el servidor, seria deseable expandir el ambito de la VPN de manera que los clientes puedan alcanzar multiples maquinas en la red de el servidor, en lugar de solo la maquina servidor en si. Para el proposito de este ejemplo, asumiremos que la LAN de el lado de el servidor usa una subred de 10.0.0.0/24 y el pool de direcciones IP de la VPN usa 10.8.0.0/24 como fue citado en la directiva "server" en el archivo de configuracion de el servidor OpenVPN. Primero debes de anunciar la subred 10.0.0.0/24 a los clientes para que sea accesible a travez de la VPN. esto puede ser facilmente hecho con la siguiente directiva en el archivo de configuracion de el lado servidor: push "route 10.0.0.0 255.255.255.0" Lo siguiente, debes de de configurar una ruta en el gateway de la LAN en el lado de el servidor para enrutar la subred de el cliente VPN (10.8.0.0/24) hacia el seridor OpenVPN (esto es solo necesario si el servidor OpenVPN y el gateway de la LAN estan en diferentes maquinas). Asegurate de que has activado IP y TUN/TAP forwarding en la maquina servidor OpenVPN.