Creative Commons License
Excepto donde se indique otra cosa, todo el contenido de este lugar está bajo una licencia de Creative Commons.
Taquiones > sysadmin > NFS y NIS

NIS

El objetivo pretendido es compartir un árbol de directorios y archivos a través de la red entre varios usuarios, que en realidad comparten bastantes servicios en la red.

El servidor maestro NIS

Instalando el software

En nuestro servidor (que utiliza una Debian etch) basta con instalar el paquete nis, aunque es probable que necesite portmapper si no está instalado aún.

Nosotros hemos tenido que abortar la puesta en marcha del servicio (tras la instalación), y proceder a configurarlo mínimamente antes de volver a intentarlo. Esto se ha debido a que la instalación predeterminada en Debian de este paquete es como cliente, y al ser ésta la única máquina que va a funcionar como servidor no encuentra nada y tarda bastante en abortar la operación.

Disposiciones iniciales

Puesto que NIS no usa DNS para arrancar es muy importante que en el archivo /etc/hosts aparezca una resolución directa del nombre del servidor maestro y de los servidores esclavos

192.168.1.99    falcata.taquiones.net falcata
192.168.1.2     cimitarra.taquiones.net cimitarra

y de que la entrada correspondiente a 127.0.0.1 no apunte al nombre del servidor maestro, tal y como ésta

127.0.0.1   localhost.localdomain   localhost

Configurando el servidor

Ahora guardamos el nombre del dominio NIS en el archivo /etc/defaultdomain teniendo en cuenta lo siguiente:

  1. El nombre del dominio NIS no es un nombre de máquina, tan sólo es un identificador del grupo de sistemas que usan este mecanismo, aunque es habitual emplear el mismo nombre de dominio DNS.
  2. El nombre de dominio es sensible a mayúsculas y minúsculas, por lo que se debe tener en cuenta en todo el sistema.
  3. No es aconsejable poner un nombre de dominio enrevesado en aras de la seguridad, puesto que existen mecanismos para proteger el acceso desde el exterior.

En el archivo /etc/default/nis cambiamos el rol del programa para que actúe como servidor maestro:

NISSERVER=true
NISCLIENT=false

Después se añaden las máquinas con acceso al servidor NIS en /etc/ypserv.securenets definiendo la máscara y la red:

255.255.255.0 192.168.1.0
255.255.255.0 192.168.2.0

Para luego proceder a inicializar el servidor NIS con el siguiente comando:

# /usr/lib/yp/ypinit -m

At this point, we have to construct a list of the hosts which will run NIS
servers.  falcata.taquiones.net is in the list of NIS server hosts.  Please continue to add
the names for the other hosts, one per line.  When you are done with the
list, type a <control D>.
        next host to add:  falcata.taquiones.net
        next host to add:
The current list of NIS servers looks like this:

falcata.taquiones.net


Is this correct?  [y/n: y]  y
We need a few minutes to build the databases...
Building /var/yp/taquiones.net/ypservers...
Running /var/yp/Makefile...
make[1]: se ingresa al directorio `/var/yp/taquiones.net'
Updating passwd.byname...
Updating passwd.byuid...
Updating group.byname...
Updating group.bygid...
Updating hosts.byname...
Updating hosts.byaddr...
Updating rpc.byname...
Updating rpc.bynumber...
Updating services.byname...
Updating services.byservicename...
Updating netid.byname...
Updating protocols.bynumber...
Updating protocols.byname...
Updating netgroup...
Updating netgroup.byhost...
Updating netgroup.byuser...
Updating shadow.byname...
make[1]: se sale del directorio `/var/yp/taquiones.net'

falcata.taquiones.net has been set up as a NIS master server.

Now you can run ypinit -s falcata.taquiones.net on all slave server.

Reiniciamos el servidor NIS:

# /etc/init.d/nis restart

