Cómo instalar OpenConnect VPN Server en Ubuntu 22.04

OpenConnect VPN, también conocida como ocserv, es una solución VPN gratuita de código abierto con prestaciones y características de nivel empresarial. Se basa en el protocolo Cisco AnyConnect VPN, ampliamente utilizado en el sector empresarial. En este tutorial, aprenderás a instalar el servidor VPN OpenConnect en una máquina Ubuntu 22.04. También aprenderás a utilizar un cliente OpenConnect para conectarte al servidor.

Requisitos previos

  • Un servidor con Ubuntu 22.04.
  • Un usuario no root con privilegios sudo.
  • Un nombre de dominio completo (FQDN) como vpn.example.com.
  • Asegúrate de que todo está actualizado.
    $ sudo apt update
    $ sudo apt upgrade
    
  • Pocos paquetes que necesite tu sistema.
    $ sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y
    

    Puede que algunos de estos paquetes ya estén instalados en tu sistema.

Paso 1 – Configurar el Cortafuegos

El primer paso es configurar el cortafuegos. Ubuntu viene con ufw (Uncomplicated Firewall) por defecto.

Comprueba si el cortafuegos se está ejecutando.

$ sudo ufw status

Deberías obtener la siguiente salida.

Status: inactive

Permite el puerto SSH para que el cortafuegos no rompa la conexión actual al activarlo.

$ sudo ufw allow OpenSSH

Permite también los puertos HTTP y HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Habilita el cortafuegos

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Comprueba de nuevo el estado del cortafuegos.

$ sudo ufw status

Deberías ver un resultado similar.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Paso 2 – Instala Git

Paso 3 – Instala OpenConnect

Ubuntu 22.04 incluye una versión antigua (1.1.3) de OpenConnect. Si estás satisfecho con ella, puedes instalarla utilizando el siguiente comando.

$ sudo apt install ocserv

Sin embargo, para este tutorial, instalaremos la última versión (1.1.6) de OpenConnect. Para ello, tendremos que compilarla desde el código fuente.

Instala las dependencias necesarias para compilar el código fuente.

$ sudo apt install -y libgnutls28-dev libev-dev libpam0g-dev liblz4-dev libseccomp-dev \
	libreadline-dev libnl-route-3-dev libkrb5-dev libradcli-dev \
	libcurl4-gnutls-dev libcjose-dev libjansson-dev libprotobuf-c-dev \
	libtalloc-dev libhttp-parser-dev protobuf-c-compiler gperf \
	nuttcp lcov libuid-wrapper libpam-wrapper libnss-wrapper \
	libsocket-wrapper gss-ntlmssp haproxy iputils-ping freeradius \
	gawk gnutls-bin iproute2 yajl-tools tcpdump autoconf automake

Clona el repositorio Git ocserv.

$ git clone https://gitlab.com/openconnect/ocserv.git

Cambia al directorio clonado.

$ cd ocserv

Genera los scripts de configuración.

$ autoreconf -fvi

Compila el código fuente. Ignora las advertencias de obsoleto.

$ ./configure && make

Instala ocserv.

$ sudo make install

Los archivos se instalarán en los directorios /usr/local/bin y /usr/local/sbin. Copia el archivo de servicio systemd.

$ sudo cp doc/systemd/standalone/ocserv.service /etc/systemd/system/ocserv.service

Abre el archivo de servicio para editarlo.

$ sudo nano /etc/systemd/system/ocserv.service

Cambia la ruta al binario ocserv en la siguiente línea

$ ExecStart=/usr/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf

por la siguiente.

$ ExecStart=/usr/local/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te solicite.

Vuelve a cargar el demonio del sistema.

$ sudo systemctl daemon-reload

Paso 4 – Generar certificados SSL

Necesitamos instalar Certbot para generar el certificado SSL. Puedes instalar Certbot utilizando el repositorio de Ubuntu u obtener la última versión utilizando la herramienta Snapd. Nosotros utilizaremos la versión Snapd.

