Domina la gestión de permisos y propiedades en sistemas Unix/Linux para mantener la seguridad y control de acceso
Los permisos y propiedades de archivos son fundamentales para la seguridad y administración de sistemas Unix/Linux. En este módulo aprenderás a gestionar permisos, usar ACLs avanzadas y implementar políticas de seguridad robustas.
En sistemas Unix/Linux, cada archivo y directorio tiene permisos que determinan quién puede leer, escribir o ejecutar ese archivo. Los permisos se dividen en tres categorías:
Categoría | Símbolo | Descripción |
---|---|---|
Propietario (User) | u | El usuario que posee el archivo |
Grupo (Group) | g | El grupo al que pertenece el archivo |
Otros (Others) | o | Todos los demás usuarios |
Permiso | Símbolo | Valor Octal | Para Archivos | Para Directorios |
---|---|---|---|---|
Lectura | r | 4 | Ver contenido del archivo | Listar archivos del directorio |
Escritura | w | 2 | Modificar el archivo | Crear/eliminar archivos |
Ejecución | x | 1 | Ejecutar el archivo | Acceder al directorio |
-rwxr-xr--
significa:
-
: Es un archivo regular (no directorio)rwx
: Propietario puede leer, escribir y ejecutarr-x
: Grupo puede leer y ejecutar (no escribir)r--
: Otros solo pueden leerEn notación octal: 754
(4+2+1=7, 4+1=5, 4=4)
#!/bin/bash
# Modo simbólico
chmod u+x archivo.sh # Dar permiso de ejecución al propietario
chmod g-w archivo.txt # Quitar permiso de escritura al grupo
chmod o+r archivo.txt # Dar permiso de lectura a otros
chmod a+x script.sh # Dar permiso de ejecución a todos (all)
# Modo octal
chmod 755 script.sh # rwxr-xr-x
chmod 644 archivo.txt # rw-r--r--
chmod 600 archivo_privado # rw-------
chmod 777 archivo_publico # rwxrwxrwx
# Aplicar recursivamente
chmod -R 755 directorio/ # Aplicar permisos a directorio y contenido
# Ejemplos combinados
chmod u+x,g+x,o-rwx script.sh # Solo propietario y grupo pueden ejecutar
chmod u=rwx,g=rx,o=r archivo # Establecer permisos específicos
#!/bin/bash
# Cambiar propietario
sudo chown usuario archivo.txt
# Cambiar propietario y grupo
sudo chown usuario:grupo archivo.txt
# Solo cambiar grupo
sudo chown :grupo archivo.txt
# Aplicar recursivamente
sudo chown -R usuario:grupo directorio/
# Verificar cambios
ls -la archivo.txt
#!/bin/bash
# permission_manager.sh - Gestor avanzado de permisos
show_permissions() {
local file="$1"
if [[ ! -e "$file" ]]; then
echo "Error: Archivo no existe - $file"
return 1
fi
echo "=== Información de Permisos: $file ==="
# Información básica
ls -la "$file"
# Desglose detallado
local perms=$(stat -f%Sp "$file" 2>/dev/null || stat -c%A "$file" 2>/dev/null)
local owner=$(stat -f%Su "$file" 2>/dev/null || stat -c%U "$file" 2>/dev/null)
local group=$(stat -f%Sg "$file" 2>/dev/null || stat -c%G "$file" 2>/dev/null)
local octal=$(stat -f%Lp "$file" 2>/dev/null || stat -c%a "$file" 2>/dev/null)
echo "Propietario: $owner"
echo "Grupo: $group"
echo "Permisos simbólicos: $perms"
echo "Permisos octales: $octal"
# Análisis de permisos
echo ""
echo "=== Análisis de Permisos ==="
if [[ -r "$file" ]]; then
echo "✓ Puedes leer este archivo"
else
echo "✗ NO puedes leer este archivo"
fi
if [[ -w "$file" ]]; then
echo "✓ Puedes escribir en este archivo"
else
echo "✗ NO puedes escribir en este archivo"
fi
if [[ -x "$file" ]]; then
echo "✓ Puedes ejecutar este archivo"
else
echo "✗ NO puedes ejecutar este archivo"
fi
}
set_secure_permissions() {
local file="$1"
local type="$2"
if [[ ! -e "$file" ]]; then
echo "Error: Archivo no existe - $file"
return 1
fi
case "$type" in
"script")
echo "Configurando permisos seguros para script..."
chmod 750 "$file" # rwxr-x---
echo "Permisos establecidos: 750 (rwxr-x---)"
;;
"config")
echo "Configurando permisos seguros para archivo de configuración..."
chmod 640 "$file" # rw-r-----
echo "Permisos establecidos: 640 (rw-r-----)"
;;
"private")
echo "Configurando permisos privados..."
chmod 600 "$file" # rw-------
echo "Permisos establecidos: 600 (rw-------)"
;;
"public")
echo "Configurando permisos públicos de solo lectura..."
chmod 644 "$file" # rw-r--r--
echo "Permisos establecidos: 644 (rw-r--r--)"
;;
"executable")
echo "Configurando permisos para ejecutable..."
chmod 755 "$file" # rwxr-xr-x
echo "Permisos establecidos: 755 (rwxr-xr-x)"
;;
*)
echo "Tipos disponibles: script, config, private, public, executable"
return 1
;;
esac
show_permissions "$file"
}
find_insecure_files() {
local search_path="${1:-.}"
echo "=== Buscando archivos con permisos inseguros en: $search_path ==="
echo "Archivos escribibles por todos (world-writable):"
find "$search_path" -type f -perm -002 2>/dev/null | head -10
echo ""
echo "Directorios escribibles por todos:"
find "$search_path" -type d -perm -002 2>/dev/null | head -10
echo ""
echo "Archivos con SUID bit:"
find "$search_path" -type f -perm -4000 2>/dev/null | head -10
echo ""
echo "Archivos con SGID bit:"
find "$search_path" -type f -perm -2000 2>/dev/null | head -10
echo ""
echo "Archivos sin propietario:"
find "$search_path" -nouser 2>/dev/null | head -10
echo ""
echo "Archivos sin grupo:"
find "$search_path" -nogroup 2>/dev/null | head -10
}
fix_permissions_recursively() {
local directory="$1"
local file_perms="${2:-644}"
local dir_perms="${3:-755}"
if [[ ! -d "$directory" ]]; then
echo "Error: Directorio no existe - $directory"
return 1
fi
echo "Corrigiendo permisos recursivamente en: $directory"
echo "Permisos para archivos: $file_perms"
echo "Permisos para directorios: $dir_perms"
read -p "¿Continuar? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Operación cancelada"
return 1
fi
# Cambiar permisos de directorios
find "$directory" -type d -exec chmod "$dir_perms" {} \;
# Cambiar permisos de archivos
find "$directory" -type f -exec chmod "$file_perms" {} \;
echo "Permisos corregidos exitosamente"
}
backup_permissions() {
local directory="$1"
local backup_file="${2:-permissions_backup_$(date +%Y%m%d_%H%M%S).txt}"
if [[ ! -e "$directory" ]]; then
echo "Error: Ruta no existe - $directory"
return 1
fi
echo "Creando backup de permisos en: $backup_file"
# Crear backup de permisos
find "$directory" -exec stat -f "%N %Mp%Lp %Su %Sg" {} \; 2>/dev/null > "$backup_file" || \
find "$directory" -exec stat -c "%n %a %U %G" {} \; 2>/dev/null > "$backup_file"
echo "Backup creado: $backup_file"
echo "Archivos incluidos: $(wc -l < "$backup_file")"
}
restore_permissions() {
local backup_file="$1"
if [[ ! -f "$backup_file" ]]; then
echo "Error: Archivo de backup no existe - $backup_file"
return 1
fi
echo "Restaurando permisos desde: $backup_file"
read -p "¿Continuar con la restauración? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Restauración cancelada"
return 1
fi
while read -r line; do
local file=$(echo "$line" | awk '{print $1}')
local perms=$(echo "$line" | awk '{print $2}')
local owner=$(echo "$line" | awk '{print $3}')
local group=$(echo "$line" | awk '{print $4}')
if [[ -e "$file" ]]; then
chmod "$perms" "$file" 2>/dev/null
# Solo intentar cambiar propietario si tenemos privilegios
if [[ $EUID -eq 0 ]]; then
chown "$owner:$group" "$file" 2>/dev/null
fi
fi
done < "$backup_file"
echo "Restauración completada"
}
# Función principal con menú
main() {
if [[ $# -eq 0 ]]; then
echo "=== Gestor de Permisos de Archivos ==="
echo "1. Mostrar información de permisos"
echo "2. Establecer permisos seguros"
echo "3. Buscar archivos inseguros"
echo "4. Corregir permisos recursivamente"
echo "5. Crear backup de permisos"
echo "6. Restaurar permisos desde backup"
read -p "Seleccione opción [1-6]: " option
case "$option" in
1)
read -p "Archivo/directorio: " file
show_permissions "$file"
;;
2)
read -p "Archivo: " file
echo "Tipos: script, config, private, public, executable"
read -p "Tipo: " type
set_secure_permissions "$file" "$type"
;;
3)
read -p "Ruta de búsqueda [.]: " path
find_insecure_files "${path:-.}"
;;
4)
read -p "Directorio: " dir
read -p "Permisos archivos [644]: " fperms
read -p "Permisos directorios [755]: " dperms
fix_permissions_recursively "$dir" "${fperms:-644}" "${dperms:-755}"
;;
5)
read -p "Directorio: " dir
read -p "Archivo backup [auto]: " backup
backup_permissions "$dir" "$backup"
;;
6)
read -p "Archivo de backup: " backup
restore_permissions "$backup"
;;
esac
else
case "$1" in
"show") show_permissions "$2" ;;
"secure") set_secure_permissions "$2" "$3" ;;
"scan") find_insecure_files "$2" ;;
"fix") fix_permissions_recursively "$2" "$3" "$4" ;;
"backup") backup_permissions "$2" "$3" ;;
"restore") restore_permissions "$2" ;;
*) echo "Comandos: show, secure, scan, fix, backup, restore" ;;
esac
fi
}
# Ejecutar función principal
main "$@"
Bit | Valor | Símbolo | Descripción | Ejemplo |
---|---|---|---|---|
SUID | 4000 | s/S | Se ejecuta con permisos del propietario | /usr/bin/passwd |
SGID | 2000 | s/S | Se ejecuta con permisos del grupo | /usr/bin/wall |
Sticky | 1000 | t/T | Solo el propietario puede eliminar | /tmp |
#!/bin/bash
# Establecer SUID bit
chmod u+s programa
chmod 4755 programa # También funciona
# Establecer SGID bit
chmod g+s programa
chmod 2755 programa
# Establecer Sticky bit
chmod +t directorio
chmod 1755 directorio
# Combinar permisos especiales
chmod 6755 programa # SUID + SGID
chmod 7755 programa # SUID + SGID + Sticky
# Verificar permisos especiales
ls -la /usr/bin/passwd # Debería mostrar -rwsr-xr-x
ls -ld /tmp # Debería mostrar drwxrwxrwt
Las ACLs permiten permisos más granulares que el sistema tradicional Unix. Puedes dar permisos específicos a usuarios y grupos individuales.
#!/bin/bash
# Ver ACLs actuales
getfacl archivo.txt
# Dar permisos de lectura a un usuario específico
setfacl -m u:usuario:r archivo.txt
# Dar permisos de escritura a un grupo específico
setfacl -m g:grupo:rw archivo.txt
# Establecer ACL por defecto para directorios
setfacl -d -m u:usuario:rwx directorio/
# Eliminar ACL específica
setfacl -x u:usuario archivo.txt
# Eliminar todas las ACLs
setfacl -b archivo.txt
# Aplicar ACLs recursivamente
setfacl -R -m u:usuario:rx directorio/
# Copiar ACLs de un archivo a otro
getfacl archivo1.txt | setfacl --set-file=- archivo2.txt
#!/bin/bash
# acl_manager.sh - Gestor de ACLs
check_acl_support() {
# Verificar si el sistema soporta ACLs
if ! command -v getfacl >/dev/null 2>&1; then
echo "Error: ACLs no están instaladas"
echo "Instala con: sudo apt-get install acl (Ubuntu/Debian)"
echo "o: sudo yum install acl (RHEL/CentOS)"
return 1
fi
# Verificar si el filesystem soporta ACLs
local file="${1:-/tmp/test_acl}"
touch "$file"
if ! setfacl -m u:root:r "$file" 2>/dev/null; then
echo "Warning: El filesystem puede no soportar ACLs"
echo "Monta con opción 'acl' si es necesario"
fi
rm -f "$file"
return 0
}
show_detailed_acl() {
local file="$1"
if [[ ! -e "$file" ]]; then
echo "Error: Archivo no existe - $file"
return 1
fi
echo "=== ACLs para: $file ==="
getfacl "$file"
echo ""
echo "=== Análisis de ACLs ==="
# Verificar si tiene ACLs extendidas
if getfacl --skip-base "$file" 2>/dev/null | grep -q "^user:\|^group:"; then
echo "✓ Este archivo tiene ACLs extendidas"
else
echo "✗ Este archivo no tiene ACLs extendidas"
fi
# Mostrar usuarios con acceso
echo ""
echo "Usuarios con acceso específico:"
getfacl "$file" 2>/dev/null | grep "^user:" | sed 's/user://' | while read acl; do
if [[ "$acl" =~ ^([^:]+):(.+)$ ]]; then
local user="${BASH_REMATCH[1]}"
local perms="${BASH_REMATCH[2]}"
if [[ -n "$user" ]]; then
echo " $user: $perms"
fi
fi
done
# Mostrar grupos con acceso
echo ""
echo "Grupos con acceso específico:"
getfacl "$file" 2>/dev/null | grep "^group:" | sed 's/group://' | while read acl; do
if [[ "$acl" =~ ^([^:]+):(.+)$ ]]; then
local group="${BASH_REMATCH[1]}"
local perms="${BASH_REMATCH[2]}"
if [[ -n "$group" ]]; then
echo " $group: $perms"
fi
fi
done
}
set_project_acls() {
local project_dir="$1"
local project_group="$2"
local readonly_group="$3"
if [[ ! -d "$project_dir" ]]; then
echo "Error: Directorio no existe - $project_dir"
return 1
fi
echo "Configurando ACLs para proyecto en: $project_dir"
echo "Grupo del proyecto: $project_group"
echo "Grupo de solo lectura: $readonly_group"
# ACLs por defecto para directorios
setfacl -d -m g:$project_group:rwx "$project_dir"
setfacl -d -m g:$readonly_group:rx "$project_dir"
setfacl -d -m o::--- "$project_dir"
# ACLs para el directorio actual
setfacl -m g:$project_group:rwx "$project_dir"
setfacl -m g:$readonly_group:rx "$project_dir"
setfacl -m o::--- "$project_dir"
# Aplicar a contenido existente
find "$project_dir" -type d -exec setfacl -m g:$project_group:rwx {} \;
find "$project_dir" -type d -exec setfacl -m g:$readonly_group:rx {} \;
find "$project_dir" -type f -exec setfacl -m g:$project_group:rw {} \;
find "$project_dir" -type f -exec setfacl -m g:$readonly_group:r {} \;
echo "ACLs configuradas exitosamente"
echo ""
show_detailed_acl "$project_dir"
}
backup_acls() {
local directory="$1"
local backup_file="${2:-acls_backup_$(date +%Y%m%d_%H%M%S).txt}"
if [[ ! -e "$directory" ]]; then
echo "Error: Directorio no existe - $directory"
return 1
fi
echo "Creando backup de ACLs en: $backup_file"
# Crear backup de ACLs
find "$directory" -exec getfacl {} \; > "$backup_file" 2>/dev/null
echo "Backup creado: $backup_file"
echo "Archivos incluidos: $(grep -c "^# file:" "$backup_file")"
}
restore_acls() {
local backup_file="$1"
if [[ ! -f "$backup_file" ]]; then
echo "Error: Archivo de backup no existe - $backup_file"
return 1
fi
echo "Restaurando ACLs desde: $backup_file"
read -p "¿Continuar con la restauración? (y/N): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Restauración cancelada"
return 1
fi
setfacl --restore="$backup_file"
if [[ $? -eq 0 ]]; then
echo "ACLs restauradas exitosamente"
else
echo "Error al restaurar ACLs"
return 1
fi
}
# Función principal
main() {
# Verificar soporte de ACLs
if ! check_acl_support; then
exit 1
fi
case "$1" in
"show")
show_detailed_acl "$2"
;;
"project")
set_project_acls "$2" "$3" "$4"
;;
"backup")
backup_acls "$2" "$3"
;;
"restore")
restore_acls "$2"
;;
*)
echo "Gestor de ACLs"
echo "Uso: $0 [comando] [argumentos]"
echo ""
echo "Comandos:"
echo " show - Mostrar ACLs detalladas"
echo " project - Configurar ACLs de proyecto"
echo " backup [archivo] - Crear backup de ACLs"
echo " restore - Restaurar ACLs"
;;
esac
}
# Ejecutar función principal
main "$@"
Crea un script que:
Desarrolla una herramienta que:
Implementa un sistema que: