Crear una red privada virtual (VPN) mediante OpenVPN es muy fácil y permite de manera sencilla conectar múltiples equipos de manera segura usando cualquier conexión a Internet. Cuando conectamos múltiples equipos surge la duda de como gestionar la comunicación entre ellos.

Cada equipo conectado a la VPN recibe una IP privada de un rango definido para esa VPN. El software OpenVPN permite configurar la VPN para que actúe como una red local de manera que la comunicación entre todos los equipos conectados puede realizarse directamente sin ningún filtro ni protección. Esto puedo ser útil en la mayoría de los casos, cuando todos los equipos forman parte de la misma organización y se busca la facilidad de configuración. Para conseguir este efecto utilizamos la directiva ‘client-to-client’.

La alternativa consiste en no indicar esa directiva. En ese caso el servidor OpenVPN lo que hace es reenviar los paquetes que pretenden ir de equipo a equipo dentro de la VPN al kernel del servidor donde se ejecuta. Este comportamiento nos permite, combinado con iptables, una flexibilidad total en la gestión de permisos. Podemos crear reglas que permitan o limiten el tráfico a nivel equipos y/o servicios (IPs y/o puertos).

Si además combinamos esto con subredes y múltiples instancias de OpenVPN tenemos poderosas herramientas para planificar nuestra red con el máximo detalle.

A continuación uno ejemplo de una configuración con dos instancias VPN, basado en un caso real, en el que tenemos una VPN de administración propia y otra VPN para clientes.

Introducción

La instalación básica del software es muy sencilla, se puede seguir el HOW-TO oficial para más detalles.Queremos montar varias VPN para nuestros clientes, queremos que dos usuarios de la misma VPN no se puedan ver, pero necesitamos que los usuarios de la VPN-Empresa si que puedan ver a los usuarios de otras VPN para poder tener acceso para administración de las maquinas.

 Instalación

Primero tenemos que escoger un nombre para la nueva vpn, por ejemplo test.

Necesitamos un directorio donde generar los pares de claves para la nueva vpn, copiaremos los ficheros por defecto de /usr/share/doc/openvpn/examples/:

sb3:/# cd /usr/share/doc/openvpn/examples/
sb3:/usr/share/doc/openvpn/examples# cp -R easy-rsa/2.0 /etc/openvpn/rsa-test

Modificamos el fichero vars del directorio /etc/openvpn/rsa-test modificando las siguientes lineas:

# Increase this to 2048 if you
# are paranoid.  This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=2048
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY=ES
export KEY_PROVINCE=BCN
export KEY_CITY=Barcelona
export KEY_ORG="TestVPN"
export KEY_EMAIL="soporte@empresa.com"

Ejecutamos los comandos para generar la Autoridad de Certificacion y las claves para el servidor:

sb3:/etc/openvpn/rsa-test# . ./vars
NOTE: when you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/rsa-test/keys
sb3:/etc/openvpn/rsa-test# ./clean-all
sb3:/etc/openvpn/rsa-test# ./build-ca
Generating a 2048 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) [ES]:
State or Province Name (full name) [BCN]:
Locality Name (eg, city) [Barcelona]:
Organization Name (eg, company) [TestVPN]:
Organizational Unit Name (eg, section) []:TestVPNCA
Common Name (eg, your name or your server's hostname) []:TestVPNCA
Email Address [soporte@empresa.com]:
sb3:/etc/openvpn/rsa-test# ./build-key-server server
Generating a 2048 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) [ES]:
State or Province Name (full name) [BCN]:
Locality Name (eg, city) [Barcelona]:
Organization Name (eg, company) [TestVPN]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:TestVPNServer
Email Address [soporte@empresa.com]:
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/rsa-test/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'ES'
stateOrProvinceName   :PRINTABLE:'BCN'
localityName          :PRINTABLE:'Barcelona'
organizationName      :PRINTABLE:'TestVPN'
commonName            :PRINTABLE:'TestVPNServer'
emailAddress          :IA5STRING:'soporte@empresa.com'
Certificate is to be certified until Jun  3 17:32:14 2016 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
sb3:/etc/openvpn/rsa-test# ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...............................................................................................................

Por ultimo necestamos un directorio donde guardar las ips de los clientes:

sb3:/etc/openvpn/rsa-test# mkdir ../ccd-test

 Configuración

 Servidor

En el directorio /etc/openvpn/ vamos a tener tantos ficheros server*.conf como VPN queramos. El fichero serverEmpresa.conf quedaria de la siguiente forma:

port 9760
proto udp
dev tun51
ca easy-empresa/keys/ca.crt
cert easy-empresa/keys/server.crt
key easy-empresa/keys/server.key  # This file should be kept secret
dh easy-empresa/keys/dh2048.pem
server 10.34.21.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.34.22.0 255.255.255.0"
client-config-dir ccd-empresa
keepalive 10 120
tls-auth ta.key 0 # This file is secret
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status-empresa.log
log openvpn-empresa.log
verb 3

El fichero serverClientes.conf es el siguiente:

port 9761
proto udp
dev tun52
ca easy-clientes/keys/ca.crt
cert easy-clientes/keys/server.crt
key easy-clientes/keys/server.key  # This file should be kept secret
dh easy-clientes/keys/dh2048.pem
server 10.34.22.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.34.21.0 255.255.255.0"
client-config-dir ccd-clientes
keepalive 10 120
tls-auth ta.key 0 # This file is secret
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status-clientes.log
log openvpn-clientes.log
verb 3

