Fondo
Para una exportación/compartición de NFSv4, la opción root_squash habilitada de forma predeterminada obligará a NFS a cambiar la raíz del cliente a una ID anónima. De hecho, esto aumentará la seguridad al evitar que la propiedad de la cuenta raíz en un sistema migre al otro sistema.
Overlayfs permite montar un sistema de archivos local transparente encima de otro sistema de archivos. Desafortunadamente, parece que accede al sistema de archivos subyacente utilizando el usuario root y no el usuario real. Al menos esa es la conclusión que saqué del siguiente experimento.
¿Por qué montar un Overlayfs sobre un recurso compartido NFS? Para permitir que una máquina menos confiable tenga la capacidad de fingir que puede escribir en el sistema de archivos compartido.
Configuración de prueba
Primero instale el servidor del kernel NFS según corresponda para su distribución. Luego asegúrese de exportar solo NFSv4. (Aunque probablemente no sea importante para este problema, es una buena medida de seguridad).
$ sudo cat /proc/fs/nfsd/versions
-2 -3 +4 +4.1 +4.2
Si no, échale un vistazo /etc/nfs.conf
y configúralo vers3=n
.
Luego cree un sistema de archivos Ext4 en un archivo disperso y móntelo en el sistema de archivos local. Este será el sistema de archivos que sustentará nuestro recurso compartido NFS.
$ truncate -s 512M 512BM-ext4.img
$ mkfs.ext4 512BM-ext4.img
$ sudo mkdir /mnt/ext4-file
$ sudo mount -o loop,noacl 512BM-ext4.img /mnt/ext4-file
Luego comparta/exporte este sistema de archivos a través de la red con NFSv4 a una máquina adecuada. En este ejemplo usaré localhost, pero podría ser cualquier máquina de la red local. Haga esto editando /etc/exports
para tener una línea como la siguiente.
/mnt/ext4-file/ localhost(ro,fsid=123123)
Luego reinicie el servidor NFS en su máquina; los archivos de servicio podrían ser diferentes en su sistema operativo.
$ sudo systemctl restart nfs-server.service nfs-mountd.service
$ sudo exportfs -v
/mnt/ext4-file localhost(sync,wdelay,hide,no_subtree_check,fsid=123123,sec=sys,ro,secure,root_squash,no_all_squash)
Asegúrese de que root_squash
y ro
esté habilitado.
Ahora debería ser posible montar el recurso compartido NFSv4 en el cliente deseado.
$ sudo mount -t nfs -o ro localhost:/mnt/ext4-file /mnt/nfs-share/
$ findmnt /mnt/nfs-share
TARGET SOURCE FSTYPE OPTIONS
/mnt/nfs-share localhost:/mnt/ext4-file nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255
Y luego montamos overlayfs2 encima de este recurso compartido.
$ mkdir -p /tmp/overlay/{work,upper}
$ sudo mkdir /mnt/overlay
$ sudo mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
Para nuestro experimento, crearemos una carpeta en el sistema de archivos en la que solo un usuario puede leer y escribir y un grupo puede leerla. Elegí el grupo que pertenece a mi usuario.
$ sudo mkdir /mnt/ext4-file/rovanion
$ sudo chown rovanion:rovanion /mnt/ext4-file/rovanion
$ sudo chmod 2750 /mnt/ext4-file/rovanion
$ touch /mnt/ext4-file/rovanion/hi-from-ext4
$ ls -la /mnt/nfs-share/rovanion/
totalt 8,0K
drwxr-s--- 2 rovanion rovanion 4,0K sep 6 14:14 .
drwxr-xr-x 4 root root 4,0K sep 6 14:12 ..
-rw-rw-r-- 1 rovanion rovanion 0 sep 6 14:14 hi-from-ext4
$ touch /mnt/nfs-share/rovanion/hi-from-nfs
touch: cannot touch '/mnt/nfs-share/rovanion/hi-from-nfs': Read-only file system
Podemos enumerar el contenido de /mnt/nfs-share/rovanion
, pero no podemos tocar el sistema de archivos aunque tengamos permiso para hacerlo, porque el recurso compartido NFS está montado como de solo lectura. Todo es como se esperaba.
Falla
Pero aquí viene el problema.
$ ls -la /mnt/overlay/rovanion/
ls: cannot open directory '/mnt/overlay/rovanion/': Permission denied
$ ls -l /mnt/overlay/
total 28K
drwx------ 2 root root 16K Sep 6 13:04 lost+found
drwxr-s--- 2 rovanion rovanion 4.0K Sep 6 14:14 rovanion
$ whoami
rovanion
$ groups
rovanion sudo
Se nos niega el acceso a la lista /mnt/overlay/rovanion
aunque el sistema de permisos debería permitirnos hacerlo.
Mi mejor suposición sobre lo que está sucediendo es que Overlayfs accede al sistema de archivos subyacente, por root
lo que mediante el root squash de NFS se asigna a nobody
quién no tiene permiso para acceder a la carpeta, ya que nobody
no pertenece al grupo rovanion
y a otros no se les permite acceder. enumera la carpeta.
Pregunta
Mi pregunta entonces es: ¿Es posible solucionar este problema? Para permitir que un usuario acceda a una carpeta a través de Overlayfs a la que solo tiene acceso un grupo selecto, sin deshabilitar root_squash en la exportación/compartición NFS ni agregar o+rx
a la carpeta.
Respuesta1
La siguiente sección delDocumentación del kernel de Linux sobre Overlayfsdescribe el modelo de permiso.
La verificación de permisos en el sistema de archivos superpuesto sigue estos principios:
1) permission check SHOULD return the same result before and after copy up 2) task creating the overlay mount MUST NOT gain additional privileges 3) non-mounting task MAY gain additional privileges through the overlay, compared to direct access on underlying lower or upper filesystems
Esto se logra realizando dos comprobaciones de permisos en cada acceso.
a) check if current task is allowed access based on local DAC (owner, group, mode and posix acl), as well as MAC checks b) check if mounting task would be allowed real operation on lower or upper layer based on underlying filesystem permissions, again including MAC checks
La verificación (a) garantiza la coherencia (1) ya que se copian las ACL de propietario, grupo, modo y posix. Por otro lado, puede provocar que se ignoren los permisos aplicados por el servidor (utilizados por NFS, por ejemplo) (3).
La marca (b) garantiza que ninguna tarea obtenga permisos para las capas subyacentes que la tarea de montaje no tiene (2).Esto también significa que es posible crear configuraciones donde la regla de coherencia (1) no se cumple; Sin embargo, normalmente la tarea de montaje tendrá privilegios suficientes para realizar todas las operaciones.
El énfasis es mío. Mi lectura es que he logrado crear tal situación. Uno en el que la tarea de montaje, que se ejecuta como root, no tiene el privilegio de enumerar la carpeta y, por lo tanto, Overlayfs no permite al usuario acceder a la carpeta.
Si tuviéramos que montar Overlayfs como un usuario al que se le permite acceder a los archivos, que no es root para que el UID no se aplaste, entonces ¿quizás podamos enumerar el directorio y crear un archivo en él?
$ unshare --mount --map-root-user
# mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
# ls -la /mnt/overlay/
totalt 28K
drwxrwxr-x 1 root root 4,0K sep 6 14:08 .
drwxr-xr-x 7 nobody nogroup 4,0K sep 6 14:09 ..
drwx------ 2 nobody nogroup 16K sep 6 13:04 lost+found
drwxr-s--- 2 root root 4,0K sep 6 14:14 rovanion
# touch /mnt/overlay/rovanion/hi-from-overlay
¡Y que podemos! Y el archivo existe sólo en la superposición.
$ ls /mnt/ext4-file/rovanion/
hi-from-ext4
$ ls /tmp/overlay/upper/rovanion/
hi-from-overlay
Aunque esta solución tiene sus propias implicaciones interesantes. Ahora debemos tener espacios de nombres de usuario habilitados en nuestras máquinas que no son 100% confiables y de repente nos encontramos en un espacio donde nuestro UID parece ser 0 pero está asignado a nuestro ID de usuario normal para el mundo exterior. Desgraciadamente unshare --mount
sin ello --map-root-user
no parece posible.