Lo hice y lo entendí

El blog de Vicente Navarro
22 ago

Samba/CIFS: Enlaces simbólicos y Unix CIFS Extensions

Tengo por aquí un sistema Linux en el que exporto el directorio $HOME de los usuarios por red a través de Samba/CIFS.

Para conseguir tal cosa, apenas es necesario descomentar unas líneas de la configuración por defecto de Samba en Debian y Ubuntu (/etc/samba/smb.conf) y releer la configuración (sudo /etc/init.d/samba reload):

# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares.  This will share each
# user's home directory as \\server\username
[homes]
   comment = Home Directories
   browseable = no

Normalmente un usuario tiene en su $HOME todos los ficheros que pueda necesitar, pero en los PC a menudo tenemos otros sistemas de ficheros (unidades externas, particiones grandes que se comparten entre sistemas operativos, etc.) en los que los usuarios guardan otros ficheros. Por ejemplo, yo tengo unas particiones adicionales que suelo montar en /mnt/e y en /mnt/i con los permisos adecuados para que los usuarios puedan escribir en ellas. En el $HOME de los usuarios tengo unos enlaces simbólicos a estos sistemas de ficheros:

vicente@servidorcifs ~ $ pwd
/home/vicente

vicente@servidorcifs ~ $ ll e i
lrwxrwxrwx 1 vicente vicente 7 2008-04-30 20:51 e -> /mnt/e/
lrwxrwxrwx 1 vicente vicente 7 2008-07-17 15:11 i -> /mnt/i/

Pues bien, ¿qué diríais que pasa cuando monto //servidorcifs/vicente/ desde otro sistema e intento acceder a //servidorcifs/vicente/e/ o a //servidorcifs/vicente/i/?

Pues que si intento acceder desde Windows, los enlaces e, i aparecerán como un directorio más al que puedo acceder y en donde encuentro los ficheros de /mnt/e/, /mnt/i/ que hay en la máquina. Este es el comportamiento deseado en este caso.

Sin embargo, si intento acceder desde otro Linux (con una versión reciente de Samba), tras montar el sistema de ficheros remoto:

vicente@clientecifs ~ $ sudo mount -t cifs -o username=vicente //servidorcifs/vicente /mnt/smb/

lo que ocurrirá es que en la máquina donde hemos montado el sistema de ficheros CIFS, los enlaces simbólicos e, i se verán como lo que son, enlaces simbólicos, y apuntarán a los directorios /mnt/e/, /mnt/i/ del cliente de CIFS, no del servidor de CIFS, con lo cual no tendremos acceso a los ficheros del usuario:

vicente@clientecifs ~ $ ll /mnt/smb/e /mnt/smb/i
lrwxrwxrwx 1 vicente vicente 7 2008-04-30 20:51 /mnt/smb/e -> /mnt/e/
lrwxrwxrwx 1 vicente vicente 7 2008-07-17 15:11 /mnt/smb/i -> /mnt/i/

vicente@clientecifs ~ $ cd /mnt/smb/e
-bash: cd: /mnt/smb/e: No such file or directory

Esto nos lleva a hablar de las CIFS UNIX/POSIX Extensions. Se trata de una ampliación del protocolo CIFS que permite, cuando ambos extremos las soportan, mantener los permisos de los ficheros y los enlaces simbólicos. Sobre las mismas, en el libro de O’Reilly Using Samba, 2nd Edition, leemos:

Unix CIFS Extensions

The Unix CIFS extensions were developed at Hewlett-Packard and introduced in Samba 2.2.4. They allow Samba servers to support Unix filesystem attributes, such as links and permissions, when sharing files with other Unix systems. This allows Samba to be used as an alternative to network file sharing (NFS) for Unix-to-Unix file sharing. An advantage of using Samba is that it authenticates individual users, whereas NFS authenticates only clients (based on their IP addresses, which is a poor security model). This gives Samba an edge in the area of security, along with its much greater configurability. See Chapter 5 for information on how to operate Unix systems as Samba clients

