docs: Plan P2603.01 Automatización Zoom y actualizaciones P2601.09

This commit is contained in:
Ricardo Monla
2026-03-31 18:03:21 -03:00
parent 160da47f96
commit 1fd213173e
72 changed files with 19694 additions and 460 deletions
@@ -0,0 +1,685 @@
# [PROC-2601-6.1.B] - Procedimiento de Comunicación Directa Local entre srv-dasu y pc-dasu0
## 1. Identificación y Objetivo
- **ID**: `PROC-2601-6.1.B`
- **Responsable**: Administrador de Infraestructura / Usuario Autorizado
- **Objetivo**: Establecer comunicación de red directa local entre `srv-dasu` (hypervisor Proxmox) y `pc-dasu0` (PC física) cuando ambos dispositivos comparten el mismo router ISP en la oficina DASUTEN, optimizando el rendimiento y reduciendo la dependencia de Tailscale para operaciones locales.
- **Frecuencia**: Manual / Bajo Demanda (cuando ambos dispositivos están en la misma red física)
## 2. Alcance y Prerrequisitos
- **Nodos Afectados**:
- `srv-dasu` (Hypervisor Proxmox VE - IP: 10.0.10.205 / Tailscale: 100.116.210.36)
- `pc-dasu0` (PC física Windows 10 - Tailscale: 100.65.62.44)
- `dc-dasuten` (VM 100 - Controlador de Dominio - IP: 10.0.100.10)
- **Sistemas**: Linux (Proxmox/Debian), Windows 10, Windows Server Core
- **Prerrequisitos**:
- [ ] Acceso SSH a `srv-dasu` con privilegios sudo
- [ ] Acceso administrativo a `pc-dasu0` (local o remoto)
- [ ] Ambos dispositivos conectados al mismo router ISP en oficina DASUTEN
- [ ] Tailscale operativo en ambos dispositivos (para failover)
- [ ] Backup previo de configuraciones de red
## 3. Flujo de Tareas (Ejecución)
Este flujo debe seguirse secuencialmente. Utilizar iconos de estado según el `adn/02_protocolo.md`.
| Paso | Tarea | Estado | Notas |
| :--- | :--- | :---: | :--- |
| 1 | **Diagnóstico de Topología de Red Local** | 📍 | Identificar configuración actual del router ISP |
| 2 | **Configuración de IPs Locales en srv-dasu** | ⏳ | Asignar IP local en subred del router |
| 3 | **Configuración de IP Local en pc-dasu0** | ⏳ | Asignar IP en misma subred |
| 4 | **Pruebas de Conectividad Básica** | ⏳ | Verificar ping bidireccional |
| 5 | **Configuración de DNS Local** | ⏳ | Apuntar a dc-dasuten via ruta local |
| 6 | **Validación de AD-Join** | ⏳ | Probar resolución de dominio |
| 7 | **Configuración de Failover Tailscale** | ⏳ | Mantener ruta Tailscale como backup |
| 8 | **Scripts de Validación Automática** | ⏳ | Crear e instalar herramientas de monitoreo |
### 3.1 Paso 1: Diagnóstico de Topología de Red Local
**Objetivo**: Determinar la subred local asignada por el router ISP.
**Procedimiento en pc-dasu0 (Windows):**
```powershell
# Obtener configuración IP actual
ipconfig /all
# Identificar:
# - Dirección IP asignada por DHCP
# - Máscara de subred
# - Gateway predeterminado
# - Servidores DNS
# Determinar rango de subred completa
$ipInfo = Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -like "*Ethernet*"}
$subnetMask = $ipInfo.PrefixLength
$ipAddress = $ipInfo.IPAddress
$gateway = (Get-NetRoute -DestinationPrefix "0.0.0.0/0" -AddressFamily IPv4).NextHop
# Calcular subred
$subnet = [System.Net.IPAddress]::Parse($ipAddress).GetAddressBytes()
$mask = [System.Net.IPAddress]::Parse(([System.Net.IPAddress]::Parse("255.255.255.255").GetAddressBytes() | ForEach-Object {$_ -shl (32-$subnetMask)}))
$network = [System.Net.IPAddress]::new(($subnet | ForEach-Object {$_ -band $mask.GetAddressBytes()[$i]; $i++}))
Write-Host "Subred detectada: $network/$subnetMask"
Write-Host "Gateway: $gateway"
Write-Host "IP Local: $ipAddress"
# Escanear dispositivos en la red local
arp -a | Select-String "dynamic" | ForEach-Object {
$_.ToString().Split()[0]
} | Select-Object -First 10
```
**Procedimiento en srv-dasu (Linux via SSH):**
```bash
# Conectarse a srv-dasu via Tailscale
ssh -J root@100.116.210.36 rmonla@10.0.100.1
# Ver configuración de red actual
echo "=== Configuración de Interfaces ==="
ip addr show vmbr0
echo ""
echo "=== Tabla de Rutas ==="
ip route show
echo ""
echo "=== Información DHCP (si aplica) ==="
cat /var/lib/dhcp/dhclient.leases 2>/dev/null | grep -A5 -B5 "interface.*vmbr0" || echo "No hay leases DHCP disponibles"
echo ""
# Detectar gateway local automáticamente
GATEWAY=$(ip route show default | awk '/default/ {print $3}')
if [ -n "$GATEWAY" ]; then
echo "Gateway detectado: $GATEWAY"
echo "=== Probando conectividad a gateway ==="
ping -c 4 $GATEWAY
# Determinar subred del gateway
SUBNET=$(ip route show | grep "link src" | awk '{print $1}' | head -1)
if [ -n "$SUBNET" ]; then
echo "Subred detectada: $SUBNET"
# Escanear dispositivos en la subred local
echo "=== Dispositivos en subred local (primeros 5) ==="
nmap -sn $SUBNET 2>/dev/null | grep "Nmap scan report" | head -5 || \
echo "Instale nmap para escaneo completo: sudo apt install nmap"
fi
else
echo "⚠️ No se detectó gateway predeterminado"
echo "Verifique conectividad física y configuración DHCP"
fi
# Verificar si hay IP local ya configurada
echo "=== IPs locales configuradas ==="
ip addr show vmbr0 | grep -E "inet (192\.168|10\.0\.0|172\.(1[6-9]|2[0-9]|3[0-1]))"
```
**Salida Esperada**:
- Subred local identificada (ej: 192.168.1.0/24, 10.0.0.0/24)
- Gateway del router ISP
- Rango de IPs disponibles en la subred
- Dispositivos detectados en la red local
- Confirmación de que srv-dasu y pc-dasu0 están en la misma subred física
**Registro de Diagnóstico**:
```bash
# Crear archivo de diagnóstico
sudo tee /tmp/red-local-diagnostico-$(date +%Y%m%d).txt << EOF
=== DIAGNÓSTICO DE RED LOCAL ===
Fecha: $(date)
Hostname: $(hostname)
CONFIGURACIÓN ACTUAL:
$(ip addr show vmbr0)
TABLA DE RUTAS:
$(ip route show)
GATEWAY DETECTADO: $GATEWAY
SUBRED DETECTADA: $SUBNET
DISPOSITIVOS EN RED (si se escaneó):
$(nmap -sn $SUBNET 2>/dev/null | grep "Nmap scan report" | head -10)
RECOMENDACIÓN DE IP LOCAL:
# Usar IP fuera del rango DHCP del router
# Ejemplo: Si router asigna 192.168.1.100-200
# Usar: 192.168.1.205 para srv-dasu
# Usar: 192.168.1.100 para pc-dasu0 (si está disponible)
EOF
```
### 3.2 Paso 2: Configuración de IP Local en srv-dasu
**Objetivo**: Asignar IP estática en subred local manteniendo configuración existente.
**Procedimiento en srv-dasu:**
```bash
# 1. Backup de configuración actual
sudo cp /etc/network/interfaces /etc/network/interfaces.backup.$(date +%Y%m%d)
# 2. Editar configuración de red
sudo nano /etc/network/interfaces
```
**Configuración Recomendada** (adaptar según subred local detectada):
```bash
# Configuración actual de vmbr0 (mantener)
auto vmbr0
iface vmbr0 inet dhcp
bridge-ports enp3s0
bridge-stp off
bridge-fd 0
# Red interna para VMs (mantener)
post-up ip addr add 10.0.100.1/24 dev vmbr0
pre-down ip addr del 10.0.100.1/24 dev vmbr0
# IP estática local (agregar - adaptar según subred)
post-up ip addr add 192.168.1.205/24 dev vmbr0
pre-down ip addr del 192.168.1.205/24 dev vmbr0
```
**Aplicar cambios:**
```bash
# 3. Reiniciar servicio de red
sudo systemctl restart networking
# 4. Verificar configuración
ip addr show vmbr0
# Debe mostrar:
# - IP DHCP (de la red facultad si está conectado)
# - 10.0.100.1/24 (red interna VMs)
# - 192.168.1.205/24 (IP local)
# 5. Probar conectividad local
ping -c 4 192.168.1.1 # Gateway del router
```
### 3.3 Paso 3: Configuración de IP Local en pc-dasu0
**Objetivo**: Configurar IP estática en pc-dasu0 en misma subred.
**Procedimiento en pc-dasu0 (Windows):**
```powershell
# 1. Abrir configuración de red
ncpa.cpl
# 2. Propiedades del adaptador Ethernet -> IPv4
# Configurar:
# - IP: 192.168.1.100 (ejemplo, usar IP disponible)
# - Máscara: 255.255.255.0
# - Gateway: 192.168.1.1 (router ISP)
# - DNS Primario: 10.0.100.10 (dc-dasuten via ruta local)
# - DNS Secundario: 8.8.8.8
# 3. Aplicar cambios
```
**Alternativa via PowerShell (remoto):**
```powershell
# Si se tiene acceso remoto via Tailscale
$adapter = Get-NetAdapter -Name "Ethernet"
New-NetIPAddress -InterfaceIndex $adapter.ifIndex `
-IPAddress 192.168.1.100 `
-PrefixLength 24 `
-DefaultGateway 192.168.1.1
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex `
-ServerAddresses ("10.0.100.10", "8.8.8.8")
```
### 3.4 Paso 4: Pruebas de Conectividad Básica
**Objetivo**: Validar comunicación bidireccional.
**Desde pc-dasu0:**
```powershell
# Probar conectividad a srv-dasu
ping 192.168.1.205
ping 10.0.100.1 # Gateway interno VMs
# Probar conectividad a dc-dasuten (via srv-dasu)
ping 10.0.100.10
# Verificar ruta
tracert 10.0.100.10
# Debe mostrar: pc-dasu0 -> router -> srv-dasu -> dc-dasuten
```
**Desde srv-dasu:**
```bash
# Probar conectividad a pc-dasu0
ping -c 4 192.168.1.100
# Verificar que VMs pueden comunicarse
ping -c 4 10.0.100.10 # dc-dasuten
```
### 3.5 Paso 5: Configuración de DNS Local
**Objetivo**: Configurar resolución DNS directa al controlador de dominio.
**En pc-dasu0:**
```powershell
# Verificar resolución DNS
nslookup dc-dasuten.dasuten.utnlr
# Debe resolver a 10.0.100.10
# Probar resolución inversa
nslookup 10.0.100.10
# Debe resolver a dc-dasuten.dasuten.utnlr
# Verificar registro en DNS del dominio
nslookup -type=SRV _ldap._tcp.dasuten.utnlr
```
**Configuración de Suffix DNS (si es necesario):**
```powershell
# Agregar suffix DNS al adaptador
Set-DnsClientGlobalSetting -SuffixSearchList @("dasuten.utnlr")
```
### 3.6 Paso 6: Validación de AD-Join
**Objetivo**: Probar funcionalidad de unión al dominio.
**Pruebas preliminares:**
```powershell
# 1. Verificar que se puede alcanzar el dominio
Test-Connection dc-dasuten.dasuten.utnlr -Count 4
# 2. Probar autenticación (sin unir aún)
Test-ComputerSecureChannel -Server dc-dasuten.dasuten.utnlr
# 3. Verificar puertos LDAP/Kerberos
Test-NetConnection dc-dasuten.dasuten.utnlr -Port 389 # LDAP
Test-NetConnection dc-dasuten.dasuten.utnlr -Port 88 # Kerberos
Test-NetConnection dc-dasuten.dasuten.utnlr -Port 445 # SMB
```
**Procedimiento de unión al dominio (si aplica):**
```powershell
# Unir al dominio (solo si es necesario)
Add-Computer -DomainName "dasuten.utnlr" `
-Credential (Get-Credential) `
-Restart
```
### 3.7 Paso 7: Configuración de Failover Tailscale
**Objetivo**: Mantener Tailscale como ruta de respaldo.
**Verificar estado Tailscale:**
```bash
# En srv-dasu
tailscale status
# Debe mostrar: 100.116.210.36
# En pc-dasu0 (via PowerShell)
tailscale status
# Debe mostrar: 100.65.62.44
```
**Configurar métricas de ruta (en srv-dasu):**
```bash
# Verificar rutas actuales
ip route show
# Tailscale debe tener métrica más alta (menos preferida)
# La ruta local (192.168.1.0/24) debe tener métrica más baja
```
**Script de monitoreo de conectividad:**
```bash
#!/bin/bash
# /usr/local/bin/check-local-connectivity.sh
LOCAL_IP="192.168.1.100"
TAILSCALE_IP="100.65.62.44"
if ping -c 2 -W 1 $LOCAL_IP > /dev/null 2>&1; then
echo "✅ Conectividad LOCAL activa"
exit 0
else
echo "⚠️ Fallo conectividad local, usando Tailscale"
# Aquí se podrían activar reglas de failover
exit 1
fi
```
### 3.8 Paso 8: Scripts de Validación Automática
**Crear script de validación completo:**
**Script para srv-dasu (`/usr/local/bin/validate-local-network.sh`):**
*Nota: También disponible en `docs/procedimientos/scripts/diagnostico_red_local.sh`*
```bash
#!/bin/bash
# Script de validación de red local
LOG_FILE="/var/log/local-network-validation.log"
echo "=== Validación de Red Local $(date) ===" | tee -a $LOG_FILE
# 1. Verificar IPs locales
echo "1. Verificando IPs configuradas..." | tee -a $LOG_FILE
ip addr show vmbr0 | grep -E "192\.168\.1|10\.0\.100\.1" | tee -a $LOG_FILE
# 2. Probar conectividad a pc-dasu0
echo "2. Probando conectividad a pc-dasu0..." | tee -a $LOG_FILE
if ping -c 3 -W 2 192.168.1.100 > /dev/null 2>&1; then
echo "✅ Ping exitoso a pc-dasu0" | tee -a $LOG_FILE
else
echo "❌ Fallo ping a pc-dasu0" | tee -a $LOG_FILE
fi
# 3. Verificar rutas
echo "3. Verificando tabla de rutas..." | tee -a $LOG_FILE
ip route show | grep -E "192\.168\.1|10\.0\.100" | tee -a $LOG_FILE
# 4. Verificar estado Tailscale
echo "4. Verificando estado Tailscale..." | tee -a $LOG_FILE
tailscale status --json | jq -r '.Self.TailscaleIPs[0]' | tee -a $LOG_FILE
echo "=== Validación completada ===" | tee -a $LOG_FILE
```
**Script para pc-dasu0 (`C:\Scripts\Validate-LocalNetwork.ps1`):**
*Nota: También disponible en `docs/procedimientos/scripts/Diagnose-LocalNetwork.ps1`*
```powershell
# Script de validación para Windows
$LogFile = "C:\Logs\LocalNetwork-Validation.log"
$LocalIP = "192.168.1.205" # srv-dasu
$DomainController = "10.0.100.10"
"=== Validación de Red Local $(Get-Date) ===" | Out-File -FilePath $LogFile -Append
# 1. Verificar IP local
"1. Configuración IP local:" | Out-File -FilePath $LogFile -Append
Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -like "192.168.1.*"} |
Select-Object IPAddress, PrefixLength | Out-File -FilePath $LogFile -Append
# 2. Probar conectividad
"2. Probando conectividad:" | Out-File -FilePath $LogFile -Append
if (Test-Connection -ComputerName $LocalIP -Count 2 -Quiet) {
"✅ Conectividad local OK" | Out-File -FilePath $LogFile -Append
} else {
"❌ Fallo conectividad local" | Out-File -FilePath $LogFile -Append
}
# 3. Verificar DNS
"3. Verificando resolución DNS:" | Out-File -FilePath $LogFile -Append
try {
$DnsResult = Resolve-DnsName -Name "dc-dasuten.dasuten.utnlr" -ErrorAction Stop
"✅ DNS resuelve: $($DnsResult.IPAddress)" | Out-File -FilePath $LogFile -Append
} catch {
"❌ Fallo resolución DNS" | Out-File -FilePath $LogFile -Append
}
# 4. Verificar puertos críticos
"4. Verificando puertos del dominio:" | Out-File -FilePath $LogFile -Append
$Ports = @(389, 88, 445, 53)
foreach ($Port in $Ports) {
$Test = Test-NetConnection -ComputerName $DomainController -Port $Port -WarningAction SilentlyContinue
if ($Test.TcpTestSucceeded) {
"✅ Puerto $Port abierto" | Out-File -FilePath $LogFile -Append
} else {
"❌ Puerto $Port cerrado" | Out-File -FilePath $LogFile -Append
}
}
```
## 4. Verificación y Validación
- [ ] Ping bidireccional exitoso entre `pc-dasu0` (192.168.1.100) y `srv-dasu` (192.168.1.205)
- [ ] Resolución DNS de `dc-dasuten.dasuten.utnlr` a `10.0.100.10`
- [ ] Conexión LDAP/Kerberos al controlador de dominio
- [ ] Tailscale operativo como respaldo (IPs: 100.116.210.36 y 100.65.62.44)
- [ ] Scripts de validación ejecutados sin errores críticos
- **Resultado Esperado**: ✅ Comunicación local establecida con latencia <5ms, failover Tailscale configurado, capacidad de AD-Join verificada
## 5. Plan de Reversión (Hombre Muerto)
> [!IMPORTANT]
> En caso de fallo crítico o pérdida de conectividad, seguir estos pasos inmediatamente.
1. **Gatillo de Reversión**:
- Error en paso 4 (fallo ping bidireccional tras 3 intentos)
- Pérdida completa de conectividad a internet
- Incapacidad para acceder a recursos críticos por más de 5 minutos
2. **Acciones de Reversión**:
- **En pc-dasu0**: Restaurar configuración DHCP automática
```powershell
Set-NetIPInterface -Dhcp Enabled
Set-DnsClientServerAddress -ResetServerAddresses
```
- **En srv-dasu**: Remover IP local manteniendo configuración base
```bash
sudo ip addr del 192.168.1.205/24 dev vmbr0
sudo systemctl restart networking
```
- **Forzar uso de Tailscale**: Verificar que ambas máquinas están conectadas a Tailscale
```bash
# En srv-dasu
tailscale up --reset
# En pc-dasu0 (via PowerShell si hay acceso)
tailscale up --reset
```
3. **Verificación post-reversión**:
- Confirmar conectividad via Tailscale entre nodos
- Verificar que servicios críticos (dc-dasuten) son accesibles
- Documentar incidente y causas raíz identificadas
---
## 6. Anexos Técnicos
### Anexo 0: Scripts de Diagnóstico Automático
**Scripts disponibles en `docs/procedimientos/scripts/`:**
1. **`diagnostico_red_local.sh`** (para srv-dasu - Linux):
```bash
# Copiar y hacer ejecutable
sudo cp docs/procedimientos/scripts/diagnostico_red_local.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/diagnostico_red_local.sh
# Ejecutar diagnóstico
sudo diagnostico_red_local.sh vmbr0
```
2. **`Diagnose-LocalNetwork.ps1`** (para pc-dasu0 - Windows PowerShell):
```powershell
# Ejecutar como administrador
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
.\docs\procedimientos\scripts\Diagnose-LocalNetwork.ps1 -Detailed $true
```
**Características de los scripts:**
- Diagnóstico automático de topología de red
- Detección de subred local y gateway
- Verificación de conectividad a recursos críticos
- Validación de configuración DNS
- Comprobación de estado Tailscale
- Generación de reportes detallados
- Recomendaciones específicas para configuración local
### Anexo A: Configuración de Red de Referencia
**Topología Final Objetivo**:
```
Router ISP (Oficina DASUTEN)
├── Subred Local: 192.168.1.0/24
│ ├── srv-dasu: 192.168.1.205/24 (IP local) + 10.0.100.1/24 (gateway VMs)
│ └── pc-dasu0: 192.168.1.100/24
└── Conexión WAN a Internet
└── Tailscale VPN (Failover)
├── srv-dasu: 100.116.210.36
└── pc-dasu0: 100.65.62.44
```
**Tabla de IPs Críticas**:
| Nodo | IP Local | IP Tailscale | IP Interna VMs | Propósito |
| :--- | :--- | :--- | :--- | :--- |
| srv-dasu | 192.168.1.205 | 100.116.210.36 | 10.0.100.1 | Hypervisor Proxmox |
| pc-dasu0 | 192.168.1.100 | 100.65.62.44 | - | PC física cliente |
| dc-dasuten | - | - | 10.0.100.10 | Controlador de Dominio |
| sql-dasuten | - | - | 10.0.100.11 | SQL Server |
### Anexo B: Comandos de Diagnóstico Rápido
**Diagnóstico de Conectividad Local**:
```bash
# Desde srv-dasu
ping -c 4 192.168.1.100
traceroute 192.168.1.100
ss -tulpn | grep :22 # Verificar SSH
# Desde pc-dasu0 (PowerShell)
Test-NetConnection 192.168.1.205 -Port 22
Test-NetConnection 10.0.100.10 -Port 389
Resolve-DnsName dc-dasuten.dasuten.utnlr
```
**Diagnóstico de Rutas**:
```bash
# En srv-dasu
ip route show
ip rule show
tailscale status --json | jq '.Self.TailscaleIPs'
# En pc-dasu0
route print
Get-NetRoute -AddressFamily IPv4
```
### Anexo C: Script de Monitoreo Automático
**Script para crontab (srv-dasu)**:
```bash
#!/bin/bash
# /usr/local/bin/monitor-local-network.sh
LOCAL_PC="192.168.1.100"
TAILSCALE_PC="100.65.62.44"
LOG="/var/log/network-monitor.log"
ALERT_THRESHOLD=3
check_connectivity() {
local target=$1
local type=$2
if ping -c 2 -W 1 "$target" > /dev/null 2>&1; then
echo "$(date): ✅ $type conectividad OK a $target" >> "$LOG"
return 0
else
echo "$(date): ⚠️ $type conectividad FALLIDA a $target" >> "$LOG"
return 1
fi
}
# Monitoreo principal
if check_connectivity "$LOCAL_PC" "LOCAL"; then
# Conectividad local OK
exit 0
else
# Fallo local, verificar Tailscale
if check_connectivity "$TAILSCALE_PC" "TAILSCALE"; then
echo "$(date): 🔄 Cambiando a ruta Tailscale" >> "$LOG"
# Aquí se podrían activar reglas de failover automático
else
echo "$(date): 🚨 FALLO CRÍTICO - Sin conectividad local ni Tailscale" >> "$LOG"
# Notificación de alerta
fi
fi
```
**Configurar en crontab**:
```bash
# Ejecutar cada 5 minutos
*/5 * * * * /usr/local/bin/monitor-local-network.sh
```
### Anexo D: Solución de Problemas Comunes
**Problema 1: No hay respuesta de ping entre dispositivos**
- **Causas posibles**: Firewall bloqueando ICMP, subred incorrecta, VLANs
- **Solución**:
```bash
# En srv-dasu
sudo iptables -I INPUT -s 192.168.1.0/24 -j ACCEPT
sudo iptables -I OUTPUT -d 192.168.1.0/24 -j ACCEPT
# En pc-dasu0 (PowerShell como Admin)
New-NetFirewallRule -DisplayName "Allow-Local-ICMP" `
-Direction Inbound -Protocol ICMPv4 -IcmpType 8 `
-RemoteAddress 192.168.1.0/24 -Action Allow
```
**Problema 2: DNS no resuelve dc-dasuten**
- **Causas posibles**: Ruta no configurada, firewall bloqueando puerto 53
- **Solución**:
```powershell
# Verificar que la ruta existe
Test-NetConnection 10.0.100.10 -Port 53
# Forzar registro DNS
ipconfig /flushdns
ipconfig /registerdns
# Probar con nslookup especificando servidor
nslookup dc-dasuten.dasuten.utnlr 10.0.100.10
```
**Problema 3: Conflictos de IP**
- **Causas posibles**: IP duplicada en la red
- **Solución**:
```bash
# En srv-dasu
sudo arping -c 3 -I vmbr0 192.168.1.205
# Si hay respuesta, cambiar IP
sudo ip addr del 192.168.1.205/24 dev vmbr0
sudo ip addr add 192.168.1.206/24 dev vmbr0
```
### Anexo E: Checklist de Implementación
**Pre-Implementación**:
- [ ] Backup de configuraciones de red actuales
- [ ] Documentar IPs actuales de todos los dispositivos
- [ ] Verificar que Tailscale está operativo en ambos nodos
- [ ] Comunicar ventana de mantenimiento a usuarios afectados
**Implementación**:
- [ ] Configurar IP local en srv-dasu (Paso 2)
- [ ] Configurar IP local en pc-dasu0 (Paso 3)
- [ ] Validar conectividad básica (Paso 4)
- [ ] Configurar DNS (Paso 5)
- [ ] Validar AD-Join (Paso 6)
- [ ] Configurar failover Tailscale (Paso 7)
- [ ] Instalar scripts de validación (Paso 8)
**Post-Implementación**:
- [ ] Ejecutar scripts de validación completos
- [ ] Documentar configuración final
- [ ] Probar failover manualmente
- [ ] Monitorear durante 24 horas
---
## 7. Referencias
1. **Documentación Relacionada**:
- [Plan P2601_6.1.B - AD-Join: pc-dasu0 al Dominio](../plan/P2601_6.1.B%20-%20AD-Join:%20pc-dasu0%20al%20Dominio.md)
- [Nodo srv-dasu](../../nodos/srv-dasu.md)
- [Nodo pc-dasu0](../../nodos/pc-dasu0.md)
- [ADN 03 - Seguridad y Red](../../adn/03_seguridad.md)
2. **Scripts de Soporte**:
- `docs/procedimientos/scripts/diagnostico_red_local.sh` - Diagnóstico Linux
- `docs/procedimientos/scripts/Diagnose-LocalNetwork.ps1` - Diagnóstico Windows
- Scripts de validación incluidos en este documento
3. **Herramientas Utilizadas**:
- Tailscale: VPN mesh para failover
- OpenSSH: Administración remota de srv-dasu
- PowerShell: Automatización en Windows
- iptables/nftables: Gestión de firewall en Linux
4. **Estándares de Red**:
- RFC 1918: Direccionamiento IP privado
- Best Practices para redes híbridas
- Protocolos AD DS: LDAP (389), Kerberos (88), DNS (53)
---
*Documento generado bajo el ADN del proyecto srv-ns8.*
*Última actualización: $(date +%Y-%m-%d)*
*Versión: 1.0*
@@ -0,0 +1,399 @@
# Script de diagnóstico de red local para pc-dasu0
# Uso: .\Diagnose-LocalNetwork.ps1 [-InterfaceAlias "Ethernet"] [-Detailed $true]
param(
[string]$InterfaceAlias = "Ethernet",
[bool]$Detailed = $true,
[string]$LogPath = "C:\Logs\NetworkDiagnostic"
)
# Configuración inicial
$ErrorActionPreference = "Stop"
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$LogFile = Join-Path $LogPath "NetworkDiagnostic_$Timestamp.log"
$ReportFile = Join-Path $LogPath "NetworkReport_$Timestamp.md"
# Crear directorio de logs si no existe
if (-not (Test-Path $LogPath)) {
New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
}
# Funciones de logging
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$FormattedMessage = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] [$Level] $Message"
switch ($Level) {
"ERROR" { Write-Host $FormattedMessage -ForegroundColor Red }
"WARNING" { Write-Host $FormattedMessage -ForegroundColor Yellow }
"SUCCESS" { Write-Host $FormattedMessage -ForegroundColor Green }
default { Write-Host $FormattedMessage -ForegroundColor Cyan }
}
$FormattedMessage | Out-File -FilePath $LogFile -Append
}
function Write-Report {
param([string]$Content)
$Content | Out-File -FilePath $ReportFile -Append
}
function Test-Command {
param([string]$Command)
try {
Get-Command $Command -ErrorAction Stop | Out-Null
return $true
} catch {
return $false
}
}
# Inicio del diagnóstico
Write-Log "========================================"
Write-Log " DIAGNÓSTICO DE RED LOCAL - pc-dasu0"
Write-Log "========================================"
Write-Log ""
Write-Report "# Reporte de Diagnóstico de Red Local"
Write-Report "Fecha: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Report "Hostname: $env:COMPUTERNAME"
Write-Report "Usuario: $env:USERNAME"
Write-Report ""
# 1. Verificar adaptador de red
Write-Log "1. Verificando adaptador de red '$InterfaceAlias'..."
Write-Report "## 1. Información del Adaptador de Red"
try {
$NetworkAdapter = Get-NetAdapter -Name $InterfaceAlias -ErrorAction Stop
Write-Log " Adaptador encontrado: $($NetworkAdapter.Name)"
Write-Log " Estado: $($NetworkAdapter.Status)"
Write-Log " Velocidad: $($NetworkAdapter.LinkSpeed)"
Write-Report "### Adaptador: $($NetworkAdapter.Name)"
Write-Report "- Estado: $($NetworkAdapter.Status)"
Write-Report "- Velocidad: $($NetworkAdapter.LinkSpeed)"
Write-Report "- MAC Address: $($NetworkAdapter.MacAddress)"
Write-Report "- Interface Description: $($NetworkAdapter.InterfaceDescription)"
Write-Report ""
if ($NetworkAdapter.Status -ne "Up") {
Write-Log " ADVERTENCIA: El adaptador no está activo" -Level "WARNING"
}
} catch {
Write-Log " ERROR: No se encontró el adaptador '$InterfaceAlias'" -Level "ERROR"
Write-Log " Adaptadores disponibles:"
Get-NetAdapter | ForEach-Object {
Write-Log " - $($_.Name): $($_.Status)"
}
Write-Report "ERROR: Adaptador '$InterfaceAlias' no encontrado"
exit 1
}
# 2. Obtener configuración IP
Write-Log "2. Obteniendo configuración IP..."
Write-Report "## 2. Configuración IP"
try {
$IPConfiguration = Get-NetIPConfiguration -InterfaceAlias $InterfaceAlias -ErrorAction Stop
Write-Log " IPv4 Address: $($IPConfiguration.IPv4Address.IPAddress)"
Write-Log " Subnet Mask: $($IPConfiguration.IPv4Address.PrefixLength)"
Write-Log " Gateway: $($IPConfiguration.IPv4DefaultGateway.NextHop)"
Write-Report "### Configuración IPv4"
Write-Report "- Dirección IP: $($IPConfiguration.IPv4Address.IPAddress)"
Write-Report "- Prefijo: /$($IPConfiguration.IPv4Address.PrefixLength)"
Write-Report "- Gateway: $($IPConfiguration.IPv4DefaultGateway.NextHop)"
Write-Report ""
# Calcular subred
$IPAddress = $IPConfiguration.IPv4Address.IPAddress
$PrefixLength = $IPConfiguration.IPv4Address.PrefixLength
$SubnetMask = [System.Net.IPAddress]::Parse(([System.Net.IPAddress]::Parse("255.255.255.255").GetAddressBytes() |
ForEach-Object { $_ -shl (32 - $PrefixLength) }))
$NetworkAddress = [System.Net.IPAddress]::new((
[System.Net.IPAddress]::Parse($IPAddress).GetAddressBytes() |
ForEach-Object { $_ -band $SubnetMask.GetAddressBytes()[$i]; $i++ }))
$Subnet = "$NetworkAddress/$PrefixLength"
Write-Log " Subred calculada: $Subnet"
Write-Report "- Subred: $Subnet"
Write-Report ""
# Servidores DNS
Write-Log " Servidores DNS:"
$DNSServers = $IPConfiguration.DNSServer.ServerAddresses
if ($DNSServers) {
$i = 1
foreach ($DNS in $DNSServers) {
Write-Log " $i. $DNS"
Write-Report "- DNS $($i): $DNS"
$i++
}
} else {
Write-Log " ADVERTENCIA: No hay servidores DNS configurados" -Level "WARNING"
Write-Report "- DNS: No configurado"
}
Write-Report ""
} catch {
Write-Log " ERROR: No se pudo obtener configuración IP" -Level "ERROR"
Write-Report "ERROR: No se pudo obtener configuración IP"
}
# 3. Probar conectividad
Write-Log "3. Probando conectividad de red..."
Write-Report "## 3. Pruebas de Conectividad"
# Gateway
$Gateway = $IPConfiguration.IPv4DefaultGateway.NextHop
if ($Gateway) {
Write-Log " Probando gateway $Gateway..."
$GatewayTest = Test-NetConnection -ComputerName $Gateway -InformationLevel Quiet
if ($GatewayTest) {
Write-Log " ✅ Gateway alcanzable" -Level "SUCCESS"
Write-Report "- Gateway ($Gateway): ✅ Alcanzable"
} else {
Write-Log " ❌ Gateway no alcanzable" -Level "ERROR"
Write-Report "- Gateway ($Gateway): ❌ No alcanzable"
}
} else {
Write-Log " ADVERTENCIA: No hay gateway configurado" -Level "WARNING"
Write-Report "- Gateway: No configurado"
}
# Internet
Write-Log " Probando conectividad a internet (8.8.8.8)..."
$InternetTest = Test-NetConnection -ComputerName "8.8.8.8" -InformationLevel Quiet -WarningAction SilentlyContinue
if ($InternetTest) {
Write-Log " ✅ Internet alcanzable" -Level "SUCCESS"
Write-Report "- Internet (8.8.8.8): ✅ Alcanzable"
} else {
Write-Log " ❌ Internet no alcanzable" -Level "ERROR"
Write-Report "- Internet (8.8.8.8): ❌ No alcanzable"
}
# srv-dasu (si se conoce la IP)
Write-Log " Probando conectividad a srv-dasu (192.168.1.205)..."
$SrvDasuTest = Test-NetConnection -ComputerName "192.168.1.205" -InformationLevel Quiet -WarningAction SilentlyContinue
if ($SrvDasuTest) {
Write-Log " ✅ srv-dasu alcanzable localmente" -Level "SUCCESS"
Write-Report "- srv-dasu (192.168.1.205): ✅ Alcanzable"
} else {
Write-Log " ⚠️ srv-dasu no alcanzable localmente" -Level "WARNING"
Write-Report "- srv-dasu (192.168.1.205): ⚠️ No alcanzable"
}
Write-Report ""
# 4. Verificar DNS
Write-Log "4. Verificando resolución DNS..."
Write-Report "## 4. Pruebas de DNS"
# Resolución de dominio DASUTEN
Write-Log " Probando resolución de dc-dasuten.dasuten.utnlr..."
try {
$DNSResult = Resolve-DnsName -Name "dc-dasuten.dasuten.utnlr" -ErrorAction Stop
if ($DNSResult.IPAddress) {
Write-Log " ✅ DNS resuelve a: $($DNSResult.IPAddress)" -Level "SUCCESS"
Write-Report "- dc-dasuten.dasuten.utnlr: ✅ $($DNSResult.IPAddress)"
} else {
Write-Log " ❌ DNS no devolvió IP" -Level "ERROR"
Write-Report "- dc-dasuten.dasuten.utnlr: ❌ Sin respuesta"
}
} catch {
Write-Log " ❌ Error en resolución DNS: $_" -Level "ERROR"
Write-Report "- dc-dasuten.dasuten.utnlr: ❌ Error: $_"
}
# Resolución inversa
Write-Log " Probando resolución inversa de 10.0.100.10..."
try {
$ReverseDNS = Resolve-DnsName -Name "10.0.100.10" -Type PTR -ErrorAction Stop
if ($ReverseDNS.NameHost) {
Write-Log " ✅ Resolución inversa: $($ReverseDNS.NameHost)" -Level "SUCCESS"
Write-Report "- 10.0.100.10 (PTR): ✅ $($ReverseDNS.NameHost)"
}
} catch {
Write-Log " ⚠️ No se pudo resolver PTR para 10.0.100.10" -Level "WARNING"
Write-Report "- 10.0.100.10 (PTR): ⚠️ No resuelto"
}
Write-Report ""
# 5. Verificar puertos críticos del dominio
Write-Log "5. Verificando puertos críticos del dominio..."
Write-Report "## 5. Puertos del Dominio DASUTEN"
$DomainController = "10.0.100.10"
$CriticalPorts = @(
@{Port=389; Service="LDAP"},
@{Port=88; Service="Kerberos"},
@{Port=445; Service="SMB"},
@{Port=53; Service="DNS"},
@{Port=135; Service="RPC"},
@{Port=636; Service="LDAPS"}
)
foreach ($PortInfo in $CriticalPorts) {
Write-Log " Probando puerto $($PortInfo.Port) ($($PortInfo.Service))..."
$PortTest = Test-NetConnection -ComputerName $DomainController -Port $PortInfo.Port -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
if ($PortTest.TcpTestSucceeded) {
Write-Log " ✅ Puerto $($PortInfo.Port) abierto" -Level "SUCCESS"
Write-Report "- $($PortInfo.Service) (puerto $($PortInfo.Port)): ✅ Abierto"
} else {
Write-Log " ❌ Puerto $($PortInfo.Port) cerrado" -Level "ERROR"
Write-Report "- $($PortInfo.Service) (puerto $($PortInfo.Port)): ❌ Cerrado"
}
}
Write-Report ""
# 6. Verificar Tailscale
Write-Log "6. Verificando estado de Tailscale..."
Write-Report "## 6. Estado de Tailscale"
if (Test-Command "tailscale") {
try {
$TailscaleStatus = & tailscale status --json 2>$null | ConvertFrom-Json
if ($TailscaleStatus.Self.TailscaleIPs) {
$TailscaleIP = $TailscaleStatus.Self.TailscaleIPs[0]
Write-Log " ✅ Tailscale conectado: $TailscaleIP" -Level "SUCCESS"
Write-Report "- Estado: ✅ Conectado"
Write-Report "- IP Tailscale: $TailscaleIP"
# Verificar peers
$PeerCount = ($TailscaleStatus.Peer | Measure-Object).Count
Write-Log " Peers conectados: $PeerCount"
Write-Report "- Peers conectados: $PeerCount"
} else {
Write-Log " ⚠️ Tailscale instalado pero no conectado" -Level "WARNING"
Write-Report "- Estado: ⚠️ Instalado pero no conectado"
}
} catch {
Write-Log " ⚠️ No se pudo obtener estado de Tailscale" -Level "WARNING"
Write-Report "- Estado: ⚠️ Error al obtener estado"
}
} else {
Write-Log " ⚠️ Tailscale no está instalado" -Level "WARNING"
Write-Report "- Estado: ⚠️ No instalado"
}
Write-Report ""
# 7. Escanear red local (opcional)
if ($Detailed) {
Write-Log "7. Escaneando dispositivos en red local..."
Write-Report "## 7. Dispositivos en Red Local"
try {
# Usar ARP para detectar dispositivos
$ARPTable = arp -a | Select-String "dynamic" | ForEach-Object {
$Line = $_.ToString().Trim()
$Parts = $Line -split '\s+'
[PSCustomObject]@{
IP = $Parts[0]
MAC = $Parts[1]
Type = $Parts[2]
}
}
$DeviceCount = ($ARPTable | Measure-Object).Count
Write-Log " Dispositivos detectados en ARP: $DeviceCount"
Write-Report "- Dispositivos en tabla ARP: $DeviceCount"
if ($DeviceCount -gt 0) {
Write-Report ""
Write-Report "### Primeros 10 dispositivos:"
$ARPTable | Select-Object -First 10 | ForEach-Object {
Write-Report "- $($_.IP) ($($_.MAC))"
}
}
} catch {
Write-Log " ⚠️ No se pudo escanear red local" -Level "WARNING"
Write-Report "- Escaneo: ⚠️ No disponible"
}
Write-Report ""
}
# 8. Generar recomendaciones
Write-Log "8. Generando recomendaciones..."
Write-Report "## 8. Recomendaciones para Comunicación Local"
$BaseNetwork = $IPAddress -replace '\.\d+$', ''
$RecommendedSrvIP = "$BaseNetwork.205"
$RecommendedPcIP = "$BaseNetwork.100"
Write-Report "### Configuración recomendada para comunicación local:"
Write-Report ""
Write-Report "1. **IPs estáticas locales:**"
Write-Report " - srv-dasu: $RecommendedSrvIP/24"
Write-Report " - pc-dasu0: $RecommendedPcIP/24"
Write-Report ""
Write-Report "2. **Configuración de red en pc-dasu0:**"
Write-Report " - IP: $RecommendedPcIP"
Write-Report " - Máscara: 255.255.255.0"
Write-Report " - Gateway: $Gateway"
Write-Report " - DNS Primario: 10.0.100.10 (dc-dasuten)"
Write-Report " - DNS Secundario: 8.8.8.8"
Write-Report " - Suffix DNS: dasuten.utnlr"
Write-Report ""
Write-Report "3. **Verificaciones previas:**"
Write-Report " - Confirmar que $RecommendedSrvIP y $RecommendedPcIP no están en uso"
Write-Report " - Verificar firewall (permitir ICMP, puertos 389, 88, 445, 53)"
Write-Report " - Mantener Tailscale activo como respaldo"
Write-Report ""
Write-Report "4. **Comandos de prueba post-configuración:**"
Write-Report " ```powershell"
Write-Report " # Probar conectividad local"
Write-Report " Test-NetConnection $RecommendedSrvIP"
Write-Report " "
Write-Report " # Probar resolución DNS"
Write-Report " Resolve-DnsName dc-dasuten.dasuten.utnlr"
Write-Report " "
Write-Report " # Probar puertos del dominio"
Write-Report " Test-NetConnection 10.0.100.10 -Port 389"
Write-Report " ```"
Write-Report ""
# 9. Resumen final
Write-Log "9. Generando resumen final..."
Write-Report "## 9. Resumen del Diagnóstico"
Write-Report "- **Adaptador de red**: $($NetworkAdapter.Name) ($($NetworkAdapter.Status))"
Write-Report "- **IP Configurada**: $IPAddress/$PrefixLength"
Write-Report "- **Gateway**: $(if($Gateway) {$Gateway} else {"No configurado"})"
Write-Report "- **Subred**: $Subnet"
Write-Report "- **DNS Servers**: $(if($DNSServers) {$DNSServers -join ', '} else {"No configurado"})"
Write-Report "- **Internet**: $(if($InternetTest) {"✅ Alcanzable"} else {"❌ No alcanzable"})"
Write-Report "- **srv-dasu local**: $(if($SrvDasuTest) {"✅ Alcanzable"} else {"⚠️ No alcanzable"})"
Write-Report "- **Tailscale**: $(if(Test-Command "tailscale") {"✅ Instalado"} else {"⚠️ No instalado"})"
Write-Report ""
Write-Report "### Archivos generados:"
Write-Report "- Log detallado: $LogFile"
Write-Report "- Reporte completo: $ReportFile"
Write-Report ""
Write-Report "### Próximos pasos:"
Write-Report "1. Si la conectividad local falla, verificar configuración del router ISP"
Write-Report "2. Configurar IPs estáticas según recomendaciones"
Write-Report "3. Probar AD-Join después de configurar comunicación local"
Write-Report "4. Mantener Tailscale como respaldo para acceso remoto"
Write-Report ""
Write-Report "*Diagnóstico completado: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')*"
@@ -0,0 +1,337 @@
#!/bin/bash
# Script de diagnóstico automático para red local
# Uso: ./diagnostico_red_local.sh [interface]
# Ejemplo: ./diagnostico_red_local.sh vmbr0
set -e
# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Variables
INTERFACE="${1:-vmbr0}"
LOG_FILE="/tmp/diagnostico_red_local_$(date +%Y%m%d_%H%M%S).log"
REPORT_FILE="/tmp/reporte_red_local_$(date +%Y%m%d_%H%M%S).md"
# Funciones de utilidad
log() {
echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}
warning() {
echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}
error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
}
check_dependencies() {
local deps=("ip" "ping" "awk" "grep" "tee")
local missing=()
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
missing+=("$dep")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
error "Dependencias faltantes: ${missing[*]}"
return 1
fi
# Dependencias opcionales
if command -v "nmap" &> /dev/null; then
HAS_NMAP=true
else
HAS_NMAP=false
warning "nmap no encontrado. El escaneo de red será limitado."
fi
if command -v "jq" &> /dev/null; then
HAS_JQ=true
else
HAS_JQ=false
fi
return 0
}
check_interface() {
if ! ip link show "$INTERFACE" &> /dev/null; then
error "Interfaz $INTERFACE no encontrada"
echo "Interfaces disponibles:"
ip link show | awk -F': ' '/^[0-9]+:/ {print $2}' | grep -v lo
return 1
fi
if [ "$(cat /sys/class/net/"$INTERFACE"/operstate 2>/dev/null)" != "up" ]; then
warning "Interfaz $INTERFACE no está activa (operstate: $(cat /sys/class/net/"$INTERFACE"/operstate 2>/dev/null))"
fi
return 0
}
get_interface_info() {
log "Obteniendo información de la interfaz $INTERFACE..."
echo "=== INFORMACIÓN DE INTERFAZ ===" | tee -a "$REPORT_FILE"
ip addr show "$INTERFACE" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
# Extraer IPs configuradas
IPS=$(ip addr show "$INTERFACE" | awk '/inet / {print $2}')
if [ -z "$IPS" ]; then
warning "No hay IPs configuradas en $INTERFACE"
else
success "IPs configuradas:"
echo "$IPS" | while read -r ip; do
echo " - $ip"
done | tee -a "$REPORT_FILE"
fi
}
get_routing_info() {
log "Obteniendo información de enrutamiento..."
echo "=== TABLA DE RUTAS ===" | tee -a "$REPORT_FILE"
ip route show | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
# Detectar gateway predeterminado
DEFAULT_GW=$(ip route show default | awk '/default/ {print $3}')
if [ -n "$DEFAULT_GW" ]; then
success "Gateway predeterminado: $DEFAULT_GW"
echo "Gateway: $DEFAULT_GW" | tee -a "$REPORT_FILE"
# Probar conectividad al gateway
log "Probando conectividad al gateway $DEFAULT_GW..."
if ping -c 3 -W 2 "$DEFAULT_GW" &> /dev/null; then
success "Gateway alcanzable"
echo "Gateway alcanzable: Sí" | tee -a "$REPORT_FILE"
else
warning "Gateway no alcanzable"
echo "Gateway alcanzable: No" | tee -a "$REPORT_FILE"
fi
else
warning "No se encontró gateway predeterminado"
echo "Gateway: No encontrado" | tee -a "$REPORT_FILE"
fi
# Detectar subred local
LOCAL_SUBNET=$(ip route show | grep "link src" | awk '{print $1}' | head -1)
if [ -n "$LOCAL_SUBNET" ]; then
success "Subred local detectada: $LOCAL_SUBNET"
echo "Subred local: $LOCAL_SUBNET" | tee -a "$REPORT_FILE"
else
warning "No se pudo detectar subred local"
echo "Subred local: No detectada" | tee -a "$REPORT_FILE"
fi
}
check_dhcp_info() {
log "Verificando información DHCP..."
echo "=== INFORMACIÓN DHCP ===" | tee -a "$REPORT_FILE"
# Verificar archivos de lease DHCP
DHCP_FILES=("/var/lib/dhcp/dhclient.leases" "/var/lib/dhclient/dhclient.leases")
for file in "${DHCP_FILES[@]}"; do
if [ -f "$file" ]; then
log "Analizando $file..."
if grep -q "interface.*$INTERFACE" "$file" 2>/dev/null; then
success "Se encontraron leases DHCP para $INTERFACE"
echo "Archivo DHCP: $file" | tee -a "$REPORT_FILE"
# Extraer información relevante
grep -A10 -B2 "interface.*$INTERFACE" "$file" | \
grep -E "(lease|starts|ends|option|fixed-address)" | \
head -20 | tee -a "$REPORT_FILE"
break
fi
fi
done
if ! grep -q "Archivo DHCP:" "$REPORT_FILE"; then
warning "No se encontraron leases DHCP para $INTERFACE"
echo "DHCP: No se encontraron leases" | tee -a "$REPORT_FILE"
fi
echo "" | tee -a "$REPORT_FILE"
}
scan_local_network() {
if [ -z "$LOCAL_SUBNET" ]; then
warning "No se puede escanear red local (subred no detectada)"
return 1
fi
log "Escaneando red local $LOCAL_SUBNET..."
echo "=== ESCANEO DE RED LOCAL ===" | tee -a "$REPORT_FILE"
if [ "$HAS_NMAP" = true ]; then
# Escaneo rápido con nmap
log "Ejecutando escaneo rápido con nmap..."
nmap -sn "$LOCAL_SUBNET" 2>/dev/null | \
grep "Nmap scan report" | \
head -20 | \
tee -a "$REPORT_FILE"
# Contar dispositivos
DEVICE_COUNT=$(nmap -sn "$LOCAL_SUBNET" 2>/dev/null | grep "Nmap scan report" | wc -l)
success "Dispositivos detectados: $DEVICE_COUNT"
echo "Total dispositivos: $DEVICE_COUNT" | tee -a "$REPORT_FILE"
else
# Método alternativo usando ping y arp
warning "Usando método básico de detección (sin nmap)..."
# Ping a broadcast (puede no funcionar en todas las redes)
log "Probando detección básica..."
ping -c 2 -b "$(echo "$LOCAL_SUBNET" | cut -d'/' -f1 | sed 's/0$/255/')" &> /dev/null || true
# Mostrar tabla ARP
ip neigh show | grep -v "FAILED" | \
head -20 | \
tee -a "$REPORT_FILE"
DEVICE_COUNT=$(ip neigh show | grep -v "FAILED" | wc -l)
echo "Dispositivos en tabla ARP: $DEVICE_COUNT" | tee -a "$REPORT_FILE"
fi
echo "" | tee -a "$REPORT_FILE"
}
check_tailscale() {
log "Verificando estado de Tailscale..."
echo "=== ESTADO TAILSCALE ===" | tee -a "$REPORT_FILE"
if command -v tailscale &> /dev/null; then
tailscale status 2>/dev/null | tee -a "$REPORT_FILE"
# Extraer IP de Tailscale
TAILSCALE_IP=$(tailscale status --json 2>/dev/null | \
$([ "$HAS_JQ" = true ] && echo "jq -r '.Self.TailscaleIPs[0]'" || echo "grep -oE '100\.[0-9]+\.[0-9]+\.[0-9]+' | head -1"))
if [ -n "$TAILSCALE_IP" ]; then
success "Tailscale IP: $TAILSCALE_IP"
echo "IP Tailscale: $TAILSCALE_IP" | tee -a "$REPORT_FILE"
else
warning "Tailscale no parece estar conectado"
echo "Tailscale: No conectado" | tee -a "$REPORT_FILE"
fi
else
warning "Tailscale no está instalado"
echo "Tailscale: No instalado" | tee -a "$REPORT_FILE"
fi
echo "" | tee -a "$REPORT_FILE"
}
generate_recommendations() {
log "Generando recomendaciones..."
echo "=== RECOMENDACIONES ===" | tee -a "$REPORT_FILE"
# Recomendación de IP local
if [ -n "$LOCAL_SUBNET" ]; then
BASE_NET=$(echo "$LOCAL_SUBNET" | cut -d'/' -f1 | cut -d'.' -f1-3)
echo "Para configuración local entre srv-dasu y pc-dasu0:" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
echo "1. **IPs recomendadas (fuera de rango DHCP común):**" | tee -a "$REPORT_FILE"
echo " - srv-dasu: ${BASE_NET}.205/24" | tee -a "$REPORT_FILE"
echo " - pc-dasu0: ${BASE_NET}.100/24" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
echo "2. **Configuración de red:**" | tee -a "$REPORT_FILE"
echo " - Gateway: $(echo "$DEFAULT_GW" || echo "[gateway-del-router]")" | tee -a "$REPORT_FILE"
echo " - Máscara: 255.255.255.0 (/24)" | tee -a "$REPORT_FILE"
echo " - DNS Primario: 10.0.100.10 (dc-dasuten)" | tee -a "$REPORT_FILE"
echo " - DNS Secundario: 8.8.8.8" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
echo "3. **Verificaciones previas:**" | tee -a "$REPORT_FILE"
echo " - Confirmar que ${BASE_NET}.205 y ${BASE_NET}.100 no están en uso" | tee -a "$REPORT_FILE"
echo " - Verificar que el firewall permite ICMP y puertos necesarios" | tee -a "$REPORT_FILE"
echo " - Tailscale debe permanecer activo como respaldo" | tee -a "$REPORT_FILE"
else
echo "No se pudo generar recomendaciones específicas (subred no detectada)" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
echo "Recomendaciones generales:" | tee -a "$REPORT_FILE"
echo "1. Identificar manualmente la subred del router ISP" | tee -a "$REPORT_FILE"
echo "2. Usar IPs estáticas fuera del rango DHCP del router" | tee -a "$REPORT_FILE"
echo "3. Mantener Tailscale como ruta de failover" | tee -a "$REPORT_FILE"
fi
echo "" | tee -a "$REPORT_FILE"
}
generate_summary() {
echo "=== RESUMEN DEL DIAGNÓSTICO ===" | tee -a "$REPORT_FILE"
echo "Fecha: $(date)" | tee -a "$REPORT_FILE"
echo "Hostname: $(hostname)" | tee -a "$REPORT_FILE"
echo "Interfaz analizada: $INTERFACE" | tee -a "$REPORT_FILE"
echo "Estado interfaz: $(cat /sys/class/net/"$INTERFACE"/operstate 2>/dev/null || echo "desconocido")" | tee -a "$REPORT_FILE"
echo "Gateway: ${DEFAULT_GW:-No detectado}" | tee -a "$REPORT_FILE"
echo "Subred local: ${LOCAL_SUBNET:-No detectada}" | tee -a "$REPORT_FILE"
echo "Tailscale: $(if command -v tailscale &> /dev/null; then echo "Instalado"; else echo "No instalado"; fi)" | tee -a "$REPORT_FILE"
echo "" | tee -a "$REPORT_FILE"
echo "Archivos generados:" | tee -a "$REPORT_FILE"
echo " - Log detallado: $LOG_FILE" | tee -a "$REPORT_FILE"
echo " - Reporte completo: $REPORT_FILE" | tee -a "$REPORT_FILE"
}
main() {
echo "========================================="
echo " DIAGNÓSTICO DE RED LOCAL - srv-dasu"
echo "========================================="
echo ""
# Inicializar archivos
> "$LOG_FILE"
> "$REPORT_FILE"
# Verificar dependencias
if ! check_dependencies; then
exit 1
fi
# Verificar interfaz
if ! check_interface; then
exit 1
fi
# Ejecutar diagnósticos
get_interface_info
get_routing_info
check_dhcp_info
scan_local_network
check_tailscale
generate_recommendations
generate_summary
echo ""
success "Diagnóstico completado exitosamente"
echo ""
echo "Para configurar IP local en $INTERFACE, edite:"
echo " sudo nano /etc/network/interfaces"
echo ""
echo "Agregue las líneas (adaptando la IP según recomendaciones):"
echo " post-up ip addr add 192.168.1.205/24 dev $INTERFACE"
echo " pre-down ip addr del 192.168.1.205/24 dev $INTERFACE"
echo ""
echo "Luego reinicie el servicio de red:"
echo " sudo systemctl restart networking"
}
# Ejecutar script principal
main "$@"