#!/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 "$@"