Las diferencias entre los dos ficheros son:

  • port: Cada VPN necesita un puerto diferente.
  • dev: Cada VPN tendra su porpia interficie de red.
  • server: Cada VPN tiene su rango de ip’s
  • client-config-dir: Cada VPN utilizara un directorio diferente donde indicar los usuarios que tiene.
  • push route: Cada VPN tiene sus propios push de rutas a los clientes, estos definen las VPN’s que van a ver los clientes, Por ejemplo la VPN de Empresa tendrà rutas para todas las otras VPN’s pero la VPN d’clientes, solo tendrà push a la de Empresa, porque no tiene porque ver las VPNs de los otros clientes.
  • certs: Cada VPN tendrà sus propios certificados
  • logs

 Cliente

En el cliente, el fichero de configuración seria el siguiente:

client
dev tun
proto udp
remote 192.168.1.39 9761
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert francesc.crt
key francesc.key
ns-cert-type server
tls-auth ta.key 1
comp-lzo
verb 3

La única operación importante és la linea ‘remote’, que es donde indicas qual és el servidor y el puerto donde esta la VPN, el puerto define a que VPN estas accediendo y los certificados si puedes acceder a ella.

 Configuración de red del servidor

Para que en el servidor se puedan reenviar los paquetes entre las interficies de dos VPNs, tun51 y tun52, tenemos que permitir el ip_forwarding, para hacer esto tenemos que ejecutar la siguiente comanda:

echo 1 > /proc/sys/net/ipv4/ip_forward

Si tenemos prohibidos los FORWARDs entre interficies tendremos que ejecutar las siguentes reglas en el iptables:

VPN_EMPRESA="tun51"
VPN_EMPRESA_IP="10.34.21.1"
VPN_EMPRESA_RANGE="10.34.21.0/24"
VPN_CLIENTES="tun52"
VPN_CLIENTES_IP="10.34.22.1"
VPN_CLIENTES_RANGE="10.34.22.0/24"
# discard source address check for packets coming from the VPN-EMPRESA or VPN-CLIENTES
$IPT -I source-address-check 1 -i $VPN_EMPRESA -s $VPN_EMPRESA_RANGE -j RETURN
$IPT -I source-address-check 1 -i $VPN_CLIENTES -s $VPN_CLIENTES_RANGE -j RETURN
###############################################################
# VPN-EMPRESA-input
logger -s [FIREWALL] Setting custom chains: VPN-input
$IPT -N VPN-EMPRESA-input
# Incoming TCP connections
$IPT -A VPN-EMPRESA-input -p tcp -m multiport --dport 22,25,53,80,110,225,443,993,995,3333,8080 -m state --state NEW -j ACCEPT
# Reject incoming AUTH requests with RST
$IPT -A VPN-EMPRESA-input -p tcp --sport $UNPRIVPORTS --dport 113 -j REJECT --reject-with tcp-reset
#.............................................................
# ICMP
$IPT -A VPN-EMPRESA-input -p icmp -j icmp-in
###############################################################
# VPN-CLIENTES-input
logger -s [FIREWALL] Setting custom chains: VPN-input
$IPT -N VPN-CLIENTES-input
# Incoming TCP connections
$IPT -A VPN-CLIENTES-input -p tcp -m multiport --dport 22,8080 -m state --state NEW -j ACCEPT
# Reject incoming AUTH requests with RST
$IPT -A VPN-CLIENTES-input -p tcp --sport $UNPRIVPORTS --dport 113 -j REJECT --reject-with tcp-reset
#.............................................................
# ICMP
$IPT -A VPN-CLIENTES-input -p icmp -j icmp-in
# Begin standard firewall tests for packets addressed to this host
$IPT -A INPUT -i $VPN_EMPRESA -d $VPN_EMPRESA_IP -j VPN-EMPRESA-input
$IPT -A INPUT -i $VPN_CLIENTES -d $VPN_CLIENTES_IP -j VPN-CLIENTES-input
# Begin standard firewall tests for packets sent from this host
# Source address spoofing by this host is  not allowed due to the
# test on source address in this rule.
$IPT -A OUTPUT -o $VPN_EMPRESA -s $VPN_EMPRESA_IP -j ACCEPT
$IPT -A OUTPUT -o $VPN_CLIENTES -s $VPN_CLIENTES_IP -j ACCEPT
###############################################################
# VPN-EMPRESA-to-VPN-CLIENTES
logger -s [FIREWALL] Setting custom chains: VPN-EMPRESA-to-VPN-CLIENTES
$IPT -N VPN-EMPRESA-to-VPN-CLIENTES
$IPT -A VPN-EMPRESA-to-VPN-CLIENTES -p tcp -m multiport --dport 5900,8080 -m state --state NEW -j ACCEPT
#............................................................
# ICMP 
$IPT -A VPN-EMPRESA-to-VPN-CLIENTES -p icmp -j icmp-out
# VPN entre EMPRESA y CLIENTES
$IPT -A FORWARD -i $VPN_EMPRESA -s $VPN_EMPRESA_RANGE -o $VPN_CLIENTES -d $VPN_CLIENTES_RANGE -j VPN-EMPRESA-to-VPN-CLIENTES