y, eso sí, nos aseguramos de que el cortafuegos permite el tráfico portmap en la red (puerto 111) para poder comunicarnos con el servidor desde las otras máquinas.

Un detalle a recordar es el directorio de trabajo de NIS, que en nuestro caso aparece en /var/yp y donde encontramos un archivo Makefile, modificable en parte, que se encarga de actualizar los mapas y sincronizarlos entre servidores.

Seguridad en el servidor

Para restringir el acceso al servidor NIS existen dos archivos que permiten definir una política de seguridad:

/etc/ypserv.conf

Este archivo contiene algunas directivas para el servidor y un juego de reglas de acceso a los mapas. Dichas reglas tienen la siguiente estructura:

  • host: dirección IP con comodines opcionales
  • domain: nombre del dominio NIS para el que se aplica la regla; un asterisco sirve como comodín.
  • map: nombre del mapa al que se accede; igualmente un asterisco sirve como comodín.
  • security: tipo de seguridad aplicable

En este último caso existen tres posibles valores:

  1. none: donde siempre se permite el acceso
  2. port: sólo se permite el acceso si la petición se origina en un puerto privilegiado (por debajo de 1024)
  3. deny: acceso denegado en cualquier caso

Es posible añadir la expresión /mangle[:field] al final de none y port, e indica que se reemplace el campo número field del mapa por una equis (x) en los siguientes casos:

  • port: siempre que el puerto originario de la conexión sea no privilegiado (por encima de 1024).
  • none: en todos los casos

El número de campo por defecto es el dos (2), dado que suele corresponder a la contraseña en los mapas passwd y shadow.

El archivo ejemplo que se incluye en Debian es algo como

# Host                     : Domain  : Map              : Security
#
# *                        : *       : passwd.byname    : port/mangle
# *                        : *       : passwd.byuid     : port/mangle

y si se descomentan las líneas proporcionará acceso al mapa passwd siempre que la petición se origine en un puerto privilegiado, y aún así se le proporcionará una x en el campo de las contraseñas.

*                          : *       : shadow.byname    : port
*                          : *       : passwd.adjunct.byname : port

En cambio, comentar estas líneas daría acceso al mapa shadow a todo el mundo que pueda hacer una petición desde un puerto privilegiado. Es importante recordar que los sistemas tipo msdog hacen que todo el mundo tenga privilegios de superusuario, por lo que esto último puede abrir mella en la seguridad del sistema.

/etc/ypserv.securenets

Cada línea en este archivo consiste en dos campos, una máscara de red y una dirección de red, e indican qué redes tienen permitido el acceso al servidor NIS:

255.255.255.0   192.168.1.0
255.255.255.0   192.168.2.0

El cliente NIS

Instalando el software

En cada cliente se procede a instalar el mismo paquete nis, que ya viene configurado como cliente por defecto, y se responde con el nombre del dominio NIS definido en el servidor (en este caso taquiones.net).

Por alguna razón que no he tenido tiempo de investigar, la búsqueda de servidores mediante broadcast (envío de peticiones a toda la red) no termina de ir bien, por lo que me he visto obligado a definir el servidor en el archivo /etc/yp.conf de esta forma

ypserver 192.168.1.99

y reiniciando el servicio de nuevo.

Configurando el sistema

Para la biblioteca libc6

Comprobamos que el archivo /etc/nsswitch.conf contenga una disposición como esta

passwd:     compat
group:      compat
shadow:     compat
netgroup:   nis

Usuarios

Se debe añadir una línea especial al final del archivo /etc/passwd con este aspecto

+::::::

para habilitar el uso transparente de NIS cuando se consulta el archivo.

En el caso de que el servidor exporte también un mapa con las contraseñas (shadow) se deberá añadir una línea similar al final del archivo /etc/shadow:

+::::::::

Grupos de usuarios

Es necesario también añadir una línea semejante al final del archivo /etc/group:

+:::

