#!/usr/bin/env bash
#=============================================================================
# Sentinela ? Intelligent Linux Security Framework
# lib/snapshot.sh ? Sistema de snapshots de reglas de firewall
#=============================================================================
#
# Gestiona snapshots de iptables para backup y rollback.
# Los snapshots se guardan en BACKUP_DIR con timestamp.
#=============================================================================
# shellcheck source=lib/common.sh
source "${SENTINELA_DIR}/lib/common.sh"
#=============================================================================
# Crear snapshot de reglas actuales
#=============================================================================
snapshot_create() {
require_root
local name="${1:-manual}"
local timestamp
timestamp=$(date '+%Y%m%d_%H%M%S')
local file="${BACKUP_DIR}/snapshot.${name}.${timestamp}"
mkdir -p "${BACKUP_DIR}"
log_info "Creando snapshot: ${file}"
if ${IPTABLES_SAVE} > "${file}" 2>/dev/null; then
log_info "Snapshot creado: ${file} ($(wc -c < "${file}") bytes)"
# Crear enlace simbólico al último snapshot
ln -sf "${file}" "${BACKUP_DIR}/snapshot.last" 2>/dev/null || true
echo "${file}"
return 0
else
log_error "Fallo al crear snapshot de iptables"
return 1
fi
}
#=============================================================================
# Restaurar snapshot
#=============================================================================
snapshot_restore() {
require_root
local file="${1:-${BACKUP_DIR}/snapshot.last}"
if [[ ! -f "${file}" ]]; then
log_error "Snapshot no encontrado: ${file}"
return 1
fi
log_info "Restaurando snapshot: ${file}"
log_warn "Las reglas actuales serán reemplazadas"
if ${IPTABLES_RESTORE} < "${file}" 2>/dev/null; then
log_info "Snapshot restaurado exitosamente"
return 0
else
log_error "Fallo al restaurar snapshot"
return 1
fi
}
#=============================================================================
# Listar snapshots disponibles
#=============================================================================
snapshot_list() {
local snapshots
snapshots=$(ls -1t "${BACKUP_DIR}"/snapshot.* 2>/dev/null || true)
if [[ -z "${snapshots}" ]]; then
log_info "No hay snapshots disponibles"
return 0
fi
echo "Snapshots disponibles:"
echo "??????????????????????????????????????????????????????????"
echo " # FECHA NOMBRE TAMAÑO"
echo "??????????????????????????????????????????????????????????"
local count=0
while IFS= read -r snap; do
count=$((count + 1))
local name
name=$(basename "${snap}")
local size
size=$(du -h "${snap}" | awk '{print $1}')
local date
date=$(stat -c '%y' "${snap}" | cut -d'.' -f1)
printf " %-3s %-19s %-20s %s\n" "${count}." "${date}" "${name}" "${size}"
done <<< "${snapshots}"
}
#=============================================================================
# Limpiar snapshots antiguos (retention)
#=============================================================================
snapshot_cleanup() {
local retention="${1:-${BACKUP_RETENTION}}"
local days=$((retention * 2)) # Mantener snapshots por el doble de días que backups
log_info "Limpiando snapshots con más de ${days} días"
find "${BACKUP_DIR}" -name "snapshot.*" -type f -mtime "+${days}" -delete 2>/dev/null || true
# Mantener solo los últimos 50 snapshots
local count
count=$(ls -1t "${BACKUP_DIR}"/snapshot.* 2>/dev/null | wc -l)
if [[ "${count}" -gt 50 ]]; then
ls -1t "${BACKUP_DIR}"/snapshot.* | tail -n $((count - 50)) | xargs rm -f 2>/dev/null || true
log_info "Limpiados snapshots excedentes"
fi
}
|