Laboratorio Enterprise: Diseñando una Red Segura con GNS3, FortiGate y Suricata

Una red corporativa no se defiende con un único dispositivo. La seguridad real funciona en capas que trabajan en paralelo: VLANs que separan el tráfico interno, un firewall en el perímetro, un IDS observando lo que entra en la DMZ, RADIUS centralizando la autenticación administrativa, y los servicios públicos aislados del resto. En este laboratorio he montado exactamente eso sobre GNS3, con equipamiento mixto: Cisco IOS, FortiGate VM, Ubuntu Server y Kali Linux.

El objetivo no era solo que funcionara. Era que cada pieza estuviera justificada, que los flujos de tráfico siguieran una política explícita y que hubiera un atacante interno (Kali desde la VLAN 60) capaz de validar que el IDS detecta lo que tiene que detectar. Lo que viene a continuación es el relato completo del diseño, la implementación y los problemas reales que aparecieron por el camino.


1. Arquitectura: seis zonas, una sola lógica

Diagrama de arquitectura de red del laboratorio enterprise

La topología se divide en seis zonas funcionales: WAN, firewalls, LAN, DMZ, pentesting y sede externa (branch). Separar por zonas permite razonar sobre la red sin que todo dependa de todo, y aplicar políticas distintas en cada parte.

El flujo de tráfico desde Internet sigue siempre la misma secuencia: nube NAT → R-ISP → FortiGate → destino interno o publicado. Cualquier flujo que no encaje con una política explícita en FortiGate se descarta.

Los componentes principales son:

  • R-ISP — Router Cisco c7200. Simula el proveedor. Aloja la loopback 8.8.8.8 y enlaza con ambos FortiGate.
  • FG-HQ — FortiGate VM. Firewall principal. WAN en port1, LAN/CORE en port2, DMZ en port3.
  • FG-BRANCH — FortiGate VM. Firewall de la sede externa.
  • R-CORE — Router Cisco c7200. Núcleo de la LAN. Hace inter-VLAN routing y autentica el acceso admin contra RADIUS.
  • Servidor DMZ — Ubuntu Server con Apache, BIND9 y Suricata en 172.16.10.10.
  • Servidor RADIUS — Ubuntu con FreeRADIUS en la VLAN 20 (192.168.20.200).
  • Kali Linux — Host de pentesting en la VLAN 60 (192.168.60.10).

2. Direccionamiento IP

Los enlaces punto a punto entre routers y firewalls usan /30 para no desperdiciar direcciones. Las VLANs internas, la DMZ y la red de la sede externa van en /24. Los rangos 203.0.113.0/30 y 198.51.100.0/30 son rangos de documentación (RFC 5737) para no colisionar con IPs públicas reales.

Dispositivo Interfaz Dirección IP Prefijo Función
R-ISP G0/0 203.0.113.1 /30 WAN ↔ FG-HQ
R-ISP G1/0 198.51.100.1 /30 WAN ↔ FG-BRANCH
R-ISP Loopback0 8.8.8.8 /32 DNS root simulado
FG-HQ port1 203.0.113.2 /30 WAN HQ
FG-HQ port2 10.0.0.1 /30 CORE ↔ R-CORE
FG-HQ port3 172.16.10.1 /24 Gateway DMZ
FG-BRANCH port1 198.51.100.2 /30 WAN Branch
R-CORE G0/0 10.0.0.2 /30 Enlace ↔ FG-HQ
R-CORE G1/0.20 192.168.20.1 /24 Gateway VLAN 20 — Admin
R-CORE G1/0.30 192.168.30.1 /24 Gateway VLAN 30 — Usuarios
R-CORE G1/0.50 192.168.50.1 /24 Gateway VLAN 50 — Invitados
R-CORE G1/0.60 192.168.60.1 /24 Gateway VLAN 60 — Pentesting
Servidor DMZ enp0s3 172.16.10.10 /24 Apache + BIND9 + Suricata
Servidor RADIUS enp0s3 192.168.20.200 /24 FreeRADIUS AAA
Kali Linux eth0 192.168.60.10 /24 Host de pentesting

3. VLANs e inter-VLAN routing

La LAN interna se divide en cuatro VLANs: 20 (administración), 30 (usuarios), 50 (invitados) y 60 (pentesting). El enrutamiento entre ellas se hace con router-on-a-stick: el enlace de SW-LAN hacia R-CORE va en modo trunk 802.1Q y R-CORE crea una subinterfaz por VLAN sobre G1/0.

interface GigabitEthernet1/0.20
 encapsulation dot1Q 20
 ip address 192.168.20.1 255.255.255.0

interface GigabitEthernet1/0.30
 encapsulation dot1Q 30
 ip address 192.168.30.1 255.255.255.0

Las VLAN 50 y 60 siguen el mismo patrón. La configuración se completa con una ruta por defecto hacia FG-HQ (10.0.0.1) y una estática hacia 172.16.10.0/24 por la misma puerta de enlace.