Nota: la estructura de campos es diferente para cada archivo, por lo que la línea debe ser diferente según dónde se añada.

Puesta en marcha

El cliente NIS se pone en marcha usando la forma estándar en Debian:

# /etc/init.d/nis start

Configurando un servidor NIS esclavo

En el servidor esclavo

Lo primero es configurar el sistema como un cliente NIS y comprobar que funciona.

Después seguimos casi los mismos pasos que para configurar el servidor maestro:

  1. Nos aseguramos de que exista una entrada IP y nombre en /etc/hosts para el servidor maestro.
  2. Establecemos el nombre de dominio NIS en /etc/defaultdomain
  3. Indicamos nuestro rol en el archivo /etc/default/nis:

    NISSERVER=slave
    

En el servidor maestro

Ahora nos queda indicar al servidor maestro qué servidores esclavos tiene y cuáles son.

En el archivo /var/yp/Makefile indicamos que envíe automáticamente cualquier modificación efectuada a los servidores esclavos con la siguiente doble negación:

NOPUSH="false"

añadimos los nombres de los servidores esclavos en el archivo /var/yp/ypservers (asegurándonos de tener entrada directa para todos los servidores en /etc/hosts) ó ejecutamos de nuevo

/usr/lib/yp/ypinit -m

y le proporcionamos el nombre de nuestro servidor esclavo; los mapas son reconstruídos, pero no se envía nada aún a los servidores esclavos.

En el servidor esclavo de nuevo

Paramos el servicio NIS, lo arrancamos de nuevo y transferimos los mapas del servidor maestro:

# /etc/init.d/nis restart
# /usr/lib/yp/ypinit -s falcata.taquiones.net
We will need a few minutes to copy the data from falcata.taquiones.net.
Transferring shadow.byname...
Transferring netgroup.byuser...
Transferring netgroup.byhost...
Transferring netgroup...
Transferring protocols.bynumber...
Transferring services.byservicename...
Transferring netid.byname...
Transferring services.byname...
Transferring rpc.bynumber...
Transferring rpc.byname...
Transferring hosts.byaddr...
Transferring hosts.byname...
Transferring group.bygid...
Transferring group.byname...
Transferring passwd.byname...
Transferring protocols.byname...
Transferring ypservers...
Transferring passwd.byuid...

cimitarra.taquiones.net's NIS data base has been set up.
If there were warnings, please figure out what went wrong, and fix it.

At this point, make sure that /etc/passwd and /etc/group have
been edited so that when the NIS is activated, the data bases you
have just created will be used, instead of the /etc ASCII files.

Réplicas de mapas automatizadas

El funcionamiento normal consiste en copiar las bases de datos desde el maestro hacia los esclavos, aunque lo que sucede realmente es que el maestro utiliza el programa yppush para notificar a sus esclavos que copien los datos utilizando ypxfr. El problema con este proceder es que si los esclavos no están funcionando en ese momento quedarán desfasados del maestro, ya que él no lo repite en un ciclo regular, sino únicamente cuando se modifican sus datos y se ejecuta /var/yp/Makefile.

En Debian se recomienda planificar transferencias regularmente en los servidores esclavos, y para ello se incluyen varios scripts de ayuda en el directorio /var/lib/yp llamados ypxfr_1perday, ypxfr_2perday y ypxfr_1perhour, cuya diferencia principal es que el primero transfiere todos los mapas, mientras que los otros sólo transfieren aquellos más proclives a cambios a lo largo del día.

Un ejemplo de entrada cron podría ser:

15  *       *   *   *    root /usr/lib/yp/ypxfr_1perhour >/dev/null 2>&1 
30  3       *   *   *    root /usr/lib/yp/ypxfr_1perday >/dev/null 2>&1 
45  3,23    *   *   *    root /usr/lib/yp/ypxfr_2perday >/dev/null 2>&1

en el archivo /etc/cron.d/nis.