Así, por ejemplo, en la página man de mount.cifs, encontramos ejemplos de parámetros relacionados con los permisos que no son necesarios si se usan estas extensiones o que nos permiten elegir los permisos que usaremos porque los negociados no nos sirven:

       uid=arg
           sets the uid that will own all files on the mounted filesystem. It
           may be specified as either a username or a numeric uid. For mounts
           to servers which do support the CIFS Unix extensions, such as a
           properly configured Samba server, the server provides the uid, gid
           and mode so this parameter should not be specified unless the
           server and client uid and gid numbering differ. If the server and
           client are in the same domain (e.g. running winbind or nss_ldap)
           and the server supports the Unix Extensions then the uid and gid
           can be retrieved from the server (and uid and gid would not have to
           be specified on the mount. For servers which do not support the
           CIFS Unix extensions, the default uid (and gid) returned on lookup
           of existing files will be the uid (gid) of the person who executed
           the mount (root, except when mount.cifs is configured setuid for
           user mounts) unless the "uid=" (gid) mount option is specified.
           [...]

       file_mode=arg
           If the server does not support the CIFS Unix extensions this
           overrides the default file mode.

       dir_mode=arg
           If the server does not support the CIFS Unix extensions this
           overrides the default mode for directories.

       setuids
           If the CIFS Unix extensions are negotiated with the server the
           client will attempt to set the effective uid and gid of the local
           process on newly created files, directories, and devices (create,
           mkdir, mknod). If the CIFS Unix Extensions are not negotiated, for
           newly created files and directories instead of using the default
           uid and gid specified on the the mount, cache the new file´s uid
           and gid locally which means that the uid for the file can change
           when the inode is reloaded (or the user remounts the share).

       nosetuids
           The client will not attempt to set the uid and gid on on newly
           created files, directories, and devices (create, mkdir, mknod)
           which will result in the server setting the uid and gid to the
           default (usually the server uid of the user who mounted the share).
           Letting the server (rather than the client) set the uid and gid is
           the default.If the CIFS Unix Extensions are not negotiated then the
           uid and gid for new files will appear to be the uid (gid) of the
           mounter or the uid (gid) parameter specified on the mount.

       noperm
           Client does not do permission checks. This can expose files on this
           mount to access by other users on the local client system. It is
           typically only needed when the server supports the CIFS Unix
           Extensions but the UIDs/GIDs on the client and server system do not
           match closely enough to allow access by the user doing the mount.
           Note that this does not affect the normal ACL check on the target
           machine done by the server software (of the server ACL against the
           user name provided at mount time).

Sin embargo, la página man de mount.cifs no nos explica cómo evitar que se negocien estas extensiones. Esto sería deseable en mi caso, por ejemplo, en el que quiero que los enlaces simbólicos no se vean en el lado del cliente y que simplemente aparezcan los ficheros finales del destino.

El fichero de las fuentes del kernel fs/cifs/README nos cuenta detalles muy interesantes sobre la implementación del cliente de CIFS en el kernel de Linux. Por ejemplo, que podemos chequear si las extensiones UNIX están habilitadas así:

# cat /proc/fs/cifs/LinuxExtensionsEnabled 
1

También nos cuenta cómo deshabilitarlas para un montaje en concreto (¿por qué no estará esto documentado en el man?):

 nounix         Disable the CIFS Unix Extensions for this mount (tree
                connection). This is rarely needed, but it may be useful
                in order to turn off multiple settings all at once (ie
                posix acls, posix locks, posix paths, symlink support
                and retrieving uids/gids/mode from the server) or to
                work around a bug in server which implement the Unix
                Extensions.

De forma que si ahora montamos el directorio remoto con -o nounix:

vicente@clientecifs ~ $ sudo mount -t cifs -o nounix,username=vicente //servidorcifs/vicente /mnt/smb/

lo que veo desde el cliente son directorios y no enlaces:

vicente@clientecifs ~ $ ll -d /mnt/smb/e /mnt/smb/i
drwxrwxrwx 1 root root 0 2009-08-20 12:47 /mnt/smb/e/
drwxrwxrwx 1 root root 0 2009-08-20 12:47 /mnt/smb/i/

Por supuesto, ahora ya no funcionan los enlaces simbólicos en todos los sentidos, puesto que tampoco podría yo crearme uno en el sistema de ficheros que acabamos de montar que apuntara a un directorio del servidor que yo quisiera alterar maliciosamente:

vicente@clientecifs /mnt/smb $ ln -s /boot/ boot
ln: creating symbolic link `boot': Operation not supported

Así, nos damos cuenta del problema de seguridad que podría aparecer si, con las extensiones UNIX activadas, pudiéramos usar los enlaces simbólicos como si estuviéramos en el servidor: ¡tendríamos acceso a todos los ficheros remotos a los que el usuario pudiera acceder con tan sólo un enlace simbólico!

En el lado del servidor, podríamos deshabilitar las extensiones UNIX usando el parámetro global:

unix extensions = no

en el smb.conf.

:wq

Entradas relacionadas

7 Comentarios a “Samba/CIFS: Enlaces simbólicos y Unix CIFS Extensions”

  • luis dice:

    Genial! Muchas gracias por tus posteos tan útiles, interesantes y bien explicados!

  • DaniP dice:

    Buen artículo !

  • RuBiCK dice:

    Curioso… Sigo sin entender el porqué esta información no aparece en el man. A veces linux es tan oscuro… :)

  • cmd_ dice:

    Pues esto me ha venido genial, pero le encuentro un problema, si quiero que los enlaces simbólicos funcionen correctamente (en el servidor) me quedo sin poder tocar permisos, uid… de los archivos y directorios. Supongo que no habrá manera de activar las extensiones exceptuando la de los symlinks verdad?

    • Pues que yo sepa, no. Si la encontraras, no dejes de comentármela :-)

      • cmd_ dice:

        Bueno, uso una solución que no es muy incómoda. Accedo por sshfs, solo se necesita tener ssh activo en el servidor, luego se puede montar o acceder como yo hago, usando el explorador de archivos mediante la ruta fish://servidor, haces login con tu usuario y listos.

  • dayer dice:

    Probando OpenID y a ver si de paso al usar WP de servidor OpenID carga el avatar o conviene más usar uno propio xD
    Un saludo :oops:

Tema LHYLE09, creado por Vicente Navarro