pfctl - cómo agregar un ancla y activarlo / cargarlo

Entonces puedo agregar un ancla al firewall ya habilitado haciendo algo como esto:

$ pfctl -a anchor_name -f /etc/anchor_rules.txt

el archivo "anchor_rules.txt" podría contener algo como esto:

table <some-hosts> persist file /etc/someHostsToBlock.txt
block quick from any to some-hosts

Ahora, puedo ver las reglas dentro del ancla haciendo esto:

$ pfctl -a anchor_name -sr
No ALTQ support in kernel
ALTQ related functions disabled
block drop quick from any to some-hosts

Sin embargo , cuando muestro el conjunto de reglas activo actual con:

$ pfctl -sr
No ALTQ support in kernel
ALTQ related functions disabled
scrub-anchor "com.apple/*" all fragment reassemble
anchor "com.apple/*" all

No veo el ancla llamada " nombre_anclaje " que acabo de agregar. Entonces, el ancla no está realmente activa/cargada...

¿Por qué no, y cómo cargarlo?

Respuestas (2)

En mi comprensión de pf, falta su ancla principal. Puede utilizar las anclas de Apple o una ancla definida por el usuario.

Se prefiere un ancla definida por el usuario:

  1. Modificar /private/etc/pf.conf:

    Agregue dos líneas a pf.conf así:

    ...
    load anchor "com.apple" from "/etc/pf.anchors/com.apple"
    
    #
    # usr.home anchor point
    #
    anchor "usr.home/*"
    load anchor "usr.home" from "/etc/pf.anchors/usr.home"
    
  2. Cree un archivo usr.home . En el siguiente ejemplo, creo un ancla SSH que bloquea el acceso SSH desde una red local a algunas direcciones IP del host:

    sudo nano /etc/pf.anchors/usr.home
    

    y añadir

    #
    # usr.home ruleset, referred to by the modified /etc/pf.conf file.
    # See notes in that file regarding the anchor point in the main ruleset.
    #
    
    #
    # SSH anchor point.
    #
    
    anchor "SSH"
    load anchor "SSH" from "/etc/pf.rules/pfssh.rule"
    
  3. Ahora crea un nuevo directorio

    sudo mkdir /etc/pf.rules
    

    y el archivo referenciado con:

    sudo nano /etc/pf.rules/pfssh.rule
    

    y el siguiente contenido:

    block in quick inet proto { tcp, udp } from 10.0.0.0/8 to { 10.128.8.145, 10.129.8.145 } port 22
    
  4. Analice y pruebe su pf.conf y su archivo ancla para asegurarse de que no tengan errores:

    sudo pfctl -vnf /etc/pf.conf
    sudo pfctl -vnf /etc/pf.anchors/usr.home
    
  5. Recargar pf:

    sudo pfctl -d
    sudo pfctl -e -f /etc/pf.conf
    

Puede agregar anclajes adicionales a su anclaje principal usr.home como se demuestra en el anclaje principal com.apple.

También puede agregar subanclajes dinámicos adicionales con el siguiente comando (aquí agrego una regla HTTP de bloqueo temporal similar a la regla SSH; verifique la creación de un subancla transitoria: ¡usr.home/HTTP aquí !):

echo "block drop in quick proto tcp from 10.0.0.0/8 to any port 80" | sudo pfctl -a usr.home/HTTP -f -

¡El ancla temporal no sobrevive a un reinicio!

Un posible comando para eliminar la regla temporal de inmediato es:

echo "" | sudo pfctl -a usr.home/HTTP -f -

Un script útil para verificar todas las anclas y reglas cargadas es pfdump:

pfdump.sh:

#!/bin/bash

function pfprint() {
  if [ -n "$1" ];then
    sudo pfctl -a "$2" -s"$1" 2>/dev/null
  else
    sudo pfctl -s"$1" 2>/dev/null
  fi
}

function print_all() {

  local p=$(printf "%-40s" $1)
  (
    pfprint r "$1" | sed "s,^,r     ,"
    pfprint n "$1" | sed "s,^,n     ,"
    pfprint A "$1" | sed "s,^,A     ,"
  ) | sed "s,^,$p,"

  for a in `pfprint A "$1"`; do
    print_all "$a"
  done
}

print_all

¡Todos los archivos mencionados requieren una nueva línea vacía al final!

algo a tener en cuenta... parece que pfdump.sh NO muestra la salida/los anclajes en el ORDEN en que serán evaluados. Entonces, podría decir que genera las cosas en el orden incorrecto, lo que tiene un efecto en el resultado.
Si modifica /private/etc/pf.confdirectamente, ¿sobrevivirán estos cambios a través de las actualizaciones del sistema operativo?
/etc/pf.conf@Tom No estoy 100% seguro, pero creo que se conservarán los cambios fusionables . Sin embargo, puedo afirmar con certeza que los cambios en /etc/pf.anchors/com.apple, no se conservarán. Tenga cuidado con las guías o scripts que impliquen modificar ese archivo.
@macserv ¿no se supone que debe crear un ancla a nivel de usuario y una plist de lanzamiento que le diga a pfctl que habilite ese ancla? esto parece más fácil de mantener que editar archivos de nivel de sistema (aunque personalmente nunca logré que funcionara con anclas ...)

Me tomó un tiempo descubrir cómo parece funcionar sin modificar los archivos del sistema. Una documentación oficial sobre cómo usar correctamente pf en macOS sería excelente, pero no pude encontrar ninguna.

Primero, para mostrar todos los anclajes, debe usar sudo pfctl -vsA.

Su "anchor_rules.txt" parece estar mal. He colocado el mío en "/etc/pf.anchors/block". Al menos en macOS 12.0.1 tengo errores con sudo pfctl -vnf /etc/pf.anchors/block. Las reglas de trabajo se parecen a las siguientes. Pero no estoy seguro, si hace lo que crees que hace.

table <some-hosts> persist file "/etc/someHostsToBlock.txt"
block quick from any to <some-hosts>

Para cargar el ancla y habilitar pf, debe usar sudo pfctl -a 'com.apple/block' -f /etc/pf.anchors/block -e.

Para iniciar pf y cargar su anclaje personalizado en el arranque del sistema, debe usar launchd.

/Librería/LaunchDaemons/block.pfctl.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>Label</key>
    <string>block.pfctl</string>
    <key>WorkingDirectory</key>
    <string>/var/run</string>
    <key>Program</key>
    <string>/sbin/pfctl</string>
    <key>ProgramArguments</key>
    <array>
        <string>pfctl</string>
        <string>-a</string>
        <string>com.apple/block</string>
        <string>-f</string>
        <string>/etc/pf.anchors/block</string>
        <string>-e</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

sudo launchctl load /Library/LaunchDaemons/block.pfctl.plist