Verificando el funcionamiento

Para esto se asume que ambos lados, el servidor y el cliente, tienen en marcha sus respectivos demonios:

  • Averigüar el dominio NIS:

    $ ypdomainname
    taquiones.net
    
  • Comprobar cuál es el servidor NIS:

    $ ypwhich 
    falcata.taquiones.net
    
  • Determinar qué servidor dispone de un mapa en concreto:

    $ ypwich -m passwd
    falcata.taquiones.net
    
  • Ver todos los servicios bajo control de NIS:

    # ypcat -x 
    Use "ethers"    for map "ethers.byname"
    Use "aliases"   for map "mail.aliases"
    Use "services"  for map "services.byname"
    Use "protocols" for map "protocols.bynumber"
    Use "hosts"     for map "hosts.byname"
    Use "networks"  for map "networks.byaddr"
    Use "group"     for map "group.byname"
    Use "passwd"    for map "passwd.byname"
    #
    
  • Ver todas las entradas de un mapa:

    # ypcat passwd
    custom:x:1000:1000:Personalizador,,,:/home/custom:/bin/bash
    luismiguel:x:1003:1003:Luis Miguel,,,:/home/luismiguel:/bin/bash
    angel:x:1002:1002:Angel,,,:/home/angel:/bin/bash
    #
    
  • Recuperar una entrada vía getent:

    $ getent passwd luismiguel
    luismiguel:x:1003:1003:Luis Miguel,,,:/home/luismiguel:/bin/bash
    $
    

Y, por supuesto, la prueba final es intentar entrar en la máquina cliente con una cuenta de usuario que no existe localmente. Si esto funciona, a pesar de los problemas que pueden aparecer por la falta de directorios y demás, es que el sistema está funcionando.

Ajustando usuarios

En este punto asumimos que, dado que el mecanismo de usuarios globales ya está funcionando, podemos borrar las cuentas locales para no duplicar información. Ojo que esto es tan peligroso como parece; es conveniente dejar alguna cuenta en el sistema local si necesitamos entrar en él cuando la red no funcione.

Se me olvidaba indicar que siempre que hablamos de usuarios estamos haciendo referencia a usuarios del sistema, cuyos identificadores numéricos están por encima de 1000 en un sistema Debian, y no a cuentas del sistema (entre 0 y 500) ó de aplicación (entre 500 y 1000).

Lo idóneo con algo así es instalarlo junto con el resto de la red; es más difícil hacerlo cuando lleva en funcionamiento unos años y los usuarios están más que duplicados por ahí.

Añadiendo usuarios y grupos

Creando directorios de usuario automáticamente

PENDIENTE DE COMPLETAR

NFS

[!] Lo descrito aquí se aplica a la versión 3 del protocolo NFS. He reunido notas sobre la versión 4 en su propia página.

Instalación en el servidor NFS

En el lado servidor necesitamos el paquete nfs-kernel-server (ó su alternativa nfs-user-server que no necesita soporte directo en el núcleo). La instalación ya incluye el paquete común nfs-common y sólo queda configurar.

Exportando directorios

Como premisa, el programa rpc.mountd impide el montaje de cualquier cosa, por lo que se hace necesario indicarle, expresamente, qué está disponible para los clientes.

El archivo /etc/exports contiene los puntos de montaje, sus atributos y permisos de acceso, cada uno en una línea al estilo de

/var/db/music   cimitarra.taquiones.net(rw) *taquiones.net(ro)

y que consisten en un directorio seguido por una lista de máquinas que tienen acceso al mismo, y que opcionalmente pueden incluir una lista de opciones, (entre paréntesis y separadas por comas).

Para el nombre de la máquina existen varias posiblidades:

  • Nombre único, que debe ser el canónico según el sistema DNS (ya que se usa la llamada al sistema gethostbyaddr), y no un alias funcional

  • Grupo de máquinas, expresados utilizando asteriscos (*) y cierres de interrogación (?), que actúan como los comodines en un shell Bourne con los nombres de archivos.

    Así es posible especificar grupos de máquinas como daga.*.taquiones.net que terminarían aceptando nombres como daga.static.taquiones.net y data.dynamic.taquiones.net.

  • Direcciones IP, incluyendo rangos ó combinaciones de direcciones y máscaras de red.

  • No incluir nada, lo que permite el acceso a todo el mundo al recurso exportado. Es fácil hacer esto por error, dado que incluir un espacio en blanco entre el nombre del cliente y las opciones de exportación es suficiente para activar dicha característica.

  • Grupos NIS, que pueden indicarse precediendo con una arroba el nombre de dominio: @taquiones.net.

Para las opciones de montaje existen estas posibilidades:

  • secure: obliga a que la conexión se realice desde un puerto privilegiado (<= 1024) y está activa por omisión.
  • insecure: desactiva lo anterior y no obliga a usar ningún puerto origen concreto.
  • ro: el acceso se realiza sólo para lectura.
  • rw: se permite la lectura y la escritura (lo que incluye crear archivos y directorios); es la opción predeterminada.
  • noaccess: deshabilita todos los accesos por debajo del punto de montaje y es útil cuando se quiere exportar una jerarquía de directorios y excluir algunos en concreto. Es posible hacerlo dado que esta versión del servidor NFS permite la exportación de un directorio y un subdirectorio del mismo a la vez.
  • link_relative: convierte los enlaces simbólicos absolutos en relativos, sustituyendo la barra inicial por ../ tantas veces como sea necesario.
  • link_absolute: deja los enlaces simbólicos sin alterar; es la opción predeterminada.

Mapas de usuarios

Debido a que un montaje NFS rompe el esquema habitual UNIX en varios sentidos, los usuarios de un máquina cliente necesitan disponer de una identidad global de alguna forma. En nuestro caso estamos empleando NIS, pero existen otras cuantas opciones de exportación relativas al caso:

  • anonuid y anongid: define explícitamente los valores para el usuario y el grupo anónimo, útil en clientes PC/NFS a los que queremos forzar a emplear un usuario en concreto.
  • root_squash: convierte al superusuario (con id 0) en el usuario anónimo, incluyendo el grupo, que en Debian corresponden a nobody y nogroup. Los otros usuarios del sistema no sufren dicha conversión.
  • no_root_squash: deshabilita el comportamiento anterior y parece ser útil con clientes que no disponen de disco duro y exportan su raíz desde el servidor NFS.
  • all_squash: convierte a todos los usuarios en anónimos, y es útil en directorios públicos como las colas de news; está desactivado por omisión, y su opuesta es no_all_squash.
  • squash_uids y squash_gids: son listas de usuarios y grupos que deberán convertirse en anónimos.
  • map_daemon: habilita el uso del demonio rpc.ugidd para efectuar las conversiones entre usuarios.
  • map_static: habilita la correspondencia estática entre usuarios, usando un archivo que los describe.
  • map_nis: habilita los usuarios globales de NIS.

El uso de NIS como mapa de usuarios funciona consultando al servidor correspondiente por la identidad real de un identificador de usuario, cuando éste es encontrado en los archivos exportados. Igual para los grupos, por cierto.

Es necesario indicar el dominio NIS y asegurarnos de que el servidor NFS puede contactar con él; es decir, el servicio tiene que estar activo y la dirección IP correspondiente en el archivo /etc/yp.conf (puede haber varios).

Un ejemplo sería:

/var/docs  *taquiones.net(map_nis=taquiones.net,rw)

Es importante recordar que cuando se efectúen cambios en el archivo /etc/exports no es necesario reiniciar el servicio, pero sí actualizar el estado de los servidores, por lo que existe una herramienta para ello:

# exportfs -ra

