[Seguridad] Consolidar scripts de bóveda en scripts/seguridad/ + documentar mecanismo candado.rb en ADN
This commit is contained in:
@@ -25,3 +25,4 @@ tmp/
|
|||||||
scripts/.agent_token
|
scripts/.agent_token
|
||||||
scripts/.agent_token
|
scripts/.agent_token
|
||||||
scripts/.agent_secrets.json
|
scripts/.agent_secrets.json
|
||||||
|
scripts/seguridad/.agent_secrets.json
|
||||||
|
|||||||
+65
-13
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> Referencia canónica: [`adn/00_indice.md`](00_indice.md)
|
> Referencia canónica: [`adn/00_indice.md`](00_indice.md)
|
||||||
|
|
||||||
Esta hebra gobierna los protocolos de seguridad de red, gestión de secretos y contingencia ante fallos críticos de conectividad.
|
Esta hebra gobierna los protocolos de seguridad de red, gestión de secretos, autorización SSH y contingencia ante fallos críticos de conectividad.
|
||||||
|
|
||||||
## 1. Protocolo de Seguridad de Red (Hombre Muerto)
|
## 1. Protocolo de Seguridad de Red (Hombre Muerto)
|
||||||
|
|
||||||
@@ -18,24 +18,76 @@ Esta hebra gobierna los protocolos de seguridad de red, gestión de secretos y c
|
|||||||
|
|
||||||
## 2. Gestión de Secretos (Bóveda Operativa)
|
## 2. Gestión de Secretos (Bóveda Operativa)
|
||||||
|
|
||||||
|
Todos los artefactos de seguridad residen en `scripts/seguridad/`.
|
||||||
|
|
||||||
### 2.1 Prohibición de Texto Plano
|
### 2.1 Prohibición de Texto Plano
|
||||||
La Inteligencia Artificial operante tiene **expresamente prohibido** solicitar contraseñas administrativas, tokens o claves privadas al operador, así como también plasmarlas en logs, comandos literales temporales o en la bitácora.
|
La Inteligencia Artificial operante tiene **expresamente prohibido** solicitar contraseñas administrativas, tokens o claves privadas al operador, así como también plasmarlas en logs, comandos literales temporales o en la bitácora.
|
||||||
|
|
||||||
### 2.2 Consumo Efímero de Bóveda
|
### 2.2 Componentes de la Bóveda
|
||||||
Ante requerimientos de escalada de privilegios (`sudo`, `root`, `sshpass`), la IA accederá de forma autónoma a la bóveda encriptada:
|
|
||||||
|
|
||||||
- **Ubicación**: `scripts/.agent_secrets.json`
|
| Archivo | Ubicación | Git | Descripción |
|
||||||
- **Interfaz**: `ruby scripts/secret_box.rb decrypt <payload>`
|
| :--- | :--- | :---: | :--- |
|
||||||
- **Cifrado**: AES-256-GCM con `.master.key` local (ignorada en Git).
|
| `secret_box.rb` | `scripts/seguridad/` | ✅ | Motor de cifrado AES-256-GCM. Encripta/desencripta payloads. |
|
||||||
- **Ejecución**: Exclusivamente inyectando subshells para enmascarar la variable en los árboles de procesos:
|
| `.agent_secrets.json` | `scripts/seguridad/` | ❌ | Payloads cifrados (sudo, rsa, domain_admin). |
|
||||||
```bash
|
| `.master.key` | Raíz del proyecto | ❌ | Clave maestra de la bóveda (nunca en Git). |
|
||||||
CMD_PASS=$(ruby scripts/secret_box.rb decrypt "$PAYLOAD")
|
|
||||||
sshpass -p "$CMD_PASS" ssh ...
|
### 2.3 Consumo Efímero de Bóveda
|
||||||
```
|
|
||||||
|
Ante requerimientos de escalada de privilegios (`sudo`, `root`, `sshpass`), la IA accederá de forma autónoma a la bóveda:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ejemplo: ejecutar comando con privilegios en un nodo remoto
|
||||||
|
CMD_PASS=$(ruby scripts/seguridad/secret_box.rb decrypt "$PAYLOAD")
|
||||||
|
sshpass -p "$CMD_PASS" ssh root@10.0.10.205 "comando"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Payloads disponibles** (en `.agent_secrets.json`):
|
||||||
|
- `sudo`: Contraseña de sudo/root del entorno local.
|
||||||
|
- `rsa`: Passphrase de la llave SSH (`~/.ssh/id_rsa`).
|
||||||
|
- `domain_admin`: Credenciales de administrador del dominio `dasuten.utnlr`.
|
||||||
|
|
||||||
|
## 3. Autorización SSH (Candado)
|
||||||
|
|
||||||
|
### 3.1 Problema
|
||||||
|
La llave SSH del operador está protegida con passphrase. El agente SSH no retiene las identidades entre sesiones. La IA no puede inyectar la passphrase de forma no interactiva sin `expect`.
|
||||||
|
|
||||||
|
### 3.2 Solución: `candado.rb`
|
||||||
|
El operador ejecuta el script **interactivamente** para autorizar a la IA durante una ventana de tiempo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ruby scripts/seguridad/candado.rb [minutos]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Flujo:**
|
||||||
|
1. 🧹 Limpia identidades previas del agente SSH (`ssh-add -D`).
|
||||||
|
2. 🔑 Pide la passphrase al operador (`ssh-add`).
|
||||||
|
3. ✅ Verifica que la llave se cargó correctamente.
|
||||||
|
4. 🔓 Genera un token temporal (`.agent_token`, 5 min por defecto).
|
||||||
|
5. La IA puede ahora ejecutar comandos SSH sin intervención.
|
||||||
|
|
||||||
|
### 3.3 Flujo Operativo Completo
|
||||||
|
|
||||||
|
```
|
||||||
|
OPERADOR IA (Agente)
|
||||||
|
│ │
|
||||||
|
│ ruby candado.rb 10 │
|
||||||
|
│ → Ingresa passphrase │
|
||||||
|
│ → Token activo 10 min │
|
||||||
|
│ │
|
||||||
|
│ "Listo, el candado está abierto"│
|
||||||
|
│─────────────────────────────────→│
|
||||||
|
│ │ ssh root@srv-dasu "qm create..."
|
||||||
|
│ │ (usa llave cargada en agente)
|
||||||
|
│ │
|
||||||
|
│ ⏳ Token expira │
|
||||||
|
│ │ ssh → ❌ (sin identidad)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Archivos Protegidos (`.gitignore`)
|
||||||
|
|
||||||
### 2.3 Archivos Protegidos (`.gitignore`)
|
|
||||||
Los siguientes artefactos **nunca** deben ser rastreados por Git:
|
Los siguientes artefactos **nunca** deben ser rastreados por Git:
|
||||||
- `.master.key` (clave maestra de la bóveda)
|
- `.master.key` (clave maestra de la bóveda)
|
||||||
- `scripts/.agent_secrets.json` (payloads cifrados)
|
- `scripts/seguridad/.agent_secrets.json` (payloads cifrados)
|
||||||
|
- `.agent_token` (token temporal de autorización)
|
||||||
- `*.key` (claves privadas)
|
- `*.key` (claves privadas)
|
||||||
- `tmp/` (artefactos transitorios de la IA)
|
- `tmp/` (artefactos transitorios de la IA)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#### 👁️ - SINC02 - Sincronización de Inicio de Jornada
|
#### 👁️ - SINC02 - Sincronización de Inicio de Jornada
|
||||||
| Tiempo | Descripción |
|
| Tiempo | Descripción |
|
||||||
| :--- | :--- |
|
| :--- | :--- |
|
||||||
|
| ⏳ 18:58 | (IA) 🚀 Despliegue de VM de Pruebas (pcv-dasu0, Win 7). Creación de VM Windows 7 en Proxmox para validar la unión al dominio `dasuten.utnlr` y realizar pruebas del sistema DASUTeN antes de configurar la PC física final (`pc-dasu0`). Actualización del manifiesto P2601 con contexto institucional y arquitectura ampliada. `[Remoto: Iniciado 18:58]` |
|
||||||
| ✅ 18:33 | (IA) 🧬 Extensión del ADN: Ruby como estándar de codificación y nueva hebra de Proyectos (`07_proyectos.md`). Creación del primer manifiesto de proyecto (`proyectos/P2601_dasuten.md`) con arquitectura de red, hitos clave, stakeholders y referencia al dashboard. `[Remoto: 0:18 hs]` |
|
| ✅ 18:33 | (IA) 🧬 Extensión del ADN: Ruby como estándar de codificación y nueva hebra de Proyectos (`07_proyectos.md`). Creación del primer manifiesto de proyecto (`proyectos/P2601_dasuten.md`) con arquitectura de red, hitos clave, stakeholders y referencia al dashboard. `[Remoto: 0:18 hs]` |
|
||||||
| ✅ 18:15 | (IA) 🧬 Armonización Integral de Bitácoras Históricas. Migración del formato de tabla plana a H4+párrafo+tabla en las bitácoras del 20 y 23/02. Inyección de métricas `[Físico/Remoto: H:MM hs]` en las 5 bitácoras históricas. Canonización de footers IA en los 5 archivos. Mejora de la hebra `02_bitacora.md` con ejemplo estructural y sintaxis de rollover. `[Remoto: 0:35 hs]` |
|
| ✅ 18:15 | (IA) 🧬 Armonización Integral de Bitácoras Históricas. Migración del formato de tabla plana a H4+párrafo+tabla en las bitácoras del 20 y 23/02. Inyección de métricas `[Físico/Remoto: H:MM hs]` en las 5 bitácoras históricas. Canonización de footers IA en los 5 archivos. Mejora de la hebra `02_bitacora.md` con ejemplo estructural y sintaxis de rollover. `[Remoto: 0:35 hs]` |
|
||||||
| ✅ 17:40 | (IA) 🧬 Refactorización del ADN a Arquitectura Multi-Hebra. El operador aprobó el plan de descomposición del protocolo monolítico (`02_protocolo.md`) en 6 hebras temáticas independientes, integrando el principio de Armonía Integral como eje transversal. Se extraen las Premisas IA del footer de las bitácoras hacia una hebra canónica única (`05_ia.md`). Se eliminan archivos obsoletos y se reemplazan los footers duplicados por referencias canónicas. `[Remoto: 0:20 hs]` |
|
| ✅ 17:40 | (IA) 🧬 Refactorización del ADN a Arquitectura Multi-Hebra. El operador aprobó el plan de descomposición del protocolo monolítico (`02_protocolo.md`) en 6 hebras temáticas independientes, integrando el principio de Armonía Integral como eje transversal. Se extraen las Premisas IA del footer de las bitácoras hacia una hebra canónica única (`05_ia.md`). Se eliminan archivos obsoletos y se reemplazan los footers duplicados por referencias canónicas. `[Remoto: 0:20 hs]` |
|
||||||
|
|||||||
@@ -14,7 +14,13 @@
|
|||||||
|
|
||||||
## Objetivo
|
## Objetivo
|
||||||
|
|
||||||
Desplegar la infraestructura completa de servidor para la oficina de DASUTEN (Departamento de Alumnos SUTen) de la Facultad Regional La Rioja (UTN), incluyendo un Controlador de Dominio Active Directory, un motor de Base de Datos SQL Server 2019, y el sistema de gestión administrativa DASUTEN, operando sobre un hipervisor Proxmox VE standalone aislado de la red principal del campus.
|
**DASUTeN** (Departamento de Acción Social Universitaria Tecnológica Nacional) es la obra social de empleados, docentes y alumnos de la Universidad Tecnológica Nacional. Si bien cuenta con una oficina en la Facultad Regional La Rioja, depende directamente de su **sede central en el Rectorado (Buenos Aires)**.
|
||||||
|
|
||||||
|
Actualmente, el sistema de gestión administrativa de DASUTeN funciona dentro de los servidores de la Facultad. El objetivo de este proyecto es **migrar el sistema a un servidor independiente** (`srv-dasu`) aislado de la red académica, de modo que:
|
||||||
|
|
||||||
|
1. La **PC física de la oficina** (`pc-dasu0`) consuma el sistema directamente desde el nuevo servidor.
|
||||||
|
2. La infraestructura quede **autocontenida** dentro de la oficina DASUTeN: una PC cliente + un servidor con sus VMs (DC, SQL, y a futuro posibles servicios adicionales).
|
||||||
|
3. Se logre **independencia operativa** respecto a los servidores de la Facultad, facilitando la gestión desde Rectorado si fuera necesario.
|
||||||
|
|
||||||
## Stakeholders
|
## Stakeholders
|
||||||
|
|
||||||
@@ -37,6 +43,8 @@ Desplegar la infraestructura completa de servidor para la oficina de DASUTEN (De
|
|||||||
| [**srv-dasu**](../nodos/srv-dasu.md) | `10.0.10.205` | Hipervisor Proxmox VE (standalone) |
|
| [**srv-dasu**](../nodos/srv-dasu.md) | `10.0.10.205` | Hipervisor Proxmox VE (standalone) |
|
||||||
| **dc-dasuten** (VM 100) | `10.0.100.10` | Controlador de Dominio AD DS + DNS |
|
| **dc-dasuten** (VM 100) | `10.0.100.10` | Controlador de Dominio AD DS + DNS |
|
||||||
| **sql-dasuten** (VM 101) | `10.0.100.11` | Motor SQL Server 2019 (Core) |
|
| **sql-dasuten** (VM 101) | `10.0.100.11` | Motor SQL Server 2019 (Core) |
|
||||||
|
| **pcv-dasu0** (VM 102) | `10.0.100.12` | VM de pruebas (Win 7) → Emula la config final de `pc-dasu0` |
|
||||||
|
| [**pc-dasu0**](../nodos/pc-dasu0.md) | Oficina DASUTeN | PC física cliente (Win 10, Ryzen 5) — Nodo final destino |
|
||||||
| [**srv-ns8**](../nodos/srv-ns8.md) | `10.0.10.8` | Nodo central de gestión y dashboard |
|
| [**srv-ns8**](../nodos/srv-ns8.md) | `10.0.10.8` | Nodo central de gestión y dashboard |
|
||||||
|
|
||||||
## Herramientas
|
## Herramientas
|
||||||
@@ -62,8 +70,11 @@ Desplegar la infraestructura completa de servidor para la oficina de DASUTEN (De
|
|||||||
| 26/02 | SSH | ✅ | Despliegue de OpenSSH Server nativo en ambas VMs Windows. |
|
| 26/02 | SSH | ✅ | Despliegue de OpenSSH Server nativo en ambas VMs Windows. |
|
||||||
| 26/02 | BKP | ✅ | Resguardo VZDump offline (stop mode) de DC y SQL. |
|
| 26/02 | BKP | ✅ | Resguardo VZDump offline (stop mode) de DC y SQL. |
|
||||||
| 27/02 | ADN | ✅ | Refactorización del ADN a arquitectura multi-hebra con Armonía Integral. |
|
| 27/02 | ADN | ✅ | Refactorización del ADN a arquitectura multi-hebra con Armonía Integral. |
|
||||||
|
| 27/02 | TEST | ⏳ | Despliegue de VM de pruebas (Windows 7) para validar dominio y sistema antes de configurar `pc-dasu0`. |
|
||||||
| — | P02 | 📍 | Instalación del sistema DASUTEN sobre el motor SQL. |
|
| — | P02 | 📍 | Instalación del sistema DASUTEN sobre el motor SQL. |
|
||||||
| — | S02 | 📍 | Hardenización SSH (llaves, passphrases, auditoría). |
|
| — | S02 | 📍 | Hardenización SSH (llaves, passphrases, auditoría). |
|
||||||
|
| — | MIG | 📍 | Migración de datos del sistema actual a la nueva infraestructura. |
|
||||||
|
| — | CLI | 📍 | Configuración final de `pc-dasu0` como cliente del dominio `dasuten.utnlr`. |
|
||||||
|
|
||||||
## Arquitectura de Red
|
## Arquitectura de Red
|
||||||
|
|
||||||
@@ -85,6 +96,9 @@ Desplegar la infraestructura completa de servidor para la oficina de DASUTEN (De
|
|||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ │ sql-dasuten │ │
|
│ │ sql-dasuten │ │
|
||||||
│ │ (.11) [SQL] │ │
|
│ │ (.11) [SQL] │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ pcv-dasu0 │ pc-dasu0 │
|
||||||
|
│ │ (.12) [Test] │ [Cliente] │
|
||||||
│ └──────────────┘ │
|
│ └──────────────┘ │
|
||||||
└─────────────────────────────────────────┘
|
└─────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
require 'json'
|
require 'json'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
|
||||||
TOKEN_FILE = File.expand_path('../.agent_token', __dir__)
|
TOKEN_FILE = File.expand_path('../../.agent_token', __dir__)
|
||||||
DEFAULT_DURATION_MINS = 5
|
DEFAULT_DURATION_MINS = 5
|
||||||
|
|
||||||
# 1. Validación de Identidad (Proof of User Presence)
|
# 1. Validación de Identidad (Proof of User Presence)
|
||||||
@@ -66,7 +66,7 @@ if __FILE__ == $0
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Buscar el archivo .master.key en el root del proyecto
|
# Buscar el archivo .master.key en el root del proyecto
|
||||||
key_path = File.join(File.expand_path('..', __dir__), '.master.key')
|
key_path = File.join(File.expand_path('../..', __dir__), '.master.key')
|
||||||
|
|
||||||
unless File.exist?(key_path)
|
unless File.exist?(key_path)
|
||||||
require 'securerandom'
|
require 'securerandom'
|
||||||
Reference in New Issue
Block a user