Ubuntu 22.04 viene con Snapd instalado por defecto. Ejecuta los siguientes comandos para asegurarte de que tu versión de Snapd está actualizada.

$ sudo snap install core && sudo snap refresh core

Instala Certbot.

$ sudo snap install --classic certbot

Utiliza el siguiente comando para asegurarte de que se puede ejecutar el comando Certbot creando un enlace simbólico al directorio /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Existen dos posibilidades a la hora de generar un certificado SSL. Si no tienes un servidor web ejecutándose en tu sistema, puedes utilizar el método autónomo para generar el certificado. Ejecuta el siguiente comando para crear el certificado utilizando el plugin independiente para Certbot.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d vpn.example.com

El comando anterior descargará un certificado en el directorio /etc/letsencrypt/live/vpn.example.com de tu servidor.

A continuación, si tienes un servidor ejecutándose en tu sistema, puedes utilizar el plugin de webroot o los plugins de Nginx o Apache si los estás utilizando. En el caso de los servidores Nginx o Apache, basta con que ejecutes el siguiente comando.

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d vpn.example.com

o

$ sudo certbot certonly --apache --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d vpn.example.com

Si tienes un servidor diferente, entonces tendremos que utilizar el plugin webroot. Para ello, crea el directorio raíz web.

$ sudo mkdir -p /var/www/ocserv

Establece el servidor como propietario del directorio raíz web. En nuestro caso, utilizaremos www-data como usuario del servidor.

$ sudo chown www-data:www-data /var/www/ocserv -R

A continuación, configura tu servidor para que sirva el dominio vpn.example.com en el directorio /var/www/ocserv. Reinicia el servidor. A continuación, genera el certificado utilizando el siguiente comando.

$ sudo certbot certonly --webroot --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d vpn.example.com

Comprueba el servicio programador de renovación de Certbot.

$ sudo systemctl list-timers

Encontrarás snap.certbot.renew.service como uno de los servicios programados para ejecutarse.

NEXT                        LEFT          LAST                        PASSED        UNIT                       ACTIVATES
Wed 2023-04-19 10:31:47 UTC 2h 55min left Wed 2023-04-19 03:31:58 UTC 4h 3min ago   ua-timer.timer             ua-timer.service
Wed 2023-04-19 12:02:42 UTC 4h 26min left Wed 2023-04-19 03:19:20 UTC 4h 16min ago  motd-news.timer            motd-news.service
Wed 2023-04-19 18:19:56 UTC 10h left      Wed 2023-04-19 07:19:52 UTC 16min ago     apt-daily.timer            apt-daily.service
Wed 2023-04-19 22:51:00 UTC 15h left      n/a                         n/a           snap.certbot.renew.timer   snap.certbot.renew.service

Realiza una ejecución en seco del proceso para comprobar si la renovación SSL funciona correctamente.

$ sudo certbot renew --dry-run

Si no ves ningún error, ya está todo listo. Tu certificado se renovará automáticamente.

Paso 5 – Configurar OpenConnect

Si has instalado ocserv mediante APT, el archivo de configuración ya debería estar disponible en la ubicación /etc/ocserv/ocserv.conf. Pero si has creado el paquete desde el código fuente, tendremos que copiar el archivo de configuración.

Crea el directorio para el archivo de configuración.

$ sudo mkdir /etc/ocserv

Copia el archivo de configuración.

$ sudo cp /home/username/ocserv/doc/sample.config /etc/ocserv/ocserv.conf

Abre el archivo para editarlo.

$ sudo nano /etc/ocserv/ocserv.conf

Cambia el valor del parámetro auth por el siguiente. Esto permitirá a los usuarios utilizar cuentas VPN independientes.

auth = "plain[passwd=/etc/ocserv/ocpasswd]"

Por defecto, OpenConnect utiliza los puertos 443 TCP y UDP. Sólo utilizaremos el puerto TCP para la conexión, por lo tanto, desactiva el puerto UDP comentándolo.