Una cosa que costó tiempo: si el switch tiene el puerto hacia R-CORE en modo access en lugar de trunk, las subinterfaces aparecen pero no hay tráfico. Hay que asegurarse de que ese puerto pasa todas las VLAN, y no olvidar write memory después de cada cambio porque si el router reinicia sin guardar, las subinterfaces desaparecen por completo.


4. Firewalls FortiGate

FG-HQ separa WAN, CORE/LAN y DMZ. FG-BRANCH separa WAN y sede externa. La filosofía durante las pruebas ha sido trabajar primero con reglas amplias (service ALL) para validar conectividad, y dejar el endurecimiento para después: sustituir esas reglas por los servicios mínimos que cada flujo necesita.

Los flujos definidos son:

Flujo Servicios Justificación
LAN → DMZ Recomendado: HTTP, HTTPS, DNS Acceso controlado a servicios DMZ
DMZ → LAN Denegado por defecto Aislamiento de la DMZ
Kali / Pentesting → DMZ Permitido para pruebas Validación de Suricata
LAN → WAN Parcial según NAT Salida exterior del laboratorio
WAN → DMZ VIP HTTP Publicación del servidor web

El aislamiento de la DMZ es el punto más importante: si un atacante comprometiera el servidor web, no tendría acceso directo a los hosts de la LAN. El firewall lo bloquea por defecto.


5. DMZ: Apache y BIND9

El servidor de la DMZ (172.16.10.10) ofrece dos servicios internos: Apache sirviendo la página corporativa y BIND9 para resolución DNS del dominio empresa.local.

Apache:

sudo systemctl status apache2
curl http://172.16.10.10
curl http://web.empresa.local

BIND9:

zone "empresa.local" {
    type master;
    file "/etc/bind/db.empresa.local";
};

La validación de DNS se hizo desde Kali y desde el propio servidor Ubuntu, apuntando al 172.16.10.10 como nameserver. Los VPCS de GNS3 no admitían el comando dns en la versión utilizada, así que esos clientes se usaron solo para pruebas de conectividad IP básica.

nslookup web.empresa.local 172.16.10.10
named-checkzone empresa.local /etc/bind/db.empresa.local

6. IDS Suricata

Suricata corre en el mismo servidor de la DMZ y escucha la interfaz que da al switch de la DMZ. Para tener una validación clara, añadí una regla personalizada que dispara una alerta ante cualquier ICMP que entre en la red. Con esa regla, hacer un ping desde Kali es suficiente para verla aparecer en fast.log.

alert icmp any any -> $HOME_NET any (msg:"ICMP Ping Detectado"; sid:1000001; rev:1;)
sudo tail -f /var/log/suricata/fast.log

# Desde Kali:
ping 172.16.10.10
nmap 172.16.10.10

El escaneo Nmap también genera alertas por la cantidad de paquetes hacia puertos distintos. Ambas pruebas confirman que el IDS está procesando el tráfico de la DMZ correctamente.


7. AAA centralizada: FreeRADIUS + Cisco IOS

Esta fue la parte que más tiempo consumió, pero también la más interesante de debuggear.

El servidor FreeRADIUS vive en la VLAN 20 (192.168.20.200) y autentica los accesos administrativos a R-CORE. La configuración tiene tres piezas: los usuarios en el servidor, los clientes autorizados y la configuración AAA en el router.

En el servidor FreeRADIUS:

# /etc/freeradius/3.0/users
proyecto   Cleartext-Password := "admin"

# /etc/freeradius/3.0/clients.conf
client localhost {
    ipaddr = 127.0.0.1
    secret = testing123
}
client rcore {
    ipaddr = 192.168.20.1
    secret = radiuskey
}

En R-CORE:

aaa new-model
aaa authentication login default group radius local
radius-server host 192.168.20.200 auth-port 1812 acct-port 1813 key radiuskey
ip radius source-interface GigabitEthernet1/0.20
username admin privilege 15 secret cisco

Hay dos detalles que conviene resaltar porque no son obvios:

El primero: el cliente que FreeRADIUS espera ver es la IP origen real de los paquetes del router. Con ip radius source-interface G1/0.20, esa IP es 192.168.20.1, no la IP del enlace 10.0.0.2. Si no se fija la source-interface, el router sale por otra interfaz y FreeRADIUS descarta el paquete porque no reconoce al cliente.

El segundo: Cisco IOS por defecto intenta usar los puertos RADIUS legacy 1645/1646. Hay que forzar 1812/1813 explícitamente con auth-port y acct-port, porque FreeRADIUS moderno no escucha en los puertos legacy.

Con estos dos detalles resueltos, radtest devuelve Access-Accept y el login Telnet a R-CORE pasa por RADIUS con local como respaldo.

radtest proyecto admin localhost 0 testing123

8. Pentesting con Kali

