Product SiteDocumentation Site

10.2. Red virtual privada

Una red virtual privada (VPN: «Virtual Private Network») es una forma de enlazar dos redes locales diferentes a través de Internet utilizando un túnel; el túnel generalmente está cifrado para confidencialidad. Usualmente se utilizan VPNs para integrar una máquina remota a la red local de una empresa.
Muchas herramientas lo proveen. OpenVPN es una solución eficiente, fácil de desplegar y mantener, basada en SSL/TLS. Otra posibilidad es utilizar IPsec para cifrar el tráfico IP entre dos máquinas; este cifrado es transparente, lo que significa que no necesita modificar las aplicaciones ejecutando en estos equipos para tener en cuenta la VPN. También puede utilizar SSH, además de para sus funcionalidades más convencionales, para proveer una VPN. Finalmente, puede establecer una VPN utilizando el protocolo PPTP de Microsoft. Existen otras soluciones, pero están más allá del alcance de este libro.

10.2.1. OpenVPN

OpenVPN es un pedazo de software dedicado a crear redes privadas virtuales. Su configuración involucra crear interfaces de red virtuales en el servidor VPN y en los clientes; es compatible con interfaces tun (para túneles a nivel de IP) y tap (para túneles a nivel Ethernet). En la práctica, usualmente utilizará interfaces tun excepto cuando los clientes VPN deban intengrarse a la red local del servidor a través de un puente Ethernet.
OpenVPN se basa en OpenSSL para toda la criptografía SSL/TLS y funcionalidades asociadas (confidencialidad, autenticación, integridad, falta de repudio). Puede configurarlo con una llave privada compartida o con un certificado X.509 basado en la infraestructura de llave pública. Se prefiere fuertemente esta última configuración ya que permite más flexibilidad cuando se enfrenta a un número creciente de usuarios itinerantes que acceden a la VPN.

10.2.1.1. Infraestructura de llave pública: easy-rsa

El algoritmo RSA es ampliamente utilizado en criptografía de llave pública. Involucra un «par de llaves», compuestas de una llave privada y una llave pública. Las dos llaves están fuertemente relacionadas entre ellas y sus propiedades matemáticas son tales que un mensaje cifrado con la llave pública sólo puede ser descifrado por alguien que conozca la llave privada, lo que asegura confidencialidad. En la dirección opuesta, un mensaje cifrado con la clave privada puede ser descifrado por cualquiera que conozca la llave pública, lo que permite autenticar el origen del mensaje ya que sólo pudo haber sido generado por alguien con acceso a la llave privada. Cuando se asocie una función de hash digital (MD5, SHA1 o una variante más reciente), esto lleva a un mecanismo de firma que puede aplicarse a cualquier mensaje.
Sin embargo, cualquiera puede crear un par de llaves, almacenar cualquier identidad en ella y pretender ser la identidad que elijan. Una solución involucra el concepto de una autoridad de certificación (CA: «Certification Authority») formalizado por el estándar X.509. Este término se refiere a una entidad que posee un par de llaves confiable conocido como certificado raíz. Sólo se utiliza este certificado para firmar otros certificados (pares de llaves), luego que se siguieron suficientes pasos para revisar la identidad almacenada en el par de llaves. Las aplicaciones que utilizan X.509 luego pueden verificar los certificados que se les presente si conocen los certificados raíz confiables.
OpenVPN sigue esta regla. Dado que los CA públicos sólo expiden certificados a cambio de un pago (importante), también es posible crear una autoridad de certificación privada dentro de la empresa. El paquete easy-rsa proporciona herramientas que dan soporte a la infraestructura de certificados X.509, implementados como un conjunto de scripts haciendo usp del comando openssl.
Los administradores de Falcot Corp utilizan esta herramienta para crear los certificados necesarios, tanto para los servidores como para los clientes. Esto permite que la configuración de todos los clientes sea similar ya que sólo deberán configurarlos para confiar en certificados que provengan de la CA local de Falcot. Esta CA es el primer certificado a crear; para ello los administradores preparan un directorio con los ficheros necesarios para la CA en una ubicación apropiada, preferentemente a una máquina que no está conectada a la red para evitar el riesgo de robo de la llave privada de la CA.
$ make-cadir pki-falcot
$ cd pki-falcot
They then store the required parameters into the vars file, which can be uncommented and edited:
$ vim vars
$ grep EASYRSA vars
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
export KEY_DIR="$EASY_RSA/keys"
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export KEY_SIZE=2048
export KEY_EXPIRE=3650
export KEY_COUNTRY="FR"
export KEY_PROVINCE="Loire"
export KEY_CITY="Saint-Étienne"
export KEY_ORG="Falcot Corp"
export KEY_EMAIL="admin@falcot.com"
export KEY_OU="Certificate authority"
export KEY_NAME="Certificate authority for Falcot Corp"
# If you'd like to sign all keys with the same Common Name, uncomment the KEY_CN export below
# export KEY_CN="CommonName"
$ 
El siguiente paso es crear el par de llaves en sí de la CA (durante este paso se almacenarán las dos partes del par de llaves en keys/ca.crt y keys/ca.key):
The next step is the creation of the CA's key pair itself (the two parts of the key pair will be stored under pki/ca.crt and pki/private/ca.key during this step). We can add the option nopass to avoid entering a password each time the private key is used:
$ ./easyrsa build-ca nopass

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating RSA private key, 2048 bit long modulus (2 primes)
......................................................................................+++++
......................+++++
e is 65537 (0x010001)
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.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/roland/pki-falcot/pki/ca.crt

