← Volver a Publicaciones

Hardening de Infraestructura en OpenBSD con Packet Filter (PF) y Pledge/Unveil

OpenBSD continúa siendo el estándar de oro en simplicidad arquitectónica, código auditado y determinismo en sistemas operativos UNIX. En esta nota desglosamos las directrices esenciales para endurecer un host expuesto a internet y asegurar servicios web estáticos con superficie de ataque mínima.

1. Filosofía de Aislamiento y Mínimo Privilegio

El diseño de OpenBSD no depende de capas pesadas de abstracción. Su seguridad se fundamenta en mecanismos nativos del kernel:

  • pledge(2): Restringe las llamadas al sistema (syscalls) que un proceso puede ejecutar una vez inicializado.
  • unveil(2): Oculta y restringe el acceso al sistema de archivos a únicamente las rutas declaradas de forma explícita.
  • W^X (Write XOR Execute): Protección estricta contra inyección y ejecución arbitraria de memoria por defecto.
+-------------------------------------------------------------+
|                      OpenBSD Host                           |
|  +---------------------+        +-------------------------+ |
|  |     relayd(8)       |  --->  |        httpd(8)         | |
|  |  (TLS Termination)  |        | (pledge: rpath, inet)   | |
|  +---------------------+        +-------------------------+ |
|            ^                                 |              |
|            | PF stateful inspection          v              |
|      [ Public WAN ]                /var/www/htdocs          |
+-------------------------------------------------------------+

2. Reglas de Filtrado con Packet Filter (/etc/pf.conf)

Una política por defecto de bloqueo total (block return all) combinada con paso selectivo con estado (stateful) y protección contra abusos de red:

# /etc/pf.conf - Reglas para host de borde OpenBSD
ext_if = "vio0"

# Opciones globales de normalización
set skip on lo
set block-policy drop
set loginterface $ext_if

# Scrubbing de paquetes para prevenir fragmentación maliciosa
match in all scrub (no-df random-id max-mss 1440)

# Política por defecto: Bloquear todo el tráfico entrante y saliente no autorizado
block drop in log all
block return out all

# Permitir salida esencial (DNS, NTP, HTTPS para actualizaciones de paquetes)
pass out quick on $ext_if proto udp to any port { domain, ntp } keep state
pass out quick on $ext_if proto tcp to any port { http, https, domain } keep state

# Permitir ICMP controlado (necesario para Path MTU Discovery)
pass in quick on $ext_if inet proto icmp icmp-type { echoreq, unreach, timex } keep state

# SSH seguro con límite de conexiones (Prevenir ataques de fuerza bruta)
table <bruteforce> persist
block quick from <bruteforce>
pass in quick on $ext_if proto tcp to ($ext_if) port 22 \
    flags S/SA keep state \
    (max-src-conn 10, max-src-conn-rate 3/60, overload <bruteforce> flush global)

# Tráfico Web Público (HTTP/HTTPS servido por httpd y relayd)
pass in quick on $ext_if proto tcp to ($ext_if) port { 80, 443 } keep state

3. Configuración de httpd(8) con Encabezados de Seguridad Estrictos

El servidor nativo httpd(8) de OpenBSD corre dentro de un entorno chroot en /var/www por diseño, reduciendo al mínimo absoluto cualquier vector de escalada:

# /etc/httpd.conf
server "valmis.net" {
    listen on * port 80
    root "/htdocs/valmis.net"

    # Redirección forzada a TLS en producción
    # block return 301 "https://$HTTP_HOST$REQUEST_URI"

    hsts {
        preload
        subdomains
        max-age 31536000
    }

    # Encabezados de seguridad estrictos
    tls {
        ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
    }
}

4. Ajustes del Kernel con sysctl.conf

# /etc/sysctl.conf
net.inet.ip.forwarding=0
net.inet.ip.redirect=0
net.inet.ip.sourceroute=0
net.inet.tcp.drop_synfin=1
net.inet.tcp.always_keepalive=1
net.inet.tcp.syn_use_2msl=1

Conclusión

La combinación de SSG estático compilado en Go + OpenBSD httpd(8) + PF elimina completamente la superficie de ataque típica de la web moderna. Sin intérpretes PHP/Node dinámicos, sin bases de datos SQL y sin privilegios innecesarios.