Kali Linux (192.168.60.10) actúa como atacante interno desde la VLAN 60. Desde ahí se comprueba la conectividad hacia la DMZ, la resolución DNS interna, el acceso al servidor web y la generación de tráfico que Suricata tiene que ver.

Las herramientas usadas son las habituales: ping, nslookup, curl, nmap, nikto y dirb. El objetivo no es comprometer nada, sino confirmar que el IDS dispara las alertas correctas y que las políticas del firewall permiten solo lo que deben permitir.


9. Las incidencias que nadie documenta (pero que hay que documentar)

I-01 — apt update falla y no hay salida estable a Internet

El ping a IPs externas funcionaba, pero apt update fallaba por DNS. El servidor tenía conectividad IP pero el /etc/resolv.conf no apuntaba a nada válido. Además, la nube NAT de GNS3 pasando por R-ISP y los FortiGate VM legacy tiene un comportamiento errático. Se ajustó resolv.conf para las instalaciones puntuales y se asumió como limitación del entorno: los servicios internos no dependen de Internet.

I-02 — Pérdida de subinterfaces VLAN tras reiniciar R-CORE

Clásico. La configuración no se había guardado con write memory. Al reiniciar, las cuatro subinterfaces desaparecieron y los clientes de las VLAN perdieron la puerta de enlace. Encima, el puerto del switch hacia R-CORE había vuelto a modo access. Solución: recrear las subinterfaces, write memory y verificar que el trunk está bien configurado.

I-03 — Los VPCS no resuelven DNS

Limitación conocida de la versión de VPCS incluida en GNS3: en algunas builds no acepta el comando dns desde su shell. Se asume como limitación de la herramienta. La validación de BIND9 se hace desde Kali y desde el servidor Ubuntu.

I-04 — FreeRADIUS no arranca

Errores de sintaxis en /etc/freeradius/3.0/users y en clients.conf. El formato del atributo Cleartext-Password no admite variaciones. Se corrigió y radtest empezó a devolver Access-Accept.

I-05 — Cisco IOS rechaza la autenticación contra RADIUS

El Telnet llegaba, pedía credenciales y devolvía “Authentication failed”. FreeRADIUS ni siquiera registraba intentos del router. Causa: puertos legacy y IP origen incorrecta, los dos detalles descritos en el apartado anterior.

I-06 — El túnel IPSec entre los dos FortiGate no se establece

Este fue el problema sin solución completa. get vpn ipsec tunnel summary mostraba selectors(total,up): 1/0. El debug IKE (diagnose debug application ike -1) apuntaba a un probable pre-shared secret mismatch, incluso después de reescribir la PSK en ambos extremos y recrear las fases.

Se verificaron todos los parámetros: PSK, proposals, dhgrp, subredes de fase 2, rutas y políticas. El problema es el build de FortiGate VM legacy que usa GNS3: tiene bugs conocidos en la negociación IKE que no responden a las correcciones habituales. El diseño está completo y el debug da pistas claras, pero el túnel no llega a estado operativo. Para superarlo habría que migrar a una FortiGate-VM más reciente.


Estado final

Lo que funciona completamente:

  • Segmentación VLAN 20/30/50/60 e inter-VLAN routing.
  • FG-HQ con separación efectiva entre LAN, DMZ y WAN.
  • DMZ con Apache sirviendo la página corporativa y BIND9 resolviendo empresa.local.
  • Suricata generando alertas ICMP y con escaneos Nmap desde Kali.
  • FreeRADIUS con Access-Accept y AAA de Cisco autenticando vía Telnet.
  • Kali Linux con acceso operativo a la DMZ para las pruebas.

Lo que queda parcial:

  • VPN IPSec site-to-site: diseño completo, configuración aplicada, negociación final no estable.
  • Salida a Internet real: útil para instalaciones puntuales, no fiable como dependencia continua.

Conclusiones

El laboratorio funciona como una red multizona razonablemente defendible. Los controles principales están en su sitio y se han validado con pruebas concretas, no solo con la configuración escrita.

Trabajar con cuatro plataformas distintas (Cisco IOS, FortiGate, Ubuntu y Kali) obliga a tocar problemas reales que no aparecen en los ejercicios cerrados: puertos RADIUS legacy, IPs origen que el router no envía por donde uno espera, builds de FortiGate VM con bugs en IKE, VPCS sin soporte para DNS, una nube NAT que decide cuándo funciona. Resolver esos problemas, o al menos documentarlos honestamente, es lo que da consistencia a un proyecto de este tipo.

Las mejoras evidentes para una siguiente iteración serían completar la VPN IPSec con una versión moderna de FortiGate VM, endurecer las políticas de FortiGate sustituyendo service ALL por servicios mínimos, habilitar HTTPS en Apache y añadir una capa de monitorización centralizada (Wazuh, Grafana o ELK) para correlacionar los logs del IDS con los del firewall.

Las limitaciones que quedan están identificadas y son consecuencia del entorno virtualizado, no del diseño.