36 KiB
📘 Guía Completa: Compartir Recursos entre Proxmox Host y Contenedores LXC
📋 Índice
1. Conceptos Fundamentales
Usuarios y Grupos en Linux
¿Qué es un Usuario?
Un usuario en Linux es una identidad que puede:
- Poseer archivos y directorios
- Ejecutar procesos
- Tener permisos específicos
Cada usuario tiene:
- Nombre: Como
root
,www-data
,juan
- UID (User ID): Número único, como
0
(root),33
(www-data),1000
(primer usuario)
# Ver información de un usuario
id www-data
# Salida: uid=33(www-data) gid=33(www-data) groups=33(www-data)
# Listar todos los usuarios del sistema
cat /etc/passwd | head -5
# Salida:
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# bin:x:2:2:bin:/bin:/usr/sbin/nologin
¿Qué es un Grupo?
Un grupo es una colección de usuarios que comparten permisos. Permite:
- Dar acceso a múltiples usuarios sin configurar cada uno individualmente
- Organizar permisos de manera lógica
- Simplificar la administración
Cada grupo tiene:
- Nombre: Como
root
,www-data
,sharedfiles
- GID (Group ID): Número único, como
0
(root),33
(www-data),1000
(usuarios)
# Ver todos los grupos
cat /etc/group | head -5
# Salida:
# root:x:0:
# daemon:x:1:
# bin:x:2:
# Ver grupos de un usuario
groups www-data
# Salida: www-data : www-data
# Crear un nuevo grupo
groupadd -g 1001 migrupo
# Añadir usuario a un grupo
usermod -aG migrupo www-data
¿Por qué son importantes los grupos?
Ejemplo práctico: Tienes 3 contenedores que ejecutan aplicaciones web:
- Sin grupos: Tendrías que dar permisos individuales a cada usuario de cada contenedor
- Con grupos: Creas un grupo
webapps
, añades todos los usuarios web, y das permisos al grupo
Permisos Básicos
Tipos de Permisos
Cada archivo y directorio tiene tres tipos de permisos para tres categorías de usuarios:
Permiso | Símbolo | Valor | En Archivos | En Directorios |
---|---|---|---|---|
Lectura | r |
4 | Leer contenido | Listar archivos |
Escritura | w |
2 | Modificar archivo | Crear/eliminar archivos |
Ejecución | x |
1 | Ejecutar archivo | Entrar al directorio |
Categorías de Usuarios
Categoría | Descripción | Posición |
---|---|---|
Propietario (user) | El dueño del archivo | Primera posición |
Grupo (group) | Miembros del grupo propietario | Segunda posición |
Otros (others) | Todos los demás usuarios | Tercera posición |
Lectura de Permisos
ls -l /mnt/ejemplo
# Salida: drwxrwxr-x 2 root sharedfiles 4096 sep 8 10:30 ejemplo
# │││││││││
# │└┴┴┴┴┴┴┴─ Permisos
# └─────────── Tipo (d=directorio, -=archivo)
# Desglose de permisos: rwxrwxr-x
# Propietario (root): rwx = 7 (lectura + escritura + ejecución)
# Grupo (sharedfiles): rwx = 7 (lectura + escritura + ejecución)
# Otros: r-x = 5 (lectura + ejecución, sin escritura)
Permisos Numéricos
Los permisos se pueden expresar como números de 3 dígitos:
# Ejemplos comunes
chmod 755 archivo # rwxr-xr-x (propietario: todo, otros: lectura+ejecución)
chmod 644 archivo # rw-r--r-- (propietario: lectura+escritura, otros: solo lectura)
chmod 775 directorio # rwxrwxr-x (propietario y grupo: todo, otros: lectura+ejecución)
El Bit Setgid
El setgid es uno de los conceptos más importantes para directorios compartidos, pero también uno de los menos comprendidos.
¿Qué hace el setgid?
Cuando se aplica a un directorio, el setgid hace que:
- Todos los archivos y subdirectorios creados dentro hereden automáticamente el grupo del directorio padre
- No importa qué usuario o proceso cree el archivo, siempre tendrá el mismo grupo
Ejemplo Práctico: Sin setgid
# Crear directorio sin setgid
mkdir /tmp/sin_setgid
chmod 775 /tmp/sin_setgid
chgrp sharedfiles /tmp/sin_setgid
ls -ld /tmp/sin_setgid
# Salida: drwxrwxr-x 2 root sharedfiles 4096 sep 8 10:30 /tmp/sin_setgid
# ↑ No hay 's' en la posición del grupo
# Crear archivo como usuario www-data
sudo -u www-data touch /tmp/sin_setgid/archivo1
ls -l /tmp/sin_setgid/archivo1
# Salida: -rw-r--r-- 1 www-data www-data 0 sep 8 10:35 archivo1
# ❌ El archivo pertenece al grupo 'www-data', NO 'sharedfiles'
# Crear archivo como usuario root
touch /tmp/sin_setgid/archivo2
ls -l /tmp/sin_setgid/archivo2
# Salida: -rw-r--r-- 1 root root 0 sep 8 10:36 archivo2
# ❌ El archivo pertenece al grupo 'root', NO 'sharedfiles'
Problema: Cada usuario crea archivos con su grupo primario, causando inconsistencias.
Ejemplo Práctico: Con setgid
# Crear directorio CON setgid
mkdir /tmp/con_setgid
chmod 2775 /tmp/con_setgid # El '2' inicial activa setgid
chgrp sharedfiles /tmp/con_setgid
ls -ld /tmp/con_setgid
# Salida: drwxrwsr-x 2 root sharedfiles 4096 sep 8 10:37 /tmp/con_setgid
# ↑ La 's' indica que setgid está activo
# Crear archivo como usuario www-data
sudo -u www-data touch /tmp/con_setgid/archivo1
ls -l /tmp/con_setgid/archivo1
# Salida: -rw-r--r-- 1 www-data sharedfiles 0 sep 8 10:38 archivo1
# ✅ El archivo hereda el grupo 'sharedfiles' del directorio padre
# Crear archivo como usuario root
touch /tmp/con_setgid/archivo2
ls -l /tmp/con_setgid/archivo2
# Salida: -rw-r--r-- 1 root sharedfiles 0 sep 8 10:39 archivo2
# ✅ El archivo también hereda el grupo 'sharedfiles'
# Crear subdirectorio
mkdir /tmp/con_setgid/subdir
ls -ld /tmp/con_setgid/subdir
# Salida: drwxr-sr-x 2 root sharedfiles 4096 sep 8 10:40 subdir
# ✅ El subdirectorio hereda el grupo Y también tiene setgid activo
¿Por qué es crucial setgid para recursos compartidos?
- Consistencia: Todos los archivos tienen el mismo grupo, independientemente de quién los cree
- Simplicidad: No necesitas cambiar manualmente el grupo de cada archivo nuevo
- Herencia: Los subdirectorios también heredan el setgid, manteniendo la consistencia en toda la estructura
- Compatibilidad: Funciona con NFS, Samba, y contenedores sin configuración adicional
Access Control Lists (ACL)
Limitaciones de los Permisos Tradicionales
Los permisos tradicionales de Linux solo permiten:
- 1 propietario
- 1 grupo
- Permisos para "otros"
Problema: ¿Qué pasa si necesitas que 3 grupos diferentes tengan acceso de escritura?
¿Qué son las ACL?
Las Access Control Lists (ACL) extienden los permisos tradicionales permitiendo:
- Múltiples usuarios con permisos específicos
- Múltiples grupos con permisos específicos
- Permisos por defecto que se heredan automáticamente
# Instalar herramientas ACL
apt-get install acl
# Ver ACL de un archivo/directorio
getfacl /mnt/shared
# Salida:
# file: mnt/shared
# owner: root
# group: sharedfiles
# user::rwx
# group::rwx
# group:webapps:rwx
# group:developers:r-x
# other::r-x
# default:user::rwx
# default:group::rwx
# default:group:webapps:rwx
# default:other::r-x
Configurar ACL
# Dar permisos a un grupo específico
setfacl -m g:webapps:rwx /mnt/shared
# Dar permisos a un usuario específico
setfacl -m u:juan:rw /mnt/shared
# Configurar permisos por defecto (se heredan)
setfacl -d -m g:webapps:rwx /mnt/shared
# Aplicar ACL recursivamente a todo el contenido existente
setfacl -R -m g:webapps:rwx /mnt/shared
# Combinar: aplicar a existente Y configurar por defecto
setfacl -R -m g:webapps:rwx /mnt/shared
setfacl -d -m g:webapps:rwx /mnt/shared
¿Por qué son importantes las ACL para NFS y Samba?
NFS y mapeo de IDs:
- NFS transmite solo números (UID/GID), no nombres
- Si el cliente tiene usuarios con IDs diferentes, los permisos se rompen
- Las ACL aseguran que el grupo correcto siempre tenga acceso
Ejemplo práctico:
# Servidor NFS: usuario 'web' tiene UID 1001
# Cliente NFS: usuario 'web' tiene UID 1002
# Sin ACL: El cliente ve archivos del UID 1001 (usuario inexistente)
# Con ACL: El grupo 'webapps' siempre tiene acceso, independiente de UIDs
Contenedores Privilegiados vs No Privilegiados
¿Qué son los Contenedores No Privilegiados?
Los contenedores no privilegiados son más seguros porque:
- El usuario
root
del contenedor NO esroot
del host - Los IDs de usuario/grupo están "desplazados"
- Limitan el daño si el contenedor es comprometido
Mapeo de IDs
En un contenedor no privilegiado típico:
Contenedor | Host | Explicación |
---|---|---|
UID 0 (root) | UID 100000 | Root del contenedor = usuario 100000 del host |
UID 1 | UID 100001 | Usuario 1 del contenedor = usuario 100001 del host |
UID 1000 (usuario) | UID 101000 | Usuario 1000 del contenedor = usuario 101000 del host |
GID 0 (root) | GID 100000 | Grupo root del contenedor = grupo 100000 del host |
GID 1000 (grupo) | GID 101000 | Grupo 1000 del contenedor = grupo 101000 del host |
El Problema en la Práctica
# En el HOST: Crear archivo con grupo 'sharedfiles' (GID 1000)
echo "datos" > /mnt/shared/archivo.txt
chgrp sharedfiles /mnt/shared/archivo.txt
ls -l /mnt/shared/archivo.txt
# Salida: -rw-r--r-- 1 root sharedfiles 6 sep 8 archivo.txt
# En el CONTENEDOR NO PRIVILEGIADO: Ver el mismo archivo
pct exec 101 -- ls -l /mnt/shared/archivo.txt
# Salida: -rw-r--r-- 1 nobody nogroup 6 sep 8 archivo.txt
# ❌ El contenedor ve 'nobody:nogroup' porque no conoce el GID 1000 del host
¿Por qué pasa esto?
- Host: El archivo pertenece al GID 1000 (
sharedfiles
) - Contenedor: Busca qué grupo tiene GID 1000 en SU
/etc/group
- Resultado: Si no existe ese GID en el contenedor, muestra
nogroup
- Consecuencia: El usuario del contenedor no puede escribir
2. Cómo Funcionan los Permisos en Recursos Compartidos
Servidores NFS
¿Cómo maneja NFS los permisos?
Los servidores NFS (ya sean Linux, TrueNAS, Synology, etc.) funcionan de manera similar:
- Solo transmiten números: NFS envía UID/GID numéricos, no nombres de usuario
- No hay autenticación de usuario: NFS confía en que el cliente ya autenticó al usuario
- Los permisos se evalúan en el servidor: El servidor NFS verifica permisos usando sus propios archivos
/etc/passwd
y/etc/group
Ejemplo con TrueNAS
# En TrueNAS: Crear dataset con permisos
# Dataset: /mnt/pool/shared
# Propietario: root (UID 0)
# Grupo: shared (GID 1001)
# Permisos: 775
# En Proxmox: Montar el NFS
mount -t nfs 192.168.1.100:/mnt/pool/shared /mnt/truenas_shared
# Ver cómo se ven los permisos en Proxmox
ls -ld /mnt/truenas_shared
# Salida: drwxrwxr-x 2 root 1001 4096 sep 8 10:45 /mnt/truenas_shared
# ↑ Aparece el GID numérico porque Proxmox no tiene grupo con GID 1001
Solución: Crear grupo con el mismo GID
# En Proxmox: Crear grupo con el mismo GID que TrueNAS
groupadd -g 1001 truenas_shared
# Ahora se ve correctamente
ls -ld /mnt/truenas_shared
# Salida: drwxrwxr-x 2 root truenas_shared 4096 sep 8 10:45 /mnt/truenas_shared
Configuraciones comunes en servidores NFS
TrueNAS/FreeNAS:
- Maptype: Unix
- Usuario: root o usuario específico
- Grupo: wheel, shared, o grupo personalizado
Synology:
- Squash: No mapping
- Usuario: root o admin
- Grupo: users o grupo personalizado
Linux (Ubuntu/Debian):
# /etc/exports
/export/shared 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)
Servidores Samba/CIFS
¿Cómo maneja Samba los permisos?
Samba es más complejo porque debe mapear entre:
- Usuarios Windows (autenticación SMB)
- Usuarios Linux (permisos del sistema de archivos)
Ejemplo con Synology
# En Synology: Crear carpeta compartida
# Nombre: SharedData
# Permisos SMB: Grupo 'users' con lectura/escritura
# Permisos Linux: 775, propietario 'admin', grupo 'users'
# En Proxmox: Montar Samba
mount -t cifs //192.168.1.200/SharedData /mnt/synology_shared \
-o username=admin,password=mipassword,uid=root,gid=1000,file_mode=0664,dir_mode=0775
# Ver permisos
ls -ld /mnt/synology_shared
# Salida: drwxrwxr-x 2 root 1000 4096 sep 8 10:50 /mnt/synology_shared
# ↑ Usa el GID especificado en las opciones de montaje
Opciones importantes de montaje CIFS
uid=
: UID que se asigna a todos los archivosgid=
: GID que se asigna a todos los archivosfile_mode=
: Permisos para archivos (ej: 0664)dir_mode=
: Permisos para directorios (ej: 0775)forceuid/forcegid
: Fuerza el uso de uid/gid especificados
Directorios Locales
Los directorios locales son los más simples:
- Los permisos se respetan directamente
- No hay mapeo de red
- Funciona con usuarios y grupos locales del sistema
3. Preparación del Host Proxmox
Crear Directorio Local
Para crear un directorio local que se compartirá con contenedores:
# 1. Crear directorio
mkdir -p /mnt/local_shared
# 2. Crear grupo común (usaremos GID 101000 para compatibilidad universal)
groupadd -g 101000 sharedfiles
# 3. Configurar propietario y permisos con setgid
chown root:sharedfiles /mnt/local_shared
chmod 2775 /mnt/local_shared
# 4. Aplicar ACL para garantizar permisos
setfacl -R -m g:sharedfiles:rwx /mnt/local_shared
setfacl -d -m g:sharedfiles:rwx /mnt/local_shared
# 5. Verificar configuración
ls -ld /mnt/local_shared
# Salida esperada: drwxrwsr-x+ 2 root sharedfiles 4096 sep 8 11:00 /mnt/local_shared
# ↑ 's' indica setgid activo
# ↑ '+' indica ACL aplicadas
getfacl /mnt/local_shared
# Salida esperada:
# file: mnt/local_shared
# owner: root
# group: sharedfiles
# user::rwx
# group::rwx
# other::r-x
# default:user::rwx
# default:group::rwx
# default:other::r-x
Montar Recurso NFS
Montaje Temporal
# 1. Crear punto de montaje
mkdir -p /mnt/nfs_shared
# 2. Montar NFS
mount -t nfs 192.168.1.100:/export/shared /mnt/nfs_shared
# 3. Verificar montaje
df -h | grep nfs
mount | grep nfs
# 4. Ver permisos originales
ls -ld /mnt/nfs_shared
# Ejemplo: drwxrwxr-x 2 root 1001 4096 sep 8 11:05 /mnt/nfs_shared
Crear Grupo Compatible
# Si el directorio NFS tiene un GID específico (ej: 1001), crear grupo local
groupadd -g 1001 nfs_shared
# Verificar que ahora se ve el nombre del grupo
ls -ld /mnt/nfs_shared
# Salida: drwxrwxr-x 2 root nfs_shared 4096 sep 8 11:05 /mnt/nfs_shared
Aplicar Configuración Universal
# Para compatibilidad con contenedores, aplicar nuestro esquema estándar
# IMPORTANTE: Solo si tienes permisos de escritura en el NFS
# Crear nuestro grupo estándar
groupadd -g 101000 sharedfiles
# Cambiar grupo del directorio NFS (si es posible)
chgrp sharedfiles /mnt/nfs_shared
# Aplicar setgid y ACL
chmod 2775 /mnt/nfs_shared
setfacl -R -m g:sharedfiles:rwx /mnt/nfs_shared
setfacl -d -m g:sharedfiles:rwx /mnt/nfs_shared
Montaje Persistente
# Editar /etc/fstab
nano /etc/fstab
# Añadir línea:
192.168.1.100:/export/shared /mnt/nfs_shared nfs rw,hard,nofail,rsize=131072,wsize=131072,timeo=600,retrans=2,_netdev 0 0
# Explicación de opciones:
# rw: lectura/escritura
# hard: reintentar indefinidamente si el servidor no responde
# nofail: no fallar el arranque si no se puede montar
# rsize/wsize: tamaño de buffer para lectura/escritura (mejor rendimiento)
# timeo: timeout en décimas de segundo (60 segundos)
# retrans: número de reintentos antes de reportar error
# _netdev: esperar a que la red esté disponible
# 0 0: no hacer dump ni fsck (siempre para recursos de red)
# Probar montaje
mount -a
# Verificar
df -h | grep nfs
Montar Recurso Samba
Crear Archivo de Credenciales
# Crear archivo de credenciales seguro
nano /etc/cifs-credentials
# Contenido:
username=tu_usuario
password=tu_password
domain=tu_dominio
# Proteger archivo
chmod 600 /etc/cifs-credentials
chown root:root /etc/cifs-credentials
Montaje Temporal
# 1. Crear punto de montaje
mkdir -p /mnt/samba_shared
# 2. Montar Samba con opciones específicas
mount -t cifs //192.168.1.200/SharedData /mnt/samba_shared \
-o credentials=/etc/cifs-credentials,uid=root,gid=101000,file_mode=0664,dir_mode=2775,iocharset=utf8,vers=3.0
# Explicación de opciones:
# credentials: archivo con usuario/password
# uid=root: todos los archivos aparecen como propietario root
# gid=101000: todos los archivos aparecen con grupo sharedfiles
# file_mode=0664: permisos para archivos (rw-rw-r--)
# dir_mode=2775: permisos para directorios (rwxrwsr-x) con setgid
# iocharset=utf8: codificación de caracteres
# vers=3.0: versión del protocolo SMB
# 3. Verificar montaje
df -h | grep cifs
ls -ld /mnt/samba_shared
Configurar Grupo y Permisos
# Crear grupo si no existe
groupadd -g 101000 sharedfiles
# Verificar que los permisos son correctos
ls -ld /mnt/samba_shared
# Salida esperada: drwxrwsr-x 2 root sharedfiles 4096 sep 8 11:10 /mnt/samba_shared
# Aplicar ACL adicionales si es necesario
setfacl -R -m g:sharedfiles:rwx /mnt/samba_shared
setfacl -d -m g:sharedfiles:rwx /mnt/samba_shared
Montaje Persistente
# Editar /etc/fstab
nano /etc/fstab
# Añadir línea:
//192.168.1.200/SharedData /mnt/samba_shared cifs credentials=/etc/cifs-credentials,uid=root,gid=101000,file_mode=0664,dir_mode=2775,iocharset=utf8,vers=3.0,_netdev,nofail 0 0
# Probar montaje
mount -a
# Verificar
df -h | grep cifs
4. Configuración de Contenedores
Contenedores Privilegiados
Los contenedores privilegiados comparten los mismos UIDs/GIDs que el host, por lo que la configuración es más directa.
¿Necesitan configuración especial?
Respuesta corta: Generalmente NO, pero hay casos donde SÍ es recomendable.
Cuándo NO necesitan configuración
Si el contenedor privilegiado:
- Solo usa el usuario
root
- No ejecuta servicios con usuarios específicos (como
www-data
) - Los archivos siempre se crean como
root:root
# Ejemplo: Contenedor que solo usa root
pct exec 100 -- bash
whoami # root
id # uid=0(root) gid=0(root) groups=0(root)
# Crear archivo en directorio compartido
echo "test" > /mnt/shared/archivo.txt
ls -l /mnt/shared/archivo.txt
# Salida: -rw-r--r-- 1 root root 5 sep 8 11:15 archivo.txt
# ❌ El archivo pertenece al grupo 'root', no 'sharedfiles'
Cuándo SÍ necesitan configuración
Si el contenedor privilegiado:
- Ejecuta servicios web (
www-data
,nginx
,apache
) - Tiene aplicaciones que crean archivos con usuarios específicos
- Necesita compatibilidad con otros contenedores o servicios
# Ejemplo: Contenedor con Nextcloud
pct exec 100 -- bash
# Ver usuarios del sistema
cat /etc/passwd | grep -E "(www-data|nginx|apache)"
# Salida: www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
# Sin configuración: Nextcloud crea archivos como www-data:www-data
sudo -u www-data touch /mnt/shared/nextcloud_file.txt
ls -l /mnt/shared/nextcloud_file.txt
# Salida: -rw-r--r-- 1 www-data www-data 0 sep 8 11:20 nextcloud_file.txt
# ❌ Grupo 'www-data' no es compatible con otros contenedores
Configuración Recomendada para Contenedores Privilegiados
# 1. Entrar al contenedor
pct exec 100 -- bash
# 2. Crear grupo con el mismo GID que el host
groupadd -g 101000 sharedfiles
# 3. Añadir usuarios relevantes al grupo
usermod -aG sharedfiles root
usermod -aG sharedfiles www-data
# Si tienes otros usuarios específicos de aplicaciones:
usermod -aG sharedfiles nextcloud 2>/dev/null || true
usermod -aG sharedfiles nginx 2>/dev/null || true
# 4. Verificar membresía
groups root
# Salida: root : root sharedfiles
groups www-data
# Salida: www-data : www-data sharedfiles
# 5. Salir del contenedor
exit
¿Por qué es importante esta configuración?
- Consistencia: Los archivos creados por diferentes usuarios mantienen el grupo
sharedfiles
- Compatibilidad: Funciona con contenedores no privilegiados y otros servicios
- Flexibilidad: Permite que múltiples usuarios/servicios accedan a los mismos archivos
Contenedores No Privilegiados
Los contenedores no privilegiados SIEMPRE necesitan configuración especial debido al mapeo de UIDs/GIDs.
Configuración Obligatoria
# 1. Entrar al contenedor
pct exec 101 -- bash
# 2. Crear grupo con GID mapeado
# GID 1000 en contenedor = GID 101000 en host
groupadd -g 1000 sharedfiles
# 3. Listar usuarios disponibles en el contenedor
awk -F: '$3>=1000 && $1!="nobody" {print $1 " (UID: " $3 ")"}' /etc/passwd
# Salida típica:
# root (UID: 0)
# www-data (UID: 33)
# ncp (UID: 1000)
# También incluir usuarios del sistema si es necesario
awk -F: '$3<1000 && $3>0 && $1!="nobody" {print $1 " (UID: " $3 ")"}' /etc/passwd
# 4. Añadir usuarios al grupo
usermod -aG sharedfiles root
usermod -aG sharedfiles www-data
# Si tienes usuarios específicos de aplicaciones:
usermod -aG sharedfiles ncp 2>/dev/null || true
usermod -aG sharedfiles nextcloud 2>/dev/null || true
# 5. Verificar configuración
id www-data
# Salida esperada: uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(sharedfiles)
# 6. Salir del contenedor
exit
Cómo Añadir Más Usuarios
Si instalas nuevas aplicaciones que crean usuarios adicionales:
# Entrar al contenedor
pct exec 101 -- bash
# Buscar nuevos usuarios (UID >= 100)
awk -F: '$3>=100 && $3<65534 {print $1 " (UID: " $3 ", GID: " $4 ")"}' /etc/passwd
# Añadir al grupo sharedfiles
usermod -aG sharedfiles nombre_usuario
# Verificar
groups nombre_usuario
Añadir TODOS los usuarios automáticamente
# Script para añadir todos los usuarios relevantes
pct exec 101 -- bash -c '
# Obtener todos los usuarios con UID >= 100 y < 65534 (excluyendo nobody)
for user in $(awk -F: "$3>=100 && $3<65534 && $1!=\"nobody\" {print $1}" /etc/passwd); do
echo "Añadiendo usuario: $user"
usermod -aG sharedfiles "$user" 2>/dev/null || echo "Error añadiendo $user"
done
# Verificar usuarios añadidos
echo "Usuarios en grupo sharedfiles:"
getent group sharedfiles
'
5. Montaje en Contenedores
Configuración del Montaje
Para ambos tipos de contenedores, el montaje se configura igual, pero con consideraciones importantes:
# Para contenedor privilegiado (ID 100)
pct set 100 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1
# Para contenedor no privilegiado (ID 101)
pct set 101 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1
# Reiniciar contenedores para activar montajes
pct reboot 100
pct reboot 101
# Esperar a que arranquen
sleep 15
Explicación de Parámetros
/mnt/shared_data
: Ruta en el HOST (donde está montado el recurso)mp=/mnt/shared
: Ruta en el CONTENEDOR (donde aparecerá el directorio)backup=0
: Excluir del backup de vzdump (recomendado para recursos de red)acl=1
: Habilitar soporte para ACL dentro del contenedorshared=1
: CRUCIAL para clusters - permite migración sin copiar datos
¿Por qué shared=1 es importante?
Sin shared=1
:
- Proxmox intenta copiar todo el contenido durante migraciones
- Falla si el directorio contiene muchos datos
- No funciona con recursos de red
Con shared=1
:
- Proxmox asume que el directorio está disponible en todos los nodos
- Solo migra la configuración, no los datos
- Funciona perfectamente con NFS, Samba, y almacenamiento compartido
Verificación del Montaje
# Verificar que el montaje está activo
pct exec 100 -- df -h | grep shared
pct exec 101 -- df -h | grep shared
# Verificar permisos dentro de los contenedores
pct exec 100 -- ls -ld /mnt/shared
pct exec 101 -- ls -ld /mnt/shared
# Verificar ACL dentro de los contenedores
pct exec 100 -- getfacl /mnt/shared
pct exec 101 -- getfacl /mnt/shared
6. Verificación y Pruebas
Prueba Básica de Escritura
Desde el Host
# Crear archivo de prueba desde el host
echo "Archivo creado desde HOST" > /mnt/shared_data/test_host.txt
# Verificar propietario y permisos
ls -l /mnt/shared_data/test_host.txt
# Salida esperada: -rw-rw-r--+ 1 root sharedfiles 26 sep 8 12:00 test_host.txt
Desde Contenedor Privilegiado
# Crear archivo como root
pct exec 100 -- bash -c 'echo "Archivo desde contenedor privilegiado (root)" > /mnt/shared/test_priv_root.txt'
# Crear archivo como www-data
pct exec 100 -- sudo -u www-data bash -c 'echo "Archivo desde contenedor privilegiado (www-data)" > /mnt/shared/test_priv_www.txt'
# Verificar en el host
ls -l /mnt/shared_data/test_priv_*
# Salida esperada:
# -rw-rw-r--+ 1 root sharedfiles 42 sep 8 12:01 test_priv_root.txt
# -rw-rw-r--+ 1 www-data sharedfiles 48 sep 8 12:01 test_priv_www.txt
Desde Contenedor No Privilegiado
# Crear archivo como root del contenedor
pct exec 101 -- bash -c 'echo "Archivo desde contenedor no privilegiado (root)" > /mnt/shared/test_unpriv_root.txt'
# Crear archivo como www-data del contenedor
pct exec 101 -- sudo -u www-data bash -c 'echo "Archivo desde contenedor no privilegiado (www-data)" > /mnt/shared/test_unpriv_www.txt'
# Verificar en el host
ls -l /mnt/shared_data/test_unpriv_*
# Salida esperada:
# -rw-rw-r--+ 1 100000 sharedfiles 46 sep 8 12:02 test_unpriv_root.txt
# -rw-rw-r--+ 1 100033 sharedfiles 52 sep 8 12:02 test_unpriv_www.txt
# ↑ UIDs mapeados (+100000)
Prueba de Acceso Cruzado
# Desde contenedor privilegiado, leer archivo del no privilegiado
pct exec 100 -- cat /mnt/shared/test_unpriv_root.txt
# Salida: Archivo desde contenedor no privilegiado (root)
# Desde contenedor no privilegiado, leer archivo del privilegiado
pct exec 101 -- cat /mnt/shared/test_priv_root.txt
# Salida: Archivo desde contenedor privilegiado (root)
# Modificar archivo desde diferentes contenedores
pct exec 100 -- bash -c 'echo "Modificado desde privilegiado" >> /mnt/shared/test_unpriv_root.txt'
pct exec 101 -- bash -c 'echo "Modificado desde no privilegiado" >> /mnt/shared/test_priv_root.txt'
# Verificar contenido
cat /mnt/shared_data/test_unpriv_root.txt
cat /mnt/shared_data/test_priv_root.txt
Prueba de Herencia de Permisos
# Crear subdirectorio desde contenedor
pct exec 100 -- mkdir /mnt/shared/subdir_test
# Verificar que hereda setgid y grupo
ls -ld /mnt/shared_data/subdir_test
# Salida esperada: drwxrwsr-x+ 2 root sharedfiles 4096 sep 8 12:05 subdir_test
# ↑ 's' indica setgid heredado
# Crear archivo en subdirectorio
pct exec 101 -- touch /mnt/shared/subdir_test/archivo_en_subdir.txt
# Verificar herencia
ls -l /mnt/shared_data/subdir_test/archivo_en_subdir.txt
# Salida esperada: -rw-rw-r--+ 1 100000 sharedfiles 0 sep 8 12:06 archivo_en_subdir.txt
Script de Verificación Completa
#!/bin/bash
# Script de verificación completa
echo "=== VERIFICACIÓN DE CONFIGURACIÓN COMPARTIDA ==="
echo
# Verificar host
echo "1. Verificando configuración del host:"
echo " Directorio: $(ls -ld /mnt/shared_data)"
echo " ACL: $(getfacl /mnt/shared_data | grep -E '(group:sharedfiles|default:group:sharedfiles)')"
echo
# Verificar contenedores
for ct in 100 101; do
if pct status $ct | grep -q running; then
echo "2. Verificando contenedor $ct:"
echo " Montaje: $(pct exec $ct -- df -h | grep shared || echo 'No montado')"
echo " Grupo: $(pct exec $ct -- getent group sharedfiles || echo 'Grupo no existe')"
echo " Usuarios en grupo: $(pct exec $ct -- getent group sharedfiles | cut -d: -f4)"
echo
fi
done
# Prueba de escritura
echo "3. Prueba de escritura:"
test_file="/mnt/shared_data/verification_test.txt"
echo "Test desde host" > "$test_file"
for ct in 100 101; do
if pct status $ct | grep -q running; then
pct exec $ct -- bash -c "echo 'Test desde contenedor $ct' >> /mnt/shared/verification_test.txt" 2>/dev/null
if [ $? -eq 0 ]; then
echo " ✅ Contenedor $ct puede escribir"
else
echo " ❌ Contenedor $ct NO puede escribir"
fi
fi
done
echo
echo "4. Contenido final del archivo de prueba:"
cat "$test_file" 2>/dev/null || echo " ❌ No se puede leer el archivo"
echo
echo "5. Permisos del archivo de prueba:"
ls -l "$test_file" 2>/dev/null || echo " ❌ Archivo no existe"
7. Solución de Problemas
Error: "Permission denied" al escribir
Síntomas
pct exec 101 -- touch /mnt/shared/test.txt
# touch: cannot touch '/mnt/shared/test.txt': Permission denied
Diagnóstico
# 1. Verificar permisos en el host
ls -ld /mnt/shared_data
getfacl /mnt/shared_data
# 2. Verificar grupo en el contenedor
pct exec 101 -- getent group sharedfiles
# 3. Verificar membresía del usuario
pct exec 101 -- groups www-data
Soluciones
# Solución 1: Recrear grupo en contenedor
pct exec 101 -- groupadd -g 1000 sharedfiles
pct exec 101 -- usermod -aG sharedfiles www-data
# Solución 2: Reaplicar ACL en host
setfacl -R -m g:sharedfiles:rwx /mnt/shared_data
setfacl -d -m g:sharedfiles:rwx /mnt/shared_data
# Solución 3: Verificar setgid
chmod 2775 /mnt/shared_data
Error: Archivos aparecen como "nobody:nogroup"
Síntomas
pct exec 101 -- ls -l /mnt/shared/
# -rw-r--r-- 1 nobody nogroup 100 sep 8 12:00 archivo.txt
Causa
El contenedor no tiene un grupo con el GID del archivo.
Solución
# 1. Ver GID numérico en el host
ls -n /mnt/shared_data/archivo.txt
# -rw-r--r-- 1 0 101000 100 sep 8 12:00 archivo.txt
# ↑ GID 101000
# 2. Crear grupo en contenedor con GID mapeado
# GID 101000 en host = GID 1000 en contenedor no privilegiado
pct exec 101 -- groupadd -g 1000 sharedfiles
# 3. Verificar que ahora se ve correctamente
pct exec 101 -- ls -l /mnt/shared/archivo.txt
# -rw-r--r-- 1 nobody sharedfiles 100 sep 8 12:00 archivo.txt
Error: "Transport endpoint is not connected" (NFS)
Síntomas
ls /mnt/nfs_shared
# ls: cannot access '/mnt/nfs_shared': Transport endpoint is not connected
Diagnóstico
# Verificar estado del montaje
mount | grep nfs
df -h | grep nfs
# Verificar conectividad
ping 192.168.1.100
showmount -e 192.168.1.100
Soluciones
# Solución 1: Remontar
umount /mnt/nfs_shared
mount -t nfs 192.168.1.100:/export/shared /mnt/nfs_shared
# Solución 2: Usar opciones más robustas
mount -t nfs 192.168.1.100:/export/shared /mnt/nfs_shared \
-o hard,intr,rsize=32768,wsize=32768,timeo=600,retrans=2
# Solución 3: Verificar servicios NFS
systemctl status nfs-common
systemctl restart nfs-common
Error: Contenedor no puede acceder después de migración
Síntomas
Después de migrar un contenedor a otro nodo, no puede acceder al directorio compartido.
Causa
El directorio compartido no está montado en el nodo destino, o falta shared=1
.
Solución
# 1. Verificar configuración del contenedor
cat /etc/pve/lxc/101.conf | grep mp0
# Debe incluir: shared=1
# 2. Si falta shared=1, añadirlo
pct set 101 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1
# 3. Verificar que el directorio existe en el nodo destino
ls -ld /mnt/shared_data
# 4. Si no existe, montar el recurso en el nodo destino
# (repetir pasos de montaje NFS/Samba según corresponda)
Error: "Operation not supported" con ACL
Síntomas
setfacl -m g:sharedfiles:rwx /mnt/shared_data
# setfacl: /mnt/shared_data: Operation not supported
Causa
El sistema de archivos no soporta ACL.
Diagnóstico
# Verificar tipo de sistema de archivos
df -T /mnt/shared_data
# Verificar opciones de montaje
mount | grep shared_data
Soluciones
# Para ext4: Remontar con soporte ACL
mount -o remount,acl /mnt/shared_data
# Para NFS: Añadir opción acl
umount /mnt/shared_data
mount -t nfs 192.168.1.100:/export/shared /mnt/shared_data -o acl
# Para sistemas de archivos que no soportan ACL:
# Usar solo permisos tradicionales con setgid
chmod 2775 /mnt/shared_data
Archivos creados con permisos incorrectos
Síntomas
Los archivos se crean con permisos 644 en lugar de 664.
Causa
La umask del proceso no permite escritura de grupo.
Solución
# Verificar umask actual
pct exec 101 -- umask
# Si es 022, cambiar a 002
# Cambiar umask temporalmente
pct exec 101 -- umask 002
# Cambiar umask permanentemente
pct exec 101 -- bash -c 'echo "umask 002" >> /etc/profile'
# Alternativa: Usar ACL por defecto (más robusta)
setfacl -d -m g:sharedfiles:rwx /mnt/shared_data
setfacl -d -m o::r-x /mnt/shared_data
📋 Resumen de Comandos Clave
Configuración del Host
# Crear directorio local
mkdir -p /mnt/shared_data
groupadd -g 101000 sharedfiles
chown root:sharedfiles /mnt/shared_data
chmod 2775 /mnt/shared_data
setfacl -R -m g:sharedfiles:rwx /mnt/shared_data
setfacl -d -m g:sharedfiles:rwx /mnt/shared_data
# Montar NFS persistente
echo "192.168.1.100:/export/shared /mnt/nfs_shared nfs rw,hard,nofail,_netdev 0 0" >> /etc/fstab
# Montar Samba persistente
echo "//192.168.1.200/share /mnt/samba_shared cifs credentials=/etc/cifs-creds,uid=root,gid=101000,file_mode=0664,dir_mode=2775,_netdev,nofail 0 0" >> /etc/fstab
Configuración de Contenedores
# Contenedor privilegiado
pct exec 100 -- groupadd -g 101000 sharedfiles
pct exec 100 -- usermod -aG sharedfiles root
pct exec 100 -- usermod -aG sharedfiles www-data
# Contenedor no privilegiado
pct exec 101 -- groupadd -g 1000 sharedfiles
pct exec 101 -- usermod -aG sharedfiles root
pct exec 101 -- usermod -aG sharedfiles www-data
# Montaje
pct set 100 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1
pct set 101 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1
Verificación
# Verificar configuración
ls -ld /mnt/shared_data
getfacl /mnt/shared_data
pct exec 101 -- groups www-data
# Prueba de escritura
echo "test" > /mnt/shared_data/test.txt
pct exec 100 -- touch /mnt/shared/test_priv.txt
pct exec 101 -- touch /mnt/shared/test_unpriv.txt
🎯 Conclusión
Esta guía te ha mostrado cómo configurar correctamente recursos compartidos entre Proxmox y contenedores LXC, tanto privilegiados como no privilegiados. Los conceptos clave son:
- Grupo común (
sharedfiles
) con GID consistente - Setgid (2775) para herencia automática de grupo
- ACL para garantizar permisos robustos
- Mapeo correcto de UIDs/GIDs en contenedores no privilegiados
- Configuración adecuada de montajes con
shared=1
,backup=0
,acl=1
Con esta configuración, tendrás un sistema robusto que funciona con NFS, Samba, directorios locales, y es compatible con clusters y migraciones de Proxmox.