Network File System (sistema de archivos de red), o NFS, es un protocolo de nivel de aplicación, según el Modelo OSI. Es utilizado para sistemas de archivos distribuido en un entorno de red de ordenadores de área local. Posibilita que distintos sistemas conectados a una misma red accedan a ficheros remotos como si se tratara de locales. Originalmente fue desarrollado en 1984 por Sun Microsystems, con el objetivo de que sea independiente de la máquina, el sistema operativo y el protocolo de transporte, esto fue posible gracias a que está implementado sobre los protocolos XDR (presentación) y ONC RPC (sesión). El protocolo NFS está incluido por defecto en los Sistemas Operativos UNIX y la mayoría de distribuciones Linux.

El sistema NFS está dividido al menos en dos partes principales: un servidor y uno o más clientes. Los clientes acceden de forma remota a los datos que se encuentran almacenados en el servidor.

Las estaciones de trabajo locales utilizan menos espacio de disco debido a que los datos se encuentran centralizados en un único lugar pero pueden ser accedidos y modificados por varios usuarios, de tal forma que no es necesario replicar la información.

Los usuarios no necesitan disponer de un directorio “home” en cada una de las máquinas de la organización. Los directorios “home” pueden crearse en el servidor de NFS para posteriormente poder acceder a ellos desde cualquier máquina a través de la infraestructura de red.

También se pueden compartir a través de la red dispositivos de almacenamiento como disqueteras, CD-ROM y unidades ZIP. Esto puede reducir la inversión en dichos dispositivos y mejorar el aprovechamiento del hardware existente en la organización.

Todas las operaciones sobre ficheros son síncronas. Esto significa que la operación solo retorna cuando el servidor ha completado todo el trabajo asociado para esa operación. En caso de una solicitud de escritura, el servidor escribirá físicamente los datos en el disco, y si es necesario, actualizará la estructura de directorios, antes de devolver una respuesta al cliente. Esto garantiza la integridad de los ficheros.

Arquitectura Suponemos que un cliente de un sistema de archivos (NFS) de red trata de montar un directorio sacado del servidor NFS a un directorio local. Para llevar a cabo esto, necesitara la siguiente orden:

# mount -t nfs maquina_remota:/home /dir_local

En esta orden especificamos el tipo de sistema de archivos que se va a montar con –t, la máquina remota y el directorio donde vamos a montarlo.

Esta orden lo que trata es conectar con el demonio rpc mountd que se está ejecutando en la máquina remota a través de RPC. El servidor comprueba los permisos del cliente sobre el directorio /home donde se va a montar y si los tiene se lleva a cabo el montaje como si fuera cualquier otro dispositivo físico. Una vez realizado el montaje, cuando se acceda al directorio del cliente se estará accediendo al directorio del servidor remoto.

Cuando el directorio /dir_local tenga ya montado el directorio /home de la máquina remota, la única protección que tienen los archivos de dicho directorio son sus permisos.

Al acceder a los archivos del directorio NFS se generará una llamada RPC al demonio rpc nfsd en el servidor, en la cual van incluidos los parámetros correspondientes al UID y el GID del usuario y el descriptor del archivo, con los que se comprobarán los permisos.

Implementación típica Suponiendo un escenario de estilo Unix en el que una máquina (el cliente) necesita acceder a los datos almacenados en otra máquina (el servidor NFS):

El servidor implementa procesos de daemon NFS, que se ejecutan de forma predeterminada como nfsd, para que sus datos estén genéricamente disponibles para los clientes. El administrador del servidor determina qué poner a disposición, exportando los nombres y parámetros de los directorios, generalmente usando el archivo de configuración / etc / exports y el comando exportfs. La administración de seguridad del servidor asegura que pueda reconocer y aprobar clientes validados. La configuración de la red del servidor asegura que los clientes apropiados puedan negociar con ella a través de cualquier sistema de firewall. El equipo del cliente solicita acceso a los datos exportados, normalmente emitiendo un comando de montaje. El cliente le pregunta al servidor (rpcbind) qué puerto está usando el servidor NFS, el cliente se conecta al servidor NFS (nfsd), nfsd pasa la solicitud a mountd. Si todo va bien, los usuarios de la máquina cliente pueden ver e interactuar con los sistemas de archivos montados en el servidor dentro de los parámetros permitidos. Tenga en cuenta que la automatización del proceso de montaje de NFS puede tener lugar, tal vez utilizando / etc / fstab y / o instalaciones de montaje.

Este sistema de archivos se utiliza para que en una red local diferentes equipos puedan acceder a archivos y compartirlos, de esta manera, una equipo puede acceder a la información de otro equipo como si fuera un disco duro. NFS se centra en la consistencia, asumiendo operaciones write pesadas que probablemente no sean muy frecuentes.

Uno de los usos principales del protocolo NFS es para poder tener todos los archivos centralizados en un único servidor. Esto va a permitir prescindir de unidades de memoria en los demás equipos y poder entrar de forma remota para leer cualquier archivo o descargarlo.

Es muy útil especialmente cuando son muchos los usuarios que van a tener que entrar para modificar esos archivos

Pros Múltiples clientes pueden acceder a los archivos. Reduce la necesidad de tener espacio en disco. Cualquier usuario puede modificar y actualizar los archivos. Compatibilidad con muchos equipos. Bajo costo para compartir archivos en red. Administración centralizada reduce necesidad de software y espacio en disco de usuarios.

Contras Seguridad: solo hay que usarlo en redes seguras y detrás de un firewall. Requiere de una gran sobrecarga para leer archivos. No es sencillo bloquear archivos o dar permisos.

Cliente NFS El cliente simula las funcionalidades del sistema de archivos de UNIX, integrado directamente en el kernel. Se encarga de controlar las peticiones del VFS al servidor. Manda los bloques o archivos desde el servidor y hasta el servidor. Cuando es posible almacena en la caché local los bloques.

Memoria caché El módulo cliente de NFS guarda en caché los resultados de las operaciones <readwritegetattlookup> y readdir. Los clientes son responsables de sondear al servidor para comprobar la actualidad de sus datos de caché.

Método de marcas temporales para mantener las cachés:

Cada elemento es etiquetado con dos tiempos diferentes, uno el de la última vez que se validó el elemento y otro la última vez que fue modificado en el servidor. Una entrada en caché es válida en un momento t si t-tiempo que se validó por última vez es menor que el intervalo de refresco tolerado. Si no es válida la entrada se obtiene el tiempo en el que se modificó por última vez en el servidor y si es igual al del cliente, entonces la entrada es válida y se actualiza el tiempo del cliente, si no la entrada es invalida.

Para minimizar las llamadas a getattr, cuando se recibe un valor del servidor de un archivo, se aplica a todas las entradas relevantes de dicho archivo.

Aún con esto habrá problemas de consistencia si tenemos escrituras en dos clientes con una diferencia de tiempo menos que el intervalo de refresco tolerado. Para solucionar este problema tendremos que usar bloqueo de archivos convirtiendo en una sección crítica el archivo, esto se consigue en NFS mediante el protocolo Network Lock Manager (NLM).

Servidor NFS El servidor NFS es parte del núcleo Linux, en los núcleos que Debian provee está compilado como un módulo de núcleo. Su interfaz está definida en el RFC 1813.

Se encarga de recibir las peticiones, que pueden ser similares a las de modelo de archivos plano o pueden simular las del sistema de UNIX.

El servidor también ofrece servicios de montaje, de control de autenticación y acceso y una caché.

Memoria caché Hay dos opciones para mantener y asegurar la consistencia en escritura:

write-through: los datos de las operaciones de escritura se guardan en caché y se escriben en disco antes de responder al cliente. Commit: los datos de las operaciones de escritura se guardan solo en caché. Solo se escriben a disco cuando se recibe una operación commit.

Los demonios imprescindibles del servicio NFS son los siguientes:

rpc.mountd: demonio que se encarga del montaje remoto. Recibe la petición desde el cliente NFS y comprueba que el sistema de archivos este exportado y si está disponible permite las solicitudes de acceso de NFS y proporciona información sobre ello (showmount). rpc.nfsd: demonio para servir archivos. Se pueden arrancar varias copias de este demonio. Utiliza el puerto TCP/UDP 2049. rpc.portmap: Se encarga de indicar a los clientes donde se encuentra el servicio real en el servidor. Los servicios basados en RPC usan portmap para atender las peticiones de los clientes por lo cual este servicio debe estar disponible el primero. No se utiliza en NFSv4. Para comprobar que está activo ejecutar: # portmap status rpc.lockd: encargado de proporcionar el servicio de bloqueo de archivos para asegurar su consistencia ya que pueden ser accedidos de forma concurrente. Se ejecuta tanto en el servidor como en el cliente. rpc.statd: Este demonio trabaja conjuntamente con lockd para recuperar en caída de sistemas. Mantiene información sobre los procesos en los clientes que poseen locks de archivos de determinado servidor. Cuando el servidor NFS se recupera statd informa a los otros de los clientes, que el servidor se ha recuperado y así ellos resuelven los locks que tenían.

Seguridad Si queremos que nuestro servicio NFS sea más seguro deberíamos tener en cuenta una serie de detalles, como son:

Utilizar los comodines (metacaracteres) lo menos posible, ya que podemos dar acceso a más equipos de los que estamos pensando. Utilizar reglas de Iptables (cortafuegos) para limitar el acceso a los puertos utilizados por los demonios del servicio NFS. El uso de los archivos /etc/hosts.allow y /etc/hosts.deny no es obligatorio pero es preferible configurarlos para garantizar la seguridad de los datos. Exportar sistemas de archivos de lectura (ro) siempre que sea posible. El dueño de los archivos y directorios exportados que sea root ya que es posible mapear el UID de root al del usuario nobody. Intentar que los archivos exportados no tengan permiso de escritura para el grupo (ACL). Las versiones 2 y 3 de NFS no disponen de control de acceso para los usuarios concretos. En ellas, cuando un sistema de archivos es exportado, cualquier usuario en cualquier máquina remota conectada al servidor NFS puede acceder a los datos compartidos. El único mecanismo de seguridad que tienen es utilizar el acceso de solo lectura y reducir todos los usuarios a uno común cuyo UID y GID especificamos. Si no se utiliza la opción de exportación squash, cualquier usuario root en el equipo cliente puede convertirse en un usuario con acceso privilegiado simplemente ejecutando la orden: su - . Conviene siempre tener activada alguna opción de squash. La versión más segura de NFS es la 4.

<Kerberos> NFS incluye la identidad del usuario por defecto en las peticiones al servidor, pero solo para compararla con los permisos de accesos, no la valida.

Con kerberos se realiza la autenticación del usuario en el momento del montaje del sistema de archivos. Los resultados de estas autenticaciones se almacenan y se utilizan en cada petición NFS. Esto protege contra la mayoría de ataques.

Versiones NFS Las versiones de NFS más importantes son NFSv2 (RFC 1094), NFSv3 (RFC 1813) y NFSv4 (RFC 3530).