La segmentación de red no es una capa secundaria de defensa: es el límite fundamental que previene el movimiento lateral en caso de que un nodo perimetral resulte comprometido. En entornos basados en OpenBSD, Packet Filter (PF) proporciona un motor de filtrado con estado (stateful), determinista y de alto rendimiento que permite modelar políticas de mínimo privilegio con claridad absoluta en texto plano.
1. Topología de Segmentación por Zonas de Confianza
Una arquitectura de red resiliente separa el tráfico en dominios aislados mediante interfaces físicas o VLANs etiquetadas (802.1Q):
+-------------------+
| WAN / ISP |
+-------------------+
|
[ vio0: WAN ]
|
+-------------------+
| OpenBSD Edge |
| PF Firewall |
+-------------------+
/ | \
[ vlan10: DMZ ] ----/ | \---- [ vlan30: MGMT ]
| | |
+---------------------+ | +---------------------+
| Public Services | | | Out-of-Band Admin |
| (httpd, relayd) | | | (SSH bastion, PDU) |
+---------------------+ | +---------------------+
|
[ vlan20: CORE LAN ]
|
+-------------------------+
| Workstations & Storage |
+-------------------------+
Principios de Aislamiento
- Tráfico Ingress WAN: Únicamente puede alcanzar puertos explícitos de la zona DMZ (
80/tcp,443/tcp). - Aislamiento DMZ: Los nodos de la DMZ jamás pueden iniciar conexiones TCP/UDP hacia la red interna (CORE) ni hacia la interfaz de administración (MGMT).
- Zona de Gestión (MGMT): Totalmente inaccesible desde internet y desde la DMZ; únicamente alcanzable desde IPs autorizadas de la red interna mediante llaves SSH ED25519 con autenticación multifactor.
2. Reglas Completas de Packet Filter (/etc/pf.conf)
A continuación se detalla el archivo de configuración /etc/pf.conf con normalización de paquetes, tablas dinámicas contra ataques de fuerza bruta y políticas de estado estrictas:
# ==============================================================================
# /etc/pf.conf - Configuración de Segmentación y Hardening de Red
# ==============================================================================
# --- 1. Definición de Interfaces y Macros ---
if_wan = "vio0"
if_dmz = "vlan10"
if_lan = "vlan20"
if_mgmt = "vlan30"
net_dmz = "172.16.10.0/24"
net_lan = "10.0.20.0/24"
net_mgmt = "10.0.30.0/24"
# Puertos Web Públicos
pub_ports = "{ 80, 443 }"
# --- 2. Tablas Dinámicas y Listas Negras ---
table <bruteforce> persist
table <bogon_ips> persist file "/etc/pf.bogons"
# --- 3. Opciones Globales de Normalización y Límites ---
set skip on lo
set block-policy drop
set loginterface $if_wan
set state-defaults pflow, no-sync
# Optimización de tabla de estados y timeouts
set limit states 50000
set limit src-nodes 20000
set timeout { interval 10, frag 30 }
# Scrubbing y Reensamblado de Paquetes
match in all scrub (no-df random-id max-mss 1440 reassemble tcp)
# Antispoofing en todas las interfaces internas
antispoof quick for { $if_wan, $if_dmz, $if_lan, $if_mgmt }
# --- 4. Política por Defecto: Bloqueo Total ---
block log all
block quick from <bogon_ips>
block quick from <bruteforce>
# --- 5. Tráfico Saliente desde el Propio Firewall (Egress) ---
pass out on $if_wan proto udp to any port domain keep state
pass out on $if_wan proto udp to any port ntp keep state
pass out on $if_wan proto tcp to any port { http, https } keep state
# Permitir ICMP controlado para Path MTU Discovery
pass in inet proto icmp icmp-type { echoreq, unreach, timex } keep state
pass out inet proto icmp keep state
# --- 6. Reglas de Ingress WAN (Servicios Públicos en DMZ) ---
# Protección contra saturación SYN y fuerza bruta
pass in quick on $if_wan proto tcp to ($if_wan) port $pub_ports \
flags S/SA synproxy state \
(max-src-conn 100, max-src-conn-rate 30/5, overload <bruteforce> flush global)
# SSH hacia el host (Solo con límite estricto de intentos)
pass in quick on $if_wan proto tcp to ($if_wan) port 22 \
flags S/SA keep state \
(max-src-conn 5, max-src-conn-rate 3/60, overload <bruteforce> flush global)
# --- 7. Reglas de Enrutamiento Interno (Inter-VLAN Routing) ---
# LAN -> Internet (NAT Egress)
match out on $if_wan from $net_lan to any nat-to ($if_wan)
pass in on $if_lan from $net_lan to any keep state
# LAN -> DMZ (Permitido para pruebas internas)
pass in on $if_lan from $net_lan to $net_dmz keep state
# DMZ -> LAN / MGMT: BLOQUEADO POR DEFECTO (Previene movimiento lateral)
# Solo se permite tráfico saliente de DMZ a Internet si es indispensable
pass in on $if_dmz from $net_dmz to ! { $net_lan, $net_mgmt } keep state
# MGMT -> Cualquier interfaz (Administración autorizada)
pass in on $if_mgmt from $net_mgmt to any keep state
3. Verificación y Monitoreo en Tiempo Real
Para validar que las reglas no contengan errores sintácticos antes de cargarlas al kernel:
# Validar sintaxis sin aplicar cambios
doas pfctl -nf /etc/pf.conf
# Cargar reglas en vivo
doas pfctl -f /etc/pf.conf
# Inspeccionar estadísticas de tablas y bloqueos en tiempo real
doas pfctl -s info
doas pfctl -t bruteforce -T show
doas tcpdump -n -e -ttt -i pflog0
Conclusión
El uso riguroso de tablas (tables), protección synproxy, normalización de paquetes y políticas de bloqueo por defecto en OpenBSD PF garantiza que cada flujo de red esté auditado y controlado, dejando a los atacantes sin superficie de movimiento lateral.