Sintaxis actualizada (FreeBSD 14 usa PF de OpenBSD 6.9–7.0 aproximadamente, hay cambios importantes).
# Macros
lan_if = "re0"
zt_if = "zt1ocu1pr8e2sac"
wg_if = "wg0"
lan_net = "192.168.88.0/24"
zt_net = "192.168.192.0/24"
my_zt_ip = "192.168.192.204"
lan_ip = "192.168.88.160"
ssh_port = "{ 22 }"
nfs_ports_tcp = "{ 111, 892, 2049 }"
nfs_ports_udp = "{ 111, 892 }"
# Opciones
set block-policy return
set ruleset-optimization none
set skip on lo0
match in all scrub (no-df random-id max-mss 1440)
# Tablas
table <bruteforce> persist
table <wg_peers> { 192.168.88.51 }
# LAN confiable
pass in quick on $lan_if from $lan_net to $lan_ip keep state
# WireGuard
pass in quick on $lan_if proto udp from <wg_peers> to $lan_ip port 51820 keep state
pass in quick on $wg_if from $lan_net to any keep state
# Anti-spoofing (excluyendo interfaces internas)
block in quick on ! { $lan_if, $zt_if, $wg_if } from { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 } to any
block in quick from any to { 127.0.0.0/8, 0.0.0.0/8 }
# Lista negra
block in quick from <bruteforce>
# Salida
pass out quick inet keep state
# ICMP esencial
pass in inet proto icmp all icmp-type { unreach, timex, paramprob } keep state
# ====================== SSH DESDE LAN ======================
pass in quick on $lan_if proto tcp \
from $lan_net to $lan_ip port $ssh_port \
flags S/SFRA keep state
# SSH desde ZeroTier con rate-limit
pass in on $zt_if proto tcp from $zt_net to $my_zt_ip port $ssh_port \
flags S/SFRA keep state \
(max-src-conn-rate 15/5, overload <bruteforce> flush global)
# DNS para ZeroTier
pass in on $zt_if proto { tcp udp } from $zt_net to $my_zt_ip port 53
# ZeroTier control
pass in quick on $zt_if proto udp from any to any port 9993
# Bloqueo final
block drop in log all
Pasos típicos una vez aplicado el ruleset
Validar sin aplicar
pfctl -nf /etc/pf.conf
Aplicar y verificar
pfctl -f /etc/pf.conf pfctl -sr # reglas activas pfctl -ss # estados actuales pfctl -t bruteforce -T show # IPs en la tabla
Test desde fuera (desde otro host, no desde la propia máquina):
nmap -Pn -p 22,53,111,2049,51820,9993 192.168.88.160
Ver logs en vivo de lo bloqueado:
tcpdump -n -e -ttt -i pflog0
Integrar sshguard o pf-badhost para que <bruteforce> se llene y expire solo:
pkg install sshguard sysrc sshguard_enable=YES
Y en /usr/local/etc/sshguard.conf apuntar el backend a PF con pfctl.
Cómo crear el archivo de configuración?
Ejecutar el siguiente comando para crear el archivo a partir de la plantilla:
cp /usr/local/etc/sshguard.conf.sample /usr/local/etc/sshguard.conf
Una vez creado, editar /usr/local/etc/sshguard.conf con los parámetros esenciales para que funcione con el firewall PF:
# Backend para PF (requerido) BACKEND="/usr/local/libexec/sshg-fw-pf" # Archivos de log a monitorizar FILES="/var/log/auth.log" # Umbral de bloqueo (ej: 120 segundos de bloqueo por defecto) # Formato: <segundos_bloqueo>:<ruta_al_archivo_de_lista_negra> BLACKLIST_FILE=120:/var/db/sshguard/blacklist.db # Opcional: subnet a bloquear IPV4_SUBNET=32 IPV6_SUBNET=128
Nota sobre el BLACKLIST_FILE: Si se encuentra que el umbral de bloqueo definido en sshguard.conf no surte efecto, puede deberse a una configuración por defecto en el script rc.d. Para solucionarlo, se añade la siguiente línea en el archivo /etc/rc.conf:
sshguard_blacklist=""
De esta forma, solo se aplicarán los valores que se definan en el archivo sshguard.conf
Habilitar e iniciar SSHGuard:
sysrc sshguard_enable=YES service sshguard start
Hacer persistente PF en el arranque:
sysrc pf_enable=YES sysrc pflog_enable=YES
Comprobar el estado y las IPs bloqueadas:
service sshguard status pfctl -t sshguard -T showFreeBSD es genial!.
No hay comentarios:
Publicar un comentario