Construcción de servidor OpenVPN propio

2 de abril de 2016 • fjbalon

Antes de realizar cualquier comprobación es necesario tener claros unos conceptos teóricos referentes a las interfaces de redes virtuales TUN y TAP, interfaces de red virtuales a nivel de kernel.

Aunque TUN y TAP tienen el mismo propósito de «tunneling» divergen en su funcionamiento técnico. TUN simula un dispositivo de capa de red y opera en la capa 3 del modelo OSI transportando paquetes IP mientras que TAP simula un dispositivo en la capa de enlace y opera en la capa 2 del modelo OSI, creando un puente (bridge) de red.

Los paquetes enviados por un sistema operativo a través de un dispositivo TUN/TAP son entregados a un programa de espacio de usuario que se conecta al dispositivo. Un programa de espacio de usuario también puede pasar paquetes en un dispositivo TUN/TAP. En este caso el dispositivo TUN/TAP inyecta estos paquetes a la pila de red del sistema operativo simulando así su recepción desde una fuente externa.

En el caso de sistemas Linux, el soporte a TUN puede habilitarse de forma nativa en el kernel desde la versión 2.1.60. Debemos pues, comprobar si el kernel de nuestro servidor tiene habilitado este soporte, ya que al utilizar un servicio VPS algunas capas de virtualización vServers y OpenVZ requieren que TUN esté habilitado en la máquina host y podría ser necesario contactar con el administrador o proveedor del servicio para ser habilitado y así poder continuar. Debemos asegurar pues que el módulo CONFIG\_TUN está habilitado en el kernel, esto lo podemos ver rápidamente con la siguiente línea de comandos:

test ! -c /dev/net/tun && echo openvpn requires tun support || echo tun is available

Entonces, para OpenVPN debemos crear:

Descarga de easy-rsa:

wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz
tar xvf EasyRSA-unix-v3.0.6.tgz
cd EasyRSA-v3.0.6/

En el directorio easy-rsa crearemos el subderectorio vars:

cp vars.example vars

Con el contenido:

# vars
set_var EASYRSA_REQ_COUNTRY "AR"
set_var EASYRSA_REQ_PROVINCE "Arrakis"
set_var EASYRSA_REQ_CITY "Arrakeen"
set_var EASYRSA_REQ_ORG "Dune"
set_var EASYRSA_REQ_EMAIL "paul_muaddib@atreides"
set_var EASYRSA_REQ_OU "arrakis"

Posteriormente, realizaremos las distintas acciones de inicialización y generación de claves RSA y certificados para servidor y clientes.

./easyrsa init-pki                  # Inicialización del entorno PKI de EasyRSA
./easyrsa gen-dh                    # Generación de parámetros de Diffie-Hellman
./easyrsa build-ca nopass           # RSA key and CA certificate

                                    # Clave RSA y certificado de servidor (arrakis)
./easyrsa gen-req arrakis nopass
./easyrsa sign-req server arrakis

                                    # Clave RSA y cliente de servidor (oldscizor)
./easyrsa gen-req oldscizor nopass
./easyrsa sign-req client oldscizor

openvpn --genkey --secret ta.key    # Generación de clave TLS

Distribución de claves

En este punto ya tenemos estos archivos generados y listos para usar:

Enviando claves al servidor (en este caso es la misma máquina):

cp pki/dh.pem /etc/openvpn/server/
cp pki/ca.crt /etc/openvpn/server/
cp pki/private/arrakis.key /etc/openvpn/server/
cp pki/issued/arrakis.crt /etc/openvpn/server/
cp ta.key /etc/openvpn/server/

Enviando claves al cliente oldscizor (mediante SCP):

scp pki/private/oldscizor.key oldscizor.es:/tmp
scp pki/issued/oldscizor.crt oldscizor.es:/tmp
scp pki/ca.crt oldscizor.es:/tmp
scp ta.key oldscizor.es:/tmp

Entonces, en el cliente oldscizor, los movemos a su localización final:

sudo mv /tmp/oldscizor.key /etc/openvpn
sudo mv /tmp/oldscizor.crt /etc/openvpn
sudo mv /tmp/ca.crt /etc/openvpn
sudo mv /tmp/ta.key /etc/openvpn

Configuración de servidor arrakis

port 1194
proto udp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/arrakis.crt
key /etc/openvpn/server/arrakis.key
dh /etc/openvpn/server/dh.pem
server 10.10.0.0 255.255.255.0
ifconfig-pool-persist ipp.code
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-CBC
persist-key
persist-tun
status openvpn-status.log
log /var/log/openvpn
verb 3
explicit-exit-notify 1

Configuración de cliente oldscizor

client
dev tun
proto udp
remote arrakis 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/oldscizor.crt
key /etc/openvpn/oldscizor.key
remote-cert-tls server
tls-auth /etc/openvpn/ta.key 1
cipher AES-256-CBC
verb 3

Asignación de una dirección IP fija al cliente oldscizor

echo "client-config-dir ccd" >> /etc/openvpn/server/arrakis.conf
mkdir /etc/openvpn/server/ccd
echo "ifconfig-push 10.10.0.100 255.255.255.0" >> /etc/openvpn/server/ccd/oldscizor

Permiso de comunicación 'client to client'

echo "client-to-client" >> /etc/openvpn/server/arrakis.conf

Generación de nuevo cliente maquina

En el servidor arrakis:

./easyrsa gen-req maquina nopass
./easyrsa sign-req client maquina
cp pki/private/maquina.key /tmp
cp pki/issued/maquina.crt /tmp
cp pki/ca.crt /tmp
cp ta.key /tmp
echo "ifconfig-push 10.10.0.101 255.255.255.0" >> /etc/openvpn/server/ccd/maquina

En el nuevo cliente:

scp arrakis:/tmp/maquina.key /etc/openvpn
scp arrakis:/tmp/maquina.crt /etc/openvpn
scp arrakis:/tmp/ca.crt /etc/openvpn
scp arrakis:/tmp/ta.key /etc/openvpn
echo "client
dev tun
proto udp
remote arrakis 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/maquina.crt
key /etc/openvpn/maquina.key
remote-cert-tls server
tls-auth /etc/openvpn/ta.key 1
cipher AES-256-CBC
verb 3
auth-nocache" > /etc/openvpn/maquina.conf
chmod 700 /etc/openvpn/*