tcp-port = 443
#udp-port = 443

Si tienes un servidor web ejecutándose en el puerto 443, cambia el valor del puerto TCP modificando el valor.

tcp-port = 8443

A continuación, busca las variables server-crt y server-key y cambia sus valores como se indica a continuación.

server-cert = /etc/letsencrypt/live/vpn.example.com/fullchain.pem
server-key = /etc/letsencrypt/live/vpn.example.com/privkey.pem

Establece el número máximo de clientes permitidos. El valor por defecto es 16. Establécelo como 0 para ilimitado.

max-clients = 16

Establece el número de dispositivos que un usuario puede utilizar al mismo tiempo. El valor por defecto es 2. Establécelo como 0 para ilimitado.

max-same-clients = 2

Por defecto, OpenConnect envía paquetes keepalive cada 9 horas (32400 segundos). Este valor es demasiado alto. Fíjalo en 60 segundos para reducir la posibilidad de que se interrumpa la conexión VPN.

keepalive = 60

Cambia el valor de try-mtu-discovery a true para activar el descubrimiento de MTU. Puede optimizar el rendimiento de la VPN.

try-mtu-discovery = true

Configura el tiempo que un cliente puede permanecer inactivo antes de ser desconectado descomentando las siguientes variables. Si quieres que el cliente permanezca conectado indefinidamente, déjalas como están.

idle-timeout=1200
mobile-idle-timeout=1800

Establece el nombre de dominio por defecto para la VPN OpenConnect.

default-domain = vpn.example.com

Cambia la configuración IPv4 por defecto para evitar la colisión de direcciones IP. Utilizaremos 10.10.10.0 como valor.

ipv4-network = 10.10.10.0

Descomenta la siguiente línea para tunelizar todas las consultas DNS a través de la VPN.

tunnel-all-dns = true

Cambia el DNS resolver a Google DNS. Añade también la segunda entrada.

dns = 8.8.8.8
dns = 8.8.4.4

