Dim - Continuado

Cómo guardar las películas en otra máquina como un NAS, de una manera segura y privada

Vamos a configurar NFS para permitir la máquina de Dim acceder las películas, que están guardadas en otro servidor, y mantenerlas sincronizadas. Para eso, vamos a crear un túnel de wireguard, para prevenir que otros modifiquen las películas, y asegurarse que todas las comunicaciones estén cifradas.

Mucha gente tiene un servidor NAS en el que puede guardar archivos y películas. Muchos pueden no tener la funcionalidad de compilar y correr Dim, o puede que no quieran correr otros programas en él.

Afortunadamente, se puede compartir un directorio por el internet usando NFS. NFS es un sistema de archivos de la red, y está incluido en el kérnel de Linux. Hay clientes de Windows y MacOS para el protocolo, y se puede usar usando Kubernetes y Docker Swarm.

Por qué crear un túnel de Wireguard?

El problema de NFS es que la configuración por defecto, tiene el sistema de autorización usando un simple IP, y por eso es muy fácil de engañar. Ademas, no está cifrado, por lo que es fácil de hackear. Por eso podemos crear un túnel usando Wireguard, que solo permite la máquina con la clave pública adecuada conectarse al directorio NFS.

Wireguard es un protocolo de VPN, también incluido en el kérnel de Linux. Hay clientes para Android, OpenWRT, MacOS y Windows.

NFS permite restringir el acceso a un directorio de la red a solo un IP, y Wireguard permite dar un IP específico, en un subnet distincto, a clientes que se autorizan usando sus claves.

Wireguard

El túnel de Wireguard corre en un subnet distinto al IP de los servidores. Por ejemplo, el servidor puede tener un IP de 192.168.1.10, pero tener otro IP distinto de Wireguard, en otro subnet, como 10.1.0.1.

NFS

Para el servidor/NAS de NFS, que contiene las películas

sudo apt install nfs-kernel-server

Tenemos que configurar el servicio de NFS para solo escuchar en un IP (el del túnel de Wireguard). Además, lo vamos a configurar para usar solo el protocolo más nuevo NFSv4.

vamos a modificar el archivo /etc/default/nfs-kernel-server

nano /etc/default/nfs-kernel-server

Y encontramos y agregamos las siguientes líneas:

RPCNFSDOPTS="-N 2 -N 3"

para forzarlo usar solo el protocolo versión 4.

RPCMOUNTDOPTS="--manage-gids -N 2 -N 3 -H 10.1.0.1"

para forzarlo usar el IP del túnel.

Vamos a abrir el archivo /etc/nfs.conf

nano /etc/nfs.conf

y agregamos lo siguiente, para hacer que el servicio de NFS solo escuche en el IP del túnel.

[nfsd] host=10.1.0.1

Tenemos que averiguar dónde se guardan las películas.

Modificamos el archivo de exports (nano /etc/exports) para contener lo siguiente:

/la/ruta/al/directorio/de/las/películas (el IP en el túnel del cliente)/32(rw,sync,no_subtree_check,no_root_squash)

Por ejemplo, como yo tengo las películas guardadas en mi nube de Nextcloud, mi configuración se ve así:

/var/nube/usuario/películas 10.1.0.2/32(rw,sync,no_subtree_check,no_root_squash)

10.1.0.2/32 es el IP del cliente, dentro del túnel

podemos exportar el directorio:

sudo exportfs -a

NFSv4 no necesita unos servicios, por lo que los podemos desactivar:

sudo systemctl mask rpcbind.service
sudo systemctl mask rpcbind.socket

y podemos empezar el servicio de NFS: sudo systemctl enable --now nfs-kernel-server.service

El Cliente:

sudo apt install nfs-common

Primero, vamos a comprobar que la autenticación trabaja. O sea, queremos comprobar que no se puede conectar al NFS sin usar Wireguard. Para eso, podemos ver el error que da cuando tratamos de conectar un cliente que no está permitido al servidor NFS.

mkdir /mnt/NFS
sudo mount -t nfs -o vers=4.2 (el IP *normal* del servidor/NAS):/la/ruta/de/las/películas /mnt/NFS

Si todo trabaja bien, queremos un error como estos: mount.nfs: Operación no permitida o mount.nfs: accesso denegado...

Wireguard

Instalando Wireguard en el servidor y el cliente (correr esto en ambos):

sudo apt install wireguard
sudo modprobe wireguard

Generar las claves:

cd /etc/wireguard
umask 077
wg genkey > claveprivada
wg pubkey < claveprivada > clavepublica

