Saltar al contenido principal

OPNsense

Firewall24.xBlue Team

Firewall/router open-source basado en FreeBSD con IDS/IPS Suricata nativo, WireGuard VPN, proxy y completo monitoreo de tráfico de red.

¿Qué es OPNsense y sus características?

Arquitectura, comparativa y casos de uso

OPNsense es un firewall/router open-source basado en FreeBSD, derivado de pfSense (bifurcado en 2015). Mantenido por Deciso BV con releases mensuales de seguridad.

¿Por qué OPNsense? • Interfaz moderna y limpia vs pfSense clásico • Actualizaciones mensuales de seguridad • API REST nativa completa • 100% código abierto (pfSense tiene partes propietarias) • Suricata IDS/IPS integrado nativamente

Componentes principales: • PF (Packet Filter): Motor de firewall de FreeBSD, extremadamente estable • Suricata: IDS/IPS para detección de intrusiones en tiempo real • Unbound: Servidor DNS recursivo con DNSSEC • Kea DHCP: Servidor DHCP moderno • OpenVPN + WireGuard: VPN client/server • HAProxy: Balanceo de carga y reverse proxy • ACME: Certificados SSL automáticos Let's Encrypt

Casos de uso: Firewall perimetral para empresa/PYME, router doméstico avanzado, VPN gateway corporativo, IDS/IPS para SOC, proxy y filtrado de contenido con Squid.

Requisitos de hardware: CPU amd64 de 1.5 GHz mínimo, 2 GB RAM (4 GB para IDS/IPS), 4 GB SSD, mínimo 2 interfaces de red.

bash
# Arquitectura de red típica con OPNsense:
#
#       INTERNET (WAN)
#             │
# ┌───────────▼────────────┐
# │       OPNsense          │
# │  ┌──────────────────┐  │
# │  │   PF Firewall    │  │
# │  │   Suricata IPS   │  │
# │  │   Unbound DNS    │  │
# │  │   WireGuard VPN  │  │
# │  └──────────────────┘  │
# └───┬──────────┬──────────┘
#     │          │
# ┌───▼───┐  ┌───▼────┐
# │  LAN  │  │  DMZ   │
# │Oficina│  │Servers │
# └───────┘  └────────┘

# Interfaces típicas:
# em0/vtnet0 → WAN (IP pública del ISP)
# em1/vtnet1 → LAN (192.168.1.0/24)
# em2/vtnet2 → DMZ (10.0.0.0/24)

# Para VM en VirtualBox:
# NIC1: NAT o Bridged (simula WAN)
# NIC2: Host-Only (simula LAN)
# Descargar ISO: https://opnsense.org/download/
# Architecture: amd64 | Type: dvd

💡OPNsense tiene releases de seguridad mensuales. Configura actualizaciones automáticas en System → Firmware → Settings para mantener el firewall parcheado.

Instalación y configuración inicial

Hardware, VM y primeros pasos críticos

OPNsense puede instalarse en hardware dedicado (Protectli, PC Engines APU, mini-PC con 2 NICs), en máquina virtual, o incluso en Raspberry Pi 4 con arm64.

Proceso de instalación: La ISO se descarga de opnsense.org. Se bootea desde USB o DVD. El instalador es minimalista: seleccionas el disco y confirmas. El sistema se instala en ~3 minutos.

Asignación de interfaces (crítico): El primer paso tras instalación es asignar qué NIC es WAN y cuál es LAN. Esto se hace en la consola con la opción "1 - Assign interfaces".

