Sintaxis actualizada (FreeBSD 14 usa PF de OpenBSD 6.9–7.0 aproximadamente, hay cambios importantes).
# ====================== MACROS ======================
lan_if = "re0"
zt_if = "zt1ocu1pr8e2sac"
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" # pon aquí la IP real de re0 si es fija
ssh_ports = "{ 22 }"
nfs_ports_tcp = "{ 111, 892, 2049 }"
nfs_ports_udp = "{ 111, 892 }"
ntp_servers = "{ pool.ntp.org 0.es.pool.ntp.org 1.es.pool.ntp.org }"
# ====================== OPCIONES GLOBALES ======================
set block-policy return # responde ICMP/TCP-RST a paquetes bloqueados
set ruleset-optimization none # en FreeBSD 14 ya no se usa "basic" ni "high-latency"
set skip on lo0
set skip on $zt_if # ZeroTier ya tiene su propio cortafuegos interno
# Normalización moderna (recomendado)
match in all scrub (no-df random-id max-mss 1440)
# ====================== TABLAS ======================
table <bruteforce> persist # aquí meterá sshguard, pf-badhost, etc.
# ====================== REGLAS DE PROTECCIÓN BÁSICA ======================
# Anti-spoofing + bogons (bloqueo rápido)
block in quick on ! $lan_if from $lan_net to any
block in quick on ! $lan_if from 192.168.0.0/16 to any
block in quick on ! $lan_if from 172.16.0.0/12 to any
block in quick on ! $lan_if from 10.0.0.0/8 to any
# ====================== TRÁFICO CONFIABLE (LAN) ======================
# ASEGURA QUE EL TRÁFICO CONFIABLE DE LA LAN SE ESTABLEZCA PRIMERO.
pass in quick on $lan_if from $lan_net to $lan_ip keep state
# --------------------------------------------------------------------
block in quick from any to { 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, ::/128, 0.0.0.0/8 }
# Bloqueo rápido de hosts en lista negra
block in quick from <bruteforce>
# ====================== LOOPBACK ======================
pass quick on lo0 all
# ====================== TRÁFICO SALIENTE (estadoful) ======================
pass out quick inet
# ====================== ICMP ======================
pass inet proto icmp icmp-type { echoreq, echorep, unreach, timex }
# ====================== SSH CON PROTECCIÓN ======================
# Desde LAN (sin límite)
pass in on $lan_if proto tcp from $lan_net to $lan_ip port $ssh_ports flags S/SFRA keep state
# Desde ZeroTier (con límite de tasa para evitar brute-force)
pass in on $zt_if proto tcp from $zt_net to $my_zt_ip port $ssh_ports \
flags S/SFRA keep state \
(max-src-conn-rate 15/5, overload <bruteforce> flush global)
# ====================== DNS (Unbound local) ======================
pass quick on $lan_if proto { tcp udp } from $lan_net to $lan_ip port 53
# ====================== NTP cliente ======================
pass out proto udp from any to $ntp_servers port 123 keep state
# ====================== NFS (solo LAN) ======================
pass in on $lan_if proto tcp from $lan_net to $lan_ip port $nfs_ports_tcp \
flags S/SFRA keep state
pass in on $lan_if proto udp from $lan_net to $lan_ip port $nfs_ports_udp \
keep state
# NFSv4 callback channel (solo desde clientes NFS de la LAN)
pass in on $lan_if proto tcp from $lan_net to $lan_ip port 3000:4000 \
flags S/SFRA keep state
# ====================== KERBEROS (si lo usas en la LAN) ======================
pass in on $lan_if proto { tcp udp } from $lan_net to any port { 88, 749, 464 } keep state
# ====================== ZeroTier (puerto de control) ======================
pass in quick on $zt_if proto udp from any to any port 9993
# ====================== BLOQUEO FINAL (por defecto) ======================
block all
FreeBSD es genial!.