🛠️ Scripts Reales de Sysadmin
Scripts de administración comentados línea a línea, con su caso de uso real, cómo programarlos con cron y posibles mejoras. Ábrelos directamente en el Sandbox para experimentar.
Backup automatizado con fecha y compresión
▾Caso de uso: Copia de seguridad diaria de un directorio importante (p. ej. /var/www) en un .tar.gz con la fecha en el nombre, conservando solo los últimos 7 backups.
#!/bin/bash # === Backup automatizado de /var/www === ORIGEN="/var/www" # qué respaldar DESTINO="/backups" # dónde guardar FECHA=$(date '+%Y-%m-%d_%H%M%S') # marca temporal única ARCHIVO="$DESTINO/www_$FECHA.tar.gz" mkdir -p "$DESTINO" # asegura que exista el destino # Comprime el origen; -c crear, -z gzip, -f fichero if tar -czf "$ARCHIVO" "$ORIGEN" 2>/dev/null; then echo "[OK] Backup creado: $ARCHIVO" else echo "[ERROR] Fallo al crear el backup" >&2 exit 1 fi # Conserva solo los 7 backups más recientes (borra el resto) ls -1t "$DESTINO"/www_*.tar.gz | tail -n +8 | xargs -r rm -- echo "[OK] Rotación completada (se conservan 7)"
Monitor de espacio en disco con alerta
▾Caso de uso: Comprueba el uso de la partición raíz y, si supera un umbral, envía un aviso (aquí simulado por pantalla y log).
#!/bin/bash
# === Alerta de disco lleno ===
UMBRAL=85 # % a partir del cual alertar
LOG="/var/log/disco_monitor.log"
# df de / ; quitamos cabecera y el símbolo %
USO=$(df -h / | awk 'NR==2 {gsub("%","",$5); print $5}')
FECHA=$(date '+%Y-%m-%d %H:%M:%S')
if [ "$USO" -ge "$UMBRAL" ]; then
MSG="[$FECHA] ALERTA: disco / al ${USO}% (umbral ${UMBRAL}%)"
echo "$MSG" | tee -a "$LOG"
# Simulación de email (en real: mail -s ... admin@dominio)
echo "$MSG" > /tmp/aviso_disco.mail
else
echo "[$FECHA] OK: disco / al ${USO}%" >> "$LOG"
fi
Rotación manual de logs
▾Caso de uso: Para un log propio de una aplicación: lo archiva con fecha, lo comprime y crea uno nuevo vacío, manteniendo permisos.
#!/bin/bash
# === Rotación manual de un log ===
LOG="/var/log/miapp/app.log"
MAX=5 # cuántos comprimidos conservar
[ -f "$LOG" ] || { echo "No existe $LOG"; exit 0; }
FECHA=$(date '+%Y%m%d')
mv "$LOG" "${LOG}.$FECHA" # archiva el actual
gzip "${LOG}.$FECHA" # lo comprime
: > "$LOG" # crea uno nuevo vacío (truncate)
chmod 640 "$LOG" # restaura permisos
# Elimina los comprimidos más antiguos que superen MAX
ls -1t "${LOG}."*.gz 2>/dev/null | tail -n +$((MAX+1)) | xargs -r rm --
echo "[OK] Log rotado: ${LOG}.$FECHA.gz"
Creación masiva de usuarios desde CSV
▾Caso de uso: Da de alta usuarios leyendo un fichero CSV con formato usuario,grupo,nombre_completo, creando home y contraseña inicial.
#!/bin/bash
# === Alta masiva de usuarios desde CSV ===
CSV="${1:-usuarios.csv}" # fichero como argumento o por defecto
[ -f "$CSV" ] || { echo "No existe $CSV"; exit 1; }
# IFS=, separa por comas; read lee cada campo
while IFS=, read -r usuario grupo nombre; do
[ -z "$usuario" ] && continue # salta líneas vacías
if id "$usuario" &>/dev/null; then
echo "[SKIP] $usuario ya existe"
continue
fi
groupadd -f "$grupo" # crea el grupo si no existe
useradd -m -g "$grupo" -c "$nombre" "$usuario"
echo "${usuario}:Cambiar123" | chpasswd # contraseña inicial
passwd --expire "$usuario" # forzar cambio al primer login
echo "[OK] Creado $usuario (grupo $grupo)"
done < "$CSV"
Auditoría de usuarios del sistema
▾Caso de uso: Informe rápido de seguridad: usuarios con shell de login, cuentas con UID 0 (peligrosas) y usuarios sin contraseña.
#!/bin/bash
# === Auditoría básica de usuarios ===
echo "=== Usuarios con shell de login ==="
grep -E '/(bash|sh|zsh)$' /etc/passwd | cut -d: -f1
echo
echo "=== Cuentas con UID 0 (deberían ser solo root) ==="
awk -F: '$3 == 0 {print $1}' /etc/passwd
echo
echo "=== Usuarios SIN contraseña (campo 2 vacío en shadow) ==="
sudo awk -F: '($2 == "" ) {print $1}' /etc/shadow
echo
echo "=== Últimos accesos ==="
last -n 5
Monitor de proceso con reinicio automático
▾Caso de uso: Vigila que un servicio crítico (p. ej. nginx) siga vivo y, si no, lo reinicia y lo registra. Útil como red de seguridad básica.
#!/bin/bash
# === Vigilante de proceso ===
PROCESO="nginx"
LOG="/var/log/watchdog.log"
FECHA=$(date '+%Y-%m-%d %H:%M:%S')
# pgrep devuelve 0 si el proceso está vivo
if pgrep -x "$PROCESO" > /dev/null; then
echo "[$FECHA] $PROCESO OK" >> "$LOG"
else
echo "[$FECHA] $PROCESO CAÍDO -> reiniciando" >> "$LOG"
systemctl restart "$PROCESO"
if pgrep -x "$PROCESO" > /dev/null; then
echo "[$FECHA] $PROCESO reiniciado correctamente" >> "$LOG"
else
echo "[$FECHA] ERROR: no se pudo reiniciar $PROCESO" >> "$LOG"
fi
fi
Limpieza de ficheros temporales antiguos
▾Caso de uso: Borra de un directorio temporal los ficheros con más de N días sin modificar, liberando espacio de forma segura.
#!/bin/bash
# === Limpieza de temporales > N días ===
DIR="/tmp/miapp"
DIAS=7 # antigüedad mínima para borrar
LOG="/var/log/limpieza_tmp.log"
FECHA=$(date '+%Y-%m-%d %H:%M:%S')
[ -d "$DIR" ] || { echo "No existe $DIR"; exit 0; }
# find: -type f ficheros, -mtime +N modificados hace más de N días
N=$(find "$DIR" -type f -mtime +$DIAS | wc -l)
find "$DIR" -type f -mtime +$DIAS -print -delete >> "$LOG"
echo "[$FECHA] Eliminados $N ficheros de más de $DIAS días" >> "$LOG"
Generador de informe del sistema
▾Caso de uso: Genera un resumen del estado del servidor (uptime, carga, memoria, disco, top de procesos) en un fichero con fecha, ideal para revisión diaria.
#!/bin/bash
# === Informe diario del sistema ===
FECHA=$(date '+%Y-%m-%d %H:%M:%S')
OUT="/var/log/informe_$(date '+%Y%m%d').txt"
{
echo "===== INFORME DEL SISTEMA — $FECHA ====="
echo; echo "--- Uptime y carga ---"; uptime
echo; echo "--- Memoria ---"; free -h
echo; echo "--- Disco ---"; df -h
echo; echo "--- Top 5 procesos por CPU ---"
ps aux --sort=-%cpu | head -n 6
echo; echo "--- Top 5 procesos por memoria ---"
ps aux --sort=-%mem | head -n 6
} > "$OUT"
echo "[OK] Informe generado en $OUT"