Primeros pasos críticos tras instalación:

  1. Asignar interfaces WAN/LAN en consola
  2. Acceder a web UI desde LAN (https://192.168.1.1)
  3. Ejecutar wizard de configuración inicial
  4. Cambiar contraseñas root y admin
  5. Configurar NTP y timezone correcto
  6. Activar HTTPS para la web UI
  7. Configurar actualizaciones automáticas

Seguridad inmediata: La web UI solo es accesible desde LAN por defecto. WAN NO tiene acceso a la web. Desactiva HTTP y fuerza HTTPS en System → Settings → Administration.

bash
# ── INSTALACIÓN EN VIRTUALBOX ─────────────────────────
# Crear VM:
VBoxManage createvm --name "OPNsense-Lab" --ostype FreeBSD_64 --register
VBoxManage modifyvm "OPNsense-Lab" --memory 2048 --cpus 2

# Configurar redes:
VBoxManage modifyvm "OPNsense-Lab" --nic1 nat        # WAN (Internet)
VBoxManage modifyvm "OPNsense-Lab" --nic2 hostonly --hostonlyadapter2 vboxnet0  # LAN

# Adjuntar ISO y arrancar:
# VirtualBox GUI → Settings → Storage → DVD → opnsense.iso
# Arrancar e instalar (usuario: installer / pass: opnsense)

# ── EN LA CONSOLA DE OPNSENSE TRAS INSTALAR ───────────
# Login: root / Password: opnsense

# Opción 1: Assign interfaces
# → WAN: em0 (NIC1 - NAT)
# → LAN: em1 (NIC2 - Host-Only)
# Proceed? y

# Opción 2: Set interface IP
# Interface: 2 (LAN)
# IPv4: 192.168.1.1
# Subnet: 24
# Enable DHCP: y (rango: 192.168.1.100-200)

# ── ACCEDER A LA WEB UI ────────────────────────────────
# Desde tu PC anfitrión (que está en la red Host-Only):
# URL: https://192.168.1.1
# Usuario: root / Password: opnsense
# ⚠️ CAMBIA la contraseña en: System → Access → Users

# ── WIZARD INICIAL ─────────────────────────────────────
# System → Wizard:
# 1. Hostname: firewall.empresa.local
# 2. DNS: 1.1.1.1, 8.8.8.8
# 3. NTP: pool.ntp.org
# 4. WAN: DHCP (si viene de ISP) o IP estática
# 5. LAN: 192.168.1.1/24
# 6. Cambiar contraseña admin

# ── ACTIVAR SSH (para administración) ─────────────────
# System → Settings → Administration → Secure Shell → Enable SSH

💡En VirtualBox, crea una red Host-Only en File → Host Network Manager antes de crear la VM. Esto permite que tu PC anfitrión se comunique con la LAN virtual.

Reglas de Firewall y NAT

Política de seguridad perimetral con PF

El firewall de OPNsense usa PF (Packet Filter) de BSD, uno de los motores más robustos y eficientes. Las reglas se crean desde la web UI.

Filosofía de reglas: • Las reglas se evalúan de arriba a abajo, primera coincidencia gana • Tráfico LAN → WAN está permitido por defecto • Tráfico WAN → LAN está bloqueado por defecto (stateful) • NAT traduce IPs privadas a la IP pública del WAN

Stateful firewall: OPNsense rastrea el estado de cada conexión TCP. Una vez permitida una conexión de salida, el tráfico de respuesta se permite automáticamente sin regla explícita.

Tipos de NAT: • Port Forward (DNAT): Redirige un puerto al servidor interno (ej: 80 → servidor web) • NAT 1:1: Mapea IP pública completa a IP interna • Outbound NAT: Controla cómo sale el tráfico de LAN a internet

Aliases (grupos reutilizables): Usa Firewall → Aliases para agrupar IPs y puertos. Hace las reglas más legibles y mantenibles. Cuando cambias el alias, todas las reglas que lo usan se actualizan automáticamente.

bash
# Las reglas se crean en Firewall → Rules → LAN/WAN
# Los siguientes son comandos de CLI para debug y verificación

# ── REGLAS RECOMENDADAS (crear en UI) ─────────────────

# Regla 1: Permitir solo admin a la web UI
# Action: Pass | Source: 192.168.1.200 | Dest: LAN address | Port: 443

# Regla 2: Bloquear acceso admin desde LAN genérica
# Action: Block | Source: LAN net | Dest: LAN address | Port: 443

# Regla 3: Bloquear BitTorrent
# Action: Block | Source: LAN net | Dest port: 6881-6889

# Regla 4: Port Forward - exponer servidor web
# Firewall → NAT → Port Forward → Add:
# Interface: WAN | Proto: TCP | Dest: WAN address | Port: 80
# Redirect IP: 192.168.1.100 | Redirect Port: 80

# ── VERIFICACIÓN EN CLI (SSH: ssh root@192.168.1.1) ───

# Ver reglas PF activas:
pfctl -sr | head -40

# Ver conexiones activas:
pfctl -ss | head -20

# Estadísticas del firewall:
pfctl -si

# Logs en tiempo real (también en Firewall → Log Files → Live View):
clog /var/log/filter.log | tail -f

# ── ALIASES ────────────────────────────────────────────
# Firewall → Aliases → Add:

# Alias IPs: "Servidores_DMZ"
# Type: Host(s)
# Content: 10.0.0.10, 10.0.0.11, 10.0.0.12

# Alias puertos: "Puertos_Web"
# Type: Port(s)
# Content: 80, 443, 8080, 8443

# Usar en reglas: Source=LAN net, Dest=Servidores_DMZ, Port=Puertos_Web

💡Usa Aliases para agrupar IPs y puertos relacionados. Las reglas serán más legibles y cuando actualices el alias, todas las reglas que lo usan se actualizan automáticamente.

Suricata IDS/IPS y monitoreo de tráfico

Detección y bloqueo de intrusiones en tiempo real

Suricata es el motor IDS/IPS integrado en OPNsense. En modo IDS solo alerta; en modo IPS bloquea activamente.

¿Cómo funciona Suricata? Analiza el tráfico en tiempo real comparándolo con miles de "signatures". Estas son mantenidas por comunidades: • ET Open (Emerging Threats): 30,000+ reglas gratuitas, actualizadas diariamente • Abuse.ch: Especializado en malware, botnet, ransomware C2 • SNORT Community: Reglas de la comunidad Snort

Modo Inline (IPS) vs Legacy (IDS): • Legacy mode: Suricata en modo tap, solo observa y logea. No puede bloquear. • Inline mode: Suricata en el path del tráfico. Puede PERMITIR o BLOQUEAR en tiempo real.

Rendimiento: Suricata usa múltiples CPU cores automáticamente. En hardware modesto (2 cores, 4GB RAM) maneja tráfico de hasta 1 Gbps cómodamente.

Monitoreo de tráfico adicional: OPNsense incluye: Interfaces → Traffic Graph, Firewall → Log Files → Live View, Interfaces → Diagnostics → Packet Capture (genera .pcap para Wireshark).

bash
# ── ACTIVAR SURICATA EN OPNSENSE ──────────────────────
# Services → Intrusion Detection → Administration:
# ✅ Enabled
# ✅ IPS mode (bloquea activamente)
# ✅ Promiscuous mode
# Interfaces: WAN, LAN
# ✅ Block offenders
# ✅ Kill states

# ── DESCARGAR REGLAS ───────────────────────────────────
# Services → Intrusion Detection → Download
# ✅ Emerging Threats Open  (obligatorio)
# ✅ Abuse.ch Feodo Tracker  (botnet/ransomware)
# ✅ Abuse.ch SSLBL          (certificados maliciosos)
# → Download & Update Rules → Apply

# ── REGLAS PERSONALIZADAS ──────────────────────────────
# Services → Intrusion Detection → Rules → Add

# Detectar escaneo de puertos:
alert tcp any any -> $HOME_NET any (
  msg:"Posible escaneo de puertos";
  flags:S;
  threshold: type both, track by_src, count 20, seconds 10;
  classtype:network-scan;
  sid:9000001; rev:1;
)

# Detectar SQL Injection:
alert http any any -> $HTTP_SERVERS $HTTP_PORTS (
  msg:"SQL Injection - UNION SELECT";
  flow:established,to_server;
  content:"union"; nocase;
  content:"select"; nocase; distance:0;
  classtype:web-application-attack;
  sid:9000002; rev:1;
)

# ── VER ALERTAS Y ESTADÍSTICAS ─────────────────────────
# Services → Intrusion Detection → Alerts (tiempo real)

# Desde SSH (análisis detallado):
tail -f /var/log/suricata/eve.json | python3 -m json.tool

# ── PACKET CAPTURE (para Wireshark) ───────────────────
# Interfaces → Diagnostics → Packet Capture:
# Interface: WAN | Protocol: TCP | Port: 80
# → Start → descargar .pcap → abrir en Wireshark

💡Comienza con Suricata en modo IDS (solo alertas) durante una semana. Revisa y crea suppressions para falsos positivos antes de activar el modo IPS bloqueante.

Labs Prácticos

Intermedio 40 min

Lab 1: Configurar VPN WireGuard para acceso remoto

Objetivo

Configurar WireGuard VPN en OPNsense para que empleados remotos accedan de forma segura a la red interna.

Escenario

Con trabajo remoto, los empleados necesitan acceder a servidores internos. En lugar de exponer SSH/RDP directamente a Internet, configuras WireGuard VPN.

Pasos

1

Instalar plugin WireGuard desde System → Firmware → Plugins

2

Generar claves para el servidor y cada cliente

3

Configurar la interfaz WireGuard con IP de túnel

4

Crear reglas de firewall para la red VPN

5

Probar conexión VPN y acceso a red interna

bash — práctica
# INSTALAR WIREGUARD
# System → Firmware → Plugins → os-wireguard → Instalar

# GENERAR CLAVES (desde SSH en OPNsense)
wg genkey | tee server_priv.key | wg pubkey > server_pub.key
wg genkey | tee client1_priv.key | wg pubkey > client1_pub.key

# CONFIGURAR SERVIDOR WireGuard
# VPN → WireGuard → Local → Add:
# Name:           wg-remote-access
# Listen Port:    51820
# Tunnel Address: 10.0.0.1/24
# DNS:            192.168.1.1

# AGREGAR CLIENTE (Peer):
# VPN → WireGuard → Peers → Add:
# Name:           empleado-juan
# Public Key:     (client1_pub.key)
# Allowed IPs:    10.0.0.2/32

# REGLAS FIREWALL para WireGuard:
# Pass | UDP | any → WAN:51820  (entrada VPN)
# Pass | any | 10.0.0.0/24 → 192.168.1.0/24  (VPN → LAN)

# ARCHIVO CONFIG PARA EL CLIENTE
cat > empleado-juan.conf << 'EOF'
[Interface]
PrivateKey = (client1_priv.key)
Address = 10.0.0.2/32
DNS = 192.168.1.1

[Peer]
PublicKey = (server_pub.key)
Endpoint = MI_IP_PUBLICA:51820
AllowedIPs = 192.168.1.0/24, 10.0.0.0/24
PersistentKeepalive = 25
EOF

# EN EL CLIENTE
sudo wg-quick up ./empleado-juan.conf
ping 192.168.1.1  # Debe responder

Resultado esperado

Empleados remotos se conectan con WireGuard y acceden a la red interna cifrada sin exponer servicios directamente a Internet.

Avanzado 50 min

Lab 2: Segmentación de red con VLANs

Objetivo

Crear VLANs para separar Oficina, IoT, Servidores y WiFi Invitados, controlando la intercomunicación.

Escenario

Tienes red mezclada: PCs, IoT, servidores y WiFi invitados. Si dispositivo IoT es comprometido, puede atacar servidores. VLANs aíslan cada segmento.

Pasos

1

Crear 4 VLANs: Oficina(10), IoT(20), Servidores(30), Invitados(40)

2

Asignar subredes diferentes a cada VLAN

3

Configurar DHCP por VLAN

4

Crear reglas inter-VLAN restrictivas

5

Configurar switch con trunking

bash — práctica
# CREAR VLANs EN OPNSENSE
# Interfaces → Other Types → VLAN → Add:
# VLAN 10: Oficina    | Parent: em1 | Tag: 10
# VLAN 20: IoT        | Parent: em1 | Tag: 20
# VLAN 30: Servidores | Parent: em1 | Tag: 30
# VLAN 40: Invitados  | Parent: em1 | Tag: 40

# ASIGNAR IPS (en cada interfaz):
# OFICINA:    192.168.10.1/24
# IOT:        192.168.20.1/24
# SERVIDORES: 192.168.30.1/24
# INVITADOS:  192.168.40.1/24

# DHCP POR VLAN (Services → DHCPv4):
# OFICINA:  .100 - .200 | DNS: 192.168.30.5
# IOT:      .100 - .200
# INVITADOS:.100 - .200

# REGLAS INTER-VLAN (Firewall → Rules):
# IoT NO puede llegar a Servidores ni Oficina:
# Block | Src: 192.168.20.0/24 | Dst: 192.168.30.0/24
# Block | Src: 192.168.20.0/24 | Dst: 192.168.10.0/24
# Pass  | Src: 192.168.20.0/24 | Dst: !192.168.0.0/16 (solo Internet)

# Invitados SOLO Internet:
# Block | Src: 192.168.40.0/24 | Dst: 192.168.0.0/16
# Pass  | Src: 192.168.40.0/24 | Dst: any

# SWITCH CISCO (Trunk hacia OPNsense):
Switch(config)# int Gi0/1
Switch(config-if)# switchport mode trunk
Switch(config-if)# switchport trunk allowed vlan 10,20,30,40

# Puerto IoT:
Switch(config)# int Gi0/10
Switch(config-if)# switchport mode access
Switch(config-if)# switchport access vlan 20

Resultado esperado

Cada VLAN aislada. Dispositivo IoT comprometido no puede acceder a servidores. Invitados WiFi solo tienen Internet.

Intermedio 35 min

Lab 3: Proxy transparente Squid con filtrado de contenido

Objetivo

Configurar Squid transparente en OPNsense para filtrar contenido web y registrar navegación sin configurar nada en los PCs.

Escenario

Tu empresa necesita bloquear redes sociales en horario laboral y registrar qué sitios visitan. Con Squid transparente ocurre sin configurar nada en los equipos.

Pasos

1

Instalar Squid y SquidGuard desde Plugins

2

Activar modo transparente para interceptar HTTP

3

Configurar listas de bloqueo (redes sociales, malware)

4

Crear regla NAT para redirigir tráfico HTTP al proxy

5

Probar bloqueo accediendo a sites en lista negra

bash — práctica
# INSTALAR (System → Firmware → Plugins)
# os-squid | os-squidguard

# CONFIGURAR SQUID (Services → Proxy Server)
# ✅ Enable Proxy
# Proxy port: 3128
# ✅ Enable Transparent HTTP proxy
# Transparent proxy interface: LAN
# ✅ Log access

# NAT PARA PROXY TRANSPARENTE
# Firewall → NAT → Port Forward → Add:
# Interface: LAN | Protocol: TCP
# Destination: !192.168.1.0/24 | Port: 80
# Redirect: 127.0.0.1:3128

# SQUIDGUARD: Listas de bloqueo
# Services → Proxy Filter SquidGuard → ✅ Enable

# Target Categories → Add:
# Name: Redes-Sociales
# Domain list:
# facebook.com twitter.com instagram.com tiktok.com youtube.com

# Target Categories → Add:
# Name: Malware-Sites
# URL: https://urlhaus.abuse.ch/downloads/text_online/

# Common ACL:
# Redes-Sociales: Deny
# Malware-Sites: Deny
# default: Allow

# PÁGINA DE BLOQUEO PERSONALIZADA
cat > /usr/local/www/blocked.html << 'HTML'
<!DOCTYPE html>
<html>
<body style="font-family:monospace;text-align:center;padding:50px;background:var(--cyber-dark);color:white">
  <h1 style="color:var(--cyber-red)">🚫 ACCESO BLOQUEADO</h1>
  <p>Este sitio está bloqueado por política de seguridad.</p>
  <p>Contacta IT: it@empresa.com</p>
</body>
</html>
HTML

# VER LOGS
tail -f /var/squid/logs/access.log

Resultado esperado

El proxy intercepta tráfico HTTP automáticamente. Los sitios en lista negra muestran página de bloqueo personalizada.

Avanzado 45 min

Lab 4: Suricata IPS + alertas a Slack en tiempo real

Objetivo

Configurar Suricata IPS con reglas personalizadas y alertas detalladas a Slack al detectar intrusiones.

Escenario

Necesitas SOC básico: Suricata detecta amenazas y envía alertas inmediatas a Slack con IP atacante, tipo de ataque y severidad.

Pasos

1

Activar Suricata en modo IPS inline en WAN

2

Descargar rulesets ET Open y Abuse.ch

3

Crear reglas personalizadas para tu entorno

4

Desarrollar script que parsea logs y envía a Slack

5

Configurar cron para notificaciones en tiempo real

bash — práctica
# ACTIVAR SURICATA
# Services → Intrusion Detection → Administration:
# ✅ Enabled | ✅ IPS mode | ✅ Promiscuous
# Interfaces: WAN | ✅ Block offenders

# DESCARGAR REGLAS
# Services → Intrusion Detection → Download:
# ✅ ET Open | ✅ Abuse.ch Feodo | ✅ Abuse.ch SSLBL
# → Download & Update Rules

# REGLAS PERSONALIZADAS
alert tcp any any -> $HOME_NET 22 (
  msg:"Fuerza bruta SSH";
  flow:to_server;
  threshold: type threshold, track by_src, count 10, seconds 60;
  sid:9001001; rev:1;
)
alert http any any -> $HTTP_SERVERS $HTTP_PORTS (
  msg:"SQLMap detectado";
  content:"sqlmap"; nocase; http_header;
  sid:9001002; rev:1;
)

# SCRIPT ALERTAS SLACK
cat > /usr/local/bin/suricata_slack.sh << 'SCRIPT'
#!/bin/bash
WEBHOOK="https://hooks.slack.com/services/TU/WEBHOOK"
tail -n0 -f /var/log/suricata/eve.json | \
python3 -c "
import sys, json, subprocess, datetime
for line in sys.stdin:
    try:
        e = json.loads(line)
        if e.get('event_type') != 'alert': continue
        a = e.get('alert', {})
        msg = json.dumps({'attachments': [{
            'color': 'danger',
            'title': f'🚨 {a.get("signature","Alert")}',
            'text': f'Src: {e.get("src_ip")}:{e.get("src_port")} → Dst: {e.get("dest_ip")}:{e.get("dest_port")}
Cat: {a.get("category")} | Sev: {a.get("severity")}'
        }]})
        subprocess.run(['curl','-s','-X','POST','$WEBHOOK','-H','Content-type: application/json','-d',msg])
    except: pass
"
SCRIPT
chmod +x /usr/local/bin/suricata_slack.sh

# COMO SERVICIO
echo "* * * * * root /usr/local/bin/suricata_slack.sh &" >> /etc/crontab

Resultado esperado

Alertas formateadas en Slack con IP atacante, tipo de ataque, puerto y timestamp cada vez que Suricata detecte una intrusión.

Aviso legal: Este contenido es estrictamente educativo. CyberFlows no apoya actividades ilegales. Úsalo solo en entornos autorizados.