Configurando OpenVPN con CentOS 6 en OpenVZ container

Recientemente adquirí un hosting VPS a un costo bajo con las siguientes especificaciones:

  • 1024MB Ram
  • 50GB DiskSpace
  • 600GB Bandwidth
  • 1 IPv4 Address
  • OpenVZ/SolusVM
  • 100 Mbps Port Speed
  • $3.99/Month

Entre las opciones disponibles para usar esta Cent0S/Debian/Ubuntu para la configuración utilizare CentOS release 6.3 (Final) e instalare el paquete openvpn. La tecnología de virtualización utilizada por el hosting es OpenVZ(base de Parallels) , que funciona similar al jail de BSD o las zonas en Solaris.

Con OpenVZ no es posible agregar módulos al Kernel desde el container por razones de seguridad, los módulos deben ser agregados al kernel del host para ser usados por el container(guest o maquina virtual).

A pesar de poder agregar modulo ipsec al kernel desde host, el container solo puede usar ciertos módulos por ejemplo iptables, ipsec verify falla en el container al verificar el soporte para los módulos de encripción en el kernel hasta el momento el soporte para IPSEC en OpenVZ container es experimental, por suerte tun/tap o ppp están disponibles, PPP no es recomendable por razones de seguridad pero si podremos usar la interfaz tun/tap con Openvpn puesto que este tipo de VPN no carga módulos en el kernel y puede usar claves o PKI(Infraestructura de llave publica) basada en OpenSSL

La VPN a configurar con OpenVPN sera para enrutar todo el trafico de los clientes por la VPN con esta configuración se puede usar por ejemplo para asegurar la comunicación sobre redes inseguras o saltar filtros de geolocalización de ciertos sitios web.

El requerimiento previo antes de iniciar es que el proveedor habilite el modulo Iptables para que este disponible en el container y habilitar la interfaz tun/tap en el panel de control del hosting.

Control Panel VPS
Control Panel VPS

Una particularidad de openvz, es que los modulos dentro del container no pueden ser listados con lsmod asi que lo que se hace es probar la funcionalidad de iptables con un scaner de puertos como Nmap y verificar los puertos abiertos con netstat.

Para el paquete Openvpn y sus dependencias habilitaremos el repositorio EPEL

 wget -c http://fedora.mirror.nexicom.net/epel/6/i386/epel-release-6-8.noarch.rpm
 yum localinstall epel-release-6-8.noarch.rpm
 yum install openvpn openssl

Openvpn provee scripts(easy-rsa) para facilitar la generación de las llaves y certificados necesarios en la configuración de la VPN, para utilizarlos copiaremos estos scripts a una locacion como /etc/openvpn, para que los cambios no sea reescrito en una actualización del paquete openvpn.

cp -r /usr/share/openvpn/easy-rsa /etc/openvpn
cd easy-rsa/2.0
ls
-rwxr-xr-x 1 root root   119 Jan 29 07:50 build-ca
-rwxr-xr-x 1 root root   352 Jan 29 07:50 build-dh
-rwxr-xr-x 1 root root   188 Jan 29 07:50 build-inter
-rwxr-xr-x 1 root root   163 Jan 29 07:50 build-key
-rwxr-xr-x 1 root root   157 Jan 29 07:50 build-key-pass
-rwxr-xr-x 1 root root   249 Jan 29 07:50 build-key-pkcs12
-rwxr-xr-x 1 root root   268 Jan 29 07:50 build-key-server
-rwxr-xr-x 1 root root   213 Jan 29 07:50 build-req
-rwxr-xr-x 1 root root   158 Jan 29 07:50 build-req-pass
-rwxr-xr-x 1 root root   428 Jan 29 07:50 clean-all
-rwxr-xr-x 1 root root   143 Jan 29 08:59 gen-crt.sh
-rwxr-xr-x 1 root root  1457 Jan 29 07:50 inherit-inter
-rwxr-xr-x 1 root root   295 Jan 29 07:50 list-crl
-rw-r--r-- 1 root root   413 Jan 29 07:50 Makefile
-rwxr-xr-x 1 root root  7768 Jan 29 07:50 openssl-0.9.6.cnf
-rwxr-xr-x 1 root root  8325 Jan 29 07:50 openssl-0.9.8.cnf
-rwxr-xr-x 1 root root  8222 Jan 29 07:50 openssl-1.0.0.cnf
-rwxr-xr-x 1 root root 12675 Jan 29 07:50 pkitool
-rw-r--r-- 1 root root  9299 Jan 29 07:50 README
-rwxr-xr-x 1 root root   918 Jan 29 07:50 revoke-full
-rwxr-xr-x 1 root root   178 Jan 29 07:50 sign-req
-rwxr-xr-x 1 root root  1829 Jan 29 08:34 vars
-rwxr-xr-x 1 root root   714 Jan 29 07:50 whichopensslcnf

Lo siguiente es editar el archivo vars y lo minimo a editar son los parametros KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG, and KEY_EMAIL, se identifica la version instalada de openssl en este caso OpenSSL 1.0.0-fips 29 Mar 2010 por lo que creamos un enlace simbolico para usar la configuracion correspondiente. luego se generaran los certificados y llaves para el servidor y el cliente, para mayor referencia de esto hay un buen articulo en la wiki de ArchLinux

cd /etc/openvpn/easy-rsa/2.0
vim vars
openssl version
ln -s openssl-1.0.0.cnf openssl.cnf
source vars                      # load vars
./clean-all                      # remove old keys
./build-ca                       # Certificate Authority (CA) 
./build-key-server myserver      # server certificate
./build-dh                       # Diffie-Hellman 
./build-key  client1             # client certificate and key 
openvpn --genkey --secret keys/ta.key   # Hash-based Message Authentication Code (HMAC)

Una vez generado los certificados y llaves, necesitaremos crear la configuración del servidor VPN para ello utilizare como base el archivo de configuración de ejemplo que viene con el paquete Openvpn. y copiare los archivos requerido para usarse con el servidor (ca.crt, dh2048.pem o dh1024.pem dependiendo del tamaño de la llave, myserver.crt, myserver.key, ta.key)

cp /usr/share/doc/openvpn-2.2.2/sample-config-files/server.conf /etc/openvpn/server.conf
cd /etc/openvpn/easy-rsa/2.0/keys 
cp ca.crt dh1024.pem  myserver.crt myserver.key ta.key ../../../
ls
-rw-r--r-- 1 root root  1627 Jan 29 09:12 ca.crt
-rw-r--r-- 1 root root   424 Jan 29 09:12 dh1024.pem
drwxr-xr-x 4 root root  4096 Jan 29 07:50 easy-rsa
-rw-r--r-- 1 root root  5312 Jan 29 09:12 myserver.crt
-rw------- 1 root root  1704 Jan 29 09:12 myserver.key
-rw-r--r-- 1 root root 10372 Jan 30 09:38 server.conf
-rw------- 1 root root   636 Jan 29 09:21 ta.key

Configuración del servidor archivo server.conf

port 1194
proto udp
dev tun
ca ca.crt
cert myserver.crt
key myserver.key  # This file should be kept secret
dh dh1024.pem
server 10.8.0.0 255.255.255.0 # vpn private network
ifconfig-pool-persist ipp.txt
push "route 10.8.0.0 255.255.255.0" 
topology subnet # necesario para fijar el gateway en el cliente
push "redirect-gateway def1" # redirigir el trafico del cliente al servidor vpn.
push "dhcp-option DNS 8.8.8.8" 
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
tls-auth ta.key 0 # This file is secret
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
verb 3

Configuración del cliente client1.ovpn

client
dev tun
proto udp
remote <server ip/hostname> 1194    # dominio o ip publica del servidor
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt                 # certificado CA
cert client1.crt          # certificado cliente
key client1.key           # llave cliente 	
ns-cert-type server
tls-auth ta.key 1         # llave HMAC
comp-lzo
verb 3

Para la conexion del cliente son necesarios los siguientes archivos el perfil client1.ovpn, certificados y llaves (ca.crt, client1.crt, client1.key, ta.key), en Linux podemos configurar la conexión usando NetworkManager openvpn, en windows podemos descargar el cliente de openvpn

Para conectarse a una VPN configurada con Openvpn hay disponibles varios clientes para Mac(tunnelblick), Windows, Linux/Unix – openvpn client, iOS -openvpn connect y Android – openvpn connect . en todos los casos los archivos del perfil son los mismos para conectarse.

Habiendo realizado los pasos anteriores es momento de probar la VPN ejecutando la configuración del servidor

cd /etc/openvpn
openvpn server.conf

Si la configuración es correcta y la interfaz tun/tap esta activada la salida del comando anterior sera algo como esto:

OpenVPN 2.2.2 i686-redhat-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] built on Aug 10 2012
NOTE: the current --script-security setting may allow this configuration to call user-defined scripts
Diffie-Hellman initialized with 2048 bit key
Control Channel Authentication: using 'ta.key' as a OpenVPN static key file
Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
TLS-Auth MTU parms [ L:1542 D:166 EF:66 EB:0 ET:0 EL:0 ]
Socket Buffers: R=[245760->131072] S=[245760->131072]
ROUTE: default_gateway=UNDEF
TUN/TAP device tun0 opened
TUN/TAP TX queue length set to 100
/sbin/ip link set dev tun0 up mtu 1500
/sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
/sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]

y el tunnel aparacera listado en las interfaces del contenedor:

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.8.0.1  P-t-P:10.8.0.1  Mask:255.255.255.0
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:217735 errors:0 dropped:0 overruns:0 frame:0
          TX packets:343811 errors:0 dropped:47 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:20645624 (19.6 MiB)  TX bytes:421775445 (402.2 MiB)

si la configuración es correcta del lado del cliente tendremos la interfaz y la red de la vpn en la tabla de ruteo del sistema operativo, con esto tenemos conexión solo al servidor pero el trafico no es enrutado para ello necesitamos habilitar el ip fowarding con iptables

# kernel params sysctl.conf
 
sysctl -w net.ipv4.ip_forward=1
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -p /etc/sysctl.conf 

Configuración iptables

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source <server ip>
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p ah -j ACCEPT
-A INPUT -p esp -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 500 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT
-A FORWARD -s 10.8.0.0/24 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT

Pruebas de conexión
Openvpn Connect iOS

openvpn connect ios
openvpn connect ios
openvpn connect ios - connected
openvpn connect ios – connected

linux openvpn connected

ping test
ping test

Referencia:

http://wiki.openvz.org/Main_Page
http://openvpn.net/index.php/download/community-downloads.html
http://openvpn.net/index.php/open-source/documentation/howto.html
https://wiki.archlinux.org/index.php/OpenVPN#Advanced_L3_IP_routing
https://wiki.archlinux.org/index.php/Create_a_Public_Key_Infrastructure_Using_the_easy-rsa_Scripts
http://en.wikipedia.org/wiki/Public_key_infrastructure

Author: rz0r

I’m computer programer, sysadmin, web developer, like video games, Linux and listen music.