Ahora puede crear el certificado para el servidor VPN, así como también los parámetros Diffie-Hellman necesarios en el servidor para la conexión SSL/TLS. Se identifica el servidor VPN por su nombre DNS vpn.falcot.com; se reutiliza este nombre para los archivos de llaves generados (keys/vpn.falcot.com.crt para el certificado público, keys/vpn.falcot.com.key para la llave privada):
$ ./easyrsa gen-req vpn.falcot.com nopass
Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating a RSA private key
.................................................................................+++++
........+++++
writing new private key to '/home/roland/pki-falcot/pki/private/vpn.falcot.com.key.E5c3RGJBUd'
-----
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.
-----
Common Name (eg: your user, host, or server name) [vpn.falcot.com]:

Keypair and certificate request completed. Your files are:
req: /home/roland/pki-falcot/pki/reqs/vpn.falcot.com.req
key: /home/roland/pki-falcot/pki/private/vpn.falcot.com.key

$ ./easyrsa sign-req server vpn.falcot.com

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019


You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.

Request subject, to be signed as a server certificate for 1080 days:

subject=
    commonName                = vpn.falcot.com


Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
Using configuration from /home/roland/pki-falcot/pki/safessl-easyrsa.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'vpn.falcot.com'
Certificate is to be certified until Jun 14 10:44:44 2022 GMT (1080 days)

Write out database with 1 new entries
Data Base Updated

Certificate created at: /home/roland/pki-falcot/pki/issued/vpn.falcot.com.crt

$ ./easyrsa gen-dh

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
[…]
DH parameters of size 2048 created at /home/roland/pki-falcot/pki/dh.pem

El siguiente paso crea los certificados para los clientes VPN; necesita un certificado para cada equipo o persona autorizada para utilizar la VPN:
$ ./build-key JoeSmith

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1b  26 Feb 2019
Generating a RSA private key
....+++++
..............................+++++
writing new private key to '/home/roland/pki-falcot/pki/private/JoeSmith.key.mY21iP8ysv'
-----
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.
-----
Common Name (eg: your user, host, or server name) [JoeSmith]:

Keypair and certificate request completed. Your files are:
req: /home/roland/pki-falcot/pki/reqs/JoeSmith.req
key: /home/roland/pki-falcot/pki/private/JoeSmith.key
Now all certificates have been created, they need to be copied where appropriate: the root certificate's public key (pki/ca.crt) will be stored on all machines (both server and clients) as /etc/ssl/certs/Falcot_CA.crt. The server's certificate is installed only on the server (pki/issued/vpn.falcot.com.crt goes to /etc/ssl/vpn.falcot.com.crt, and pki/private/vpn.falcot.com.key goes to /etc/ssl/private/vpn.falcot.com.key with restricted permissions so that only the administrator can read it), with the corresponding Diffie-Hellman parameters (pki/dh.pem) installed to /etc/openvpn/dh.pem. Client certificates are installed on the corresponding VPN client in a similar fashion.

