En entornos de servidores Linux donde se utiliza ProFTPD como servidor FTP, es habitual enfrentarse a un dilema clásico: ¿cómo otorgar a un usuario (por ejemplo, un administrador de sitios web o un desarrollador) control total sobre los archivos del sistema sin comprometer la seguridad? Muchos administradores inexpertos optan por soluciones rápidas y peligrosas, como cambiar el UID del usuario a 0 (root) o ejecutar ProFTPD con privilegios elevados. Sin embargo, esta práctica —conocida coloquialmente como “jugar con los UIDs de root”— viola principios fundamentales de seguridad y expone el servidor a riesgos innecesarios. En este artículo detallado explicaremos por qué las Access Control Lists (ACLs) son una aproximación mucho más profesional, granular y segura, combinada con restricciones específicas en la configuración de ProFTPD. Veremos conceptos teóricos, riesgos reales, pasos prácticos y ejemplos de implementación reales.
Los Riesgos de Manipular UIDs de Root
Asignar UID=0 a un usuario normal o ejecutar ProFTPD como root (o con setuid root) parece una solución sencilla: el usuario obtiene acceso completo a todo el sistema. Sin embargo, los problemas son graves:
- Violación del principio de menor privilegio: El usuario (o el proceso de ProFTPD) tiene acceso ilimitado a /etc, /root, claves SSH, bases de datos del sistema, etc.
- Un solo fallo de autenticación FTP o un exploit en el cliente del usuario otorga acceso root completo al atacante.
- Dificultad de auditoría: Los logs del sistema (auth.log, proftpd.log) ya no distinguen claramente entre acciones legítimas y maliciosas. Todo aparece como root.
- Problemas de compatibilidad: Muchos servicios (Apache, Nginx, PHP-FPM) esperan que los archivos pertenezcan a usuarios específicos.
- Cambiar UIDs rompe SELinux/AppArmor, fail2ban y herramientas de hardening.
- Riesgo permanente: Una vez que el UID es 0, revertirlo requiere reinicios y puede dejar archivos huérfanos con permisos incorrectos.
- No escalable: En entornos multiusuario (hosting compartido) es impracticable y peligroso.
Las ACLs + restricciones de ProFTPD ofrecen el mismo resultado funcional (control total sobre lo que realmente importa) con una seguridad profesional.
¿Qué son las ACLs y por qué son superiores?
Las Access Control Lists (ACLs) son una extensión del sistema de permisos POSIX tradicional (rwx para owner/group/others). Permiten definir permisos por usuario o grupo específico sobre cualquier archivo o directorio, incluso si el propietario es root.
Ventajas clave frente a UIDs de root:
- Granularidad: Puedes dar rwx completo a un usuario concreto en /var/www, /home/usuario o incluso en / (con ACLs por defecto), pero denegar explícitamente en /etc/proftpd.conf, /etc/ssh/sshd_config, /root, etc.
- No eleva privilegios: El usuario sigue teniendo UID normal (ej. 1001).
- Solo recibe permisos adicionales donde se configuran.Persistencia y heredabilidad: Las ACLs por defecto (default:) se heredan automáticamente a nuevos archivos y subdirectorios.
- Compatibilidad total: Funcionan con cualquier daemon que use el UID real del usuario (ProFTPD en modo standalone o inetd).
- Auditoría sencilla: getfacl muestra exactamente quién puede hacer qué.
Requisito previo: El filesystem debe estar montado con la opción acl. En la mayoría de distribuciones modernas (Ubuntu, Debian, Rocky Linux, AlmaLinux) ya viene habilitado por defecto en / y /home.
# Verificar
mount | grep acl
# Si no aparece, añadir en /etc/fstab (ejemplo para /)
UUID=xxxx / ext4 defaults,acl 0 1
# Luego: mount -o remount /
Permisos de Sistema (ACLs) + Restricciones en ProFTPD
La clave es dos capas de defensa:
- Capa de filesystem (ACLs): Controla el acceso real a nivel de kernel.
- Capa de aplicación (ProFTPD): Restringe los comandos FTP (STOR, DELE, MKD, etc.) en rutas sensibles, incluso si las ACLs lo permitieran.
De esta forma, el usuario tiene control total sobre sus sitios web, logs, scripts, etc., pero no puede tocar archivos de configuración críticos aunque intente hacerlo por FTP.
Paso a paso: Implementación práctica
Paso 1: Crear el usuario FTP dedicado (recomendado)
adduser --system --shell /bin/false --home /var/ftpuser ftpuser
usermod -u 1001 ftpuser # UID normal, nunca 0
Paso 2: Configurar ACLs para control total (excepto sensibles)
# 1. ACLs por defecto en directorios clave (heredables)
setfacl -R -m d:u:ftpuser:rwx /var/www
setfacl -R -m d:u:ftpuser:rwx /var/log/apache2
setfacl -R -m d:u:ftpuser:rwx /home/clientes
# 2. Dar acceso explícito a todo el sistema excepto sensibles
setfacl -R -m u:ftpuser:rwx / # ¡CUIDADO! Solo en servidores dedicados
# 3. PROTEGER archivos de configuración sensibles (denegar explícitamente)
setfacl -m u:ftpuser:--- /etc/proftpd.conf
setfacl -m u:ftpuser:--- /etc/proftpd/*
setfacl -m u:ftpuser:--- /etc/ssh/sshd_config
setfacl -m u:ftpuser:--- /root
setfacl -m u:ftpuser:--- /etc/sudoers
setfacl -m u:ftpuser:--- /var/lib/mysql # ejemplo base de datos
Verificar:
getfacl /etc/proftpd.conf
getfacl /var/www/html
Paso 3: Restricciones en la configuración de ProFTPD (/etc/proftpd/proftpd.conf)
Aquí es donde ProFTPD añade una segunda capa de protección:
# Usuario principal (sin ser root)
User ftpuser
Group ftpuser
# NO usar RootDirectory si queremos control total (o usarlo solo para clientes)
# DefaultRoot ~ !root # opcional
# Bloquear comandos de escritura en rutas sensibles
<Directory /etc>
<Limit WRITE MKD RMD DELE>
DenyAll
</Limit>
</Directory>
<Directory /root>
<Limit ALL>
DenyAll
</Limit>
</Directory>
<Directory /var/lib/mysql>
<Limit WRITE MKD RMD DELE>
DenyAll
</Limit>
</Directory>
# Permitir todo lo demás (control total)
<Directory />
<Limit WRITE MKD RMD DELE>
AllowAll
</Limit>
</Directory>
# Logs y autenticación
LogFormat full "%h %l %u %t \"%r\" %>s %b"
ExtendedLog /var/log/proftpd/access.log full
ExtendedLog /var/log/proftpd/auth.log AUTH
Reiniciar:
systemctl restart proftpd
Paso 4: Pruebas de seguridad
- Conectar por FTP como ftpuser e intentar subir un archivo a /etc/proftpd.conf → Debe fallar (tanto por ACL como por <Limit>).
- Subir archivos a /var/www/html → Debe funcionar perfectamente.
- Comprobar con ls -l y getfacl que los permisos se mantienen.
Ejemplo rápido
Supongamos que tenemos un sitio donde ya tenemos un usuario de ftp creado en /etc/passwd y hemos creado todos los archivos como root, pero queremos que el usuario ftp tenga control total sobre esos archivos.
Si no tenemos instalado ACL, primero lo instalamos (suponemos Debian / Ubuntu):
sudo apt install acl
Primero, damos control total al usuario sobre el directorio. Esto le permitirá subir, borrar y modificar archivos de root (gracias a que el permiso de “borrado” depende de la escritura en el directorio padre).
Ejecuta estos comandos como root:
# 1. Dar permisos RWA (Lectura, Escritura, Ejecución) al usuario de forma recursiva
setfacl -R -m u:tu_usuario:rwx /directorio
# 2. Establecer el "Default" para que los archivos que root cree en el futuro
# sigan siendo controlables por el usuario
setfacl -R -d -m u:tu_usuario:rwx /directorio
Aquí vamos a blindar algunos archivos que no queremos que el usuario pueda tocar como son .user.ini y .htaccess
Para evitar que el usuario pueda modificar o borrar esos archivos específicos a través de FTP, usaremos un bloque <Limit> dentro de la configuración de ProFTPD.
Edita tu /etc/proftpd/proftpd.conf y añade esto (preferiblemente dentro del bloque <VirtualHost> si usas uno, o al final del archivo):
<Directory /directorio>
# 1. Prohibir cualquier operación de escritura/borrado en estos archivos
PathDenyFilter "(\.htaccess|\.user\.ini)$"
# 2. Configuración de límites
<Limit WRITE DELE RMD>
# Denegamos el uso de estos comandos sobre el patrón de archivos
DenyFilter "(\.htaccess|\.user\.ini)$"
AllowUser usuario_ftp
</Limit>
<Limit ALL>
AllowUser usuario_ftp
DenyAll
</Limit>
</Directory>
Finamente reiniciamos el servicio:
sudo systemctl restart proftpd

