# 📘 Guía Completa: Compartir Recursos entre Proxmox Host y Contenedores LXC ## 📋 Índice 1. [Introducción](#introducción) 2. [Conceptos Fundamentales](#conceptos-fundamentales) - [Usuarios y Grupos en Linux](#usuarios-y-grupos-en-linux) - [Permisos en Linux](#permisos-en-linux) - [Access Control Lists (ACL)](#access-control-lists-acl) - [Contenedores No Privilegiados](#contenedores-no-privilegiados) 3. [Tipos de Recursos Compartidos](#tipos-de-recursos-compartidos) - [NFS (Network File System)](#nfs-network-file-system) - [Samba/CIFS](#sambacifs) - [Directorios Locales](#directorios-locales) 4. [Configuración Paso a Paso](#configuración-paso-a-paso) - [Preparación del Host](#preparación-del-host) - [Montar Recursos Compartidos](#montar-recursos-compartidos) - [Configurar Contenedores](#configurar-contenedores) - [Crear Puntos de Montaje](#crear-puntos-de-montaje) 5. [Verificación y Pruebas](#verificación-y-pruebas) 6. [Solución de Problemas](#solución-de-problemas) 7. [Mejores Prácticas](#mejores-prácticas) --- ## Introducción Esta guía explica cómo compartir recursos (NFS, Samba, directorios locales) entre el host de Proxmox y contenedores LXC, tanto privilegiados como no privilegiados, manteniendo permisos correctos y acceso de lectura/escritura. ### ¿Por qué es complejo? - Los **contenedores no privilegiados** usan IDs de usuario/grupo desplazados (+100000) - **NFS y Samba** manejan permisos de manera diferente - Los **permisos tradicionales** de Linux tienen limitaciones - La **persistencia** tras reinicios requiere configuración específica ### ¿Qué aprenderás? - Cómo funcionan los permisos en Linux y por qué fallan con contenedores - Qué son las ACL y por qué son esenciales para recursos compartidos - Cómo configurar correctamente NFS, Samba y directorios locales - Por qué usar el GID 101000 y el grupo `sharedfiles` - Cómo hacer que todo sea persistente tras reinicios --- ## 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`, `ncp` - **UID (User ID)**: Número único, como `0` (root), `33` (www-data), `1000` (primer usuario) ```bash # Ver información de un usuario id www-data # Salida: uid=33(www-data) gid=33(www-data) groups=33(www-data) # Listar usuarios del sistema (solo los relevantes) awk -F: '$3>=1000 && $1!="nobody"{print $1 " (UID: " $3 ")"}' /etc/passwd # Salida ejemplo: # ncp (UID: 1000) # usuario1 (UID: 1001) ``` #### ¿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) ```bash # Ver todos los grupos relevantes getent group | grep -E "(root|www-data|sharedfiles)" | head -5 # Salida: # root:x:0: # www-data:x:33: # sharedfiles:x:101000: # Ver grupos de un usuario groups www-data # Salida: www-data : www-data # Crear un nuevo grupo con GID específico groupadd -g 101000 sharedfiles # Añadir usuario a un grupo usermod -aG sharedfiles 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 `sharedfiles`, añades todos los usuarios web, y das permisos al grupo --- ### Permisos en Linux #### 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 ```bash # Ver permisos de un directorio específico ls -ld /mnt/shared_data # Salida: drwxrwxr-x 2 root sharedfiles 4096 sep 8 10:30 /mnt/shared_data # │││││││││ # │└┴┴┴┴┴┴┴─ 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: ```bash # 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 (Herencia de Grupo) El **setgid** es crucial para directorios compartidos y es la clave para que funcionen correctamente: ```bash # Sin setgid - PROBLEMA mkdir /tmp/sin_setgid chmod 775 /tmp/sin_setgid chgrp sharedfiles /tmp/sin_setgid # Crear archivo como usuario diferente sudo -u www-data touch /tmp/sin_setgid/archivo1 ls -ld /tmp/sin_setgid/archivo1 # Salida: -rw-r--r-- 1 www-data www-data 0 sep 8 10:35 /tmp/sin_setgid/archivo1 # ❌ El archivo pertenece al grupo 'www-data', no 'sharedfiles' # Con setgid - SOLUCIÓN mkdir /tmp/con_setgid chmod 2775 /tmp/con_setgid # El '2' inicial activa setgid chgrp sharedfiles /tmp/con_setgid sudo -u www-data touch /tmp/con_setgid/archivo2 ls -ld /tmp/con_setgid/archivo2 # Salida: -rw-r--r-- 1 www-data sharedfiles 0 sep 8 10:36 /tmp/con_setgid/archivo2 # ✅ El archivo hereda el grupo 'sharedfiles' del directorio padre ``` **¿Por qué es importante setgid?** - **Sin setgid**: Cada proceso crea archivos con su grupo primario → inconsistencia - **Con setgid**: Todos los archivos nuevos heredan el grupo del directorio → consistencia - **Resultado**: Todos los usuarios del grupo pueden leer/escribir todos los archivos **Identificar setgid visualmente**: ```bash ls -ld /mnt/shared_data # Con setgid: drwxrwsr-x (nota la 's' en lugar de 'x' en el grupo) # Sin setgid: drwxrwxr-x (nota la 'x' normal en el grupo) ``` --- ### 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 ```bash # Instalar herramientas ACL (si no están instaladas) apt-get update && apt-get install -y acl # Ver ACL de un directorio getfacl /mnt/shared_data # Salida: # file: mnt/shared_data # 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 ```bash # Dar permisos a un grupo específico setfacl -m g:webapps:rwx /mnt/shared_data # Dar permisos a un usuario específico setfacl -m u:ncp:rwx /mnt/shared_data # Configurar permisos por defecto (se heredan en archivos nuevos) setfacl -d -m g:sharedfiles:rwx /mnt/shared_data # Aplicar ACL recursivamente a todo el contenido existente setfacl -R -m g:sharedfiles:rwx /mnt/shared_data # Combinar: aplicar a existente Y configurar por defecto setfacl -R -m g:sharedfiles:rwx /mnt/shared_data setfacl -d -m g:sharedfiles:rwx /mnt/shared_data ``` #### ¿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**: ```bash # 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 'sharedfiles' siempre tiene acceso, independiente de UIDs ``` **Samba y herencia**: - Samba puede forzar grupos, pero las ACL son más flexibles - Las ACL por defecto aseguran herencia correcta - Funcionan incluso si Samba no está configurado perfectamente --- ### Contenedores No Privilegiados #### ¿Qué son los Contenedores No Privilegiados? Los contenedores **no privilegiados** son más seguros porque: - El usuario `root` del contenedor NO es `root` del host - Los IDs de usuario/grupo están "desplazados" - Limitan el daño si el contenedor es comprometido #### Mapeo de IDs en Proxmox En un contenedor no privilegiado típico de Proxmox: | 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 | #### ¿Por qué usar GID 101000? **El GID 101000 es estratégico porque**: - Es el **primer GID mapeado** para contenedores no privilegiados en Proxmox - Corresponde al **GID 1000 dentro del contenedor**, que es el GID estándar para grupos de usuarios - Garantiza **compatibilidad universal** entre contenedores privilegiados y no privilegiados - Es **predecible** y **consistente** en todas las instalaciones de Proxmox ```bash # En el HOST: Crear grupo con GID 101000 groupadd -g 101000 sharedfiles # En CONTENEDOR NO PRIVILEGIADO: Crear grupo con GID 1000 groupadd -g 1000 sharedfiles # Este GID 1000 del contenedor se mapea automáticamente al GID 101000 del host # En CONTENEDOR PRIVILEGIADO: Crear grupo con GID 101000 groupadd -g 101000 sharedfiles # Mismo GID que el host, sin mapeo ``` #### El Problema en la Práctica ```bash # En el HOST: Crear archivo con grupo 'sharedfiles' (GID 101000) echo "datos importantes" > /mnt/shared_data/archivo.txt chgrp sharedfiles /mnt/shared_data/archivo.txt ls -ld /mnt/shared_data/archivo.txt # Salida: -rw-r--r-- 1 root sharedfiles 18 sep 8 archivo.txt # En el CONTENEDOR NO PRIVILEGIADO (sin configurar): Ver el mismo archivo pct exec 101 -- ls -ld /mnt/shared_data/archivo.txt # Salida: -rw-r--r-- 1 nobody nogroup 18 sep 8 archivo.txt # ❌ El contenedor ve 'nobody:nogroup' porque no conoce el GID 101000 del host # En el CONTENEDOR NO PRIVILEGIADO (configurado): Ver el mismo archivo pct exec 101 -- ls -ld /mnt/shared_data/archivo.txt # Salida: -rw-r--r-- 1 root sharedfiles 18 sep 8 archivo.txt # ✅ El contenedor reconoce el grupo porque tiene 'sharedfiles' con GID 1000 (mapeado a 101000) ``` #### ¿Por qué pasa esto? 1. **Host**: El archivo pertenece al GID 101000 (`sharedfiles`) 2. **Contenedor**: Busca qué grupo tiene GID 1000 en SU `/etc/group` (porque 101000 - 100000 = 1000) 3. **Sin configurar**: Si no existe ese GID en el contenedor, muestra `nogroup` 4. **Configurado**: Si existe el grupo `sharedfiles` con GID 1000, lo reconoce correctamente 5. **Consecuencia**: Solo con la configuración correcta el usuario del contenedor puede escribir --- ## Tipos de Recursos Compartidos ### NFS (Network File System) #### ¿Qué es NFS? **NFS** es un protocolo que permite montar directorios remotos como si fueran locales. Es especialmente popular en entornos Linux/Unix. #### ¿Cómo funcionan los permisos en NFS? **Característica clave**: NFS transmite solo **números** (UID/GID), no nombres de usuarios/grupos. ```bash # Servidor NFS (ej: TrueNAS, Synology, servidor Linux) # Archivo creado por usuario 'admin' (UID 1001) en grupo 'storage' (GID 2000) -rw-rw-r-- 1 admin storage 1024 sep 8 archivo.txt # Cliente NFS (Proxmox host) # NFS transmite: UID=1001, GID=2000 # Proxmox busca en su /etc/passwd y /etc/group: # - ¿Existe UID 1001? Si no → muestra número o 'nobody' # - ¿Existe GID 2000? Si no → muestra número o 'nogroup' # Resultado típico en Proxmox: -rw-rw-r-- 1 1001 2000 1024 sep 8 archivo.txt # o -rw-rw-r-- 1 nobody nogroup 1024 sep 8 archivo.txt ``` #### Problemas comunes con permisos NFS **Problema 1: UIDs/GIDs diferentes** ```bash # Servidor NFS: usuario 'web' = UID 500 # Cliente: usuario 'web' = UID 1000 # Resultado: El cliente no puede acceder a archivos del servidor ``` **Problema 2: Usuarios inexistentes** ```bash # Servidor: archivo creado por UID 1500 (usuario 'app') # Cliente: no existe UID 1500 # Resultado: archivo aparece como 'nobody' y no es accesible ``` **Solución: Grupo universal + ACL** ```bash # En lugar de depender de UIDs específicos, usar un grupo común: # 1. Crear grupo 'sharedfiles' con GID 101000 en host y contenedores # 2. Aplicar ACL para dar permisos al grupo # 3. Todos los usuarios relevantes pertenecen al grupo # Resultado: Funciona independientemente de los UIDs individuales ``` #### Configuración típica de servidores NFS **TrueNAS/FreeNAS**: - Crear dataset con permisos Unix - Configurar servicio NFS - Definir redes permitidas - Los permisos se basan en UID/GID numéricos **Synology**: - Crear carpeta compartida - Habilitar servicio NFS - Configurar permisos de acceso - Mapear usuarios si es necesario **Servidor Linux**: ```bash # /etc/exports /export/data 192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash) ``` --- ### Samba/CIFS #### ¿Qué es Samba? **Samba** implementa el protocolo SMB/CIFS, permitiendo que sistemas Linux compartan archivos con Windows y otros sistemas. #### ¿Cómo funcionan los permisos en Samba? Samba tiene **dos capas de permisos**: 1. **Permisos de Samba** (definidos en smb.conf) 2. **Permisos del sistema de archivos** (permisos Unix tradicionales + ACL) ```bash # Ejemplo de configuración Samba [shared_data] path = /srv/samba/shared browseable = yes read only = no valid users = @storage_users force group = storage_users create mask = 0664 directory mask = 2775 ``` #### Diferencias con NFS | Aspecto | NFS | Samba | |---------|-----|-------| | **Autenticación** | Basada en IP/red | Usuario/contraseña | | **Permisos** | Solo UID/GID numéricos | Mapeo de usuarios + permisos Unix | | **Herencia** | Depende del sistema de archivos | Configurable (force group, masks) | | **Compatibilidad** | Linux/Unix nativo | Multiplataforma (Windows, Linux, macOS) | #### Configuración típica de servidores Samba **Servidor Linux con Samba**: ```bash # /etc/samba/smb.conf [global] workgroup = WORKGROUP security = user map to guest = bad user [shared] path = /srv/samba/shared valid users = @sharedfiles force group = sharedfiles create mask = 0664 directory mask = 2775 read only = no ``` **NAS (Synology, QNAP, etc.)**: - Crear carpeta compartida - Configurar usuarios y grupos - Habilitar SMB/CIFS - Definir permisos por usuario/grupo --- ### Directorios Locales #### ¿Qué son los directorios locales? Son carpetas que existen directamente en el host de Proxmox, sin involucrar protocolos de red. #### Ventajas - **Rendimiento máximo** (sin overhead de red) - **Simplicidad** (sin configuración de red) - **Control total** sobre permisos - **Ideal para datos críticos** o de alta frecuencia de acceso #### Casos de uso típicos ```bash # Logs centralizados /var/log/containers/ # Configuraciones compartidas /etc/shared-configs/ # Datos de aplicaciones /opt/app-data/ # Backups locales /backup/containers/ ``` --- ## Configuración Paso a Paso ### Preparación del Host #### Paso 1: Instalar herramientas necesarias ```bash # Actualizar sistema apt-get update # Instalar herramientas ACL apt-get install -y acl # Instalar cliente NFS (si vas a usar NFS) apt-get install -y nfs-common # Instalar cliente Samba (si vas a usar Samba) apt-get install -y cifs-utils # Verificar instalación which setfacl getfacl mount.nfs mount.cifs ``` #### Paso 2: Crear grupo universal ```bash # Crear grupo con GID específico para compatibilidad universal groupadd -g 101000 sharedfiles # Verificar creación getent group sharedfiles # Salida: sharedfiles:x:101000: # Añadir usuario root al grupo (opcional, para pruebas) usermod -aG sharedfiles root ``` **¿Por qué GID 101000?** - Es el primer GID mapeado en contenedores no privilegiados de Proxmox - Corresponde al GID 1000 dentro del contenedor (GID estándar de usuarios) - Garantiza compatibilidad entre contenedores privilegiados y no privilegiados - Es predecible y consistente en todas las instalaciones --- ### Montar Recursos Compartidos #### Opción A: Montar recurso NFS ```bash # Crear punto de montaje mkdir -p /mnt/nfs_share # Montar temporalmente para probar mount -t nfs 192.168.1.100:/export/data /mnt/nfs_share # Verificar montaje df -h | grep nfs_share # Salida: 192.168.1.100:/export/data 100G 50G 50G 50% /mnt/nfs_share # Ver permisos originales ls -ld /mnt/nfs_share # Salida típica: drwxr-xr-x 2 1001 1001 4096 sep 8 /mnt/nfs_share ``` **Hacer montaje persistente**: ```bash # Editar /etc/fstab echo "192.168.1.100:/export/data /mnt/nfs_share nfs rw,hard,nofail,rsize=131072,wsize=131072,timeo=600,retrans=2,_netdev 0 0" >> /etc/fstab # Verificar sintaxis mount -a # Comprobar que funciona tras reinicio systemctl reboot # Tras reinicio: df -h | grep nfs_share ``` **Explicación de opciones NFS**: - `rw`: Lectura y escritura - `hard`: Reintentar indefinidamente si el servidor no responde - `nofail`: No fallar el arranque si no se puede montar - `rsize/wsize=131072`: Tamaño de buffer para mejor rendimiento - `timeo=600`: Timeout de 60 segundos - `retrans=2`: Reintentar 2 veces antes de reportar error - `_netdev`: Esperar a que la red esté lista - `0 0`: No hacer dump ni fsck (siempre para recursos de red) #### Opción B: Montar recurso Samba ```bash # Crear punto de montaje mkdir -p /mnt/samba_share # Crear archivo de credenciales cat > /etc/cifs-credentials << EOF username=tu_usuario password=tu_password domain=tu_dominio EOF # Proteger archivo de credenciales chmod 600 /etc/cifs-credentials # Montar temporalmente para probar mount -t cifs //192.168.1.200/shared /mnt/samba_share -o credentials=/etc/cifs-credentials,iocharset=utf8,vers=3.0 # Verificar montaje df -h | grep samba_share # Salida: //192.168.1.200/shared 500G 200G 300G 40% /mnt/samba_share # Ver permisos originales ls -ld /mnt/samba_share ``` **Hacer montaje persistente**: ```bash # Editar /etc/fstab echo "//192.168.1.200/shared /mnt/samba_share cifs credentials=/etc/cifs-credentials,iocharset=utf8,vers=3.0,_netdev,nofail 0 0" >> /etc/fstab # Verificar sintaxis mount -a ``` **Explicación de opciones Samba**: - `credentials=`: Archivo con usuario/contraseña - `iocharset=utf8`: Codificación de caracteres - `vers=3.0`: Versión del protocolo SMB - `_netdev`: Esperar a que la red esté lista - `nofail`: No fallar el arranque si no se puede montar #### Opción C: Crear directorio local ```bash # Crear directorio local mkdir -p /mnt/local_share # Ver permisos iniciales ls -ld /mnt/local_share # Salida: drwxr-xr-x 2 root root 4096 sep 8 /mnt/local_share ``` --- ### Configurar Permisos Universales **Independientemente del tipo de recurso (NFS, Samba, local), aplicar la misma configuración**: ```bash # Ejemplo con /mnt/shared_data (cambiar por tu ruta) SHARED_DIR="/mnt/shared_data" # Paso 1: Asignar propietario y grupo chown root:sharedfiles "$SHARED_DIR" # Paso 2: Aplicar permisos con setgid chmod 2775 "$SHARED_DIR" # Paso 3: Verificar setgid (debe aparecer 's' en lugar de 'x' para el grupo) ls -ld "$SHARED_DIR" # Salida esperada: drwxrwsr-x 2 root sharedfiles 4096 sep 8 /mnt/shared_data # ↑ Esta 's' indica setgid activo # Paso 4: Aplicar ACL para contenido existente setfacl -R -m g:sharedfiles:rwx "$SHARED_DIR" # Paso 5: Configurar ACL por defecto para archivos nuevos setfacl -d -m g:sharedfiles:rwx "$SHARED_DIR" # Paso 6: Verificar ACL getfacl "$SHARED_DIR" # Salida esperada: # file: mnt/shared_data # owner: root # group: sharedfiles # user::rwx # group::rwx # other::r-x # default:user::rwx # default:group::rwx # default:other::r-x ``` **¿Por qué esta configuración funciona universalmente?** - **chown root:sharedfiles**: Establece un propietario conocido y el grupo universal - **chmod 2775**: Da permisos completos al propietario y grupo, y activa setgid - **setgid (el '2' en 2775)**: Asegura que todos los archivos nuevos hereden el grupo `sharedfiles` - **ACL recursiva (-R)**: Corrige permisos de archivos/directorios existentes - **ACL por defecto (-d)**: Asegura que archivos nuevos tengan permisos correctos --- ### Configurar Contenedores #### Contenedores Privilegiados Los contenedores privilegiados comparten los mismos UIDs/GIDs que el host, por lo que la configuración es más simple: ```bash # Entrar al contenedor privilegiado (ejemplo: ID 100) pct exec 100 -- bash # Crear grupo idéntico al host groupadd -g 101000 sharedfiles # Añadir usuarios relevantes al grupo usermod -aG sharedfiles root usermod -aG sharedfiles www-data # Si tienes Nextcloud u otras aplicaciones usermod -aG sharedfiles ncp 2>/dev/null || true # Verificar membresía groups root # Salida: root : root sharedfiles groups www-data # Salida: www-data : www-data sharedfiles # Salir del contenedor exit ``` **Nota importante**: En contenedores privilegiados, técnicamente no es estrictamente necesario añadir usuarios al grupo si solo el propietario (root) va a escribir archivos. Sin embargo, es una buena práctica porque: - **Consistencia**: Mantiene la misma configuración en todos los contenedores - **Flexibilidad**: Permite que servicios web (www-data) o aplicaciones (ncp) escriban directamente - **Futuro**: Si cambias permisos o añades servicios, ya está configurado - **Depuración**: Es más fácil diagnosticar problemas cuando la configuración es uniforme #### Contenedores No Privilegiados Los contenedores no privilegiados requieren mapeo de IDs, por lo que necesitan configuración específica: ```bash # Entrar al contenedor no privilegiado (ejemplo: ID 101) pct exec 101 -- bash # Crear grupo con GID mapeado groupadd -g 1000 sharedfiles # Importante: GID 1000 en contenedor = GID 101000 en host # Listar usuarios disponibles en el contenedor awk -F: '$3>=1000 && $1!="nobody"{print $1 " (UID: " $3 ")"}' /etc/passwd # Salida ejemplo: # ncp (UID: 1000) # www-data (UID: 33) # Añadir usuarios al grupo usermod -aG sharedfiles root usermod -aG sharedfiles www-data # Ejemplo específico: añadir usuario de Nextcloud usermod -aG sharedfiles ncp 2>/dev/null || true # Verificar configuración completa id www-data # Salida esperada: uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(sharedfiles) id ncp 2>/dev/null || echo "Usuario ncp no existe" # Si existe: uid=1000(ncp) gid=1000(ncp) groups=1000(ncp),1000(sharedfiles) # Salir del contenedor exit ``` **¿Cómo añadir más usuarios?** Si necesitas añadir usuarios adicionales (por ejemplo, para otras aplicaciones): ```bash # Dentro del contenedor no privilegiado pct exec 101 -- bash # Ver todos los usuarios del sistema cat /etc/passwd | grep -v nologin | grep -v false | awk -F: '{print $1 " (UID: " $3 ")"}' # Añadir usuarios específicos usermod -aG sharedfiles usuario1 usermod -aG sharedfiles usuario2 # Para añadir TODOS los usuarios con UID >= 1000 automáticamente: for user in $(awk -F: '$3>=1000 && $1!="nobody"{print $1}' /etc/passwd); do usermod -aG sharedfiles "$user" 2>/dev/null || true echo "Añadido usuario: $user" done # Verificar todos los usuarios añadidos getent group sharedfiles # Salida: sharedfiles:x:1000:root,www-data,ncp,usuario1,usuario2 exit ``` --- ### Crear Puntos de Montaje #### Configurar montajes en contenedores ```bash # Para contenedor privilegiado (ID 100) pct set 100 -mp0 /mnt/shared_data,mp=/mnt/shared,shared=1,backup=0,acl=1 # Para contenedor no privilegiado (ID 101) pct set 101 -mp0 /mnt/shared_data,mp=/mnt/shared,shared=1,backup=0,acl=1 # Reiniciar contenedores para activar montajes pct reboot 100 pct reboot 101 # Esperar a que arranquen sleep 15 # Verificar que los montajes están activos pct exec 100 -- df -h | grep shared pct exec 101 -- df -h | grep shared ``` **Explicación de parámetros**: - `mp0`: Primer punto de montaje (mp1, mp2, etc. para adicionales) - `/mnt/shared_data`: Ruta en el host - `mp=/mnt/shared`: Ruta dentro del contenedor - `shared=1`: **Esencial para clusters** - permite migración sin copiar datos - `backup=0`: Excluye del backup de vzdump (evita duplicar datos) - `acl=1`: Habilita soporte ACL dentro del contenedor **¿Por qué shared=1 es importante?** - Sin `shared=1`: Proxmox copia todos los datos al migrar el contenedor - Con `shared=1`: Proxmox asume que los datos están disponibles en todos los nodos - **Resultado**: Migraciones rápidas y sin duplicar almacenamiento --- ## Verificación y Pruebas ### Prueba básica de funcionamiento ```bash # Desde el HOST: Crear archivo de prueba echo "Archivo creado desde el host" > /mnt/shared_data/test_host.txt ls -ld /mnt/shared_data/test_host.txt # Salida esperada: -rw-r--r-- 1 root sharedfiles 29 sep 8 test_host.txt # Desde CONTENEDOR PRIVILEGIADO: Crear archivo pct exec 100 -- bash -c 'echo "Archivo desde contenedor privilegiado" > /mnt/shared/test_privileged.txt' pct exec 100 -- ls -ld /mnt/shared/test_privileged.txt # Salida esperada: -rw-r--r-- 1 root sharedfiles 35 sep 8 test_privileged.txt # Desde CONTENEDOR NO PRIVILEGIADO: Crear archivo pct exec 101 -- bash -c 'echo "Archivo desde contenedor no privilegiado" > /mnt/shared/test_unprivileged.txt' pct exec 101 -- ls -ld /mnt/shared/test_unprivileged.txt # Salida esperada: -rw-r--r-- 1 root sharedfiles 38 sep 8 test_unprivileged.txt # Verificar desde el HOST que todos los archivos son accesibles ls -ld /mnt/shared_data/test_*.txt # Todos deben mostrar grupo 'sharedfiles' y ser legibles ``` ### Prueba de escritura cruzada ```bash # Desde HOST: Modificar archivo creado por contenedor echo "Modificado desde host" >> /mnt/shared_data/test_privileged.txt # Desde CONTENEDOR PRIVILEGIADO: Modificar archivo creado por host pct exec 100 -- bash -c 'echo "Modificado desde privilegiado" >> /mnt/shared/test_host.txt' # Desde CONTENEDOR NO PRIVILEGIADO: Modificar archivo creado por privilegiado pct exec 101 -- bash -c 'echo "Modificado desde no privilegiado" >> /mnt/shared/test_privileged.txt' # Verificar que todas las modificaciones funcionaron cat /mnt/shared_data/test_host.txt cat /mnt/shared_data/test_privileged.txt ``` ### Verificar herencia de permisos ```bash # Crear subdirectorio desde contenedor no privilegiado pct exec 101 -- mkdir -p /mnt/shared/subdir_test # Verificar que hereda el grupo correcto ls -ld /mnt/shared_data/subdir_test # Salida esperada: drwxrwsr-x 2 root sharedfiles 4096 sep 8 subdir_test # ↑ La 's' indica que setgid se heredó # Crear archivo dentro del subdirectorio pct exec 101 -- bash -c 'echo "test herencia" > /mnt/shared/subdir_test/archivo.txt' # Verificar herencia de grupo ls -ld /mnt/shared_data/subdir_test/archivo.txt # Salida esperada: -rw-r--r-- 1 root sharedfiles 14 sep 8 archivo.txt ``` --- ## Solución de Problemas ### Error: "Permission denied" al escribir **Síntomas**: ```bash pct exec 101 -- bash -c 'echo "test" > /mnt/shared/test.txt' # bash: /mnt/shared/test.txt: Permission denied ``` **Diagnóstico**: ```bash # 1. Verificar permisos del directorio ls -ld /mnt/shared_data # ¿Tiene permisos de escritura para el grupo? ¿Está activo setgid? # 2. Verificar grupo en el contenedor pct exec 101 -- getent group sharedfiles # ¿Existe el grupo? ¿Tiene el GID correcto? # 3. Verificar membresía del usuario pct exec 101 -- groups root # ¿El usuario pertenece al grupo sharedfiles? # 4. Verificar ACL getfacl /mnt/shared_data # ¿Están configuradas las ACL para el grupo? ``` **Soluciones**: ```bash # Solución 1: Reconfigurar permisos básicos chmod 2775 /mnt/shared_data chgrp sharedfiles /mnt/shared_data # Solución 2: Recrear grupo en contenedor pct exec 101 -- groupadd -g 1000 sharedfiles pct exec 101 -- usermod -aG sharedfiles root # Solución 3: Reconfigurar ACL setfacl -R -m g:sharedfiles:rwx /mnt/shared_data setfacl -d -m g:sharedfiles:rwx /mnt/shared_data # Solución 4: Reiniciar contenedor pct reboot 101 ``` ### Error: Archivos aparecen como "nobody:nogroup" **Síntomas**: ```bash pct exec 101 -- ls -ld /mnt/shared/archivo.txt # -rw-r--r-- 1 nobody nogroup 100 sep 8 archivo.txt ``` **Causa**: El contenedor no reconoce los UIDs/GIDs del host. **Solución**: ```bash # Crear grupo con GID correcto en el contenedor pct exec 101 -- groupadd -g 1000 sharedfiles # Si el problema persiste, verificar mapeo pct exec 101 -- cat /proc/self/uid_map pct exec 101 -- cat /proc/self/gid_map ``` ### Error: Montaje NFS falla **Síntomas**: ```bash mount -t nfs 192.168.1.100:/export/data /mnt/nfs_share # mount.nfs: Connection refused ``` **Diagnóstico**: ```bash # 1. Verificar conectividad ping 192.168.1.100 # 2. Verificar servicio NFS en el servidor showmount -e 192.168.1.100 # 3. Verificar puertos nmap -p 111,2049 192.168.1.100 # 4. Verificar logs journalctl -u nfs-client -f ``` **Soluciones**: ```bash # Instalar cliente NFS si no está apt-get install -y nfs-common # Reiniciar servicios NFS systemctl restart nfs-client.target # Probar con opciones específicas mount -t nfs -o vers=3 192.168.1.100:/export/data /mnt/nfs_share ``` ### Error: Montaje Samba falla **Síntomas**: ```bash mount -t cifs //192.168.1.200/shared /mnt/samba_share # mount error(13): Permission denied ``` **Diagnóstico**: ```bash # 1. Verificar credenciales cat /etc/cifs-credentials # 2. Probar conexión manual smbclient -L //192.168.1.200 -U usuario # 3. Verificar versión SMB mount -t cifs //192.168.1.200/shared /mnt/samba_share -o vers=1.0,username=usuario ``` **Soluciones**: ```bash # Instalar cliente Samba si no está apt-get install -y cifs-utils # Probar diferentes versiones SMB mount -t cifs //192.168.1.200/shared /mnt/samba_share -o vers=3.0,credentials=/etc/cifs-credentials # Verificar y corregir credenciales chmod 600 /etc/cifs-credentials ``` ### Error: Contenedor no arranca tras añadir montaje **Síntomas**: ```bash pct start 101 # TASK ERROR: startup for container '101' failed ``` **Diagnóstico**: ```bash # Ver configuración del contenedor cat /etc/pve/lxc/101.conf | grep mp # Ver logs del contenedor journalctl -u pve-container@101 -f ``` **Soluciones**: ```bash # Verificar que la ruta del host existe ls -ld /mnt/shared_data # Corregir configuración si es necesaria pct set 101 -delete mp0 pct set 101 -mp0 /mnt/shared_data,mp=/mnt/shared,shared=1,backup=0,acl=1 # Arrancar contenedor pct start 101 ``` --- ## Mejores Prácticas ### Organización de directorios ```bash # Estructura recomendada /mnt/ ├── nfs_shares/ │ ├── documents/ │ ├── media/ │ └── backups/ ├── samba_shares/ │ ├── public/ │ └── private/ └── local_shares/ ├── configs/ ├── logs/ └── data/ ``` ### Nomenclatura consistente ```bash # Usar nombres descriptivos y consistentes /mnt/nfs_documents # En lugar de /mnt/share1 /mnt/samba_public # En lugar de /mnt/smb /mnt/local_configs # En lugar de /mnt/data ``` ### Seguridad ```bash # Limitar permisos de "otros" chmod 2770 /mnt/sensitive_data # Sin acceso para "otros" # Usar ACL específicas para datos sensibles setfacl -m u:admin:rwx /mnt/sensitive_data setfacl -m g:admins:rwx /mnt/sensitive_data setfacl -m other::--- /mnt/sensitive_data # Sin acceso para otros ``` ### Monitoreo ```bash # Script para verificar montajes #!/bin/bash for mount in /mnt/nfs_* /mnt/samba_* /mnt/local_*; do if mountpoint -q "$mount"; then echo "✅ $mount está montado" else echo "❌ $mount NO está montado" fi done # Verificar permisos for dir in /mnt/*/; do if [[ $(stat -c %G "$dir") == "sharedfiles" ]]; then echo "✅ $dir tiene grupo correcto" else echo "❌ $dir tiene grupo incorrecto: $(stat -c %G "$dir")" fi done ``` ### Backup y recuperación ```bash # Backup de configuraciones cp /etc/fstab /etc/fstab.backup cp /etc/cifs-credentials /etc/cifs-credentials.backup # Backup de configuraciones de contenedores cp /etc/pve/lxc/*.conf /backup/lxc-configs/ # Script de restauración rápida #!/bin/bash # restore_mounts.sh systemctl stop pve-container@* mount -a systemctl start pve-container@* ``` --- ## Resumen Final ### Puntos clave para recordar 1. **Grupo universal**: Usar `sharedfiles` con GID 101000 en host, GID 1000 en contenedores no privilegiados 2. **Setgid**: Siempre usar `chmod 2775` para herencia automática de grupo 3. **ACL**: Aplicar tanto recursivamente (-R) como por defecto (-d) 4. **Montajes**: Usar `shared=1,backup=0,acl=1` en configuraciones de contenedores 5. **Persistencia**: Configurar `/etc/fstab` con opciones `_netdev,nofail,0 0` ### Comando de verificación rápida ```bash # Ejecutar para verificar configuración completa #!/bin/bash echo "=== Verificación de configuración ===" echo "1. Grupo sharedfiles en host:" getent group sharedfiles echo "2. Permisos del directorio compartido:" ls -ld /mnt/shared_data echo "3. ACL configuradas:" getfacl /mnt/shared_data | grep -E "(group:sharedfiles|default:group:sharedfiles)" echo "4. Montajes en contenedores:" pct exec 100 -- df -h | grep shared 2>/dev/null || echo "Contenedor 100 no disponible" pct exec 101 -- df -h | grep shared 2>/dev/null || echo "Contenedor 101 no disponible" echo "5. Grupos en contenedores:" pct exec 100 -- getent group sharedfiles 2>/dev/null || echo "Grupo no configurado en contenedor 100" pct exec 101 -- getent group sharedfiles 2>/dev/null || echo "Grupo no configurado en contenedor 101" echo "=== Verificación completada ===" ``` Con esta configuración, tendrás un sistema robusto y flexible para compartir recursos entre Proxmox y contenedores LXC, con permisos correctos y persistencia tras reinicios. ```