10.2.1.2. Configuración del servidor OpenVPN

By default, the OpenVPN initialization script tries starting all virtual private networks defined in /etc/openvpn/*.conf. Setting up a VPN server is therefore a matter of storing a corresponding configuration file in this directory. A good starting point is /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz, which leads to a rather standard server. Of course, some parameters need to be adapted: ca, cert, key and dh need to describe the selected locations (respectively, /etc/ssl/certs/Falcot_CA.crt, /etc/ssl/vpn.falcot.com.crt, /etc/ssl/private/vpn.falcot.com.key and /etc/openvpn/dh.pem). The server 10.8.0.0 255.255.255.0 directive defines the subnet to be used by the VPN; the server uses the first IP address in that range (10.8.0.1) and the rest of the addresses are allocated to clients.
Con esta configuración OpenVPN creará una interfaz de red virtual al iniciar, generalmente con el nombre tun0. Sin embargo, normalmente se configuran los firewalls al mismo tiempo que las interfaces de red reales, lo que ocurre antes que inicie OpenVPN. La creación de una interfaz de red virtual persistente, y configurar OpenVPN para que la utilice, es una buena práctica recomendada. Esto además permite elegir el nombre de esta interfaz. A tal efecto, openvpn -mktun -dev vpn -dev-type tun crea una interfaz de red virtual llamada vpn de tipo tun; puede integrar fácilmente esta orden en el script de configuración del firewall o en la directiva up del archivo /etc/network/interfaces. Debe actualizar también el archivo de configuración de OpenVPN de forma acorde, con las directivas dev vpn y dev-type tun.
Sin más cambios, los clientes VPN sólo pueden acceder el servidor VPN en sí a través de la dirección 10.8.0.1. Para permitir a los clientes que accedan la red local (192.168.0.0/24) necesitará agregar una directiva push route 192.168.0.0 255.255.255.0 a la configuración de OpenVPN para que los clientes VPN automáticamente obtengan una ruta de red que les indique que esta red está disponible a través de la VPN. Lo que es más, los equipos en la red local también necesitarán ser informados que la ruta a la VPN es a través del servidor de VPN (esto funciona automáticamente cuando instala el servidor VPN en la puerta de enlace). Otra alternativa es configurar el servidor VPN para realizar enmascaramiento de IPs de forma que las conexiones que provengan de los clientes VPN parezcan provenir del servidor VPN en su lugar (revise la Sección 10.1, “Puerta de enlace”).

10.2.1.3. Configuración del cliente OpenVPN

Para configurar un cliente OpenVPN también necesita crear un archivo de configuración en /etc/openvpn/. Puede conseguir una configuración estándar utilizando /usr/share/doc/openvpn/examples/sample-config-files/client.conf como punto de partida. La directiva remote vpn.falcot.com 1194 describe la dirección y puerto del servidor OpenVPN; también necesita adaptar ca, cert y key para describir la ubicación de los archivos de llave.
If the VPN should not be started automatically on boot, set the AUTOSTART directive to none in the /etc/default/openvpn file. Starting or stopping a given VPN connection is always possible with the commands systemctl start openvpn@name and systemctl stop openvpn@name (where the connection name matches the one defined in /etc/openvpn/name.conf).
El paquete network-manager-openvpn-gnome contiene una extensión para Network Manager (revise la Sección 8.2.5, “Configuración de red automática para usuarios itinerantes”) que permite administrar redes privadas virtuales OpenVPN. Esto permite que cada usuario configure gráficamente sus conexiones OpenVPN y las controle desde el ícono del gestor de red.

10.2.2. Red privada virtual con SSH

En realidad existen dos formas de crear una red privada virtual con SSH. La histórica involucra establecer una capa PPP sobre el enlace SSH. Se describe este método en el siguiente «howto»:
El segundo método es más reciente y fue introducido con OpenSSH 4.3; ahora OpenSSH puede crear interfaces de red virtuales (tun*) en ambos extremos de una conexión SSH y puede configurar estas interfaces virtuales exactamente como si fueran interfaces físicas. Primero debe activar el sistema de túneles configurando PermitTunnel como «yes» en el archivo de configuración del servidor SSH (/etc/ssh/sshd_config). Cuando se establece la conexión SSH debe solicitar explícitamente la creación del túnel con la opción -w any:any (puede reemplaza any con el número de dispositivo tun deseado). Esto necesita que el usuario tenga permisos de administrador en ambos extremos para poder crear el dispositivo de red (en otras palabras, debe establecer la conexión como root).
Ambos métodos para crear redes privadas virtuales sobre SSH son bastante directos. Sin embargo, la VPN que proveen no es la más eficiente disponible; en particular, no maneja muy bien altos niveles de tráfico.
La explicación es que cuando se encapsula TCP/IP en una conexión TCP/IP (para SSH) se utiliza el protocolo TCP dos veces, una vez para la conexión SSH y una vez dentro del túnel. Esto genera problemas, especialmente debido a la forma en la que TCP se adapta a condiciones de red modificando los tiempo de espera. El siguiente sitio describe el problema en más detalle: Por lo tanto debe limitar el uso de VPNs sobre SSH a túneles esporádicos y de un solo uso que no tengan requisitos de rendimiento.

10.2.3. IPsec

IPsec, a pesar de ser el estándar en VPNs IP, es bastante más complejo en su implementación. El motor de IPsec está incorporado al núcleo Linux; el paquete ipsec-tools provee las partes necesarias en espacio de usuario, las herramientas de control y configuración. En términos concretos, el archivo /etc/ipsec-tools.conf de cada equipo contiene los parámetros de los túneles IPsec (en términos de IPsec: asociaciones de seguridad, «Security Associations») en los que el equipo está involucrado; el script /etc/init.d/setkey provee una forma de iniciar y detener el túnel (cada túnel es un enlace seguro a otra máquina conectada a la red privada virtual). Puede construir este archivo a mano desde la documentación que provee la página de manual setkey(8). Sin embargo, escribir los parámetros para todos los equipos en un conjunto de máquinas no trivial se convierte fácilmente en una tarea ardua ya que la cantidad de túneles crece rápidamente. Instalar un demonio IKE (intercambio de llaves IPsec: «IPsec Key Exchange») como racoon, strongswan hace el proceso mucho más simple centralizando la administración y más seguro rotando las claves periódicamente.
A pesar de su estado como referencia, la complejidad de configuración de IPsec restringe su uso en la práctica. Generalmente se preferirán soluciones basadas en OpenVPN cuando los túneles necesarios no sean muchos ni demasiado dinámicos.

10.2.4. PPTP

PPTP (protocolo de túneles punto a punto: «Point-to-Point Tunneling Protocol») utiliza dos canales de comunicación, uno para datos de control y otro para los datos; este último utiliza el protocolo GRE (encapsulación genérica de enrutamiento: «Generic Routing Encapsulation»). Luego se establece un enlace PPP estándar sobre el canal de intercambio de datos.

10.2.4.1. Configuración del cliente

El paquete pptp-linux contiene un cliente PPTP para Linux fácil de configurar. Las instrucciones a continuación están inspiradas en la documentación oficial:
Los administradores de Falcot crearon varios archivos: /etc/ppp/options.pptp, /etc/ppp/peers/falcot, /etc/ppp/ip-up.d/falcot y /etc/ppp/ip-down.d/falcot.

Ejemplo 10.2. El archivo /etc/ppp/options.pptp

# opciones PPP utilizadas en una conexión PPTP
lock
noauth
nobsdcomp
nodeflate

Ejemplo 10.3. El archivo /etc/ppp/peers/falcot

# vpn.falcot.com es el servidor PPTP
pty "pptp vpn.falcot.com --nolaunchpppd"
# el usuario «vpn» identificará a la conexión
user vpn
remotename pptp
# necesita cifrado
require-mppe-128
file /etc/ppp/options.pptp
ipparam falcot

Ejemplo 10.4. El archivo /etc/ppp/ip-up.d/falcot

# Create the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  ip route add 192.168.0.0/24 dev $1
fi

Ejemplo 10.5. El archivo /etc/ppp/ip-down.d/falcot

# Delete the route to the Falcot network
if [ "$6" = "falcot" ]; then
  # 192.168.0.0/24 is the (remote) Falcot network
  ip route del 192.168.0.0/24 dev $1
fi

10.2.4.2. Configuración del servidor

pptpd es el servidor PPTP para Linux. Necesitará cambiar pocas cosas de su archivo de configuración principal, /etc/pptpd.conf: localip (dirección IP local) y remoteip (dirección IP remota). En el ejemplo a continuación el servidor PPTP siempre utiliza la dirección 192.168.0.199 y los clientes PPTP reciben una dirección IP desde 192.168.0.200 a 192.168.0.250.

Ejemplo 10.6. El archivo /etc/pptpd.conf

# ETIQUETA: speed
#
#       Especifica la velocidad a la que se comunica el demonio PPP.
#
speed 115200

# ETIQUETA: option
#
#       Especifica la ubicación del archivo de opciones PPP
#       De forma predeterminada, se lo busca en «/etc/ppp/options»
#
option /etc/ppp/pptpd-options

# ETIQUETA: debug
#
#       Activa (más) depuración al registro del sistema
#
# debug

# ETIQUETA: localip
# ETIQUETA: remoteip
#
#       Especifica los rangos de direcciones IP local y remoto
#
#       Puede especificar direcciones IP individuales separadas por coma o
#       rangos o ambos. Por ejemplo:
#
#               192.168.0.234,192.168.0.245-249,192.168.0.254
#
#       RESTRICCIONES IMPORTANTES:
#
#       1. No se permiten espacios entre las comas o en las direcciones.
#
#       2. Si provee más direcciones IP que MAX_CONNECTIONS, comenzará al
#          principio de la lista y continuará hasta que obtenga
#          MAX_CONNECTIONS direcciones IPs. De lo contrario será ignorado.
#
#       3. ¡Sin atajos en los rangos! Es decir que 234-8 no significa 234
#          a 238, para esto debe tipear 234-238.
#
#       4. Está bien si provee sólo una IP local - se configurarán todas 
#          las IPs locales como la provista. DEBE proveer al menos una IP
#          remota para cada cliente simultáneo.
#
#localip 192.168.0.234-238,192.168.0.245
#remoteip 192.168.1.234-238,192.168.1.245
#localip 10.0.1.1
#remoteip 10.0.1.2-100
localip 192.168.0.199
remoteip 192.168.0.200-250
La configuración PPP utilizada por el servidor PPTP también necesita algunos cambios en el archivo /etc/ppp/pptpd-options. Los parámetros importantes son el nombre del servidor (pptp), el nombre del dominio (falcot.com y la dirección IP para los servidores DNS y WINS.

Ejemplo 10.7. El archivo /etc/ppp/pptpd-options

## activar la depuración de pppd en el registro del sistema
#debug

## modifique «servername» a lo que sea que especificó como su nombre de servidor en chap-secrets
name pptp
## modifique el nombre del dominio a su dominio local
domain falcot.com

## Estos son valores predeterminados razonables para clientes WinXXXX
## para las configuraciones relacionadas con seguridad
# El paquete pppd de Debian ahora es compatible tanto con MSCHAP como con MPPE, actívelos aquí.
# ¡Necesita tener también el módulo de núcleo para MPPE!
auth
require-chap
require-mschap
require-mschap-v2
require-mppe-128

## Complete con sus direcciones
ms-dns 192.168.0.1
ms-wins 192.168.0.1

## Complete con su máscara de red
netmask 255.255.255.0

## Algunos valores predeterminados
nodefaultroute
proxyarp
lock
El último paso consiste en registrar el usuario vpn (y su contraseña asociada) en el archivo /etc/ppp/chap-secrets. A diferencia de otras instancias en las que un asterisco («*») funcionaría, aquí debe proveer explícitamente el nombre del servidor. Lo que es más, los clientes PPTP Windows se identifican a sí mismo en la forma DOMINIO\\USUARIO en lugar de sólo proveer un nombre de usuario. Esto explica porqué el archivo también menciona el usuario FALCOT\\vpn. También es posible especificar una dirección IP individual para los usuarios; un asterisco en este campo especifica que debe utilizar direcciones dinámicas.

Ejemplo 10.8. El archivo /etc/ppp/chap-secrets

# Secretos para autenticación utilizando CHAP
# cliente       servidor secreto     dirección IP
vpn             pptp     f@Lc3au     *
FALCOT\\vpn     pptp     f@Lc3au     *