Comenta todos los parámetros de ruta añadiendo el símbolo almohadilla (#) delante.

#route = 10.10.10.0/255.255.255.0
#route = 192.168.0.0/255.255.0.0
#route = fef4:db8:1000:1001::/64
#route = default

# Subsets of the routes above that will not be routed by
# the server.

#no-route = 192.168.5.0/255.255.255.0

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Paso 6 – Iniciar el servidor OpenConnect

Inicia el servidor VPN OpenConnect.

$ sudo systemctl start ocserv

Comprueba el estado del servicio.

$ sudo systemctl status ocserv

Obtendrás un resultado similar.

? ocserv.service - OpenConnect SSL VPN server
     Loaded: loaded (/etc/systemd/system/ocserv.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-04-20 08:52:18 UTC; 2s ago
       Docs: man:ocserv(8)
   Main PID: 19965 (ocserv-main)
      Tasks: 2 (limit: 1026)
     Memory: 1.4M
        CPU: 9ms
     CGroup: /system.slice/ocserv.service
             ??19965 ocserv-main  
             ??19966 ocserv-sm 

Apr 20 08:52:18 openconnect ocserv[19965]: note: skipping 'pid-file' config option
Apr 20 08:52:18 openconnect ocserv[19965]: note: vhost:default: setting 'plain' as primary authentication method
Apr 20 08:52:18 openconnect ocserv[19965]: error connecting to sec-mod socket '/var/run/ocserv-socket.a4413bc9': No such file or directory
Apr 20 08:52:18 openconnect ocserv[19965]: note: setting 'file' as supplemental config option
Apr 20 08:52:18 openconnect ocserv[19965]: listening (TCP) on 0.0.0.0:443...
Apr 20 08:52:18 openconnect ocserv[19965]: listening (TCP) on [::]:443...
Apr 20 08:52:18 openconnect ocserv[19966]: ocserv[19966]: sec-mod: reading supplemental config from files
Apr 20 08:52:18 openconnect ocserv[19966]: sec-mod: reading supplemental config from files
Apr 20 08:52:18 openconnect ocserv[19966]: ocserv[19966]: sec-mod: sec-mod initialized (socket: /var/run/ocserv-socket.a4413bc9.0)
Apr 20 08:52:18 openconnect ocserv[19966]: sec-mod: sec-mod initialized (socket: /var/run/ocserv-socket.a4413bc9.0)

Si ves el error relativo a la conexión a sec-mod socket, ignóralo. Es normal. Inicializará el archivo si no lo encuentra.

Paso 7 – Crear cuentas VPN

Puedes crear cuentas VPN utilizando la utilidad ocpasswd. Ejecuta el siguiente comando para crear una nueva cuenta VPN.

$ sudo ocpasswd -c /etc/ocserv/ocpasswd username
Enter password:
Re-enter password:

La contraseña se guardará en el archivo /etc/ocserv/ocpasswd. Para restablecer la contraseña de username, vuelve a ejecutar el comando anterior. Ejecuta el comando anterior con un usuario diferente para crear otra cuenta.

Paso 8 – Activar el Reenvío de IP

Para que el servidor VPN enrute los paquetes entre el cliente e Internet, debes habilitar el reenvío de IP ejecutando el siguiente comando.

$ echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/60-custom.conf

Ejecuta los siguientes comandos para habilitar el algoritmo TCP BBR para aumentar la velocidad TCP.

$ echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.d/60-custom.conf
$ echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.d/60-custom.conf

Haz que los cambios sean permanentes mediante el siguiente comando.

$ sudo sysctl -p /etc/sysctl.d/60-custom.conf

Paso 9 – Configurar el Enmascaramiento IP

El siguiente paso es configurar el enmascaramiento de IP en el cortafuegos para que el servidor VPN pueda funcionar como un router virtual para los clientes. Busca el nombre de la interfaz de red principal del servidor.

$ ip addr

Obtendrás un resultado similar.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
    link/ether 56:00:04:67:7e:79 brd ff:ff:ff:ff:ff:ff
    inet 95.179.138.135/23 metric 100 brd 95.179.139.255 scope global dynamic enp1s0
       valid_lft 66999sec preferred_lft 66999sec
    inet6 2a05:f480:1400:2381:5400:4ff:fe67:7e79/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591657sec preferred_lft 604457sec
    inet6 fe80::5400:4ff:fe67:7e79/64 scope link
       valid_lft forever preferred_lft forever

En nuestro caso, enp1s0 es el nombre de la interfaz. Añade el comando iptables en un archivo de configuración UFW abriéndolo para editarlo.

$ sudo nano /etc/ufw/before.rules

Añade las siguientes líneas al final del archivo. Sustituye enp1s0 en el código por tu interfaz de red.

# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.10.10.0/24 -o enp1s0 -j MASQUERADE

# End each table with the 'COMMIT' line or these rules won't be processed
COMMIT

Busca las siguientes líneas en el archivo.

# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT

Pega las siguientes líneas a continuación.

# allow forwarding for trusted network
-A ufw-before-forward -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward -d 10.10.10.0/24 -j ACCEPT

IP Masquerading Code in UFW

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Reinicia el cortafuegos.

$ sudo systemctl restart ufw

Puedes comprobar la regla de Mascarada utilizando el siguiente comando.

$ sudo iptables -t nat -L POSTROUTING

Obtendrás el siguiente resultado.

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.10.10.0/24        anywhere

Paso 10 – Conéctate utilizando el Cliente OpenConnect

Vamos a instalar OpenConnect Client en una máquina Ubuntu 22.04. Ejecuta el siguiente comando para instalar el cliente.

$ sudo apt install openconnect

A continuación, conéctate al servidor VPN utilizando el siguiente comando. La bandera -b hace que el cliente se ejecute en segundo plano una vez establecida la conexión.

$ sudo openconnect -b vpn.example.com:443

Se te pedirá que introduzcas el nombre de usuario y la contraseña de la VPN. Introduce las credenciales creadas en el paso 7.

POST https://vpn.example.com/
Connected to 95.179.138.135:443
SSL negotiation with vpn.example.com
Connected to HTTPS on vpn.example.com with ciphersuite (TLS1.3)-(ECDHE-SECP256R1)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
XML POST enabled
Please enter your username.
Username:navjot
POST https://vpn.example.com/auth
Please enter your password.
Password:
POST https://vpn.example.com/auth

Si la conexión se establece correctamente, verás el siguiente mensaje. DTLS está desactivado porque hemos desactivado el UDP.

Got CONNECT response: HTTP/1.1 200 CONNECTED
CSTP connected. DPD 90, Keepalive 60
No DTLS address
Set up UDP failed; using SSL instead
Configured as 192.168.1.13, with SSL connected and DTLS disabled
Continuing in background; pid 1650

Ejecuta el siguiente comando para detener la conexión.

$ sudo pkill openconnect

Vamos a crear algunos scripts systemd para OpenConnect. El primer script es para que el cliente se conecte automáticamente al iniciar el sistema.

Crea y abre el archivo de servicio para editarlo.

$ sudo nano /etc/systemd/system/openconnect.service

Pega en él el siguiente código.

[Unit]
  Description=OpenConnect VPN Client
  After=network-online.target systemd-resolved.service
  Wants=network-online.target

[Service]
  Type=simple
  ExecStart=/bin/bash -c '/bin/echo -n password | /usr/sbin/openconnect vpn.example.com -u username --passwd-on-stdin'
  KillSignal=SIGINT
  Restart=always
  RestartSec=2

[Install]
  WantedBy=multi-user.target

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Habilita el servicio.

$ sudo systemctl enable openconnect.service

Inicia el servicio.

$ sudo systemctl start openconnect.service

Para reiniciar tu conexión VPN automáticamente cuando tu PC se reanude desde el estado de suspensión, necesitas crear otro script systemd.

Crea y abre el script de reinicio para editarlo.

$ sudo nano /etc/systemd/system/openconnect-restart.service

Pega en él el siguiente código.

[Unit]
Description=Restart OpenConnect client when resuming from suspend
After=suspend.target

[Service]
Type=simple
ExecStart=/bin/systemctl --no-block restart openconnect.service

[Install]
WantedBy=suspend.target

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Habilita el servicio.

$ sudo systemctl enable openconnect-restart.service

También podemos crear un servicio para reiniciar la conexión VPN automáticamente cuando se caiga. Crea y abre el servicio de comprobación de VPN para editarlo.

$ sudo nano /etc/systemd/system/openconnect-check.service

Pega en él el siguiente código.

[Unit]
Description=OpenConnect VPN Connectivity Checker
After=openconnect.service

[Service]
Type=simple
ExecStart=/bin/bash -c 'for ((; ; )) do (ping -c9 10.10.10.1 || systemctl restart openconnect) done'

[Install]
WantedBy=multi-user.target

Guarda el archivo pulsando Ctrl + X e introduciendo Y cuando se te pida.

Habilita e inicia el servicio.

$ sudo systemctl enable enable openconnect-check.service --now

Esto ejecutará siempre el comando ping para comprobar la conexión VPN. Si se cae, reiniciará automáticamente OpenConnect.

Si quieres, puedes descargar los Clientes GUI de OpenConnect. Sin embargo, hace tiempo que no se actualizan. Si quieres un cliente GUI actualizado, puedes visitar el repositorio GitLab de OpenConnect GUI y compilarlo tú mismo.

Conclusión

Esto completa nuestro tutorial sobre la instalación de un servidor VPN OpenConnect en un servidor Ubuntu 22.04 y el uso del cliente de línea de comandos para conectarse a él. Si tienes alguna pregunta, publícala en los comentarios a continuación.

También te podría gustar...