diff --git a/scripts/share/guia.md b/scripts/share/guia.md new file mode 100644 index 0000000..2daa849 --- /dev/null +++ b/scripts/share/guia.md @@ -0,0 +1,741 @@ +# 📘 Guía Completa: Compartir Recursos entre Proxmox Host y Contenedores LXC + +## 🎯 Introducción + +Esta guía explica paso a paso cómo compartir carpetas y recursos entre el host de Proxmox y contenedores LXC (privilegiados y no privilegiados). Aprenderás los conceptos fundamentales de permisos en Linux y cómo configurar correctamente NFS, Samba y directorios locales. + +### ¿Por qué es importante? + +En Proxmox es común necesitar que varios contenedores accedan a los mismos datos: +- Compartir archivos entre múltiples servicios +- Servir contenido por red (NFS/Samba) +- Centralizar almacenamiento de datos +- Hacer backups centralizados + +El mayor desafío son los **permisos**, especialmente en contenedores **no privilegiados** que usan mapeo de IDs. + +--- + +## 📚 Conceptos Fundamentales + +### ¿Qué son los Usuarios y Grupos en Linux? + +**Usuario**: Identidad que ejecuta procesos y posee archivos +- Cada usuario tiene un **UID** (User ID) numérico único +- Ejemplo: `root` tiene UID 0, `www-data` tiene UID 33 + +**Grupo**: Colección de usuarios que comparten permisos +- Cada grupo tiene un **GID** (Group ID) numérico único +- Un usuario puede pertenecer a múltiples grupos +- Ejemplo: grupo `sharedfiles` con GID 1000 + +```bash +# Ver información de un usuario +id www-data +# Salida: uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(sharedfiles) + +# Ver todos los grupos del sistema +cat /etc/group | grep shared +# Salida: sharedfiles:x:1000:www-data,root +``` + +### ¿Qué son los Permisos en Linux? + +Cada archivo y directorio tiene tres tipos de permisos para tres categorías: + +**Categorías:** +- **Propietario** (u): El usuario dueño del archivo +- **Grupo** (g): El grupo propietario del archivo +- **Otros** (o): Todos los demás usuarios + +**Permisos:** +- **Lectura (r)**: Ver contenido (valor 4) +- **Escritura (w)**: Modificar contenido (valor 2) +- **Ejecución (x)**: Ejecutar archivo o acceder a directorio (valor 1) + +```bash +# Ejemplo de permisos +ls -l /mnt/shared_data +# -rwxrw-r-- 1 root sharedfiles 1024 sep 8 archivo.txt +# ||||||| +# ||||||└─ Otros: lectura +# |||||└── Grupo: lectura + escritura +# ||||└─── Propietario: lectura + escritura + ejecución +# |||└──── Tipo: - (archivo regular) +# ||└───── Propietario: root +# |└────── Grupo: sharedfiles +# └─────── Tamaño: 1024 bytes +``` + +### ¿Qué son las ACLs (Access Control Lists)? + +Las ACLs permiten permisos más granulares que el sistema tradicional Unix: + +```bash +# Ver ACLs de un directorio +getfacl /mnt/shared_data +# Salida: +# file: /mnt/shared_data +# owner: root +# group: sharedfiles +# user::rwx +# group::rwx +# group:sharedfiles:rwx +# mask::rwx +# other::r-x +# default:user::rwx +# default:group::rwx +# default:group:sharedfiles:rwx +# default:mask::rwx +# default:other::r-x +``` + +**¿Por qué usar ACLs?** +- Garantizan permisos consistentes independientemente de la `umask` +- Permiten permisos por defecto para archivos nuevos +- Esenciales para NFS (que solo entiende UIDs/GIDs numéricos) + +### Contenedores Privilegiados vs No Privilegiados + +**Privilegiados:** +- Usan los mismos UIDs/GIDs que el host +- `root` en contenedor = `root` en host (UID 0) +- Más simples de configurar pero menos seguros + +**No Privilegiados:** +- UIDs/GIDs desplazados +100000 +- `root` en contenedor (UID 0) = UID 100000 en host +- `www-data` en contenedor (UID 33) = UID 100033 en host +- Más seguros pero requieren configuración especial + +--- + +## 🛠️ Configuración Paso a Paso + +### Paso 1: Preparar el Host + +#### 1.1 Crear Directorio Base y Grupo Universal + +```bash +# Crear directorio compartido +mkdir -p /mnt/shared_data + +# Crear grupo universal con GID específico +groupadd -g 101000 sharedfiles + +# Verificar creación +getent group sharedfiles +# Salida: sharedfiles:x:101000: +``` + +**¿Por qué GID 101000?** +- Es el mapeo que corresponde a GID 1000 dentro de contenedores no privilegiados +- Permite compatibilidad universal entre contenedores privilegiados y no privilegiados + +#### 1.2 Configurar Permisos Base + +```bash +# Asignar propietario y grupo +chown root:sharedfiles /mnt/shared_data + +# Establecer permisos con setgid +chmod 2775 /mnt/shared_data +``` + +**Explicación del chmod 2775:** +- `2`: **setgid bit** - Los archivos nuevos heredan el grupo del directorio padre +- `7`: Propietario (root) - lectura, escritura, ejecución +- `7`: Grupo (sharedfiles) - lectura, escritura, ejecución +- `5`: Otros - lectura, ejecución (sin escritura) + +#### 1.3 Aplicar ACLs + +```bash +# ACLs para contenido existente +setfacl -R -m g:sharedfiles:rwx /mnt/shared_data + +# ACLs por defecto para contenido nuevo +setfacl -d -m g:sharedfiles:rwx /mnt/shared_data + +# Verificar ACLs aplicadas +getfacl /mnt/shared_data +``` + +**¿Por qué ACLs?** +- `-R`: Aplica a todo el contenido existente recursivamente +- `-d`: Define permisos por defecto para archivos/directorios nuevos +- Garantiza que el grupo `sharedfiles` siempre tenga acceso completo + +### Paso 2: Configurar Contenedor Privilegiado + +```bash +# 2.1 Entrar al contenedor +pct exec 100 -- bash + +# 2.2 Crear grupo idéntico al host +groupadd -g 101000 sharedfiles + +# 2.3 Añadir usuarios relevantes al grupo +usermod -aG sharedfiles root +usermod -aG sharedfiles www-data + +# Si tienes otros usuarios (nextcloud, etc.) +usermod -aG sharedfiles ncp 2>/dev/null || true + +# 2.4 Verificar membresía +groups root +groups www-data + +# 2.5 Salir del contenedor +exit +``` + +**¿Es necesario configurar grupos en contenedores privilegiados?** + +**SÍ, es necesario** por las siguientes razones: + +1. **Consistencia de permisos**: Aunque el contenedor privilegiado usa los mismos UIDs que el host, los **grupos** pueden no existir dentro del contenedor +2. **Servicios específicos**: Aplicaciones como Apache (`www-data`) o Nextcloud (`ncp`) necesitan pertenecer al grupo para escribir archivos +3. **ACLs**: Las ACLs verifican tanto UIDs como GIDs, por lo que el grupo debe existir en ambos lados +4. **Futuras migraciones**: Si conviertes el contenedor a no privilegiado, ya tendrás la configuración correcta + +**Ejemplo práctico:** +```bash +# Sin configurar grupo en contenedor privilegiado +echo "test" > /mnt/shared/archivo.txt +ls -l /mnt/shared/archivo.txt +# -rw-r--r-- 1 root root 5 sep 8 archivo.txt ← Grupo incorrecto + +# Con grupo configurado +echo "test2" > /mnt/shared/archivo2.txt +ls -l /mnt/shared/archivo2.txt +# -rw-rw-r-- 1 root sharedfiles 6 sep 8 archivo2.txt ← Grupo correcto +``` + +### Paso 3: Configurar Contenedor No Privilegiado + +```bash +# 3.1 Entrar al contenedor +pct exec 101 -- bash + +# 3.2 Crear grupo con GID mapeado +groupadd -g 1000 sharedfiles +# Importante: GID 1000 en contenedor = GID 101000 en host + +# 3.3 Añadir usuarios al grupo +usermod -aG sharedfiles root +usermod -aG sharedfiles www-data +usermod -aG sharedfiles ncp 2>/dev/null || true + +# 3.4 Verificar configuración +id www-data +# Salida esperada: uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(sharedfiles) + +# 3.5 Salir del contenedor +exit +``` + +#### Añadir Usuarios Adicionales + +**Método 1: Añadir usuarios específicos** +```bash +# Dentro del contenedor +usermod -aG sharedfiles usuario1 +usermod -aG sharedfiles usuario2 +``` + +**Método 2: Añadir todos los usuarios del sistema (automático)** +```bash +# Script para añadir todos los usuarios con UID >= 1000 +for user in $(awk -F: '$3>=1000 && $1!="nobody" {print $1}' /etc/passwd); do + usermod -aG sharedfiles "$user" 2>/dev/null || true + echo "Usuario $user añadido al grupo sharedfiles" +done +``` + +**Método 3: Añadir usuarios interactivamente** +```bash +# Mostrar usuarios disponibles +echo "Usuarios disponibles en el sistema:" +awk -F: '$3>=1000 && $1!="nobody" {print "- " $1 " (UID: " $3 ")"}' /etc/passwd + +# Preguntar qué usuarios añadir +read -p "¿Qué usuarios quieres añadir al grupo sharedfiles? (separados por espacios): " usuarios +for user in $usuarios; do + if id "$user" >/dev/null 2>&1; then + usermod -aG sharedfiles "$user" + echo "✓ Usuario $user añadido" + else + echo "✗ Usuario $user no existe" + fi +done +``` + +### Paso 4: Montar el Directorio en los Contenedores + +```bash +# 4.1 Para contenedor privilegiado (ID 100) +pct set 100 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1 + +# 4.2 Para contenedor no privilegiado (ID 101) +pct set 101 -mp0 /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1 + +# 4.3 Reiniciar contenedores para activar montajes +pct reboot 100 +pct reboot 101 + +# Esperar a que arranquen +sleep 10 +``` + +**Explicación de parámetros:** +- `mp0`: Mount point 0 (primer punto de montaje) +- `/mnt/shared_data`: Ruta en el host +- `mp=/mnt/shared`: Ruta dentro del contenedor +- `backup=0`: Excluir del backup de vzdump +- `acl=1`: Habilitar soporte para ACLs +- `shared=1`: **Importante para clusters** - permite migración sin copiar datos + +**¿Por qué shared=1?** +- En clusters Proxmox, permite migrar contenedores entre nodos +- El almacenamiento debe estar disponible en todos los nodos +- Sin `shared=1`, Proxmox intentará copiar los datos durante la migración + +--- + +## 🌐 Configurar Recursos de Red + +### Opción A: Montar Recurso NFS Existente + +#### A.1 Instalar Cliente NFS en el Host + +```bash +# Debian/Ubuntu +apt update && apt install nfs-common + +# Verificar servicios NFS +systemctl status rpc-statd +systemctl status rpc-gssd +``` + +#### A.2 Crear Punto de Montaje y Montar + +```bash +# Crear directorio de montaje +mkdir -p /mnt/nfs_share + +# Montar temporalmente para probar +mount -t nfs 192.168.1.50:/export/shared /mnt/nfs_share + +# Verificar montaje +df -h | grep nfs +mount | grep nfs +``` + +#### A.3 Hacer Montaje Persistente + +```bash +# Añadir a /etc/fstab +echo "192.168.1.50:/export/shared /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 +umount /mnt/nfs_share +mount /mnt/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 de lectura/escritura (128KB) +- `timeo=600`: Timeout de 60 segundos (600 décimas) +- `retrans=2`: Reintentar 2 veces antes de reportar error +- `_netdev`: Esperar a que la red esté disponible +- `0 0`: No hacer dump ni fsck (siempre para recursos de red) + +#### A.4 Configurar Permisos en el Recurso NFS + +```bash +# Aplicar configuración de permisos al recurso montado +chown root:sharedfiles /mnt/nfs_share +chmod 2775 /mnt/nfs_share +setfacl -R -m g:sharedfiles:rwx /mnt/nfs_share +setfacl -d -m g:sharedfiles:rwx /mnt/nfs_share +``` + +### Opción B: Montar Recurso Samba/CIFS + +#### B.1 Instalar Cliente Samba + +```bash +# Instalar herramientas CIFS +apt update && apt install cifs-utils + +# Verificar instalación +which mount.cifs +``` + +#### B.2 Crear Credenciales Seguras + +```bash +# Crear archivo de credenciales +cat > /etc/cifs-credentials << EOF +username=tu_usuario +password=tu_password +domain=tu_dominio +EOF + +# Proteger archivo +chmod 600 /etc/cifs-credentials +chown root:root /etc/cifs-credentials +``` + +#### B.3 Montar Recurso Samba + +```bash +# Crear punto de montaje +mkdir -p /mnt/samba_share + +# Montar temporalmente +mount -t cifs //192.168.1.60/shared /mnt/samba_share -o credentials=/etc/cifs-credentials,iocharset=utf8,vers=3.0 + +# Verificar montaje +df -h | grep cifs +``` + +#### B.4 Hacer Montaje Persistente + +```bash +# Añadir a /etc/fstab +echo "//192.168.1.60/shared /mnt/samba_share cifs credentials=/etc/cifs-credentials,iocharset=utf8,vers=3.0,_netdev,nofail 0 0" >> /etc/fstab + +# Probar configuración +umount /mnt/samba_share +mount /mnt/samba_share +``` + +**Explicación de opciones CIFS:** +- `credentials=`: Archivo con usuario/contraseña +- `iocharset=utf8`: Codificación de caracteres +- `vers=3.0`: Versión del protocolo SMB +- `_netdev`: Esperar red disponible +- `nofail`: No fallar arranque si no se puede montar + +#### B.5 Configurar Permisos en Samba + +```bash +# Aplicar permisos al recurso Samba montado +chown root:sharedfiles /mnt/samba_share +chmod 2775 /mnt/samba_share +setfacl -R -m g:sharedfiles:rwx /mnt/samba_share +setfacl -d -m g:sharedfiles:rwx /mnt/samba_share +``` + +### Opción C: Crear Directorio Local + +```bash +# Crear directorio local para compartir +mkdir -p /mnt/local_share + +# Aplicar configuración estándar +chown root:sharedfiles /mnt/local_share +chmod 2775 /mnt/local_share +setfacl -R -m g:sharedfiles:rwx /mnt/local_share +setfacl -d -m g:sharedfiles:rwx /mnt/local_share + +# Crear estructura de ejemplo +mkdir -p /mnt/local_share/{documentos,imagenes,backups} +chown -R root:sharedfiles /mnt/local_share/* +``` + +--- + +## ✅ Verificación y Pruebas + +### Prueba 1: Verificar Montajes + +```bash +# En el host +df -h | grep -E "(nfs|cifs|/mnt)" +mount | grep -E "(nfs|cifs|/mnt)" + +# Verificar permisos +ls -la /mnt/shared_data +getfacl /mnt/shared_data +``` + +### Prueba 2: Probar Escritura desde Contenedores + +```bash +# Contenedor privilegiado (100) +pct exec 100 -- bash -c "echo 'Prueba desde privilegiado' > /mnt/shared/test_privilegiado.txt" + +# Contenedor no privilegiado (101) +pct exec 101 -- bash -c "echo 'Prueba desde no privilegiado' > /mnt/shared/test_no_privilegiado.txt" + +# Verificar en el host +ls -la /mnt/shared_data/ +# Ambos archivos deben tener grupo 'sharedfiles' +``` + +### Prueba 3: Verificar Permisos Cruzados + +```bash +# Desde contenedor 100, modificar archivo creado por contenedor 101 +pct exec 100 -- bash -c "echo 'Modificado por privilegiado' >> /mnt/shared/test_no_privilegiado.txt" + +# Desde contenedor 101, modificar archivo creado por contenedor 100 +pct exec 101 -- bash -c "echo 'Modificado por no privilegiado' >> /mnt/shared/test_privilegiado.txt" + +# Verificar contenido +cat /mnt/shared_data/test_privilegiado.txt +cat /mnt/shared_data/test_no_privilegiado.txt +``` + +### Prueba 4: Verificar Persistencia tras Reinicio + +```bash +# Reiniciar host +reboot + +# Tras reinicio, verificar montajes automáticos +df -h | grep -E "(nfs|cifs)" +ls -la /mnt/shared_data/ + +# Verificar que contenedores pueden seguir escribiendo +pct start 100 && pct start 101 +sleep 10 +pct exec 100 -- bash -c "echo 'Post-reinicio privilegiado' > /mnt/shared/test_post_reboot.txt" +pct exec 101 -- bash -c "echo 'Post-reinicio no privilegiado' >> /mnt/shared/test_post_reboot.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 +# Verificar permisos del directorio +ls -la /mnt/shared_data/ +getfacl /mnt/shared_data/ + +# Verificar grupo en contenedor +pct exec 101 -- groups www-data +pct exec 101 -- id www-data +``` + +**Soluciones:** +1. **Falta grupo en contenedor:** + ```bash + pct exec 101 -- groupadd -g 1000 sharedfiles + pct exec 101 -- usermod -aG sharedfiles www-data + ``` + +2. **Faltan ACLs en host:** + ```bash + setfacl -R -m g:sharedfiles:rwx /mnt/shared_data + setfacl -d -m g:sharedfiles:rwx /mnt/shared_data + ``` + +3. **Permisos base incorrectos:** + ```bash + chmod 2775 /mnt/shared_data + chown root:sharedfiles /mnt/shared_data + ``` + +### Error: "No such file or directory" al montar + +**Síntomas:** +```bash +mount: /mnt/nfs_share: mount point does not exist +``` + +**Solución:** +```bash +# Crear punto de montaje +mkdir -p /mnt/nfs_share + +# Verificar conectividad al servidor +ping 192.168.1.50 +showmount -e 192.168.1.50 +``` + +### Error: Archivos aparecen con propietario incorrecto + +**Síntomas:** +```bash +ls -la /mnt/shared_data/ +# -rw-r--r-- 1 100033 100033 5 sep 8 archivo.txt +``` + +**Diagnóstico:** +- UIDs/GIDs numéricos indican problema de mapeo +- 100033 = UID 33 (www-data) en contenedor no privilegiado + +**Solución:** +```bash +# Verificar mapeo en configuración LXC +cat /etc/pve/lxc/101.conf | grep -E "(lxc.idmap|mp0)" + +# Debe mostrar: +# lxc.idmap: u 0 100000 65536 +# lxc.idmap: g 0 100000 65536 +# mp0: /mnt/shared_data,mp=/mnt/shared,backup=0,acl=1,shared=1 + +# Corregir permisos con ACLs +setfacl -R -m g:sharedfiles:rwx /mnt/shared_data +``` + +### Error: Montaje no persiste tras reinicio + +**Síntomas:** +- Tras reinicio, `df -h` no muestra el recurso montado +- Contenedores no pueden acceder a `/mnt/shared` + +**Diagnóstico:** +```bash +# Verificar /etc/fstab +cat /etc/fstab | grep -E "(nfs|cifs)" + +# Probar montaje manual +mount -a +``` + +**Solución:** +```bash +# Corregir entrada en /etc/fstab +# Para NFS: +192.168.1.50:/export/shared /mnt/nfs_share nfs rw,hard,nofail,_netdev 0 0 + +# Para Samba: +//192.168.1.60/shared /mnt/samba_share cifs credentials=/etc/cifs-credentials,_netdev,nofail 0 0 + +# Probar configuración +umount /mnt/nfs_share +mount /mnt/nfs_share +``` + +### Error: "Transport endpoint is not connected" + +**Síntomas:** +```bash +ls /mnt/nfs_share +# ls: cannot access '/mnt/nfs_share': Transport endpoint is not connected +``` + +**Solución:** +```bash +# Desmontar forzosamente +umount -f /mnt/nfs_share + +# O si no funciona: +umount -l /mnt/nfs_share # lazy unmount + +# Verificar conectividad +ping 192.168.1.50 +showmount -e 192.168.1.50 + +# Remontar +mount /mnt/nfs_share +``` + +--- + +## 📋 Comandos de Referencia Rápida + +### Gestión de Grupos +```bash +# Crear grupo con GID específico +groupadd -g 101000 sharedfiles + +# Añadir usuario a grupo +usermod -aG sharedfiles usuario + +# Ver grupos de un usuario +groups usuario +id usuario + +# Ver miembros de un grupo +getent group sharedfiles +``` + +### Gestión de Permisos +```bash +# Permisos básicos con setgid +chmod 2775 /directorio +chown root:sharedfiles /directorio + +# ACLs +setfacl -R -m g:sharedfiles:rwx /directorio # Existente +setfacl -d -m g:sharedfiles:rwx /directorio # Por defecto +getfacl /directorio # Ver ACLs +``` + +### Montajes de Red +```bash +# NFS +mount -t nfs servidor:/ruta /punto/montaje +showmount -e servidor + +# Samba/CIFS +mount -t cifs //servidor/recurso /punto/montaje -o credentials=/archivo +smbclient -L servidor +``` + +### Contenedores LXC +```bash +# Configurar punto de montaje +pct set ID -mp0 /host/path,mp=/container/path,backup=0,acl=1,shared=1 + +# Ejecutar comando en contenedor +pct exec ID -- comando + +# Ver configuración +cat /etc/pve/lxc/ID.conf +``` + +--- + +## 🎯 Resumen Final + +### Flujo Completo de Configuración + +1. **Host**: Crear directorio + grupo + permisos + ACLs +2. **Recurso**: Montar NFS/Samba o usar directorio local +3. **Contenedores**: Crear grupo + añadir usuarios +4. **Montaje**: Configurar puntos de montaje con `shared=1,acl=1` +5. **Verificar**: Probar escritura cruzada entre contenedores + +### Puntos Clave + +- **Grupo universal**: `sharedfiles` con GID 101000 en host, GID 1000 en contenedores no privilegiados +- **Setgid bit**: `chmod 2775` asegura herencia de grupo +- **ACLs**: Garantizan permisos consistentes independientemente de umask +- **shared=1**: Esencial para clusters y migraciones +- **_netdev**: Necesario en /etc/fstab para recursos de red + +### Compatibilidad + +Esta configuración funciona con: +- ✅ Contenedores privilegiados y no privilegiados +- ✅ NFS (todas las versiones) +- ✅ Samba/CIFS +- ✅ Directorios locales +- ✅ Clusters Proxmox +- ✅ Migraciones en vivo +- ✅ Backups con vzdump (excluye puntos de montaje) + +Con esta guía tendrás un sistema robusto y escalable para compartir recursos entre tu host Proxmox y contenedores LXC, manteniendo permisos correctos y compatibilidad total. +``` +