Firewall Dinámico en FreeBSD


Sistema de firewall dinámico basado en el principio de Privilegio Mínimo, hemos logrado que un usuario sin privilegios modifique el comportamiento del firewall (PF) sin usar sudo ni SUID bits.
Los dispositivos (devfs rules + BPF) + tcpdump. una combinación limpia, nativa y eficiente.
Optimización de Sistemas Unix: Configuración avanzada de políticas de dispositivos mediante devfs.rules y automatización de servicios mediante scripts RC personalizados y gestión de daemons.
La IP autorizada se inyecta en el firewall (Packet Filter) cuando se establece la conexión SSH.
Fichero: /etc/pf.conf
# Interfaces
ext_if="vtnet0"
# Definir la tabla (persist permite que exista aunque esté vacía)
table <mi_ip> persist
# Block abusive hosts
block quick from <abusive_hosts>
# Incoming traffic, denegación total
block all
pass out quick keep state
# Filtering
pass in quick on $ext_if reply-to ($ext_if ip-gateway) proto tcp from <mi_ip> to ip-sistema port 22 keep state (max-src-conn 5, max-src-conn-rate 15/7, overload <abusive_hosts> flush global)
Crea un pipe: mkfifo /var/run/pf_helper.pipe y dale permisos chown root:admin y chmod 620.
Fichero: /etc/ssh/sshrc
Este archivo se ejecuta automáticamente cada vez que alguien se loguea por SSH.
# Capturamos la IP, limpiamos posibles puntos finales o puertos y nos aseguramos
# de que sea solo texto IP_PUBLICA=$(tcpdump -ni vtnet0 -c 1 port XXXXX 2>/dev/null | awk '{print $3}' | cut -d. -f1-4) if [ ! -z "$IP_PUBLICA" ]; then # Enviamos al pipe en segundo plano para no bloquear el login echo "$IP_PUBLICA" > /var/run/pf_helper.pipe & fi
El Script "Daemon" (PF-Injector): Un script corriendo en segundo plano:
Fichero: /usr/local/bin/pf_injector.sh
#!/bin/sh
PIPE="/var/run/pf_helper.pipe"
while true; do
ip=$(cat "$PIPE")
if [ ! -z "$ip" ]; then
if echo "$ip" | grep -E '^([0-9]{1,3}\.){3}[0-9]{1,3}$' > /dev/null; then
/sbin/pfctl -t mi_ip -T flush >/dev/null 2>&1
/sbin/pfctl -t mi_ip -T add "$ip"
logger -t pf_injector "Tabla flusheada y nueva IP añadida: $ip"
fi
fi
done
permisos de ejecución: chmod +x /usr/local/bin/pf_injector.sh
El Script de Servicio (RC.d)
Fichero: /usr/local/etc/rc.d/pf_injector
#!/bin/sh
#
# PROVIDE: pf_injector
# REQUIRE: LOGIN pf
# KEYWORD: shutdown
. /etc/rc.subr
name="pf_injector"
rcvar="pf_injector_enable"
command="/usr/sbin/daemon"
# Parámetros para daemon:
# -f (corre en segundo plano)
# -p (crea el archivo PID)
# -u (podría ser root, pero daemon lo gestiona)
command_args="-f -p /var/run/${name}.pid /usr/local/bin/pf_injector.sh"
pidfile="/var/run/${name}.pid"
load_rc_config $name
run_rc_command "$1"
permisos :chmod +x /usr/local/etc/rc.d/pf_injector
sysrc pf_injector_enable="YES"
service pf_injector start
El escenario Final:
Conectas VPN.
Haces SSH (entras por el túnel de la VPN)
SSH lanza el script(/etc/ssh/sshrc): detecta tu IP (tcpdump) y se la pasa al PIPE (pf_helper.pipe), el script RC deja como demonio a pf_injector.sh, que limpia la tabla mi_ip, e inyecta la IP autorizada en Packet Filter .
La IP pública ya esta en la tabla mi_ip de PF
Ahora conectas desde otra consola: ssh -i id_key -p XXXXX user@ip-sistema
Puedes desconectar si quieres la primera conexión SSH, y después si quieres también la VPN
El Sistema debería limpiar la tabla mi_ip , cuando te desconectes de SSH
Related Posts
Dockerizar una aplicación Next.JS con Nginx y PostgreSQL
2025-09-21 00:00:00

Entorno de desarrollo local con Next.js, Drizzle, Nginx y PostgreSQL
2025-09-21 00:00:00

Web blog Next.js 16
2025-11-23 00:00:00

Cifrar JSON Web Token con Flask
2025-03-17 00:00:00

Low-Level Network Payloads: Bind & Reverse Shell (x86_64 Assembly)
2026-03-20 00:00:00
Popular Category
Subscribe to receive future updates
Lorem ipsum dolor sited Sed ullam corper consectur adipiscing Mae ornare massa quis lectus.
No spam guaranteed, So please don’t send any spam mail.