Refactor(DIIAA): Evolución del ADN a dtic-DIIAA, renombrando scripts/ a automatizacion/ y actualizando manifiestos y URLs de servicios web
This commit is contained in:
Executable
+231
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env ruby
|
||||
# script: alta_nodo.rb
|
||||
# Uso: ruby automatizacion/alta_nodo.rb <IP> <HOSTNAME> [USUARIO]
|
||||
# Descripción: Automatiza la configuración SSH y la documentación del ADN para un nuevo nodo.
|
||||
|
||||
require 'fileutils'
|
||||
require 'date'
|
||||
require 'json'
|
||||
require 'time'
|
||||
|
||||
# --- Configuración ---
|
||||
ADN_DIR = File.expand_path('../adn', __dir__)
|
||||
NODOS_DIR = File.join(ADN_DIR, 'nodos')
|
||||
ONTOLOGIA_FILE = File.join(ADN_DIR, '01_ontologia.md')
|
||||
SSH_CONFIG_FILE = File.expand_path('~/.ssh/config')
|
||||
SSH_PUB_KEY = File.expand_path('~/.ssh/id_rsa.pub')
|
||||
|
||||
# --- Argumentos ---
|
||||
ip = ARGV[0]
|
||||
user = ARGV[1] || 'rmonla'
|
||||
|
||||
unless ip
|
||||
puts "❌ Error: Falta la IP."
|
||||
puts "Uso correcto: ruby automatizacion/alta_nodo.rb <IP> [USUARIO]"
|
||||
puts "Ejemplo: ruby automatizacion/alta_nodo.rb 10.0.10.205 rmonla"
|
||||
exit 1
|
||||
end
|
||||
|
||||
puts "--- 🚀 Iniciando Alta de Nodo: #{ip} con Usuario: #{user} ---"
|
||||
|
||||
# --- 🚨 PROTOCOLO DE SEGURIDAD (CANDADO JIT) ---
|
||||
TOKEN_FILE = File.expand_path('../.agent_token', __dir__)
|
||||
|
||||
def verificar_autorizacion!
|
||||
unless File.exist?(TOKEN_FILE)
|
||||
puts "\n⛔ ACCESO DENEGADO: No se encontró token de autorización."
|
||||
puts "🔒 Protocolo de seguridad activo. El Agente requiere permiso explícito."
|
||||
puts "👉 Ejecuta: ruby automatizacion/candado.rb"
|
||||
exit 1
|
||||
end
|
||||
|
||||
begin
|
||||
token = JSON.parse(File.read(TOKEN_FILE))
|
||||
expires_at = Time.parse(token['expires_at'])
|
||||
|
||||
if Time.now > expires_at
|
||||
puts "\n⛔ ACCESO DENEGADO: El token de autorización ha EXPIRADO."
|
||||
puts "💀 Expiró a las: #{expires_at.strftime('%H:%M:%S')}"
|
||||
puts "👉 Ejecuta nuevamente: ruby automatizacion/candado.rb"
|
||||
exit 1
|
||||
end
|
||||
|
||||
puts "🔓 Autorización Verificada (Válida hasta #{expires_at.strftime('%H:%M:%S')})"
|
||||
rescue => e
|
||||
puts "\n❌ Error al verificar token: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
verificar_autorizacion!
|
||||
# -----------------------------------------------
|
||||
|
||||
# Variable para trackear si tenemos acceso sin password/interactivo
|
||||
ssh_access_ok = false
|
||||
|
||||
# Detectamos si necesitamos flags legacy
|
||||
# Intentamos primero con flags modernos, si falla, probamos con legacy
|
||||
ssh_flags = "-o ConnectTimeout=5 -o StrictHostKeyChecking=no"
|
||||
ssh_legacy_flags = "#{ssh_flags} -o PubkeyAcceptedAlgorithms=+ssh-rsa -o HostKeyAlgorithms=+ssh-rsa"
|
||||
|
||||
# --- 0. Detección de Hostname y Verificación de Acceso ---
|
||||
puts "\n🔍 0. Detectando Hostname y Verificando Acceso..."
|
||||
begin
|
||||
# Probamos conexión con BatchMode para ver si ya entramos sin password
|
||||
check_cmd = "ssh -o BatchMode=yes #{ssh_legacy_flags} #{user}@#{ip} hostname 2>/dev/null"
|
||||
hostname = `#{check_cmd}`.strip
|
||||
|
||||
if $?.success? && !hostname.empty?
|
||||
puts "✅ Acceso SSH verificado (Sin contraseña)."
|
||||
puts "✅ Hostname detectado: #{hostname}"
|
||||
ssh_access_ok = true
|
||||
else
|
||||
puts "⚠️ Acceso directo no disponible. Intentando conexión interactiva (pedirá password)..."
|
||||
# Usamos flags legacy aquí también por si acaso
|
||||
hostname = `ssh #{ssh_legacy_flags} #{user}@#{ip} hostname`.strip
|
||||
|
||||
if $?.success? && !hostname.empty?
|
||||
puts "✅ Hostname detectado: #{hostname}"
|
||||
else
|
||||
puts "❌ No se pudo obtener el hostname. Verifica la IP y credenciales."
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
puts "❌ Error al intentar conectar: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
# --- 1. Configuración SSH Local ---
|
||||
puts "\n🔧 1. Configurando SSH Local..."
|
||||
|
||||
if File.read(SSH_CONFIG_FILE).include?("Host #{hostname}")
|
||||
puts "ℹ️ Host '#{hostname}' ya existe en #{SSH_CONFIG_FILE}."
|
||||
else
|
||||
puts "📝 Agregando '#{hostname}' a #{SSH_CONFIG_FILE}..."
|
||||
File.open(SSH_CONFIG_FILE, 'a') do |f|
|
||||
f.puts "\nHost #{hostname}"
|
||||
f.puts " HostName #{ip}"
|
||||
f.puts " User #{user}"
|
||||
f.puts " StrictHostKeyChecking no"
|
||||
f.puts " PubkeyAcceptedAlgorithms +ssh-rsa"
|
||||
f.puts " HostKeyAlgorithms +ssh-rsa"
|
||||
end
|
||||
puts "✅ Configuración SSH actualizada (con soporte legacy)."
|
||||
end
|
||||
|
||||
# --- 2. Copia de Claves SSH ---
|
||||
if ssh_access_ok
|
||||
puts "\n🔑 2. Copia de Claves SSH: OMITIDO (Ya tienes acceso)."
|
||||
else
|
||||
puts "\n🔑 2. Instalando Clave SSH en #{user}@#{ip}..."
|
||||
if File.exist?(SSH_PUB_KEY)
|
||||
# ssh-copy-id pedirá password una única vez aquí
|
||||
# Pasamos opciones legacy explícitamente
|
||||
system("ssh-copy-id #{ssh_legacy_flags} -i #{SSH_PUB_KEY} #{user}@#{ip}")
|
||||
|
||||
if $?.success?
|
||||
puts "✅ Clave instalada exitosamente."
|
||||
ssh_access_ok = true
|
||||
else
|
||||
puts "⚠️ Falló ssh-copy-id. Quizás debas hacerlo manualmente o verificar password."
|
||||
end
|
||||
else
|
||||
puts "❌ No se encontró clave pública en #{SSH_PUB_KEY}."
|
||||
end
|
||||
end
|
||||
|
||||
require 'json'
|
||||
|
||||
# --- 3. Relevamiento de Hardware (Extracción Cruda & Procesamiento Local) ---
|
||||
puts "\n🔍 3. Extrayendo Datos Crudos del Nodo (Procesamiento Local)..."
|
||||
|
||||
# Script remoto minimalista: Solo "cat" de archivos clave y lsblk
|
||||
# Usamos delimitadores únicos para separar bloques
|
||||
# Agregamos recolección de evidencia para detección de roles
|
||||
remote_script = <<~SHELL
|
||||
echo "---START_HOSTNAME---"; cat /etc/hostname
|
||||
echo "---START_CPUINFO---"; cat /proc/cpuinfo
|
||||
echo "---START_MEMINFO---"; cat /proc/meminfo
|
||||
echo "---START_OSRELEASE---"; cat /etc/os-release
|
||||
echo "---START_LSBLK---"; lsblk -d -o NAME,SIZE,MODEL,TYPE -J 2>/dev/null || lsblk -d -o NAME,SIZE,MODEL,TYPE
|
||||
echo "---START_PROCESSES---"; ps -ef --sort=-%mem | head -n 20
|
||||
echo "---START_PORTS---"; ss -tuln 2>/dev/null || netstat -tuln 2>/dev/null
|
||||
echo "---START_MARKERS---"
|
||||
[ -d "/etc/xen" ] && echo "xen_config_dir_exists"
|
||||
[ -d "/etc/pve" ] && echo "pve_config_dir_exists"
|
||||
[ -d "/var/lib/docker" ] && echo "docker_lib_dir_exists"
|
||||
[ -f "/usr/bin/dockerd" ] && echo "dockerd_bin_exists"
|
||||
[ -f "/opt/xensource/bin/xe" ] && echo "citrix_xe_bin_exists"
|
||||
SHELL
|
||||
|
||||
safe_script = remote_script.gsub('"', '\\"')
|
||||
# Usamos flags legacy para la sonda también
|
||||
raw_output = `ssh #{ssh_legacy_flags} #{hostname} "#{safe_script}"`
|
||||
|
||||
# Parsers Locales (Host-Side Logic)
|
||||
def parse_block(output, key)
|
||||
return "" unless output.include?("---START_#{key}---")
|
||||
output.split("---START_#{key}---")[1].split("---START_")[0].strip
|
||||
rescue
|
||||
""
|
||||
end
|
||||
|
||||
hostname_raw = parse_block(raw_output, 'HOSTNAME')
|
||||
cpuinfo_raw = parse_block(raw_output, 'CPUINFO')
|
||||
meminfo_raw = parse_block(raw_output, 'MEMINFO')
|
||||
osrelease_raw = parse_block(raw_output, 'OSRELEASE')
|
||||
lsblk_raw = parse_block(raw_output, 'LSBLK')
|
||||
processes_raw = parse_block(raw_output, 'PROCESSES')
|
||||
ports_raw = parse_block(raw_output, 'PORTS')
|
||||
markers_raw = parse_block(raw_output, 'MARKERS')
|
||||
|
||||
# Analizador de CPU (Local)
|
||||
cpu_model = cpuinfo_raw.scan(/model name\s+:\s+(.*)/).flatten.first || "Unknown"
|
||||
cpu_cores = cpuinfo_raw.scan(/^processor\s+:/).count
|
||||
cpu_arch = "x86_64" # Default (podría sacarse de flags en cpuinfo 'lm' = long mode)
|
||||
|
||||
# Analizador de RAM (Local)
|
||||
mem_total_kb = meminfo_raw.scan(/MemTotal:\s+(\d+)\s+kB/).flatten.first.to_i
|
||||
mem_total_human = "#{(mem_total_kb / 1024.0 / 1024.0).round(2)} GiB"
|
||||
|
||||
# Analizador de OS (Local)
|
||||
os_distro = osrelease_raw.scan(/PRETTY_NAME="(.*)"/).flatten.first || "Unknown Linux"
|
||||
os_kernel_ver = "Linux (Kernel ver. unknown)" # Kernel version requiring 'uname -r', keeping simple for now or parsing from /proc/version if needed later
|
||||
|
||||
params = {}
|
||||
params[:timestamp] = Time.now.to_s
|
||||
params[:connector] = { ip: ip, user: user, hostname_detected: hostname_raw.empty? ? hostname : hostname_raw }
|
||||
|
||||
params[:cpu] = { model: cpu_model, cores: cpu_cores, arch: cpu_arch }
|
||||
params[:ram] = { total: mem_total_human, raw: mem_total_kb * 1024 }
|
||||
params[:os] = { distro: os_distro, kernel: os_kernel_ver } # Simplified
|
||||
|
||||
# Procesamiento de Discos (Local)
|
||||
if lsblk_raw.strip.start_with?("{")
|
||||
begin
|
||||
params[:disks] = JSON.parse(lsblk_raw)
|
||||
rescue
|
||||
params[:disks] = { format: 'raw', content: lsblk_raw }
|
||||
end
|
||||
else
|
||||
params[:disks] = { format: 'text', content: lsblk_raw }
|
||||
end
|
||||
|
||||
# Evidencia para Inteligencia de Agente
|
||||
params[:evidence] = {
|
||||
processes: processes_raw.lines.map(&:strip),
|
||||
ports: ports_raw.lines.map(&:strip),
|
||||
file_markers: markers_raw.lines.map(&:strip)
|
||||
}
|
||||
|
||||
puts " ✅ Datos crudos extraídos y procesados localmente."
|
||||
|
||||
# --- 4. Salida para el Agente (STDOUT) ---
|
||||
puts "\n💾 4. Telemetría Final (Para consumo del Agente)..."
|
||||
puts "---START_PAYLOAD---"
|
||||
puts JSON.pretty_generate(params)
|
||||
puts "---END_PAYLOAD---"
|
||||
|
||||
puts "\n✅ Proceso finalizado. Copia el bloque JSON anterior si necesitas procesarlo manualmente, o deja que el Agente lo lea."
|
||||
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
# Script: alta_nodo.sh
|
||||
# Uso: ./automatizacion/alta_nodo.sh <IP> <HOSTNAME> [USUARIO]
|
||||
# Descripción: Automatiza la configuración SSH local y el despliegue de claves al nuevo nodo.
|
||||
|
||||
IP=$1
|
||||
NAME=$2
|
||||
USER_SSH=${3:-rmonla} # Por defecto usa 'rmonla' si no se especifica
|
||||
|
||||
# Validar argumentos básicos
|
||||
if [ -z "$IP" ] || [ -z "$NAME" ]; then
|
||||
echo "❌ Error: Faltan argumentos."
|
||||
echo "Uso correcto: ./automatizacion/alta_nodo.sh <IP> <HOSTNAME> [USUARIO]"
|
||||
echo "Ejemplo: ./automatizacion/alta_nodo.sh 10.0.10.205 srv-pmox4 rmonla"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "--- Iniciando Alta de Nodo: $NAME ($IP) con Usuario: $USER_SSH ---"
|
||||
|
||||
# 1. Configurar SSH local (~/.ssh/config)
|
||||
if grep -q "^Host $NAME$" ~/.ssh/config; then
|
||||
echo "ℹ️ Host '$NAME' ya existe en ~/.ssh/config (Se asume configuración correcta)."
|
||||
else
|
||||
echo "🔧 Agregando '$NAME' a ~/.ssh/config..."
|
||||
cat >> ~/.ssh/config <<EOF
|
||||
|
||||
Host $NAME
|
||||
HostName $IP
|
||||
User $USER_SSH
|
||||
StrictHostKeyChecking no
|
||||
EOF
|
||||
fi
|
||||
|
||||
# 2. Verificar Conectividad
|
||||
echo "📡 Verificando conexión (Ping)..."
|
||||
ping -c 2 $IP > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "⚠️ Alerta: No hay ping a $IP. Verifica la red."
|
||||
else
|
||||
echo "✅ Ping exitoso."
|
||||
fi
|
||||
|
||||
# 3. Intentar instalación automática de clave (ssh-copy-id)
|
||||
echo "🔑 Intentando instalar clave SSH automáticamente en $USER_SSH@$IP..."
|
||||
ssh-copy-id -o ConnectTimeout=5 -i ~/.ssh/id_rsa.pub $USER_SSH@$IP 2>/dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Clave instalada exitosamente via ssh-copy-id."
|
||||
echo "🚀 Probando conexión SSH..."
|
||||
ssh -o ConnectTimeout=5 $NAME "uptime"
|
||||
else
|
||||
echo "⚠️ No se pudo copiar la clave automáticamente."
|
||||
echo "Probablemente necesites ingresar la contraseña de '$USER_SSH' si te la pide."
|
||||
echo ""
|
||||
echo "📋 SI FALLA, EJECUTA ESTO MANUALMENTE EN LA TERMINAL DEL NODO ($IP) con tu usuario:"
|
||||
echo "-----------------------------------------------------------"
|
||||
# Generamos el comando dinámicamente con la clave actual
|
||||
PUBKEY=$(cat ~/.ssh/id_rsa.pub)
|
||||
echo "mkdir -p ~/.ssh && echo \"$PUBKEY\" >> ~/.ssh/authorized_keys"
|
||||
echo "-----------------------------------------------------------"
|
||||
fi
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# scripts/configurar_red_hibrida.sh
|
||||
# CONFIGURACIÓN DE RED HÍBRIDA (Policy Routing)
|
||||
# Objetivo:
|
||||
# - Mantener Gateway Default 10.0.10.1 (Navegación Rápida).
|
||||
# - Habilitar IP Pública 190.114.205.18 para acceso entrante.
|
||||
# - Responder tráfico entrante de 190... por su propio Gateway (190.114.205.1).
|
||||
|
||||
CON_NAME="Red LAN 10"
|
||||
IP_PUB="190.114.205.18/24"
|
||||
GW_PUB="190.114.205.1"
|
||||
TABLE_ID="190"
|
||||
TIMEOUT_SEC=300 # 5 Minutos
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Ejecutar con sudo.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Configurando Red Híbrida en conexión '$CON_NAME'...${NC}"
|
||||
|
||||
# 1. Agregar IP Pública (si no existe ya)
|
||||
# Nota: nmcli es idempotente para esto si se usa correctamente, pero limpiaremos "ipv4.addresses" duplicadas si es manual.
|
||||
# Aquí simplemente agregamos.
|
||||
echo -e "[1/4] Agregando IP Pública $IP_PUB..."
|
||||
nmcli con mod "$CON_NAME" +ipv4.addresses "$IP_PUB"
|
||||
|
||||
# 2. Agregar Ruta a Tabla Secundaria
|
||||
# Sintaxis: ip/prefix next-hop priority attributes
|
||||
echo -e "[2/4] Configurando ruta de retorno (Tabla $TABLE_ID)..."
|
||||
nmcli con mod "$CON_NAME" +ipv4.routes "0.0.0.0/0 $GW_PUB 100 table=$TABLE_ID"
|
||||
|
||||
# 3. Agregar Regla de Enrutamiento
|
||||
# Sintaxis: priority from <ip> table <id>
|
||||
echo -e "[3/4] Configurando regla de política (Policy Rule)..."
|
||||
nmcli con mod "$CON_NAME" +ipv4.routing-rules "priority 30000 from ${IP_PUB%/*} table $TABLE_ID"
|
||||
|
||||
# 4. Aplicar Cambios (Temporales para validación)
|
||||
echo -e "Aplicando configuración... (Si pierdes conexión, espera $TIMEOUT_SEC segundos)"
|
||||
nmcli con mod "$CON_NAME" +ipv4.addresses "$IP_PUB"
|
||||
nmcli con mod "$CON_NAME" +ipv4.routes "0.0.0.0/0 $GW_PUB 100 table=$TABLE_ID"
|
||||
nmcli con mod "$CON_NAME" +ipv4.routing-rules "priority 30000 from ${IP_PUB%/*} table $TABLE_ID"
|
||||
nmcli con up "$CON_NAME"
|
||||
|
||||
# --- VERIFICACIÓN / ROLLBACK LOOP ---
|
||||
echo -e "\n${GREEN}*** CAMBIOS APLICADOS ***${NC}"
|
||||
echo "Verifica que tienes conectividad (tanto LAN como WAN)."
|
||||
echo "Tienes $TIMEOUT_SEC segundos para confirmar escribiendo 's' y Enter."
|
||||
|
||||
CONFIRMADO=0
|
||||
for ((i=TIMEOUT_SEC; i>0; i--)); do
|
||||
echo -ne " Tiempo restante para ROLLBACK: $i segundos \r"
|
||||
read -t 1 -n 1 key
|
||||
if [[ $key = "s" ]] || [[ $key = "S" ]]; then
|
||||
CONFIRMADO=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $CONFIRMADO -eq 1 ]; then
|
||||
echo -e "\n\n${GREEN}¡CONFIRMADO! Configuración de Red Híbrida establecida.${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "\n\n${RED}¡TIEMPO AGOTADO! REVIERTIENDO CAMBIOS...${NC}"
|
||||
|
||||
# Revertir (Undo)
|
||||
echo "Eliminando reglas..."
|
||||
nmcli con mod "$CON_NAME" -ipv4.addresses "$IP_PUB"
|
||||
nmcli con mod "$CON_NAME" -ipv4.routes "0.0.0.0/0 $GW_PUB 100 table=$TABLE_ID"
|
||||
nmcli con mod "$CON_NAME" -ipv4.routing-rules "priority 30000 from ${IP_PUB%/*} table $TABLE_ID"
|
||||
|
||||
echo "Recargando conexión..."
|
||||
nmcli con up "$CON_NAME"
|
||||
|
||||
echo -e "${GREEN}Sistema restaurado al estado original.${NC}"
|
||||
fi
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
if [ -f ".env.enc" ]; then
|
||||
openssl enc -d -aes-256-cbc -in .env.enc -out .env -pass pass:"\$2y\$10\$Xo7lM" 2>/dev/null
|
||||
echo "Secret successfully decrypted to .env for temporary use."
|
||||
else
|
||||
echo "Encrypted .env.enc not found."
|
||||
fi
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# scripts/instalar_nginx_simple.sh
|
||||
# Script para instalar Nginx y aplicar configuraciones (Sin manipulación de IP).
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Ejecutar con sudo.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[1/3] Instalando Nginx...${NC}"
|
||||
apt-get update && apt-get install -y nginx
|
||||
|
||||
echo -e "${YELLOW}[2/3] Aplicando configuraciones de servicios...${NC}"
|
||||
# Remover default si molesta
|
||||
# rm /etc/nginx/sites-enabled/default 2>/dev/null
|
||||
|
||||
# Enlazar configs
|
||||
CONFIG_DIR="/home/rmonla/Documentos/GitHub/dtic-DIIAA/servicios/nginx/conf.d"
|
||||
ln -sf $CONFIG_DIR/*.conf /etc/nginx/conf.d/
|
||||
|
||||
echo -e "${YELLOW}[3/3] Iniciando servicio...${NC}"
|
||||
systemctl enable nginx
|
||||
systemctl restart nginx
|
||||
|
||||
echo -e "${GREEN}Instalación completada.${NC}"
|
||||
echo "Nginx está corriendo en el Host."
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# scripts/instalar_ssl.sh
|
||||
# Script para instalar Certbot y obtener certificado SSL para ns8.frlr.utn.edu.ar
|
||||
|
||||
DOMAIN="ns8.frlr.utn.edu.ar"
|
||||
EMAIL="admin@ns8.frlr.utn.edu.ar" # Ajustar si es necesario, Certbot pedirá uno real interactivo o usará este
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Ejecutar con sudo.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}[1/4] Instalando Certbot y plugin Nginx...${NC}"
|
||||
apt-get update
|
||||
apt-get install -y certbot python3-certbot-nginx
|
||||
|
||||
echo -e "${YELLOW}[2/4] Activando configuración del dominio $DOMAIN...${NC}"
|
||||
# Enlazar la nueva config si no existe
|
||||
ln -sf /home/rmonla/Documentos/GitHub/dtic-DIIAA/servicios/nginx/conf.d/ns8.conf /etc/nginx/conf.d/ns8.conf
|
||||
|
||||
echo -e "${YELLOW}[3/4] Verificando y Recargando Nginx...${NC}"
|
||||
nginx -t && systemctl reload nginx
|
||||
|
||||
echo -e "${YELLOW}[4/4] Ejecutando Certbot...${NC}"
|
||||
echo "Sigue las instrucciones en pantalla (ingresa tu email si se solicita)."
|
||||
certbot --nginx -d $DOMAIN
|
||||
|
||||
echo -e "${GREEN}Proceso finalizado.${NC}"
|
||||
echo "Prueba acceder a https://$DOMAIN"
|
||||
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
# scripts/instalar_tailscale.sh
|
||||
# Automatización de la instalación de Tailscale en srv-NS8
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Ejecutar con sudo.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Iniciando instalación de Tailscale...${NC}"
|
||||
|
||||
# 1. Ejecutar script oficial de instalación
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
|
||||
# 2. Habilitar el servicio
|
||||
systemctl enable --now tailscaled
|
||||
|
||||
# 3. Informar al usuario para la autenticación
|
||||
echo -e "\n${GREEN}Tailscale ha sido instalado.${NC}"
|
||||
echo -e "${YELLOW}IMPORTANTE: Ahora debes autenticar el servidor.${NC}"
|
||||
echo -e "Ejecuta el siguiente comando en tu terminal y sigue el enlace de autenticación:"
|
||||
echo -e "${CYAN}sudo tailscale up${NC}"
|
||||
|
||||
# 4. Nota sobre Subnet Routing (opcional)
|
||||
echo -e "\n${NC}Si deseas acceder a la LAN 10.0.10.x desde fuera, usa el flag: --advertise-routes=10.0.10.0/24${NC}"
|
||||
Executable
+100
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env ruby
|
||||
# [PROC-01] - Mantenimiento de Backups Proxmox (Ruby Edition)
|
||||
# Lógica: Granular por VMID, Retención 6 días, Destino zfsDISCO1
|
||||
|
||||
require 'date'
|
||||
require 'fileutils'
|
||||
|
||||
STORAGE_NAME = "zfsDISCO1"
|
||||
# NOTA: En Proxmox, la ruta suele ser /mnt/pve/zfsDISCO1 o similar.
|
||||
# Ajustamos a la ruta montada del storage.
|
||||
BASE_PATH = "/mnt/pve/#{STORAGE_NAME}/dump"
|
||||
RETENTION_DAYS = 6
|
||||
VM_PATTERN = /^srv[v]?-/
|
||||
|
||||
def log(message, type = "INFO")
|
||||
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
puts "[#{timestamp}] [#{type}] #{message}"
|
||||
end
|
||||
|
||||
def get_vmid_list
|
||||
# Obtener IDs de VMs (QEMU) y Contenedores (LXC)
|
||||
ids = []
|
||||
|
||||
# QEMU VMs
|
||||
`qm list`.each_line.with_index do |line, idx|
|
||||
next if idx == 0 # Cabecera
|
||||
parts = line.split
|
||||
vmid = parts[0]
|
||||
name = parts[1]
|
||||
ids << vmid if name =~ VM_PATTERN
|
||||
end
|
||||
|
||||
# LXC Containers
|
||||
`pct list`.each_line.with_index do |line, idx|
|
||||
next if idx == 0
|
||||
parts = line.split
|
||||
vmid = parts[0]
|
||||
name = parts[2] # El nombre suele ser la 3er columna en pct list
|
||||
ids << vmid if name =~ VM_PATTERN
|
||||
end
|
||||
|
||||
ids.uniq
|
||||
end
|
||||
|
||||
def prune_old_backups(vmid)
|
||||
log("Iniciando fase de limpieza para VMID: #{vmid}...")
|
||||
return unless Dir.exist?(BASE_PATH)
|
||||
|
||||
# Patrón de archivos de Proxmox: vzdump-[qemu|lxc]-<VMID>-<TIMESTAMP>.*
|
||||
# Buscamos archivos de este VMID específico
|
||||
files = Dir.glob("#{BASE_PATH}/vzdump-*-#{vmid}-*")
|
||||
|
||||
files.each do |file|
|
||||
mtime = File.mtime(file)
|
||||
age_days = (Date.today - mtime.to_date).to_i
|
||||
|
||||
if age_days > RETENTION_DAYS
|
||||
log("Eliminando backup antiguo: #{File.basename(file)} (Antigüedad: #{age_days} días)", "WARN")
|
||||
begin
|
||||
FileUtils.rm(file)
|
||||
rescue => e
|
||||
log("Error al eliminar #{file}: #{e.message}", "ERROR")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_backup(vmid)
|
||||
log("Iniciando backup para VMID: #{vmid} hacia #{STORAGE_NAME}...")
|
||||
# Usamos --mode stop para asegurar reinicio automático y consistencia
|
||||
cmd = "vzdump #{vmid} --storage #{STORAGE_NAME} --mode stop --compress zstd"
|
||||
|
||||
log("Ejecutando: #{cmd}")
|
||||
success = system(cmd)
|
||||
|
||||
if success
|
||||
log("Backup completado exitosamente para VMID: #{vmid}", "SUCCESS")
|
||||
else
|
||||
log("FALLO en el backup para VMID: #{vmid}", "ERROR")
|
||||
end
|
||||
end
|
||||
|
||||
# --- EJECUCIÓN PRINCIPAL ---
|
||||
log("=== INICIO DE CICLO DE MANTENIMIENTO DE BACKUPS ===")
|
||||
|
||||
unless Dir.exist?(BASE_PATH)
|
||||
log("Error: No se encuentra la ruta del storage #{BASE_PATH}. ¿Está montado?", "ERROR")
|
||||
exit 1
|
||||
end
|
||||
|
||||
vmids = get_vmid_list
|
||||
log("Nodos detectados para procesar: #{vmids.join(', ')}")
|
||||
|
||||
vmids.each do |vmid|
|
||||
prune_old_backups(vmid)
|
||||
run_backup(vmid)
|
||||
puts "-" * 40
|
||||
end
|
||||
|
||||
log("=== FIN DE CICLO DE MANTENIMIENTO ===")
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
# scripts/respaldar_configs.sh
|
||||
# Sistema de respaldo de configuraciones críticas para srv-NS8
|
||||
|
||||
BACKUP_ROOT="/home/rmonla/Documentos/GitHub/dtic-DIIAA/backups/configs"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M)
|
||||
LOG_FILE="/home/rmonla/Documentos/GitHub/dtic-DIIAA/logs/backup_${TIMESTAMP}.log"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
mkdir -p "$BACKUP_ROOT"
|
||||
mkdir -p "/home/rmonla/Documentos/GitHub/dtic-DIIAA/logs"
|
||||
|
||||
echo -e "${GREEN}Iniciando respaldo de configuraciones...${NC}" | tee -a "$LOG_FILE"
|
||||
|
||||
# Lista de directorios a respaldar
|
||||
PATHS=(
|
||||
"/etc/anydesk"
|
||||
"/home/rmonla/.anydesk"
|
||||
"/etc/rustdesk"
|
||||
"/home/rmonla/.config/rustdesk"
|
||||
"/var/lib/tailscale"
|
||||
"/etc/nginx"
|
||||
"/home/rmonla/Documentos/GitHub/dtic-DIIAA/servicios/homepage/.env"
|
||||
)
|
||||
|
||||
for SRC in "${PATHS[@]}"; do
|
||||
if [ -d "$SRC" ] || [ -f "$SRC" ]; then
|
||||
echo "Respaldando $SRC..." | tee -a "$LOG_FILE"
|
||||
# Usamos rsync para mantener la estructura y permisos (requiere sudo para rutas root)
|
||||
DEST="${BACKUP_ROOT}${SRC}"
|
||||
mkdir -p "$(dirname "$DEST")"
|
||||
sudo rsync -avR --delete "$SRC" "$BACKUP_ROOT/" >> "$LOG_FILE" 2>&1
|
||||
else
|
||||
echo -e "${RED}Advertencia: No se encontró $SRC${NC}" | tee -a "$LOG_FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
# Generar un comprimido del respaldo actual
|
||||
tar -czf "${BACKUP_ROOT}/../configs_backup_${TIMESTAMP}.tar.gz" -C "$BACKUP_ROOT" .
|
||||
|
||||
echo -e "${GREEN}Respaldo completado en ${BACKUP_ROOT}/../configs_backup_${TIMESTAMP}.tar.gz${NC}" | tee -a "$LOG_FILE"
|
||||
Reference in New Issue
Block a user