y si ésto no funciona ó no existe el programa, debería bastar con enviar una señal SIGHUP al programa nfsd ó emplear /etc/init.d/nfs-server-kernel restart que sí que está en un sistema Debian.

Asegurando portmapper

FIXME

Poniendo en marcha el servicio

En el servidor NFS empleamos el mecanismo estándar en Debian para controlar servicios

# /etc/init.d/nfs-kernel-server start

asumiendo que empleamos al versión NFS del núcleo, y verificamos que los servicios están funcionando con

# rpcinfo -p 
programa vers proto   puerto
100000    2   tcp    111  portmapper
100000    2   udp    111  portmapper
100024    1   udp  32770  status
100024    1   tcp  41466  status
100003    2   udp   2049  nfs
100003    2   tcp   2049  nfs
100005    1   udp   1018  mountd
100005    2   udp   1018  mountd
100005    1   tcp   1021  mountd
100005    2   tcp   1021  mountd
100007    2   udp    669  ypbind
100007    1   udp    669  ypbind
100007    2   tcp    672  ypbind
100007    1   tcp    672  ypbind
#

y efectivamente están funcionando los servicios nfs, portmapper y mountd que son los que necesitamos.

Instalación en el cliente

En la máquina cliente son necesarios los paquetes nfs-common y portmap.

Una vez instalados y puestos en marcha, verificar que están activos es tan sencillo como con el servidor:

$ rpcinfo -p
programa vers proto   puerto
100000    2   tcp    111  portmapper
100000    2   udp    111  portmapper
100024    1   udp  32769  status
100024    1   tcp  50312  status
100007    2   udp    648  ypbind
100007    1   udp    648  ypbind
100007    2   tcp    651  ypbind
100007    1   tcp    651  ypbind
100021    1   tcp  53373  nlockmgr
100021    3   tcp  53373  nlockmgr
100021    4   tcp  53373  nlockmgr

y ya estamos en disposición de montar los directorios remotos de igual forma que con un recurso local:

# mount falcata.taquiones.net:/var/docs /home/docs

Si necesitamos que el montaje sea automático, en tiempo de arranque del sistema, podremos incluirlo en el archivo /etc/fstab tal que

 # device                        mountpoint     fs-type     options      dump fsckorder
 ...
 falcata.taquiones.net:/var/docs /home/docs     nfs         rw           0      0
 ...

Opciones de montaje

Dos de ellas son bastante significativas dado que determinan el funcionamiento global del montaje:

  • soft: si una petición de acceso, falla el cliente NFS informará con un error de entrada/salida (I/O) al programa que la ha efectuado, y espera que éste puede lidiar con ella. La mayoría de los programas no lo hará, y según he podido leer es fuente de problemas y de corrupción de datos.
  • hard: esta es la opción predeterminada y hace que, ante fallos de acceso, el programa se cuelgue indefinidamente, mientras el sistema informa del error por los cauces habituales (syslog y compaña).

las siguientes tienen su papel concreto en las instalaciones que tengo que administrar:

  • tcp: solicita que el montaje se efectúe vía TCP, lo que asegura menores tiempos de latencia, aunque muchos servidores no disponen de esa opción.
  • udp: solicita que el montaje se efectúe vía UDP, y es el tipo predeterminado.
  • bg: interesante opción, útil para cuando el montaje se automático, que hace que ante el primer fallo de acceso al recurso se cree en segundo plano un bucle infinito de reintentos. Muy adecuado para equipos y redes inestables ó puntos de montaje anidados. La opción opuesta y predeterminada es fg.

y como el rendimiento del servidor es muy importante existen varias opciones más, junto con métodos para verificarlo, detalladas en varios lugares de la red y que he ido guardando en la sección final de esta página.

Enlaces y referencias

Nota: el LPCI-2 es el certificado del Linux Professional Institute, creado para proporcionar, de alguna forma, un título oficial de conocimientos sobre el sistema.