Un uso muy clásico de usar una raspberry es configurarla como VPN, prácticamente cualquier modelo da un rendimiento aceptable, siempre y cuando sea para uso personal y no requiera una gran transferencia de datos, en este caso se va a dar un ejemplo con una Raspberry Pi Model B, una de las primeras que salió al mercado que tiene solo 256MB (sí, con M) de RAM y una tarjeta SD (sí, no es micro) de 8GB.
Primero como siempre actualizar el sistema, en este caso como la fundación Raspberry son muy retrocompatibles (algo que no se agradece lo suficiente) vamos a usar la última distribución disponible Bookworm.
Se recomienda esta optimización.
NoIP
Primero vamos a crear un DNS dinámico de esta forma aunque nuestra dirección IP pública cambie siempre podremos alcanzar al servidor VPN si nos estamos conectando desde el exterior, hay varios proveedores y en este caso vamos a usar NoIP.
Lo primero será crear una cuenta, gratuitamente se dan hasta 3 dominios, cada mes hay que confirmar que estamos usando el servicio, poca molestia por el servicio gratuito.
Después de crear una cuenta tendremos que usar el cliente NoIP este cliente sirve para actualizar dinámicamente la dirección IP con el servidor NoIP, esto es necesario porque si el ISP cambia la IP del router NoIP no lo sabrá a menos que se lo notifiquemos.
NoIP tiene una guia detallada de como instalar el cliente aquí.
En este caso vamos a usar la compilación manual por el simple hecho que en ciertas Raspberry podemos obtener el error Segmentation fault un equivalente al BSOD de Windows.
Las instrucciones para compilar desde fuente también se comentan en el propio documento, esta es una guía de ejemplo:
Vamos a crear una carpeta para almacenar el código y los binarios:
mkdir noip
cd noip
Ahora descargar los fuentes (revisar esta dirección si no descarga puede haber una versión nueva):
wget https://dmej8g5cpdyqd.cloudfront.net/downloads/noip-duc_3.1.0.tar.gz
Extraer los fuentes y posicionarnos en la carpeta:
tar xf noip-duc_3.1.0.tar.gz
cd noip-duc_3.1.0
Necesitamos Rust para poder compilar así que lo instalamos, la instalación dura un poco pero la compilación es muy muy larga, así que usamos screen para que no se pare:
Instalamos Rust primero:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Se recomienda aumentar la memoria swap, al menos a 512MB, esto está explicado aquí, sino se corre el riesgo (altamente probable) de que la Raspberry se quede colgada en el último paso, también se recomienda configurar zswap.
Y ahora lanzamos la compilación, primero recargamos el shell como nos indica Rust y luego el comando propio de Rust para la compilación.
. "$HOME/.cargo/env"
cargo build --release
Ahora solo queda configurar el binario que tendremos en /target/release para que se inicie al arrancar, así que lo configuramos como un servicio usando systemd.
Primero copiamos el binario que tenemos en /target/release a la carpeta /usr/bin
sudo cp target/release/noip-duc /usr/bin/
Ahora creamos un fichero en /etc/default/
sudo nano /etc/default/noip-duc
Vamos a añadir en este fichero la configuración, -la configuración completa está en la ayuda-, estamos usando el usuario y grupo de pi para arrancar el servicio por comodidad (que no seguridad).
NOIP_USERNAME=Raspberry
NOIP_PASSWORD=drN01p
NOIP_DAEMON_USER=pi
NOIP_DAEMON_GROUP=pi
NOIP_DAEMON_PID_FILE=/var/run/noip.pid
NOIP_HOSTNAMES=uno.ddns.net,dos.ddns.net
El parámetro NOIP_HOSTNAMES puede ser tanto una lista de hosts como un grupo que se puede crear para actualizar todos los hosts en bloque, la creación de un grupo se hace desde el portal de noip.
Ahora creamos un fichero noip.service in /etc/systemd/system:
sudo nano /etc/systemd/system/noip.service
y vamos a poner lo siguiente (el contenido también está en la carpeta debian):
[Unit]
Description=No-IP Dynamic Update Client
After=network.target auditd.service
[Service]
EnvironmentFile=/etc/default/noip-duc
ExecStart=/usr/bin/noip-duc
Restart=on-failure
Type=simple
[Install]
WantedBy=multi-user.target
Ahora recargamos los servicios:
sudo systemctl daemon-reload
Ahora vamos a hacer que el servicio se inicie al arrancar:
sudo systemctl enable noip.service
Finalmente vamos a arrancarlo manualmente a ver si funciona todo bien.
sudo systemctl start noip.service
Y si queremos saber el estado en el que está usamos:
sudo systemctl status noip.service
PiVPN
Vamos a usar PiVPN como herramienta software para la instalación, bastante sencilla de usar, primero la instalación:
curl -L https://install.pivpn.io | bash
Aparecerá un instalador que hará algunas preguntas:
PiVPN Automated Installer es un mensaje informativo, OK para continuar.
Static IP Needed otro mensaje informativo, OK para continuar.
IPv6 leak elegimos OK, es para que el cliente use el tunel y evitar que su dirección IPv6 se filtre a los servidores, esto no implica que hay que realizar ninguna configuración adicional relacionada con IPv6.
DHCP Reservation para usar la dirección IP del servidor DHCP que tengamos en la red, es verdad que esto es poco habitual, generalmente los servidores suelen tener una IP estática, así que indicamos No.
Static IP Address: si ya tenemos una IP asignada por un servidor DHCP podemos usar la que indica sino pulsamos No y en la siguiente pantalla IPv4 address indicamos la IP y máscara de red, después en la pantalla IPv4 gateway (router) indicamos la IP del router.
Local Users es un mensaje informativo, OK para continuar.
Choose A User sirve para indicar que usuario ejecutará el servicio, el usuario por defecto pi es una buena opción, lo normal es que en un servidor VPN no existan cuentas de usuario.
Installation Mode (1) seleccionamos OpenVPN, la siguiente opción marcamos No para poder usar el protocolo UDP, más rápido en este caso.
Installation Mode (2) usamos UDP por defecto, que en este caso da mejor rendimiento. La opción custom search domain es para indicar si en las peticiones DNS del cliente hay que adjuntar este nombre de dominio, lo normal es que no sea el caso. Seleccionamos No en esta pantalla.
Default openvpn Port el puerto que usará OpenVPN, por defecto es el 1194 (¡UDP!) importante recordarlo para configurarlo en un firewall o router.
Confirm Custom Port Number la simple confirmación de que estamos de acuerdo con el número de puerto.
DNS Provider aquí podemos elegir uno externo como Google o CloudFare, o podemos usar el propio servidor PiVPN-is-local-DNS si también es servidor DNS (algo poco habitual y recomendable), con la opción Custom podemos elegir otro, esto lo veremos más adelante pero para una configuración estándar las dos primeras opciones son correctas.
Public IP or DNS aquí a no ser que tengamos una IP pública que no cambie (no suele ser así) elegiremos DNS Entry e indicaremos un nombre de dominio como el que hemos configurado anteriormente.
Confirm DNS Name simple confirmación que el nombre elegido es correcto.
Server information seleccionamos OK para poder generar la clave HMAC, necesaria para la autenticación TLS de OpenVPN.
Unattended Upgrades seleccionamos OK de esta forma OpenVPN se actualizará automáticamente con parches, seleccionamos Yes.
Installation Complete! si todo ha ido bien llegaremos aquí, presionamos OK para poder reiniciar y confirmamos el reinicio.
Después de este paso podemos actualizar la Raspberry y después reiniciar.
sudo apt-get -y update && sudo apt-get -y upgrade
Optimizaciones
A continuación algunas mejoras de rendimiento para una Raspberry Pi 1.
Deshabilitamos algunos servicios del arranque:
# Deshabilitamos el servicio de modem
sudo systemctl disable ModemManager.service
# Deshabilitamos el servicio Avahi
sudo systemctl disable avahi-daemon.service
# Deshabilitamos triggerhappy
sudo systemctl disable triggerhappy.service
Ajustamos el tamaño de los buffers de red en /etc/sysctl.conf añadimos estas líneas
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216
net.core.netdev_max_backlog = 2000
Y recargamos los parámetros con:
sudo sysctl -p
Ahora vamos a cambiar algunos valores de OpenVPN, para esto editamos el fichero /etc/openvpn/server.conf
#Bajamos el cifrado a 128 para reducir carga en CPU
cipher AES-128-CBC
#Optimizar TUN/TAP/UDP y escrituras I/O
fast-io
#Cambiamos tamaño de buffer en cliente y servidor
sndbuf 524288
rcvbuf 524288
#Tamaño de la longitud de la cola, mismo valor que net.core.netdev_max_backlog
txqueuelen 2000
Crear clientes
Ahora solo queda crear los clientes, OpenVPN tiene aplicación cliente para prácticamente todos los sistemas, IOS, Android, Windows, Linux…. así que la opción preferida es crear una por dispositivo que vayamos a usar.
Para crear un cliente solamente tenemos que usar este comando:
pivpn add
Simplemente rellenamos las preguntas con nombre del certificado, contraseña y duración que tiene que estar entre 1 y 3650 días.
Por defecto el certificado lo creará en la carpeta /home/pi/ovpns lo recomendable es sacarlo de aquí y llevarlo al dispositivo destino usando el comando scp, por ejemplo:
scp pi@192.168.1.2:/home/pi/ovpns/client.ovpn .
Donde 192.168.128.1 es la ip del servidor y /home/pi/ovpns/client.ovpn es la ruta al certificado.
Si quisiéramos revocar un certificado, ya sea para que ese cliente no se pueda conectar o para cambiar la contraseña tendríamos que hacer.
pivpn -r client
Done client es el nombre del cliente que queremos revocar, es decir el mismo nombre que usamos al crearlo. Después de hacer esto solo tenemos que volver a crearlo usando pivpn add. Y si queremos saber que clientes están instalados podemos usar pivpn -l
Referencias
https://www.industrialshields.com/es_ES/blog/raspberry-pi-para-la-industria-26/configurar-un-servidor-vpn-en-una-raspberry-pi-566
https://linuxblog.io/improving-openvpn-performance-and-throughput