Servidor

creamos y modificamos el archivo para wireguard: nano /etc/wireguard/wgNFS.conf

y agregamos lo siguiente:

[Interface]
Address = 10.1.0.1/24 #El IP del túnel del servidor/NAS
ListenPort = 51820
PrivateKey = LA_CLAVE_PRIVADA_DEL_SERVIDOR

# cliente1
[Peer]
PublicKey = LA_CLAVE_PÚBLICA_DEL_CLIENTE
AllowedIPs = 10.1.0.2/32 #El IP del túnel del cliente

Se puede averiguar las claves usando cat claveprivada y cat clavepublica

Cliente

Como arriba, vamos a crear y modificar el archivo de Wireguard nano /etc/wireguard/wgNFS.conf

y agregamos lo siguiente:

[Interface]
Address = 10.1.0.2/24
PrivateKey = CLAVE_PRIVADA_DEL_CLIENTE

[Peer]
PublicKey = LA_CLAVE_PÚBLICA_DEL_SERVIDOR
Endpoint = El IP real del servidor:51820
AllowedIPs = 10.1.0.0/24

Podemos empezar el túnel de Wireguard usando: sudo wg-quick up wgNFS en el servidor, y luego lo mismo en el cliente.

Si todo funciona, podemos comprobarlo haciendo: ping 10.1.0.1 y ping 10.1.0.2

Montar el directorio a través de Wireguard

En el cliente podemos otra vez tratar de correr sudo mount -t nfs -o vers=4.2 (el IP *normal* del servidor/NAS):/la/ruta/de/las/películas /mnt/NFS y esta vez debe funcionar. Podemos mirar los archivos desde el cliente usando ls /mnt/NFS

Haciéndolo permanente:

Si usan systemd, pueden hacer lo siguiente:

# empezarlo automáticamente cuando se arranca el sistema
sudo systemctl enable wg-quick@wgNFS.service
sudo systemctl daemon-reload

# parar a WireGuard
sudo wg-quick down wgNFS

# Empezarlo usando systemd
sudo systemctl start wg-quick@wgNFS.service

sudo umount -f /mnt/NFS

editamos a fstab para montarlo automáticamente, y agregamos lo siguiente:

10.1.0.1:/el/directorio/de/las/películas   /un/directorio/en/el/cliente    nfs vers=4.2,_netdev,noauto,x-systemd.automount,x-systemd.requires=wg-quick@wgNFS.service

y recargamos los servicios

sudo systemctl daemon-reload 
sudo systemctl restart remote-fs.target

Si todo ha funcionado, en /un/directorio/en/el/cliente que especificamos arriba, deberían estar los archivos del servidor.

UFW

Si usan un programa de firewall como UFW, hay que dejar pasar el puerto 2049, utilizado por NFS: En el servidor, se puede correr: sudo ufw allow from (ip de wireguard) to any port 2049

,

,

,

,

,

Runit

Si usan runit:

pueden usar el siguiente archivo run para montar los directorios:

#!/bin/sh
set -e
exec 2>&1
# Load user defined variables
[ -r conf ] && . ./conf

# Ensure the network manager is running

# If it's running or not in used - rc.local - discover default gateway
if [ -z "$GATEWAY" ]; then
    set -- $(ip route show | grep default)
    GATEWAY="$3"
fi

ping -W 1 -c 1 $GATEWAY > /dev/null 2>&1 || exit 1

# Network is up and running so now mount network filesystems from fstab
mount -a -t "$NETWORK_FS" || exit 1
mount -a -O _netdev || exit 1

# Then wait to behave like the service is up
exec chpst -b netmount sleep 100000

El archivo conf:

# Configuration for netmount service

NETWORK_FS="nfs4"

Y el archivo stop

#!/bin/sh
# Load user defined variables
[ -r conf ] && . ./conf

# Don't do anything if ./run didn't exit properly
[ "$1" -eq 1 ] && exit 0

# Simply umount network filesystems
umount -a -f -t $NETWORK_FS > /dev/null 2>&1
ret=$?
[ $ret -ne 0 ] && umount -a -f -l -t $NETWORK_FS > /dev/null 2>&1

umount -a -f -O _netdev > /dev/null 2>&1
ret=$?
[ $ret -ne 0 ] && umount -a -f -l -O _netdev > /dev/null 2>&1
#chpst -b netmount pause

Para wireguard, no me funcionaba el servicio de runit, por eso puse en cron (usando crontab -e)

@reboot wg-quick up wgNFS