Configurar Cifrado NFS sobre TLS
El tráfico NFS está cifrado. Autenticación sigue siendo AUTH_SYS (UID/GID)
NFS sobre TLS proporciona cifrado en tránsito (cifrado del tráfico RPC/TLS) sin necesidad de Kerberos. Utiliza certificados X.509 (pueden ser auto-firmados para entornos locales).
Preparación (en el servidor y cliente)
Resolución DNS correcta (tormenta.local.com -> 192.168.88.160)
El kernel en FreeBSD 14.3 soporta KTLS (está en Generic desde FreeBSD 13+)
En ambos dos editar /etc/rc.conf para habilitar los daemons TLS:
tlsservd_enable="YES" # Demonio servidor TLS (necesario para mounts TLS)
tlsclntd_enable="YES" # Demonio cliente TLS
En el servidor tormenta.local.com - 192.168.88.160
Instalar y configurar Unbound en el servidor
https://gnulinuxcodigo.blogspot.com/2025/12/unbound-dns-local-en-freebsd-143.html
Generación y Colocación de Certificados
Generar los certificados y moverlos a la carpeta que tlsservd exige por defecto.
Crear directorio temporal para trabajar
mkdir -p /root/certs-work
cd /root/certs-work
Crear CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/CN=HomeLabRootCA"
Crear Certificado Servidor (tormenta)
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr -subj "/CN=tormenta.local.com"
openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
Crear Certificado Cliente (solaris) - se usará luego
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr -subj "/CN=solaris.local.com"
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt
Instalacion en rutas por defecto del servidor
Crear el directorio
mkdir /etc/rpc.tlsservd
Copiar archivos con los nombres que FreeBSD espera:
cp server.crt /etc/rpc.tlsservd/cert.pem
cp server.key /etc/rpc.tlsservd/certkey.pem
cp ca.crt /etc/rpc.tlsservd/cacert.pem
Crear lista de revocación vacía (necesaria por defecto)
touch /etc/rpc.tlsservd/crl.pem
Permisos estrictos
chmod 700 /etc/rpc.tlsservd
chmod 600 /etc/rpc.tlsservd/certkey.pem
chmod 444 /etc/rpc.tlsservd/cert.pem
chmod 444 /etc/rpc.tlsservd/cacert.pem
En el cliente (solaris.local.com) IP 192.168.88.51
Preparar directorios y certificados
mkdir /etc/rpc.tlsclntd
Copiar los archivos generados en tormenta hacia solaris y renombrarlos
scp tormenta.local.com:/root/certs-work/client.crt /etc/rpc.tlsclntd/cert.pem
scp tormenta.local.com:/root/certs-work/client.key /etc/rpc.tlsclntd/certkey.pem
scp tormenta.local.com:/root/certs-work/ca.crt /etc/rpc.tlsclntd/cacert.pem
Aplicar permisos estrictos
chmod 700 /etc/rpc.tlsclntd
chmod 600 /etc/rpc.tlsclntd/certkey.pem
chmod 444 /etc/rpc.tlsclntd/cert.pem
chmod 444 /etc/rpc.tlsclntd/cacert.pem
chmod 644 /etc/rpc.tlsclntd/crl.pem
client.crt Es el certificado público del cliente. Identifica quién es el cliente.
client.key Es la clave privada del cliente. Nunca debe compartirse. Sirve para firmar la comunicación.
cacert.pem Es el certificado de la Autoridad Certificadora. Sirve para que el cliente verifique que el servidor es confiable.
Es importante saber que cambiar la extensión del archivo no cambia su contenido, pero ayuda al software a entender qué formato esperar.
PEM (Privacy Enhanced Mail): Es el formato estándar de texto (Base64) que empieza con
-----BEGIN CERTIFICATE-----
Verificar que la Clave Privada y el Certificado coinciden
Este es el paso más crítico. Ambos archivos deben tener el mismo "Módulo" (un identificador matemático único). Si los códigos hash que obtienes son idénticos, son pareja.
Ejecuta estos dos comandos:
# Extraer el módulo del certificado público
openssl x509 -noout -modulus -in cert.pem | openssl md5
# Extraer el módulo de la clave privada
openssl rsa -noout -modulus -in certkey.pem | openssl md5
Resultado esperado: Ambos comandos deben devolver exactamente la misma cadena de caracteres (ej. (stdin)= 68b19a0d...). Si son diferentes, esa clave no pertenece a ese certificado.
Verificar que el Certificado fue firmado por la CA
Ahora comprobaremos la cadena de confianza. Queremos confirmar que cert.pem es "hijo" legítimo de cacert.pem. Ejecutando
openssl verify -CAfile cacert.pem cert.pem
cert.pem: OK
Resultado esperado: Deberías ver un mensaje final que diga: cert.pem: OK
Comprobar validez de las fechas
openssl x509 -noout -dates -in cert.pem
notBefore=Dec 9 20:38:11 2025 GMT
notAfter=Dec 7 20:38:11 2035 GMT
Crear lista de revocación vacía (necesaria por defecto)
touch /etc/rpc.tlsservd/crl.pem
Modificar /etc/exports para requerir TLS
Solo la linea V4: puede tener opciones de seguridad.
V4: /nfsv4 -tls
/nfsv4/dellhome -maproot=root -network 192.168.88.0/24
/nfsv4/poolrecovery -maproot=root -network 192.168.88.0/24
/nfsv4/docs -maproot=root -network 192.168.88.0/24
/nfsv4/confsolaris -maproot=root -network 192.168.88.0/24
/nfsv4/conftormenta -maproot=root -network 192.168.88.0/24
Aplicar cambios
service nfsuserd restart
service mountd restart
service nfsd restart
Cliente solaris.local.com (192.168.88.51)
Montar con TLS (temporal)
mount -t nfs -o nfsv4,tls tormenta.local.com:/docs /punto/de/montaje
Permanente (en /etc/fstab)
...
# nfs
tormenta:/poolrecovery /nisc4 nfs rw,nfsv4,tls,noatime,bg 0 0
tormenta:/confsolaris /nics4 nfs rw,nfsv4,tls,noatime,bg 0 0
tormenta:/docs /nids4 nfs rw,nfsv4,tls,noatime,bg 0 0
tormenta:/dellhome /nihs4 nfs ro,nfsv4,tls,noatime,bg 0 0
mount -a
Servidor - configuración de servicios /etc/rc.conf
NFS y RPC
nfs_server_enable="YES"
nfsv4_server_enable="YES"
nfsuserd_enable="YES"
mountd_enable="YES"
TLS demonio (servidor)
sysrc tlsservd_enable="YES"
Habilitar Kernel TLS
sysctl kern.ipc.tls.enable=1
echo 'kern.ipc.tls.enable=1' >> /etc/sysctl.conf
Recomendación: La seguridad debe ser en capas (Defensa en profundidad): Firewall + Restricción de IP NFS + Certificados TLS.
sysrc statd_enable="YES" # Para bloqueo de archivos (opcional pero recomendado)
sysrc lockd_enable="YES # Para bloqueo de archivos
sysrc mountd_flags="-r" # Recarga automatica al compartir datasets
Iniciar servicios
service tlsservd start
service nfsuserd restart
service mountd restart
service nfsd restart
Cliente (solaris.local.com)
Configuración (/etc/rc.conf)
nfs_client_enable="YES"
nfsv4_client_enable="YES"
nfsuserd_enable="YES"
mountd_enable="YES"
# TLS demonio (cliente)
tlsclntd_enable="YES"
Iniciar servicios
service nfsclient start
service nfsuserd start
service mountd start
Habilitar Kernel TLS
sysctl kern.ipc.tls.enable=1
echo 'kern.ipc.tls.enable=1' >> /etc/sysctl.conf
Iniciar cliente
service nfsuserd start
service tlsclntd start
Prueba de montaje
mkdir -p /mnt/docs
mount -t nfs -o nfsv4,tls 192.168.88.160:/docs /mnt/docs
Verificar cifrado
root@solaris:~# nfsstat -m
tormenta:/docs on /nids4
nfsv4,minorversion=2,tcp,resvport,tls,nconnect=1,hard,cto,sec=sys,acdirmin=3,acdirmax=60,acregmin=5,acregmax=60,nametimeo=60,negnametimeo=60,rsize=65536,wsize=65536,readdirsize=65536,readahead=1,wcommitsize=16777216,timeout=120,retrans=2147483647
Debe aparecer tls en las banderas (flags)
nfsstat -m
root@solaris:~# nfsstat -m
tormenta:/poolrecovery on /nisc4
nfsv4,minorversion=2,tcp,resvport,tls,nconnect=1,hard,cto,sec=sys,acdirmin=3,acdirmax=60,acregmin=5,acregmax=60,nametimeo=60,negnametimeo=60,rsize=65536,wsize=65536,readdirsize=65536,readahead=1,wcommitsize=16777216,timeout=120,retrans=2147483647
tormenta:/confsolaris on /nics4
nfsv4,minorversion=2,tcp,resvport,tls,nconnect=1,hard,cto,sec=sys,acdirmin=3,acdirmax=60,acregmin=5,acregmax=60,nametimeo=60,negnametimeo=60,rsize=65536,wsize=65536,readdirsize=65536,readahead=1,wcommitsize=16777216,timeout=120,retrans=2147483647
tormenta:/docs on /nids4
nfsv4,minorversion=2,tcp,resvport,tls,nconnect=1,hard,cto,sec=sys,acdirmin=3,acdirmax=60,acregmin=5,acregmax=60,nametimeo=60,negnametimeo=60,rsize=65536,wsize=65536,readdirsize=65536,readahead=1,wcommitsize=16777216,timeout=120,retrans=2147483647
tormenta:/dellhome on /nihs4
nfsv4,minorversion=2,tcp,resvport,tls,nconnect=1,hard,cto,sec=sys,acdirmin=3,acdirmax=60,acregmin=5,acregmax=60,nametimeo=60,negnametimeo=60,rsize=65536,wsize=65536,readdirsize=65536,readahead=1,wcommitsize=16777216,timeout=120,retrans=2147483647
Regla simple:
tlsservd (TLS Server Daemon): Es para la máquina que OFRECE los archivos (el Servidor). Escucha las peticiones de cifrado entrantes.
tlsclntd (TLS Client Daemon): Es para la máquina que MONTA los archivos (el Cliente). Inicia la petición de cifrado hacia afuera.
Verificar con tcpdump que el tráfico NFS sobre TLS está cifrado
Una vez que el montaje NFS con TLS funciona correctamente, se puede confirmar que el tráfico está realmente cifrado ejecutando tcpdump en el servidor o en el cliente.
Comando básico (en servidor)
tcpdump -i re0 -nn port 2049
O más específico, ver sólo NFS
tcpdump -i re0 -nn port 2049 and host 192.168.88.51
Qué esperar
Si TLS está funcionado correctamente - cifrado activo
Verás paquetes TCP en el puerto 2049
Después del handshake TLS inicial, todo el payload de los paquetes estará cifrado.
...
13:35:28.349050 IP 192.168.88.160.2049 > 192.168.88.51.773: Flags [P.], seq 469255:469785, ack 251188, win 29128, options [nop,nop,TS val 505937474 ecr 417283551], length 530
13:35:28.349301 IP 192.168.88.51.773 > 192.168.88.160.2049: Flags [.], ack 469785, win 4344, options
...
No verás texto legible como nombre de archivos, rutas, ni datos de ficheros. Todo será binario cifrado.
Ejemplo típico de texto claro
NFS request xid ... read fh .../poolrecovery/backup-2025-12-10.gz offset 0 count 32768
Comando más detallado para ver el handshake TLS
tcpdump -i re0 -nn -s 0 -A port 2049
-i <interfaz>
-A imprime cada paquete en formato ASCII (crucial para leer contenido)
-n No convierte direcciones IP a nombres de host (más rápido)
En el cliente solaris
echo 'Garantizar cifrado' > /nids4/prueba.txt
no podrás ver ni el nombre del archivo ni su contenido.
...
14:10:09.830256 IP 192.168.88.160.2049 > 192.168.88.51.890: Flags [P.], seq 1:115, ack 162, win 29128, options [nop,nop,TS val 3871689747 ecr 1810578769], length 114
E....V..@.....X...X3...z.C........q.2......
...
tcpdump -i re0 -nn port 2049 -c 50
Genera activida en el cliente solaris
ls -ltr /nihs4
...
14:12:35.627829 IP 192.168.88.160.2049 > 192.168.88.51.698: Flags [.], ack 230, win 29128, options [nop,nop,TS val 1928012123 ecr 3657311778], length 0
14:12:35.628036 IP 192.168.88.160.2049 > 192.168.88.51.698: Flags [P.], seq 1:303, ack 230, win
...
Si solo ves números de secuencia y longitudes, sin nombres de archivos -> cifrado
Si ves rutas y operaciones NFS -> sin cifrado (TLS inactivo).
FreeBSD es genial!.