One place for hosting & domains

      Filter

      Cómo configurar Packet Filter (PF) en FreeBSD 12.1


      El autor seleccionó el COVID-19 Relief Fund para que reciba una donación como parte del programa Write for DOnations.

      Introducción

      El firewall posiblemente sea una de las líneas de defensa más importantes contra los ataques cibernéticos. La capacidad de configurar un firewall desde cero es una habilidad increíble que permite al administrador tomar el control de sus redes.

      Packet Filter (PF) es una renombrada aplicación de firewall que se mantiene upstream por el proyecto orientado a la seguridad OpenBSD. Se expresa de forma más expresiva como una herramienta de filtrado de paquetes, de ahí su nombre, y es conocida por su sintaxis sencilla, facilidad de uso y gran cantidad de funciones. PF es un firewall con estados por defecto, que almacena información sobre las conexiones en una tabla de estados a la que puede accederse con fines analíticos. PF es parte del sistema básico de FreeBSD y cuenta con el apoyo de una fuerte comunidad de desarrolladores. Aunque existen diferencias entre las versiones FreeBSD y OpenBSD de PF en relación con las arquitecturas del kernel, en general su sintaxis es similar. Dependiendo de su complejidad, los conjuntos de reglas comunes pueden modificarse para que funcionen en cualquier distribución con un esfuerzo relativamente pequeño.

      A través de este tutorial, creará un firewall desde cero en un servidor FreeBSD 12.1 con PF. Diseñará un conjunto de reglas básico que puede usarse como plantilla para futuros proyectos. También explorará algunas de las funciones avanzadas de PF, como la limpieza de paquetes, la prevención de ataques por fuerza bruta, la monitorización y el registro, y otras herramientas de terceros.

      Requisitos previos

      Antes de iniciar este tutorial, necesitará lo siguiente:

      • Un servidor FreeBSD 12.1 (ZFS o UFS). Puede usar nuestro tutorial Cómo comenzar con FreeBSD para configurar su servidor con su configuración deseada.
      • FreeBSD no tiene un firewall habilitado por defecto; la personalización es una característica propia de la filosofía de FreeBSD. Por tanto, cuando inicie su servidor por primera vez, necesitará protección temporal mientras que se configura PF. Si usa DigitalOcean, puede habilitar su firewall en la nube de inmediato tras iniciar el servidor. Consulte Inicio rápido del firewall de DigitalOcean para obtener instrucciones sobre cómo configurar un firewall en la nube. Si está usando otro proveedor en la nube, determine la ruta más rápida para la protección inmediata antes de comenzar. Sea cual sea el método que elija, su firewall temporal debe permitir solo el tráfico SSH entrante y puede permitir todos los tipos de tráfico saliente.

      Paso 1: Crear su conjunto de reglas preliminares

      Comenzará este tutorial esbozando un conjunto de reglas prelimnares que proporcionan protección básica y acceso a los servicios críticos de Internet. En este momento, tendrá un servidor FreeBSD 12.1 en ejecución con un firewall en la nube activo.

      Existen dos enfoques a la hora de crear un firewall: denegación por defecto y permiso por defecto. El enfoque denegación por defecto bloquea todo el tráfico, y solo permite lo que se especifica en una regla. El enfoque permiso por defecto, hace justo lo contrario: pasa todo el tráfico y solo bloquea lo que se especifica en una regla. Utilizará el enfoque denegación por defecto.

      Los conjuntos de reglas PF se escriben en un archivo de configuración llamado /etc/pf.conf, que también es su ubicación predeterminada. Está bien guardar este archivo en otro lugar siempre que se especifique en el archivo de configuración de /etc/rc.conf. Para este tutorial, usará la ubicación predeterminada.

      Inicie sesión en su servidor con su usuario no root:

      • ssh freebsd@your_server_ip

      A continuación, cree su archivo /etc/pf.conf:

      Nota: Si desea ver el conjunto de reglas básico completo en cualquier punto de este tutorial, puede consultar los ejemplos del paso 4 o del paso 8.

      PF filtra los paquetes según tres acciones principales: block, pass y match. Cuando se combinan con otras opciones, forman reglas. Se realiza una acción cuando un paquete cumple con el criterio especificado en una regla. Como puede esperar, las reglas pass y block aplicarán pass y block al tráfico, respectivamente. Una regla match realiza una acción sobre un paquete cuando encuentra un criterio de coincidencia, pero no lo pasa o bloquea. Por ejemplo, puede realizar la traducción de dirección de red (NAT) sobre un paquete que coincida sin pasarlo o bloquearlo, y permanecerá allí hasta que le diga que haga algo en otra regla, como dirigirlo a otro equipo o puerta de enlace.

      A continuación, añada la primera regla a su archivo /etc/pf.conf:

      /etc/pf.conf

      block all
      

      Esta regla bloquea todas las formas de tráfico en cada dirección. Ya que no especifica una dirección, los valores por defecto son in y out. Esta regla es legítima para una estación de trabajo local que deba estar aislada del mundo, pero es muy poco práctica y no funcionará en un servidor remoto porque no permite tráfico SSH. De hecho, si tuviese PF habilitado habría bloqueado usted mismo su acceso al servidor.

      Revise su archivo /etc/pf.conf para permitir el tráfico SSH con la siguiente línea resaltada:

      /etc/pf.conf

      block all
      pass in proto tcp to port 22
      

      Nota: De forma alternativa, puede usar el nombre del protocolo:

      /etc/pf.conf

      block all
      pass in proto tcp to port ssh
      

      Para mantener la consistencia, usaremos los números de puerto, a menos que exista una razón válida para no hacerlo. Hay una lista detallada de protocolos y sus números de puertos respectivos en el archivo /etc/services, que le aconsejamos que vea.

      PF procesa las reglas de forma secuencial de arriba a abajo, por tanto, su conjunto de reglas inicialmente bloquea todo el tráfico, pero luego lo pasa si el criterio de la siguiente línea se cumple, como en el caso del tráfico SSH.

      Ahora podrá permitir tráfico SSH en su servidor. No obstante, bloqueará toda forma de tráfico saliente. Esto es problemático por que no puede acceder a los servicios críticos desde Internet para instalar paquetes, actualizar sus ajustes de fecha y hora, etc.

      Para corregir esto, añada la siguiente regla resaltada al final de su archivo /etc/pf.conf:

      /etc/pf.conf

      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      

      Su conjunto de reglas ahora permite tráfico SSH, DNS, HTTP, NTP y HTTPS saliente, y bloquea todo el tráfico entrante (con la excepción de SSH). Coloca los números de puerto y protocolos entre corchetes, lo que forma una lista en la sinaxis de PF, permitiéndole añadir más números de puertos si es necesario. También añada una regla de paso para el protocolo UDP en los puertos 53 y 123 porque DNS y NTP a menudo alternan entre los protocolos TCP y UDP. Casi completó el conjunto de reglas preliminares. Solo debe agregar algunas reglas para lograr una funcionalidad básica.

      Complete el conjunto de reglas preliminares con las reglas resaltadas:

      Preliminary Ruleset /etc/pf.conf

      set skip on lo0
      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass out inet proto icmp icmp-type { echoreq }
      

      Guarde el archivo y ciérrelo.

      Creará la regla set skip para el dispositivo loopback porque no necesita filtrar tráfico y probablemente haga que se aplique rastreo en su servidor. Añada una regla pass out inet para el protocolo ICMP, que le permite usar la utilidad ping(8) para resolver problemas. La opción inet representa la familia de direcciones IPv4.

      ICMP es un protocolo de mensajería polivalente usado por los dispositivos de red para varios tipos de comunicaciones. La utilidad ping, por ejemplo, utiliza un tipo de mensaje conocido como echo request, que ha añadido a su lista icmp_type. Como precaución, solo permite los tipos de mensaje que necesita para evitar que dispositivos no permitidos se pongan en contacto con su servidor. A medida que sus necesidades aumentan, puede añadir más tipos de mensajes a su lista.

      Ahora tiene un conjunto de reglas en funcionamiento que proporciona funcionalidad básica para la mayoría de las máquinas. En la siguiente sección, vamos a confirmar que todo funcione correctamente habilitando PF y probando su conjunto de reglas preliminares.

      Paso 2: Probar su conjunto de reglas preliminares

      En este paso, probará su conjunto de reglas preliminares, realizará la transición de su firewall en la nube a su firewall de PF y permitirá que PF tenga todo el control. Activará su conjunto de reglas con la utilidad pfctl, que es la herramienta de línea de comandos integrada de PF, y el método principal para interactuar con PF.

      Los conjuntos de reglas PF no son otra cosa que archivos de texto, lo cual significa que no hay procedimientos delicados implicados en la carga de nuevos conjuntos de reglas. Puede cargar un nuevo conjunto de reglas y el anterior desaparecerá. En escasas ocasiones, si es necesario, existe la necesidad de eliminar un conjunto de reglas existente.

      FreeBSD utiliza una web de secuencias de comandos shell conocida como el sistema rc para administrar cómo se inician los servicios en el momento del arranque; especificamos esos servicios en varios archivos de configuración rc. Para los servicios globales como PF, utiliza el archivo /etc/rc.conf. Debido a que los archivos rc son críticos para el bienestar de un sistema de FreeBSD, no deberían editarse directamente. En su lugar, FreeBSD ofrece una utilidad de línea de comandos conocida como sysrc diseñada para ayudarle a editar estos archivo de forma segura.

      Habilitaremos PF usando la utilidad de línea de comandos sysrc:

      • sudo sysrc pf_enable="YES"
      • sudo sysrc pflog_enable="YES"

      Verifique estos cambios imprimiendo el contenido de su archivo /etc/rc.conf:

      Verá lo siguiente:

      Output

      pf_enable="YES" pflog_enable="YES"

      También habilitará el servicio pflog que, a su vez, permite que el demonio pflogd inicie sesión en PF. Trabajará con el inicio de sesión en un paso posterior.

      Se especifican dos servicios globales en su archivo /etc/rc.conf, pero estos no se inicializarán hasta que reinicie el servidor o los ponga en marcha manualmente. Reinicie el servidor de forma que pueda probar también su acceso SSH.

      Inicie PF reiniciando el servidor:

      La conexión se caerá. Dele unos minutos para actualizarse.

      Ahora, realice SSH de nuevo en el servidor:

      • ssh freebsd@your_server_ip

      Aunque inicializó sus servicios de PF, en realidad no cargó su conjunto de reglas /etc/pf.conf, lo cual significa que su firewall no está aún activo.

      Cargue el conjunto de reglas con pfctl:

      • sudo pfctl -f /etc/pf.conf

      Si no hay errores o mensajes, significa que su conjunto de reglas no tiene errores y el firewall está activo.

      Ahora que PF está en ejecución, puede desconectar su servidor de su firewall en la nube. Esto puede conseguirse en el panel de control de su cuenta de DigitalOcean eliminando su Droplet de su portal de firewall en la nube. Si está usando otro proveedor en la nube, asegúrese que lo que esté usando para la protección temporal esté desactivado. Es casi seguro que ejecutar dos firewalls en un servidor causará problemas.

      Por seguridad, reinicie su servidor de nuevo:

      Tras unos minutos, vuelva a hacer SSH en su servidor:

      • ssh freebsd@your_server_ip

      PF es ahora su firewall activo. Puede asegurarse de que esté ejecutándose accediendo a algunos datos con la utilidad pfctl.

      Vamos a ver algunas estadísticas y contadores con pfctl -si:

      Pasará los indicadores -si, que significa mostrar info. Esta es una de las muchas combinaciones de parámetros de filtros que puede usar con pfctl para analizar datos sobre la actividad de su firewall.

      Verá los siguientes datos tabulares (los valores variarán según el equipo):

      Output

      Status: Enabled for 0 days 00:01:53 Debug: Urgent State Table Total Rate current entries 5 searches 144 1.3/s inserts 11 0.1/s removals 6 0.1/s Counters match 23 0.2/s bad-offset 0 0.0/s fragment 0 0.0/s short 0 0.0/s normalize 0 0.0/s memory 0 0.0/s bad-timestamp 0 0.0/s congestion 0 0.0/s ip-option 0 0.0/s proto-cksum 0 0.0/s state-insert 0 0.0/s state-limit 0 0.0/s src-limit 0 0.0/s synproxy 0 0.0/s map-failed 0 0.0/s

      Debido a que acaba de activar su conjunto de reglas, no verá aún mucha información. Sin embargo, este resultado muestra que PF ya registró 23 reglas que coinciden, lo cual significa que se hallaron 23 coincidencias para los criterios de su conjunto de reglas. El resultado también confirma que su firewall está funcionando.

      Su conjunto de reglas también permite que el tráfico saliente acceda a algunos servicios críticos de Internet, incluyendo la utilidad ping.

      Vamos a comprobar la conectividad a Internet y el servicio DNS con ping contra google.com:

      Ya que ejecutó el indicador de recuento -c 3, verá tres respuestas de conexión correcta:

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Asegúrese de que puede acceder al repositorio pkgs con el siguiente comando:

      Si hay paquetes para actualizar, hágalo ahora.

      Si ambos servicios están funcionando, significa que su firewall está activo y puede continuar. Aunque su conjunto de reglas preliminares ofrece protección y funcionalidad, sigue siendo un conjunto de reglas elemental y podría tener algunas mejoras. En las secciones restantes, completará su conjunto de reglas básico y usará algunas de las funciones avanzadas de PF.

      Paso 3: Completar su conjunto de reglas básico

      En este paso, creará a partir del conjunto de reglas preliminares para completar su conjunto de reglas básico. Reorganizará algunas de sus reglas y trabajará con conceptos más avanzados.

      Incorporar macros y tablas

      En su conjunto de reglas preliminares, ha predefinido el código de todos sus parámetros en cada regla, es decir, los números de los puertos que forman las listas. Esto puede ser muy difícil de administrar en el futuro, dependiendo de la naturaleza de sus redes. Con fines organizativos, PF incluye macros, listas y tablas. Ya incluyó las listas directamente en sus reglas, pero también puede separarlas de ellas y asignarlas a una variable usando macros.

      Abra su archivo para transfefrir algunos de sus parámetros a macros:

      Ahora, añada el siguiente contenido a la parte superior del conjunto de reglas:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq }"
      . . .
      

      Modifique sus reglas SSH y ICMP anteriores con sus nuevas variables:

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 }
      . . .
      pass inet proto icmp icmp-type $icmp_types
      . . .
      

      Sus reglas SSH y ICMP anteriores ahora usan macros. Los nombres de variables se indican mediante la sintaxis del símbolo de dólar en PF. Asigna su interfaz vtnet0 a una variable con el mismo nombre solo como formalidad, lo que le ofrece la opción de cambiarle el nombre en el futuro si es necesario. Otros nombres comunes de variables para las interfaces de cara al público son $pub_if o $ext_if.

      A continuación, implementará una tabla, que es similar a un macro, pero diseñada para albergar grupos de direcciones IP. Crearemos una tabla para las direcciones IP no enrutables, que a menudo juegan un papel en los ataques de denegación de servicio (DOS). Puede usar las direcciones IP especificadas en RFC6890, que define registros de direcciones IP con fines especiales. Su servidor no debería enviar o recibir paquetes a o desde estas direcciones a través de la interfaz de cara al público.

      Cree esta tabla añadiendo el siguiente contenido directamente bajo el macro icmp_types:

      /etc/pf.conf

      . . .
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      . . .
      

      Ahora, añada sus reglas para la tabla <rfc6890> debajo de la regla set skip on lo0:

      /etc/pf.conf

      . . .
      set skip on lo0
      block in quick on egress from <rfc6890>
      block return out quick on egress to <rfc6890>
      . . .
      

      Aquí introduce la opción return, que complementa su regla block out. Esto soltará los paquetes y enviará un mensaje RST al host que intentó realizar esas conexiones, lo que es útil para analizar la actividad del host. Luego, se añade la palabra clave egress, que automáticamente encuentra las rutas predeterminadas de cualquier interfaz concreta. Este es normalmente un método más limpio de encontrar rutas predeterminadas, especialmente con redes complejas. La palabra clave quick ejecuta las reglas de inmediato sin considerar el resto del conjunto de reglas. Por ejemplo, si un paquete con una dirección IP ilógica intenta establecer conexión con el servidor, le convendrá cortar la conexión de inmediato y no tendrá motivos para ejecutar ese paquete a través del conjunto de reglas restante.

      Proteger sus puertos SSH

      Ya que su puerto SSH está abierto al público, está sujeto a ataques. Una de las señales de aviso más obvias de un atacante es las cantidades masivas de intentos de inicio de sesión. Por ejemplo, si la misma dirección IP intenta iniciar sesión en su servidor 10 veces en un segundo, puede asumir que no se hizo con manos humanas, sino con un software informático que está intentando averiguar su contraseña de inicio de sesión. Estos tipos de vulneraciones de seguridad sistemáticas a menudo se denominan ataques por fuerza bruta y normalmente tienen éxito si las contraseñas del servidor son inseguras.

      Advertencia: Recomendamos encarecidamente usar autenticación con clave pública en todos los servidores. Consulte el tutorial de DigitalOcean sobre la autenticación basada en claves.

      PF tiene funciones integradas para lidiar con ataques por fuerza bruta o de tipo similar. Con PF puede limitar el número de intentos de conexión simultáneos permitidos por un único host. Si un host supera esos límites, la conexión se detendrá y se le prohibirá el acceso al servidor. Para conseguir esto, usará el mecanismo de sobrecarga de PF, que mantiene una tabla de direcciones IP baneadas.

      Modifique su regla SSH anterior para limitar el número de conexiones simultáneas desde un host único como sigue:

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      . . .
      

      Añade la opción keep state que le permite definir el criterio de estado para la tabla de sobrecarga. Se pasa el parámetro max-src-conn para especificar el número de conexiones simultáneas permitidas desde un único host por segundo y el parámetro max-src-conn-rate para especificar el número de nuevas conexiones permitidas desde un único host por segundo. Especifica 15 conexiones para max-src-conn y 3 conexiones para max-src-conn-rate. Si un host supera estos límites, el mecanismo overload añade el IP de origen a la tabla <bruteforce>, que prohíbe las conexiones desde el servidor. Finalmente, la opción flush global cierra la conexión.

      Ha definido una tabla de sobrecarga en su regla SSH, pero no ha declarado esa tabla en su conjunto de reglas.

      Añada la tabla <bruteforce> debajo de la macro icmp_types:

      /etc/pf.conf

      . . .
      icmp_types = "{ echoreq }"
      table <bruteforce> persist
      . . .
      

      La palabra clave persist permite que exista una tabla vacía en el conjunto de reglas. Sin ella, PF indicará que no hay direcciones IP en la tabla.

      Estas medidas garantizan que su puerto SSH está protegido por un potente mecanismo de seguridad. PF le permite configurar soluciones rápidas para protegerse de formas de vulneraciones de seguridad catastróficas. En las siguientes secciones, dará los pasos para limpiar los paquetes a medida que llegan a su servidor.

      Limpiar su tráfico

      Nota: En las siguientes secciones se describen los fundamentos básicos de la suite de protocolos TCP/IP. Si planea crear aplicaciones web o redes, le convendrá dominar estos conceptos. Eche un vistazo al tutorial Introducción a la terminología, interfaces y protocolos de red de DigitalOcean.

      Debido a la complejidad de la suite de protocolos TCP/IP, y a la perseverancia de actores maliciosos, los paquetes a menudo llegan con discrepancias y ambigüedades como fragmentos de IP que se solapan, direcciones IP fraudulentas, y mucho más. Es imperativo que limpie su tráfico antes de que entre en el sistema. El término técnico para este proceso es normalización.

      Cuando los datos viajan por Internet, normalmente se desglosan en fragmentos más pequeños en el origen para acomodarse a los parámetros de transmisión del host de destino, donde se vuelven a montar en paquetes completos. Desafortunadamente, un intruso puede secuestrar este proceso de varias formas que van más allá del alcance de este tutorial. Sin embargo, con PF puede gestionar la fragmentación a través de una regla. PF incluye una palabra clave scrub que normaliza los paquetes.

      Añada la palabra clave scrub directamente antes de su regla block all:

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      block all
      . . .
      

      Esta regla realiza una limpieza de todo el tráfico entrante. Incluye la opción fragment reassemble para evitar el ingreso de fragmentos en el sistema. En vez de eso, se almacenan en la memoria caché hasta que se vuelvan a ensamblar en paquetes completos, lo cual significa que sus reglas de filtro solo tendrán que tratar con paquetes uniformes. También incluye la opción max-mss 1440 que representa el tamaño máximo del segmento de los paquetes TCP reesamblados, también conocida como carga útil. Especifica un valor de 1440 bytes, que consigue un equilibrio entre tamaño y rendimiento, dejando suficiente espacio para los encabezados.

      Otro aspecto importante de la fragmentación es un término conocido como la unidad de transmisión máxima (MTU). Los protocolos TCP/IP permiten a los dispositivos negociar tamaños de paquetes para realizar conexiones. El host de destino utiliza mensajes ICMP para informar a la IP de origen de su MTU, un proceso conocido como descubrimiento de ruta MTU. El tipo de mensaje ICMP específico es el destination unreachable (destino inalcanzable). Habilitará el descubrimiento de la ruta MTU añadiendo el tipo de mensaje unreach a su lista icmp_types.

      Usará la MTU predeterminada de su servidor de 1500 bytes, que puede determinarse con el comando ifconfig:

      Verá el siguiente resultado que incluye su MTU actual:

      Output

      vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> . . .

      Actualice la lista icmp_types para incluir el tipo de mensaje destination unreachable:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach}"
      . . .
      

      Ahora que tiene las políticas implementadas para gestionar la fragmentación, los paquetes que entren en su sistema serán uniformes y consistentes. Esto es deseable porque hay muchos dispositivos intercambiando datos en Internet.

      Ahora trabajará para evitar otro problema de seguridad conocido como spoofing de IP. Los atacantes a menudo cambian sus IP de origen para que parezca que residen en un nodo confiable en una organización. PF incluye una directiva antispoofing para gestionar las IP de origen falsificadas. Cuando se aplica a una interfaz específica, el antispoofing bloquea todo el tráfico de la red de esa interfaz (a menos que se origine desde esa interfaz). Por ejemplo, si aplica antispoofing a una interfaz que reside en 5.5.5.1/24, el tráfico desde la red de 5.5.5.0/24 no puede comunicarse con el sistema a menos que se origine desde esas interfaces.

      Añada el siguiente contenido resaltado para aplicar antispoofing a su interfaz vtnet0:

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in
      antispoof quick for $vtnet0
      block all
      . . .
      

      Guarde el archivo y ciérrelo.

      Esta regla de antispoofing establece que el tráfico de las redes vtnet0 solo puede pasar a través de la interfaz de vtnet0 o se desconectará rápidamente con la palabra clave quick. Los agentes maliciosos no podrán ocultarse en la red de vtnet0 y comunicarse con otros nodos.

      Para demostrar su regla de antispoofing, imprimirá su conjunto de reglas en la pantalla en su formato detallado. Las reglas en PF se escriben normalmente en formato acortado, pero la escritura de estas también es posible en formato detallado. Normalmente es poco práctico escribir las reglas de ese modo, pero para realizar pruebas puede ser útil.

      Imprima el contenido de /etc/pf.conf usando pfctl con el siguiente comando:

      • sudo pfctl -nvf /etc/pf.conf

      Este comando pfctl toma los indicadores -nvf, que imprimen el conjunto de reglas y lo prueba sin cargar nada; se conoce también como simulacro. Verá todo el contenido de /etc/pf.conf en su formato detallado.

      Verá algo similar al siguiente resultado en la parte antispoofing:

      Output

      . . . block drop in quick on ! vtnet0 inet from your_server_ip/20 to any block drop in quick on ! vtnet0 inet from network_address/16 to any block drop in quick inet from your_server_ip to any block drop in quick inet from network_address to any block drop in quick on vtnet0 inet6 from your_IPv6_address to any . . .

      Su regla antispoofing descubrió que es parte de la red your_server_ip/20. También detectó que (para el ejemplo de este tutorial) el servidor es parte de una red network_address/16, y tiene direcciones IPv6 adicionales. Antispoofing bloquea todas estas redes para que no se comuniquen con el sistema, a menos que su tráfico pase a través de la interfaz vtnet0.

      Su regla de antispoofing es la última adición a su conjunto de reglas básico. En el siguiente paso, iniciará estos cambios y realizará algunas pruebas.

      Paso 4: Probar su conjunto de reglas básico

      En este paso revisará y probará su conjunto de reglas básico para garantizar que todo funciona adecuadamente. Es mejor evitar implementar demasiadas reglas a la vez sin probarlas. Una buena práctica es empezar con las esenciales, aumentar de forma incremental y realizar una copia de seguridad del trabajo cuando se realizan cambios en la configuración.

      Este es su conjunto de reglas básico completo:

      Base Ruleset /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Asegúrese que su archivo /etc/pf.conf es idéntico al del conjunto de reglas básico completo aquí antes de continuar. Guarde el archivo y ciérrelo.

      Su conjunto de reglas básico completo le ofrece:

      • Una colección de macros que pueden definir servicios y dispositivos clave.
      • Políticas de higiene de la red para abordar la fragmentación de paquetes y las direcciones IP ilógicas.
      • Una estructura de filtrado de default deny que bloquea todo y permite solo lo que usted especifique.
      • Acceso SSH entrante con límites sobre el número de conexiones simultáneas que puede realizar un host.
      • Políticas de tráfico saliente que le proporciona acceso a algunos servicios críticos de Internet.
      • Las políticas ICMP que proporciona acceso a la utilidad ping y el descubrimiento de ruta MTU.

      Ejecute el siguiente comando pfctl para realizar un simulacro:

      • sudo pfctl -nf /etc/pf.conf

      Se pasan los indicadores -nf que le solicitan a pfctl ejecutar el conjunto de reglas sin cargarlo, lo que generará errores si algo incorrecto.

      Ahora, una vez que no se encuentren errores, cargue el conjunto de reglas:

      • sudo pfctl -f /etc/pf.conf

      Si no hay errores, significa que su conjunto de reglas básico está activo y funciona correctamente. Como antes en el tutorial, realizará algunas pruebas en su conjunto de reglas.

      Primero pruebe la conectividad a Internet y su servicio DNS:

      Verá lo siguiente:

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      A continuación, compruebe que puede llegar al repositorio pkgs:

      Una vez más, actualice los paquetes si es necesario.

      Finalmente, reinicie su servidor:

      Dé unos minutos a su servidor para que se reinicie. Completó e implementó su conjunto de reglas básico, lo cual es un paso significativo en términos de su progreso. Ahora estará listo para explorar algunas de las funciones avanzadas de PF. En el siguiente paso impedirá ataques de fuerza bruta.

      Paso 5: Gestionar su tabla de sobrecarga

      Con el tiempo, la tabla de sobrecarga <bruteforce> se llenará de direcciones IP maliciosas deberá limpiarse periódicamente. Es improbable que un atacante siga usando la misma dirección IP, de forma que no merece la pena almacenarlas en la tabla de sobrecarga durante largos periodos de tiempo.

      Usará pfctl para borrar manualmente todas las direcciones IP que hayan sido almacenadas en la tabla de sobrecarga durante 48 horas o más con el siguiente comando:

      • sudo pfctl -t bruteforce -T expire 172800

      Verá un resultado similar a este:

      Output

      0/0 addresses expired.

      Se pasan el indicador -t bruteforce, que significa fuerza bruta para tabla, y el indicador -T, que le permite ejecutar varios comandos integrados. En este caso, ejecuta el comando expire para borrar todas las entradas de -t bruteforce, con un valor de tiempo representado en segundos. Ya que está trabajando en un nuevo servidor, probablemente no haya direcciones IP en la tabla de sobrecarga aún.

      Esta regla funciona para correcciones rápidas, pero una solución más robusta sería automatizar el proceso con el programador de trabajo cron, de FreeBSD. Vamos a crear una secuencia de comandos shell que ejecute esta secuencia de comandos.

      Cree un archivo de secuencia de comandos shell en el directorio /usr/local/bin:

      • sudo vi /usr/local/bin/clear_overload.sh

      Añada el siguiente contenido a su secuencia de comandos shel:

      /usr/local/bin/clear_overload.sh

      #!/bin/sh
      
      pfctl -t bruteforce -T expire 172800
      

      Haga que el archivo sea ejecutable con el siguiente comando:

      • sudo chmod 755 /usr/local/bin/clear_overload.sh

      A continuación, creará un trabajo cron. Hay trabajos que se ejecutarán repetitivamente según el momento que especifique. Se utilizan comúnmente para las copias de seguridad o para cualquier proceso que deba ejecutarse al mismo tiempo cada día. Crea trabajos cron con los archivos crontab. Consulte las páginas principales para obtener más información sobre cron(8) y crontab(5).

      Cree un archivo crontab con usuario root con el siguiente comando:

      Ahora añada el siguiente contenido al archivo crontab:

      crontab

      # minute    hour    mday    month   wday    command
      
        *             0     *       *     *     /usr/local/bin/clear_overload.sh
      

      Guarde el archivo y ciérrelo.

      Nota: Alinee todos los valores con su tabla correspondiente para mayor legibilidad si no se alinean adecuadamente cuando añada contenido.

      Este trabajo cron ejecuta la secuencia de comandos clear_overload.sh cada día a medianoche, eliminando las direcciones UP que tienen una antigüedad de 48 horas de la tabla de sobrecarga <bruteforce>. A continuación, añadirá anclajes a su conjunto de reglas.

      Paso 6: Introducir anclajes a sus conjuntos de reglas

      En este paso, introducirá anclajes, que se usan para aprovisionar reglas al conjunto de reglas principal, ya sea manualmente o desde un archivo de texto externo. Los anclajes pueden contener fragmentos de reglas, tablas e incluso otros anclajes, conocidos como anclajes anidados. Demostraremos la forma en que funcionan los anclajes añadiendo una tabla a un archivo externo y proporcionándolo a su conjunto de reglas. Su tabla incluirá un grupo de hosts internos cuya conexión con el mundo exterior desee impedir.

      Cree un archivo llamado /etc/blocked-hosts-anchor:

      • sudo vi /etc/blocked-hosts-anchor

      Añada el siguiente contenido al archivo:

      /etc/blocked-hosts-anchor

      table <blocked-hosts> { 192.168.47.1 192.168.47.2 192.168.47.3 }
      
      block return out quick on egress from <blocked-hosts>
      

      Guarde el archivo y ciérrelo.

      Estas reglas declaran y definen la tabla <blocked-hosts>, y luego impiden que todas las direcciones IP de la tabla <blocked-hosts> accedan a los servicios del mundo exterior. Utiliza la palabra egress como método preferido para encontrar la ruta predeterminada, o salida a Internet.

      Aún deberá declarar el anclaje en su archivo /etc/pf.conf:

      Ahora, añada las siguientes reglas de anclajes después de la regla block all:

      /etc/pf.conf

      . . .
      block all
      anchor blocked_hosts
      load anchor blocked_hosts from "/etc/blocked-hosts-anchor"
      . . .
      

      Guarde el archivo y ciérrelo.

      Estas reglas declaran los blocked_hosts y cargan las reglas de anclajes en su conjunto de reglas principal desde el archivo /etc/blocked-hosts-anchor.

      Ahora, inicie estos cambios volviendo a cargar su conjunto de reglas con pfctl:

      • sudo pfctl -f /etc/pf.conf

      Si no hay errores, significa que no hay errores en su conjunto de reglas y sus cambios está activos.

      Utilice pfctl para verificar que su anclaje se está ejecutando:

      El indicador -s Anchors significa “mostrar anclajes ”. Verá el siguiente resultado:

      Output

      blocked_hosts

      La utilidad pfctl puede también analizar las reglas específicas de su anclaje con los indicadores -a y -s:

      • sudo pfctl -a blocked_hosts -s rules

      Verá lo siguiente:

      Output

      block return out quick on egress from <blocked-hosts> to any

      Otra función de los anclajes es que permiten añadir reglas bajo demanda sin tener que volver a carga el conjunto de reglas. Esto puede ser útil para realizar pruebas, reparaciones rápidas, emergencias, etc. Por ejemplo, si un host interno está actuando de forma peculiar y desea impedir que realice conexiones salientes, tiene un anclaje puesto que le permite intervenir rápidamente desde la línea de comandos.

      Vamos a abrir /etc/pf.conf y añadir otro anclaje:

      Llamará al delmitador rogue_hosts y lo dispondrá en la regla block all:

      /etc/pf.conf

      . . .
      block all
      anchor rogue_hosts
      . . .
      

      Guarde el archivo y ciérrelo.

      Para iniciar estos cambios, vuelva a cargar el conjunto de reglas con pfctl:

      • sudo pfctl -f /etc/pf.conf

      De nuevo, utilice pfctl para verificar que el anclaje se esté ejecutando:

      Esto generará el siguiente resultado:

      Output

      blocked_hosts rogue_hosts

      Ahora que el anclaje se está ejecutando, podrá añadirle reglas en cualquier momento. Pruebe esto añadiendo la siguiente regla:

      • sudo sh -c 'echo "block return out quick on egress from 192.168.47.4" | pfctl -a rogue_hosts -f -'

      Esto invoca el comando echo y el contenido de su cadena, que luego se canaliza a la utilidad pfctl con el símbolo |, donde se procesa en otra regla de anclaje. Puede abrir otra sesión shell con el comando sh-c. Esto es porque establece un canal entre dos procesos, pero necesita privilegios sudo para que persistan en toda la secuencia de comandos. Existen varias formas de resolver esto; aquí abre un proceso shell adicional con privilegios sudo usando sudo sh -c.

      Ahora, utilice pfctl de nuevo para verificar que estas reglas está activas:

      • sudo pfctl -a rogue_hosts -s rules

      Esto generará el siguiente resultado:

      Output

      block return out quick on egress inet from 192.168.47.4 to any

      El uso de anclajes es completamente circunstancial y a menudo subjetivo. Igual que cualquier otra función, existen pros y contras a la hora de usar los anclajes. Algunas aplicaciones, como blacklistd interactúan con anclajes debido a su diseño. A continuación, centrará la atención en el registro con PF, que es un aspecto crítico de seguridad de la red. Su firewall no es útil si no puede ver lo que hace.

      Paso 7: Registro de la actividad de su firewall

      En este paso, trabajará con el registro de PF, que se gestiona mediante una pseudo interfaz llamada pflog. El registro se habilita en el momento del inicio añadiendo pflog_enabled=YES al archivo /etc/rc.conf, procedimiento que completó en el paso 2. Esto habilita el demonio pflogd que abre una interfaz llamada pflog0 y escribe registros en formato binario en un archivo llamado /var/log/pflog. Los registros pueden analizarse en tiempo real desde la interfaz, o ser leídos desde el archivo /var/log/pflog con la utilidad tcpdump(8).

      Primero acceda a algunos registros desde el archivo /var/log/pflog:

      • sudo tcpdump -ner /var/log/pflog

      Pasa los indicadores -ner que formatean el resultado para mejorar la legibilidad, y también especifica un archivo desde el que leer, que en su caso es /var/log/pflog.

      Verá lo siguiente:

      Output

      reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)

      En estas etapas tempranas es posible que no haya datos en el archivo /var/log/pflog. En poco tiempo, el archivo de registro comenzará a ampliarse.

      También puede ver los registros en tiempo real desde la interfaz pflog0 usando el siguiente comando:

      Pasa los indicadores -nei, que también formatean el resultado para mejorar la legibilidad, pero esta vez especifica una interfaz, que en su caso es pflog0.

      Verá lo siguiente:

      Output

      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes

      Ahora verá las conexiones en tiempo real. Si es posible, haga ping a su servidor desde un equipo remoto y verá cómo se producen las conexiones. El servidor permanecerá en este estado hasta que salga de él.

      Para salir de este estado y volver a la línea de comandos, pulse CTRL + Z.

      Hay mucha información en Internet sobre tcpdump(8). También se puede acceder al sitio web oficial.

      Acceder a los archivos de registro desde pftop

      La utilidad pftop es una herramienta que permite ver rápidamente la actividad del firewall en tiempo real. Su nombre se ve influenciado por la conocida utilidad top de Unix.

      Para usarlo, deberá instalar el paquete pftop:

      Ahora ejecute el binario pftop:

      Esto generará el siguiente resultado (sus IP serán diferentes):

      Output

      PR DIR SRC DEST STATE AGE EXP PKTS BYTES tcp In 251.155.237.90:27537 157.225.173.58:22 ESTABLISHED:ESTABLISHED 00:12:35 23:59:55 1890 265K tcp In 222.186.42.15:25884 157.225.173.58:22 TIME_WAIT:TIME_WAIT 00:01:25 00:00:06 22 3801 udp Out 157.245.171.59:4699 67.203.62.5:53 MULTIPLE:SINGLE 00:00:14 00:00:16 2 227

      Crear interfaces de registro adicionales

      Como cualquier otra interfaz, pueden crearse múltiples interfaces de registro y nombrarse con un archivo /etc/hostname. Es posible que encuentre esto útil con fines organizativos, por ejemplo, si desea registrar ciertos tipos de actividad por separado.

      Cree una interfaz de registro adicional llamada pflog1:

      • sudo vi /etc/hostname.pflog1

      Añada el siguiente contenido al archivo /etc/hostname.pflog1:

      /etc/hostname.pflog1

      up
      

      Ahora, habilite el dispositivo en el momento del inicio en su archivo /etc/rc.conf:

      • sudo sysrc pflog1_enable="YES"

      Puede monitorizar y registrar la actividad de su firewall. Esto le permite ver quién establece conexiones con su servidor y los tipos de conexiones establecidas.

      A lo largo de este tutorial, ha incorporado algunos conceptos avanzados a su conjunto de reglas de PF. Solo es necesario implementar las funciones avanzadas a medida que las necesite. Dicho esto, en el siguiente paso volverá al conjunto de reglas básico.

      Paso 8: Restablecer el conjunto de reglas básico

      En esta sección final, restablecerá su conjunto de reglas básico. Este es un paso rápido que le llevará de nuevo a un estado minimalista de la funcionalidad.

      Abra el conjunto de reglas básico con el siguiente comando:

      Elimine el conjunto de reglas actual en su archivo y sustitúyalo con el siguiente conjunto de reglas básico.

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Guarde el archivo y ciérrelo.

      Vuelva a cargar el conjunto de reglas:

      • sudo pfctl -f /etc/pf.conf

      Si no hay errores en el comando, significa que no hay errores en su conjunto de reglas y su firewall está funcionando correctamente.

      También deberá desactivar la interfaz pflog1 que ha creado. Ya que es posible que no sepa si lo necesita aún, puede deshabilitar pflog1 con la utilidad sysrc:

      • sudo sysrc pflog1_enable="NO"

      Ahora, elimine el archivo /etc/hostname.pflog1 del directorio /etc:

      • sudo rm /etc/hostname.pflog1

      Antes de salir, reinicie el servidor una vez más para garantizar que todos sus cambios estén activos y sean persistentes:

      Espere unos minutos antes de iniciar sesión en su servidor.

      Opcionalmente, si desea implementar PF con un servidor web, el siguiente es un conjunto de reglas para este escenario. Este conjunto de reglas es un punto de inicio suficiente para la mayoría de las aplicaciones web.

      Simple Web Server Ruleset

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <webcrawlers> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass in on $vtnet0 proto tcp to port { 80 443 } 
          keep state (max-src-conn 45, max-src-conn-rate 9/1, 
              overload <webcrawlers> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Esto crea una tabla de sobrecarga llamada <webcrawlers>, que tiene una política de sobrecarga más liberal que su puerto SSH según los valores de max-src-conn 45 y max-src-conn-rate. Esto es porque no todas las sobrecargas corresponden a agentes maliciosos. También pueden originarse de netbots no maliciosos, de forma que evite medidas de seguridad excesivas en los puertos 80 y 443. Si decide implementar el conjunto de reglas del servidor web, deberá añadir la tabla <webcrawlers> a /etc/pf.conf y borrar las IP de la tabla periódicamente. Consulte el Paso 5 para hacer esto.

      Conclusión

      A través de este tutorial, configuró PF en FreeBSD 12.1. Ahora dispondrá de un conjunto de reglas básico que puede servir como punto de inicio para todos sus proyectos de FreeBSD. Para obtener más información sobre PF, eche un vistazo a las páginas man de pf.conf(5).

      Visite nuestra página sobre el tema FreeBSD para ver más tutoriales y Preguntas y respuestas.



      Source link

      Настройка Packet Filter (PF) в FreeBSD 12.1


      Автор выбрал COVID-19 Relief Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Брандмауэр, вероятно, является одной из наиболее важных линий защиты от кибератак. Способность настроить брандмауэр с нуля — это очень важный навык, который позволяет администратору получить контроль над своими сетями.

      Packet Filter (PF) — это известный брандмауэр, поддерживаемый в рамках проекта OpenBSD для обеспечения безопасности. Если быть более точным, это инструмент фильтрации пакетов, как видно из названия, который известен простым синтаксисом, удобством для пользователей и обширным функционалом. PF — это по умолчанию хранящий состояние брандмауэр, помещающий информацию о подключениях в таблице состояния, которую можно использовать в аналитических целях. PF — это часть базовой системы FreeBSD, которая поддерживается активным сообществом разработчиков. Хотя между версиями PF во FreeBSD и OpenBSD существуют различия, связанные с разной архитектурой ядра, в целом они используют один синтаксис. В зависимости от сложности общий набор правил можно изменить, чтобы работать с любым дистрибутивом с минимальными усилиями.

      В этом обучающем руководстве мы выполним сборку брандмауэра с нуля на сервере FreeBSD 12.1 с помощью PF. Вы создадите базовый набор правил, который можно использовать в качестве шаблона для будущих проектов. Также вы познакомитесь с рядом продвинутых функций PF, таких как гигиена пакетов, предотвращение атак brute force, мониторинг и логирование, а также рядом сторонних инструментов.

      Предварительные требования

      Перед началом выполнения этого обучающего руководства вам потребуется следующее:

      • Сервер FreeBSD 12.1 с 1 ГБ памяти (ZFS или UFS). Вы можете воспользоваться нашим руководством по началу работы с FreeBSD для настройки вашего сервера согласно предпочитаемой конфигурации.
      • FreeBSD не имеет активированного по умолчанию брандмауэра, кастомизация — это один из важнейших принципов FreeBSD. Таким образом, при первом запуске вашего сервера вам потребуется временная защита, пока будет выполняться настройка PF. Если вы используете DigitalOcean, вы можете активировать облачный брандмауэр сразу после запуска сервера. Инструкции по настройке облачного брандмауэра см. в кратком руководстве по брандмауэру DigitalOcean. Если вы используете услуги другого поставщика облачных решений, воспользуйтесь самым быстрым способом для немедленной защиты перед началом работы. Какой бы метод вы ни выбрали, ваш временный брандмауэр должен разрешать только входящий трафик SSH и может разрешать любой исходящий трафик.

      Шаг 1 — Создание предварительного набора правил

      Начните выполнение данного руководства, создав черновик предварительного набора правил, который обеспечивает базовую защиту и доступ к важнейшим услугам через Интернет. В настоящий момент у вас есть работающий сервер FreeBSD 12.1 с активным облачным брандмауэром.

      Существует два подхода к созданию брандмауэра: отказ по умолчанию и разрешение по умолчанию. При использовании отказа по умолчанию блокируется весь трафик, а пропускается только трафик, указанный в правиле. Подход с разрешением по умолчанию делает противоположное: он пропускает весь трафик, блокируя только то, что указано в правиле. Вы будете использовать подход с отказом по умолчанию.

      Набор правил PF записывается в файл конфигурации /etc/pf.conf, который также является местом его расположения по умолчанию. Вы можете хранить этот файл в другом месте, если это указано в файле конфигурации /etc/rc.conf. В этом руководстве вы будете использовать местоположение по умолчанию.

      Войдите на сервер с пользователем non-root user:

      • ssh freebsd@your_server_ip

      Далее создайте ваш файл /etc/pf.conf:

      Примечание. Если вы захотите посмотреть полный базовый набор правил в любой момент при выполнении руководства, см. примеры в шаге 4 и шаге 8.

      PF фильтрует пакеты в соответствии с тремя основными действиями: block, pass и match. В сочетании с другими опциями они образуют правила. Действие выполняется, когда пакет соответствует критериям, указанным в правиле. Как вы можете ожидать, правила pass и block будут пропускать и блокировать трафик. Правило match выполняет действие с пакетом при обнаружении соответствующих критериев, но не пропускает или блокирует его. Например, оно может выполнять преобразование сетевых адресов (NAT) для соответствующего пакета, не блокируя или пропуская его, пакет останется на месте, пока вы не скажете ему сделать что-то в другом правиле, например, направите его на другой сервер или шлюз.

      Далее добавьте первое правило в ваш файл /etc/pf.conf:

      /etc/pf.conf

      block all
      

      Это правило блокирует все формы трафика в каждом направлении. Поскольку направление на указано, по умолчанию блокируется входящий и исходящий трафик. Данное правило является законным для локальных рабочих станций, которые необходимо изолировать от мира, однако оно во многом не пригодно к использованию на практике и не будет работать на удаленном сервере, поскольку оно запрещает трафик SSH. На деле, если бы вы активировали PF, то могли бы заблокировать для себя доступ к серверу.

      Измените ваш файл /etc/pf.conf, чтобы разрешить трафик SSH в следующих выделенных строках:

      /etc/pf.conf

      block all
      pass in proto tcp to port 22
      

      Примечание. В качестве альтернативы вы можете использовать имя протокола:

      /etc/pf.conf

      block all
      pass in proto tcp to port ssh
      

      Для единообразия мы будем использовать номера портов, если нет веских причин не делать этого. Существует подробный список протоколов и соответствующих номеров портов в файле /etc/services, который мы рекомендуем просмотреть.

      PF выполняет правила последовательно сверху вниз, поэтому ваш текущий набор правил на начальном этапе блокирует весь трафик, но затем пропускает его, если он отвечает критериям на следующей линии, что в данном случае соответствует трафику SSH.

      Теперь вы можете подключиться к серверу через SSH, но вы все равно можете блокировать все формы исходящего трафика. Это проблема, поскольку вы не можете получить доступ к критическим сервисам из Интернета для установки пакетов, обновления настроек времени и т. д.

      Для устранения этой проблемы добавьте следующее выделенное правило в конце файла /etc/pf.conf:

      /etc/pf.conf

      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      

      Теперь ваш набор правил разрешает исходящий трафик SSH, DNS, HTTP, NTP и HTTPS, а также блокирует весь входящий трафик (за исключением SSH). Вы размещаете номера портов и протоколы в фигурные скобки, которые образуют список в синтаксисе PF, что позволяет добавлять дополнительные номера портов, если это потребуется. Также вы добавляете разрешающее правило для протокола UDP на портах 53 и 123, поскольку DNS и NTP часто переключаются между протоколами TCP и UDP. Вы почти закончили работу с предварительным набором правил, осталось только добавить несколько правил для получения базового функционала.

      Добавьте в предварительный набор правил следующие выделенные правила:

      Preliminary Ruleset /etc/pf.conf

      set skip on lo0
      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass out inet proto icmp icmp-type { echoreq }
      

      Сохраните и закройте файл.

      Вы создали правило set skip для устройства закольцовывания, поскольку ему не требуется фильтр трафика, а такая фильтрация может вызывать заметное замедление работы сервера. Вы добавили правило pass out inet​​​ для протокола ICMP, которое позволяет использовать утилиту ping(8) для поиска и устранения проблем. Опция inet представляет семейство адресов IPv4.

      ICMP — это многоцелевой протокол обмена сообщениями, используемый сетевыми устройствами для различных видов коммуникации. Например, утилита ping использует сообщения, известные как echo request, которые вы добавили в список icmp_type. В качестве меры предосторожности вы разрешаете только типы сообщений, которые вам нужны для предотвращения контакта нежелательных устройств с вашим сервером. По мере роста ваших потребностей вы можете добавить в список новые типы сообщений.

      Теперь у вас есть рабочий набор правил, который обеспечивает базовый функционал для большинства серверов. В следующем разделе мы убедимся, что все работает корректно, активировав PF и протестировав ваш предварительный набор правил.

      Шаг 2 — Тестирование вашего предварительного набора правил

      На этом шаге мы протестируем ваш предварительный набор правил и выполним переход с облачного брандмауэра на ваш брандмауэр PF, позволив PF взять полный контроль над ситуацией. Вы активируете ваш набор правил с помощью утилиты pfctl, которая представляет собой встроенный инструмент командной строки PF и основной метод взаимодействия с PF.

      Наборы правил PF являются простым текстовым файлом, что означает, что при загрузке новых наборов правил не потребуются сложные процедуры. После загрузки нового набора правил старый исчезает. Очень редко, если это вообще возможно, требуется удалить существующий набор правил.

      FreeBSD использует сеть shell-скриптов, известную как система rc, чтобы управлять запуском служб во время загрузки, а мы укажем эти службы в разных файлах конфигурации rc. Для таких глобальных служб, как PF, вы будете использовать файл /etc/rc.conf. Поскольку файлы rc имеют критическое значение для нормальной работы системы FreeBSD, они не должны редактироваться напрямую. Вместо этого FreeBSD предоставляет утилиту командной строки sysrc, которая предназначена для безопасного редактирования этих файлов.

      Давайте активируем PF, используя утилиту командной строки sysrc:

      • sudo sysrc pf_enable="YES"
      • sudo sysrc pflog_enable="YES"

      Проверьте внесение изменений, отобразив содержимое вашего файла /etc/rc.conf:

      Результат будет выглядеть следующим образом:

      Output

      pf_enable="YES" pflog_enable="YES"

      Также вы активируете службу pflog, которая, в свою очередь, активирует демон pflogd для ведения журнала PF. Вы поработаете с журналами позже.

      Вы должны указать две глобальные службы в вашем файле /etc/rc.conf, но они не инициализируются, пока вы не перезагрузите сервер или не запустите их вручную. Перезапустите сервер, чтобы протестировать ваш доступ через SSH.

      Запустите PF, перезапустив сервер:

      Подключение будет сброшено. Подождите несколько минут, пока не закончится процесс обновления.

      Теперь снова подключитесь по SSH к серверу:

      • ssh freebsd@your_server_ip

      Хотя ваши службы PF уже проинициализированы, вы еще не загрузили ваш набор правил /etc/pf.conf, что означает, что ваш брандмауэр еще не активен.

      Загрузите набор правил с помощью pfctl:

      • sudo pfctl -f /etc/pf.conf

      Если ошибки или сообщения отсутствуют, это означает, что ваш набор правил не имеет ошибок, а брандмауэр активен.

      Теперь, когда PF запущен, вы можете отключить ваш сервер от облачного брандмауэра. Это можно сделать в панели управления вашей учетной записи DigitalOcean, удалив дроплет из портала облачного брандмауэра. Если вы используете другого поставщика облачных услуг, убедитесь, что все, что вы использовали для временной защиты, отключено. Запуск двух разных брандмауэров на сервере практически точно вызовет проблемы.

      В дополнение к этому перезагрузите ваш сервер еще раз:

      Через несколько минут подключитесь через SSH к вашему серверу:

      • ssh freebsd@your_server_ip

      Теперь PF — ваш действующий брандмауэр. Чтобы проверить, что он запущен, вы можете попробовать получить доступ к данным с помощью утилиты pfctl.

      Давайте рассмотрим некоторые статистические данные и счетчики с помощью pfctl -si​​​:

      Вы передаете флаги -si, которые означают show info, т. е. показать информацию. Это одна из многочисленных комбинаций параметров фильтра, которую вы можете использовать с pfctl для парсинга данных об активности брандмауэра.

      Вы увидите следующие данные в таблице (значения будут варьироваться в зависимости от сервера):

      Output

      Status: Enabled for 0 days 00:01:53 Debug: Urgent State Table Total Rate current entries 5 searches 144 1.3/s inserts 11 0.1/s removals 6 0.1/s Counters match 23 0.2/s bad-offset 0 0.0/s fragment 0 0.0/s short 0 0.0/s normalize 0 0.0/s memory 0 0.0/s bad-timestamp 0 0.0/s congestion 0 0.0/s ip-option 0 0.0/s proto-cksum 0 0.0/s state-insert 0 0.0/s state-limit 0 0.0/s src-limit 0 0.0/s synproxy 0 0.0/s map-failed 0 0.0/s

      Поскольку вы только что активировали набор правил, вы не увидите большое количество информации. Однако этот вывод показывает, что PF уже записал 23 совпавших правила. Это означает, что критерии набора правил были использованы 23 раза. Вывод также подтверждает, что ваш брандмауэр работает.

      Ваш набор правил также разрешает исходящий трафик для доступа к ряду критически важных сервисов в Интернете, включая утилиту ping.

      Давайте проверим подключение через Интернет и службу DNS с помощью ping для google.com:

      Поскольку вы использовали флаг -c 3 при запуске, вы увидите три успешные попытки подключения:

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Убедитесь, что у вас есть доступ к репозиторию pkgs с помощью следующей команды:

      Если имеются какие-либо обновления для пакетов, выполните обновление.

      Если обе службы работают, это означает, что ваш брандмауэр работает, и вы можете двигаться дальше. Хотя ваш предварительный набор правил обеспечивает защиту и необходимый функционал, это по-прежнему очень простой набор, который может быть улучшен. В остальных разделах мы будем дополнять базовый набор правил и используем некоторые продвинутые функции PF.

      Шаг 3 — Дополнение базового набора правил

      На этом шаге мы разберем наш предварительный набор правил, чтобы дополнить базовый набор правил. Вы измените некоторые правила и поработаете с более продвинутыми понятиями.

      Включение макросов и таблиц

      В предварительном наборе правил вы жестко задали все параметры для каждого правила, в нашем случае это номера портов, которые составляют список. В будущем такая конфигурация может стать неуправляемой, в зависимости от природы ваших сетей. Для большей организованности PF включает макросы, списки и таблицы. Вы уже включили списки прямо в ваши правила, но вы также можете отделить их от правил и назначить переменную с помощью макросов.

      Откройте ваш файл, чтобы передать некоторые параметры в макрос:

      Теперь добавьте в самый верх набора правил следующее содержание:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq }"
      . . .
      

      Измените ваши предыдущие правила SSH и ICMP, указав новые переменные:

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 }
      . . .
      pass inet proto icmp icmp-type $icmp_types
      . . .
      

      Ваши предыдущие правила SSH и ICMP теперь используют макросы. Имена переменных отображаются с помощью принятого в PF синтаксиса со знаком доллара. Вы назначаете интерфейс vtnet0 для переменной с тем же именем только в качестве формальности, что позволяет переименовать ее в будущем, если возникнет такая потребность. Другие распространенные имена переменных для общедоступных интерфейсов включают $pub_if​​​ или $ext_if.

      Далее вы должны имплементировать таблицу, которая похожа на макрос, но предназначена для хранения групп IP-адресов. Давайте создадим таблицу для немаршрутизуемых IP-адресов, которые часто используются в DoS-атаках. Вы можете использовать IP-адреса, указанные в RFC6890, где определяются реестры IP-адресов особенного назначения. Ваш сервер не должен посылать пакеты на эти адреса или получать пакеты от этих адресов через общедоступные интерфейсы.

      Создайте эту таблицу, добавив следующее содержание сразу после макроса icmp_types:

      /etc/pf.conf

      . . .
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      . . .
      

      Теперь добавьте ваши правила для таблицы <rfc6890> под правилом set skip on lo0:

      /etc/pf.conf

      . . .
      set skip on lo0
      block in quick on egress from <rfc6890>
      block return out quick on egress to <rfc6890>
      . . .
      

      Здесь вы добавляете опцию return, которая дополняет ваше правило block out​​​. Эта команда отклоняет пакеты и отправляет сообщение RST на хост, который попытался установить эти подключения, что полезно для анализа активности хоста. Затем добавьте ключевое слово egress, которое автоматически находит маршруты по умолчанию для любых заданных интерфейсов. Обычно это более простой метод поиска маршрутов по умолчанию, особенно для сложных сетей. Ключевое слово quick выполняет правила немедленно без учета остальной части набора правил. Например, если пакет с нелогичными IP-адресами попытается подключиться к серверу, вы можете захотеть немедленно сбросить соединение, и у вас не будет причин пропускать этот пакет через остальную часть набора правил.

      Защита портов SSH

      Поскольку ваш порт SSH общедоступен, он может стать объектом атаки. Один из самых очевидных признаков нападения — это массовые попытки входа в систему. Например, если один IP-адрес пытается выполнить вход на ваш сервер 10 раз за секунду, вы можете предположить, что это дело рук не человека, а компьютерного программного обеспечения, которое пытается взломать ваш пароль входа в систему. Такие виды систематических эксплойтов часто называют атаками brute force​​​, и обычно они являются успешными, если у сервера слабый пароль.

      Предупреждение. Мы настоятельно рекомендуем использовать аутентификацию по открытому ключу на всех ваших серверах. Ознакомьтесь с руководством DigitalOcean по аутентификации на базе ключей.

      PF имеет встроенные функции для противодействия атакам brute force и другим похожим атакам. С помощью PF вы можете ограничить количество попыток одновременного подключения с одного хоста. Если хост превышает эти ограничения, соединение будет сброшено, а сам хост будет запрещен на сервере. Для этого вы можете использовать механизм устранения перегрузки PF, который поддерживает таблицу запрещенных IP-адресов.

      Измените предыдущее правило SSH, чтобы ограничить количество одновременных подключений с одного хоста, следующим образом:

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      . . .
      

      Вы добавили опцию keep state, которая позволяет определить критерии состояния для таблицы устранения перегрузки: Вы передаете параметр max-src-conn, чтобы указать разрешенное количество одновременных подключений с одного хоста в секунду, а также параметр max-src-conn-rate, чтобы указать разрешенное количество новых подключений с одного хоста в секунду. Вы указали 15 подключений для max-src-conn и 3 подключения для max-src-conn-rate. Если хост превышает эти ограничения, механизм устранения перегрузки добавляет IP-адрес источника в таблицу <bruteforce>, которая запрещает его использование на сервере. Наконец, опция flush global немедленно сбрасывает подключение.

      Вы определили таблицу устранения перегрузки в вашем правиле SSH, но не объявили саму таблицу в вашем наборе правил.

      Добавьте таблицу <bruteforce> под макросом icmp_types:

      /etc/pf.conf

      . . .
      icmp_types = "{ echoreq }"
      table <bruteforce> persist
      . . .
      

      Ключевое слово persist позволяет создавать пустую таблицу в наборе правил. Без него PF будет жаловаться, что в таблице нет IP-адресов.

      Эти меры гарантируют защиту вашего порта SSH с помощью мощного механизма безопасности. PF позволяет настраивать быстрые решения для защиты от катастрофических форм атак. В следующих разделах мы выполним действия для очистки пакетов, которые поступают на сервер.

      Очистка вашего трафика

      Примечание. В следующих разделах описываются базовые принципы работы протокола TCP/IP. Если вы планируете создавать веб-приложения или работать с сетью, вам будет полезно знать эти вещи. Ознакомьтесь с руководством DigitalOcean Знакомство с сетевой терминологией, интерфейсами и протоколами.

      Из-за сложности протокола TCP/IP, а также действий злоумышленников пакеты часто поступают с отклонениями и неопределенностями, например с наложением фрагментов IP-адресов, поддельными IP-адресами и многим другим. Поэтому необходимо очищать трафик, прежде чем он поступит в систему. Технический термин, используемый для обозначения этого процесса, — нормализация.

      Когда данные передаются через Интернет, они обычно разбиваются на небольшие фрагменты в источнике, чтобы отвечать параметрам передачи целевого хоста, где эти фрагменты пересобираются в полные пакеты. К сожалению, злоумышленники могут взламывать этот процесс большим количеством способов, описание которых выходит за пределы данного руководства. Кроме того, с PF вы можете управлять фрагментацией с помощью одного правила. PF имеет ключевое слово scrub, с помощью которого производится нормализация пакетов.

      Добавьте ключевое слово scrub непосредственно перед правилом block all​​​:

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      block all
      . . .
      

      Это правило применяется для очищения входящего трафика. Вы добавили опцию fragment reassemble, которая предотвращает попадание фрагментов в систему. Вместо этого они кэшируются в памяти, пока не будут пересобраны в полные пакеты, что означает, что правилам фильтра придется работать только с единообразными пакетами. Также вы должны включить опцию max-mss 1440, которая представляет максимальный размер сегмента пересобираемых пакетов TCP, также известный как полезная нагрузка. Вы указываете значение 1440 байт, которое отражает баланс между размером и производительностью, оставляя достаточное пространство для заголовков.

      Еще один важный аспект фрагментации — это термин, известный как максимальный передаваемый модуль данных (MTU). Протоколы TCP/IP позволяют устройствам обсуждать размеры пакетов для установления подключений. Целевой хост использует сообщения ICMP для информирования IP-адреса источника о своем MTU. Данный процесс известен как открытие пути MTU. Конкретный тип сообщения ICMP — destination unreachable. Вы должны активировать открытие пути MTU, добавив тип сообщения unreach в ваш список icmp_types.

      Вы будете использовать стандартное значение MTU в 1500 байт, которое можно определить с помощью команды ifconfig:

      Вы увидите следующий вывод, который включает ваше текущее значение MTU:

      Output

      vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> . . .

      Обновите список icmp_types, чтобы добавить тип сообщения destination unreachable​​​:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach}"
      . . .
      

      Теперь, когда у вас есть политики для обработки фрагментации, пакеты, которые попадают в вашу систему, будут единообразными и согласованными. Это желательно, поскольку огромное количество устройств обмениваются данными через Интернет.

      Теперь вы можете заняться предотвращением другой опасности, известной как подмена IP (спуфинг). Злоумышленники часто изменяют IP-адрес источника, чтобы могло показаться, что он находится на доверенном узле внутри организации. PF включает директиву antispoofing для обработки подмененных IP-адресов источника. При применении для конкретного интерфейса (интерфейсов) эта директива блокирует весь трафик из сети данного интерфейса (если его источником не является сам интерфейс). Например, если вы примените директиву antispoofing для интерфейса (интерфейсов) с адресом 5.5.5.1/24, весь трафик из сети 5.5.5.0/24 не будет приниматься системой, если только его источником не является этот интерфейс (интерфейсы).

      Добавьте следующее выделенное содержание, чтобы применить antispoofing для интерфейса vtnet0:

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in
      antispoof quick for $vtnet0
      block all
      . . .
      

      Сохраните и закройте файл.

      Это правило для борьбы с подменой указывает, что весь трафик из сети (сетей) vtnet0 может передаваться только через интерфейс vtnet0, либо он будет немедленно отклонен с помощью ключевого слова quick. Злоумышленники не смогут скрыться в сети vtnet0 и взаимодействовать с другими узлами.

      Для демонстрации вашего правила для борьбы с подменой IP-адресов вы можете вывести ваш набор правил на экран в подробном виде. Правила в PF обычно написаны в сокращенной форме, но также они могут быть написаны в подробной форме. Как правило, не очень удобно писать правила таким образом, но для целей тестирования это может быть полезно.

      Выведите на экран содержимое /etc/pf.conf, используя pfctl со следующей командой:

      • sudo pfctl -nvf /etc/pf.conf

      Эта команда pfctl получает флаги -nvf, выводит набор правил и тестирует его без фактической загрузки данных, что известно как пробный прогон. Теперь вы увидите полное содержимое /etc/pf.conf в подробной форме.

      Вы увидите примерно следующий вывод внутри части для борьбы с подменой IP-адресов:

      Output

      . . . block drop in quick on ! vtnet0 inet from your_server_ip/20 to any block drop in quick on ! vtnet0 inet from network_address/16 to any block drop in quick inet from your_server_ip to any block drop in quick inet from network_address to any block drop in quick on vtnet0 inet6 from your_IPv6_address to any . . .

      Ваше правило показало, что это часть сети your_server_ip/20. Также оно обнаружило, что (в примере для данного обучающего руководства) сервер является частью сети network_address/16 и имеет дополнительный IPv6-адрес. Правило блокирует коммуникации системы со всеми этими сетями, если их трафик не проходит через интерфейс vtnet0.

      Ваше правило для борьбы с подменой IP-адреса является последним добавлением в базовый набор правил. На следующем шаге вы примените эти изменения и выполните ряд тестов.

      Шаг 4 — Тестирование базового набора правил

      На этом шаге вы просмотрите и протестируете базовый набор правил, чтобы убедиться, что все работает корректно. Рекомендуется избегать применения слишком большого количества правил одновременно без тестирования. Рекомендуется начать с основ, постепенно расширяя функционал и выполнять резервное копирование при внесении изменений в конфигурацию.

      Вот как выглядит ваш полный базовый набор правил:

      Base Ruleset /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Убедитесь, что ваш файл /etc/pf.conf идентичен полному базовому набор правил, прежде чем продолжить. Сохраните и закройте файл.

      Ваш полный базовый набор правил предоставляет вам следующее:

      • Набор макросов, который может определять ключевые службы и устройства.
      • Политика гигиены сети для решения проблем с фрагментацией пакетов и нелогичными IP-адресами.
      • Структура фильтрации default deny​​​, которая блокирует весь трафик и разрешает только то, что вы указываете.
      • Входящий доступ через SSH с ограничением количества одновременных подключений с одного хоста.
      • Политики для исходящего трафика, которые позволяют получить доступ к критически важным сервисам в Интернете.
      • Политики ICMP, которые обеспечивают доступ к утилите ping и открытию пути MTU.

      Запустите следующую команду pfctl для выполнения пробного прогона:

      • sudo pfctl -nf /etc/pf.conf

      Вы передаете флаги -nf, которые указывают pfctl запускать набор правил без загрузки, в результате чего будут брошены ошибки, если что-то пойдет не так.

      Теперь, если ошибки отсутствуют, загрузите набор правил:

      • sudo pfctl -f /etc/pf.conf

      Если ошибок нет, это означает, что ваш базовый набор правил активен и работает корректно. Как и ранее в этом руководстве, вы выполните несколько тестов для вашего набора правил.

      Первый тест — подключение к Интернету и службе DNS:

      Результат будет выглядеть следующим образом:

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Затем проверьте, что вы можете получить доступ к репозиторию pkgs:

      Еще раз обновите пакеты, если это необходимо.

      В заключение перезапустите ваш сервер:

      Подождите несколько минут, пока сервер не перезагрузится. Вы выполнили и имплементировали базовый набор правил, что является важным шагом с точки зрения вашего прогресса. Теперь вы готовы к изучению некоторых продвинутых функций PF. На следующем шаге вы сможете продолжить работу по предотвращению атак brute force.

      Шаг 5 — Управление таблицей устранения перегрузки

      Со временем таблица устранения перегрузки <bruteforce> будет заполнена IP-адресами злоумышленников, и вам придется выполнять ее периодическую очистку. Маловероятно, что злоумышленник будет использовать один и тот же IP-адрес, поэтому нет необходимости хранить эти адреса в таблице в течение длительного времени.

      Вы можете использовать pfctl для ручной очистки IP-адресов, которые хранятся в таблице устранения перегрузки в течение 48 часов и более с помощью следующей команды:

      • sudo pfctl -t bruteforce -T expire 172800

      Вы увидите примерно следующий результат:

      Output

      0/0 addresses expired.

      Вы передаете флаг -t bruteforce, что означает table bruteforce, и флаг -T, который позволяет запускать целый ряд встроенных команд. В этом случае вы должны запустить команду expire, чтобы очистить все записи из -t bruteforce со значением времени, указанным в секундах. Поскольку вы работаете на новом сервере, в таблице, вероятно, не будет IP-адресов.

      Это правило работает для быстрого исправления ситуации, но более надежным решением будет автоматизация процесса с помощью cron, планировщика заданий FreeBSD. Давайте создадим скрипт оболочки, который запускает эту последовательность выполнения команды.

      Создайте файл скрипта оболочки в директории /usr/local/bin:

      • sudo vi /usr/local/bin/clear_overload.sh

      Добавьте в скрипт оболочки следующие строки:

      /usr/local/bin/clear_overload.sh

      #!/bin/sh
      
      pfctl -t bruteforce -T expire 172800
      

      Сделайте файл исполняемым с помощью следующей команды:

      • sudo chmod 755 /usr/local/bin/clear_overload.sh

      Далее вам необходимо создать задание cron. Это задания, которые будут запускаться периодически в соответствии с указанным вами временем. Часто они используются для резервного копирования или любого процесса, который необходимо запускать в одно и то же время каждый день. Создавать задания cron можно с помощью файлов crontab. Дополнительную информацию о cron(8) и crontab(5) см. в Man Pages.

      Создайте файл crontab пользователя root с помощью следующей команды:

      Теперь добавьте в файл crontab следующее содержимое:

      crontab

      # minute    hour    mday    month   wday    command
      
        *             0     *       *     *     /usr/local/bin/clear_overload.sh
      

      Сохраните и закройте файл.

      Примечание. Пожалуйста, сопоставьте каждое значение с соответствующим элементом в таблице для удобства чтения, если содержимое размещается некорректно при добавлении контента.

      Это задание cron запускает скрипт clear_overload.sh каждый день в полночь, удаляя IP-адреса, которые находятся в таблице перегрузки <bruteforce> более 48 часов. Далее вам необходимо добавить якоря в ваш набор правил.

      Шаг 6 — Добавление якорей в ваши наборы правил

      На этом шаге вы должны ввести якоря, которые используются для поиска правил в основном наборе правил, либо вручную, либо из внешнего текстового файла. Якоря могут содержать элементы правил, таблицы и даже другие якоря, которые называются вложенными якорями. Давайте продемонстрируем, как работают якоря, добавив таблицу во внешний файл, а затем выполним ее извлечение в ваш базовый набор правил. Ваша таблица будет включать группу внутренних хостов, для которой вы хотите ограничить подключение к внешнему миру.

      Создайте файл под именем /etc/blocked-hosts-anchor:

      • sudo vi /etc/blocked-hosts-anchor

      Добавьте в файл следующие строчки:

      /etc/blocked-hosts-anchor

      table <blocked-hosts> { 192.168.47.1 192.168.47.2 192.168.47.3 }
      
      block return out quick on egress from <blocked-hosts>
      

      Сохраните и закройте файл.

      Эти правила объявляются и определяются в таблице <blocked-hosts>​​​ и запрещают доступ с любого IP-адреса в таблице <blocked-hosts> к любым сервисам внешнего мира. Вы используете ключевое слово egress в качестве предпочитаемого метода поиска маршрута по умолчанию или выхода наружу, в Интернет.

      Вам все еще необходимо объявить якорь в вашем файле /etc/pf.conf​​​:

      Теперь добавьте следующие правила якоря после правила block all​​:

      /etc/pf.conf

      . . .
      block all
      anchor blocked_hosts
      load anchor blocked_hosts from "/etc/blocked-hosts-anchor"
      . . .
      

      Сохраните и закройте файл.

      Эти правила декларируют blocked_hosts и загружают правила якоря в ваш главный набор правил из файла /etc/blocked-hosts-anchor.

      Теперь примените эти изменения, перезагрузив ваш набор правил с помощью pfctl:

      • sudo pfctl -f /etc/pf.conf

      Если ошибок нет, это означает, что в вашем наборе правил нет ошибок, а изменения активны.

      Используйте pfctl для проверки запуска якоря:

      Флаг -s Anchors означает show anchors. Вывод должен выглядеть так:

      Output

      blocked_hosts

      Утилита pfctl также может парсить конкретные правила вашего якоря с помощью флагов -a и -s:

      • sudo pfctl -a blocked_hosts -s rules

      Результат будет выглядеть следующим образом:

      Output

      block return out quick on egress from <blocked-hosts> to any

      Еще одна функция якорей состоит в том, что они позволяют вам добавить правила по запросу без необходимости перезагрузки набора правил. Это может быть полезно при тестировании, быстрых исправлениях, авариях и т. д. Например, если внутренний хост действует странно, и вы хотите заблокировать для него исходящие подключения, вы можете использовать якорь, который позволяет вам быстро исправить ситуацию из командной строки.

      Давайте откроем /etc/pf.conf и добавим еще один якорь:

      Вы можете назвать якорь rogue_hosts и поместить его в правило block all​​​:

      /etc/pf.conf

      . . .
      block all
      anchor rogue_hosts
      . . .
      

      Сохраните и закройте файл.

      Чтобы применить изменения, перезагрузите набор правил с помощью pfctl:

      • sudo pfctl -f /etc/pf.conf

      Еще раз используйте pfctl для подтверждения запуска якоря:

      Результат будет выглядеть следующим образом:

      Output

      blocked_hosts rogue_hosts

      Теперь, когда якорь запущен, вы можете добавить к нему правила в любое время. Проверьте это, добавив следующее правило:

      • sudo sh -c 'echo "block return out quick on egress from 192.168.47.4" | pfctl -a rogue_hosts -f -'

      Здесь вызывается команда echo и строковое содержимое, которое затем передается в утилиту pfctl с символом |, где оно обрабатывается в правило якоря. Откройте новый сеанс оболочки с помощью команды sh -c. Это связано с тем, что вы создаете связь между двумя процессами, но вам необходимо использовать права sudo для прохождения всей последовательности команд. Существует несколько способов решения этой проблемы, в нашем случае вы откроете дополнительный процесс оболочки с привилегиями sudo, используя для этого команду sudo sh -c.

      Теперь воспользуйтесь pfctl еще раз, чтобы убедиться, что правила активны:

      • sudo pfctl -a rogue_hosts -s rules

      Результат будет выглядеть следующим образом:

      Output

      block return out quick on egress inet from 192.168.47.4 to any

      Использование якорей является ситуационным и субъективным решением. Как и для любых других функций, существуют плюсы и минусы использования якорей. Некоторые приложения, такие как интерфейс blacklistd, изначально имеют якоря. Далее мы рассмотрим подробнее процесс записи журналов в PF, что является критически важным аспектом сетевой безопасности. Ваш брандмауэр будет бесполезен, если вы не можете посмотреть, что он делает.

      Шаг 7 — Запись журнала активности вашего брандмауэра

      На этом шаге мы будем работать с журналом PF, который управляется с помощью псевдоинтерфейса pflog. Функция ведения журнала активируется при загрузке с помощью добавления pflog_enabled=YES в файл /etc/rc.conf, что вы уже сделали на шаге 2. Это позволяет активировать демон pflogd, который генерирует интерфейс под именем pflog0 и записывает журналы в бинарном формате в файл /var/log/pflog. Журналы можно парсить в режиме реального времени из интерфейса или читать из файла /var/log/pflog с помощью утилиты tcpdump(8)​​.

      Вначале получите доступ к журналам из файла /var/log/pflog:

      • sudo tcpdump -ner /var/log/pflog

      Вы передаете флаги -ner, которые форматируют вывод в удобочитаемый вид, а также указываете файл для чтения, в нашем случае это /var/log/pflog.

      Результат будет выглядеть следующим образом:

      Output

      reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)

      На этих ранних этапах в файле /var/log/pflog может не быть данных. В очень короткий срок файл журнала начнет расти в размере.

      Также вы можете просмотреть журналы в реальном времени с помощью интерфейса pflog0, используя следующую команду:

      Вы передаете флаги -nei, которые также форматируют вывод для удобства чтения, но в этот раз указываете интерфейс, в нашем случае это pflog0.

      Результат будет выглядеть следующим образом:

      Output

      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes

      Теперь вы увидите подключения в реальном времени. Если это возможно, проверьте пинг сервера с удаленного компьютера, в результате чего вы увидите подключения. Сервер будет находиться в этом состоянии, пока вы не выйдете.

      Чтобы выйти из этого состояния и вернуться в командную строку, нажмите CTRL + Z.

      В Интернете есть огромное количество информации о tcpdump(8), включая официальный сайт.

      Доступ к файлам журнала с помощью pftop

      Утилита pftop — это инструмент для быстрого просмотра активности брандмауэра в реальном времени. Ее имя отсылает к хорошо известной утилите Unix top.

      Для ее использования вам необходимо установить пакет pftop:

      Теперь запустите бинарный файл pftop:

      В результате будет получен следующий вывод (ваши IP-адреса будут отличаться):

      Output

      PR DIR SRC DEST STATE AGE EXP PKTS BYTES tcp In 251.155.237.90:27537 157.225.173.58:22 ESTABLISHED:ESTABLISHED 00:12:35 23:59:55 1890 265K tcp In 222.186.42.15:25884 157.225.173.58:22 TIME_WAIT:TIME_WAIT 00:01:25 00:00:06 22 3801 udp Out 157.245.171.59:4699 67.203.62.5:53 MULTIPLE:SINGLE 00:00:14 00:00:16 2 227

      Создание дополнительных интерфейсов журнала

      Как и для любого другого интерфейса, можно создавать несколько интерфейсов журнала, которые могут перечисляться в файле /etc/hostname. Это может оказаться полезным в целях организации, например, если вы хотите создавать журнал для отдельных типов деятельности.

      Создайте дополнительный интерфейс журнала с именем pflog1:

      • sudo vi /etc/hostname.pflog1

      Добавьте в файл /etc/hostname.pflog1 следующие строки:

      /etc/hostname.pflog1

      up
      

      Теперь активируйте устройство при загрузке в вашем файле /etc/rc.conf​​​:

      • sudo sysrc pflog1_enable="YES"

      Теперь вы можете контролировать и регистрировать активность брандмауэра. Это позволяет посматривать данные о том, кто подключается к серверу и какие типы подключений используются.

      В этом обучающем руководстве вы включили несколько продвинутых понятий в ваш набор правил PF. Это необходимо для включения продвинутых функций, если они вам потребуются. На следующем шаге вы вернетесь к базовому набору правил.

      Шаг 8 — Возврат к вашему базовому набору правил

      В этом последнем разделе вы вернетесь к базовому набору правил. Это быстрый шаг, который позволит вернуться к минимальному набору функций.

      Откройте базовый набор правил с помощью следующей команды:

      Удалите текущий набор правил в вашем файле и замените его на следующий базовый набор правил:

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Сохраните и закройте файл.

      Перезагрузите набор правил:

      • sudo pfctl -f /etc/pf.conf

      Если ошибки при выполнении команды отсутствуют, это значит, что в вашем наборе правил нет ошибок, а ваш брандмауэр работает корректно.

      Также вам необходимо отключить созданный вами интерфейс pflog1. Поскольку вы не знаете, понадобится ли он вам еще, вы можете отключить pflog1 с помощью утилиты sysrc:

      • sudo sysrc pflog1_enable="NO"

      Теперь удалите файл /etc/hostname.pflog1 из директории /etc:

      • sudo rm /etc/hostname.pflog1

      Прежде чем выходить, перезагрузите сервер еще раз, чтобы гарантировать, что все изменения активны и сохраняются:

      Подождите несколько минут, прежде чем выполнять вход на сервер.

      В качестве опции, если вы хотите использовать PF с веб-сервером, ниже представлен следующий набор правил для этого сценария. Этот набор правил является достаточной отправной точкой для большинства веб-приложений.

      Simple Web Server Ruleset

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <webcrawlers> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass in on $vtnet0 proto tcp to port { 80 443 } 
          keep state (max-src-conn 45, max-src-conn-rate 9/1, 
              overload <webcrawlers> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      В результате создается таблица с именем <webcrawlers>, которая имеет более гибкую политику в отношении перегрузки, чем ваш порт SSH, согласно значениям max-src-conn 45 и max-src-conn-rate. Это связано с тем, что не все перегрузки связаны с действиями злоумышленников. Они также могут быть связаны с активностью незлонамеренных сетевых ботов, поэтому вы можете избежать чрезмерных мер безопасности на портах 80 и 443. Если вы решите использовать набор правил для веб-сервера, вам необходимо добавить таблицу <webcrawlers> в /etc/pf.conf и периодически очищать IP-адреса в таблице. Подробнее см. в шаге 5.

      Заключение

      В этом обучающем руководстве вы настроили PF в FreeBSD 12.1. Теперь у вас есть базовый набор правил, который может служить в качестве отправной точки для всех ваших проектов FreeBSD. Дополнительную информацию о PF можно найти на странице pf.conf(5)​​​ в Man Pages.

      Посетите нашу страницу FreeBSD, чтобы найти дополнительные обучающие руководства и ответы на частые вопросы.



      Source link

      Comment configurer Packet Filter (PF) sous FreeBSD 12.1


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Le pare-feu est sans doute l’une des plus importantes lignes de défense contre les cyberattaques. La capacité de configurer un pare-feu à partir de zéro est une compétence qui donne à l’administrateur le pouvoir de prendre le contrôle de ses réseaux.

      Packet Filter (PF) est une application de pare-feu renommée qui est maintenue en amont par le projet OpenBSD axé sur la sécurité. Il s’exprime plus précisément comme un outil de filtrage de paquets, d’où son nom, et il est connu pour sa syntaxe simple, sa facilité d’utilisation et ses nombreuses fonctionnalités. PF est un pare-feu à état par défaut, qui stocke des informations sur les connexions dans une table d’état accessible à des fins d’analyse. PF fait partie du système de base de FreeBSD et est soutenu par une forte communauté de développeurs. Bien qu’il existe des différences entre les versions FreeBSD et OpenBSD de PF concernant les architectures de noyau, en général leur syntaxe est similaire. En fonction de leur complexité, les règlements communs peuvent être modifiés pour fonctionner sur l’une ou l’autre distribution avec relativement peu d’efforts.

      Dans ce tutoriel, vous allez construire un pare-feu à partir de zéro sur un serveur FreeBSD 12.1 avec PF. Vous concevrez un ensemble de règles de base qui pourra servir de modèle pour de futurs projets. Vous explorerez également certaines des fonctionnalités avancées de PF telles que l’hygiène des paquets, la prévention de la force brute, la surveillance et l’enregistrement, ainsi que d’autres outils tiers.

      Conditions préalables

      Avant de débuter ce tutoriel, vous aurez besoin des éléments suivants :

      • Un serveur 1G FreeBSD 12.1 (soit ZFS ou UFS). Vous pouvez utiliser notre tutoriel Comment démarrer avec FreeBSD pour configurer votre serveur selon vos préférences.
      • FreeBSD n’a pas de pare-feu activé par défaut – la personnalisation est une caractéristique de l’éthique de FreeBSD. Par conséquent, lorsque vous lancez votre serveur pour la première fois, vous avez besoin d’une protection temporaire pendant que PF est en cours de configuration. Si vous utilisez DigitalOcean, vous pouvez activer votre pare-feu dans le nuage immédiatement après avoir fait tourner le serveur. Reportez-vous au tutoriel Démarrage rapide du pare-feu de DigitalOcean pour obtenir des instructions sur la configuration d’un pare-feu en nuage. Si vous utilisez un autre fournisseur de services en ligne, déterminez le chemin le plus rapide vers une protection immédiate avant de commencer. Quelle que soit la méthode que vous choisissez, votre pare-feu temporaire doit autoriser uniquement le trafic SSH entrant et peut autoriser tous les types de trafic sortant.

      Étape 1 – Établissement de votre règlement préliminaire

      Vous commencerez ce tutoriel en rédigeant un ensemble de règles préliminaires qui assurent une protection de base et l’accès aux services essentiels sur l’internet. À ce stade, vous avez un serveur FreeBSD 12.1 en cours d’exécution avec un pare-feu en nuage actif.

      Il existe deux approches pour construire un pare-feu : le refus par défaut et le permis par défaut. L’approche de refus par défaut bloque tout le trafic, et n’autorise que ce qui est spécifié dans une règle. L’approche du permis par défaut fait exactement le contraire : il passe tout le trafic, et ne bloque que ce qui est spécifié dans une règle. Vous utiliserez l’approche de refus par défaut.

      Les règlements PF sont écrits dans un fichier de configuration nommé /etc/pf.conf, qui est également son emplacement par défaut. Il est possible de stocker ce fichier ailleurs, à condition que cela soit spécifié dans le Fichier de configuration /etc/rc.conf. Dans ce tutoriel, vous utiliserez l’emplacement par défaut.

      Connectez-vous à votre serveur avec votre utilisateur non racine :

      • ssh freebsd@your_server_ip

      Créez ensuite votre fichier /etc/pf.conf :

      Remarque : Si vous souhaitez voir l’ensemble complet du règlement de base à un moment quelconque du tutoriel, vous pouvez vous référer aux exemples de l’étape 4 ou de l’étape 8.

      PF filtre les paquets en fonction de trois actions principales : bloquer, passer et faire correspondre. Lorsqu’elles sont combinées avec d’autres options, elles forment des règles. Une mesure est prise lorsqu’un paquet répond aux critères spécifiés dans une règle. Comme vous pouvez vous en douter, les règles de passage et de blocage passeront et bloqueront le trafic. Une règle de correspondance effectue une action sur un paquet lorsqu’elle trouve un critère de correspondance, mais ne le passe pas ou ne le bloque pas. Par exemple, vous pouvez effectuer une traduction d’adresse réseau (NAT) sur un paquet correspondant sans le transmettre ou le bloquer, et il restera là jusqu’à ce que vous lui demandiez de faire quelque chose dans une autre règle, comme le router vers une autre machine ou une autre passerelle.

      Ensuite, ajoutez la première règle à votre fichier /etc/pf.conf :

      /etc/pf.conf

      block all
      

      Cette règle bloque toute forme de trafic dans toutes les directions. Comme il ne spécifie pas de direction, il indique par défaut les entrées et les sorties. Cette règle est légitime pour un poste de travail local qui doit être isolé du monde, mais elle est largement inapplicable et ne fonctionnera pas sur un serveur distant car elle ne permet pas le trafic SSH. En fait, si vous aviez activé PF, vous vous seriez enfermé hors du serveur.

      Révisez votre fichier /etc/pf.conf pour autoriser le trafic SSH avec la ligne surlignée suivante :

      /etc/pf.conf

      block all
      pass in proto tcp to port 22
      

      Remarque : vous pouvez également utiliser le nom du protocole :

      /etc/pf.conf

      block all
      pass in proto tcp to port ssh
      

      Par souci de cohérence, nous utiliserons les numéros de port, à moins qu’il n’y ait une raison valable de ne pas le faire. Vous trouverez une liste détaillée des protocoles et de leurs numéros de port respectifs dans le fichier /etc/services, que nous vous invitons à consulter.

      PF traite les règles de manière séquentielle de haut en bas, donc votre règlement actuel bloque initialement tout le trafic, mais le passe ensuite si les critères de la ligne suivante sont respectés, ce qui dans ce cas est le trafic SSH.

      Vous pouvez maintenant utiliser le SSH sur votre serveur, mais vous continuez à bloquer toute forme de trafic sortant. Cela pose problème car vous ne pouvez pas accéder à des services essentiels depuis l’internet pour installer des paquets, mettre à jour vos paramètres de temps, etc.

      Pour y remédier, ajoutez la règle surlignée suivante à la fin de votre fichier /etc/pf.conf :

      /etc/pf.conf

      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      

      Votre ensemble de règles autorise désormais le trafic sortant SSH, DNS, HTTP, NTP et HTTPS, ainsi que le blocage de tout trafic entrant (à l’exception du SSH). Vous placez les numéros de port et les protocoles entre parenthèses, ce qui forme une liste dans la syntaxe PF, vous permettant d’ajouter d’autres numéros de port si nécessaire. Vous ajoutez également une règle de distribution pour le protocole UDP sur les ports 53 et 123 car le DNS et le NTP basculent souvent entre les protocoles TCP et UDP.   Vous avez presque terminé l’ensemble des règles préliminaires, et il vous suffit d’ajouter quelques règles pour obtenir une fonctionnalité de base.

      Complétez le règlement préliminaire avec les règles mises en évidence :

      Preliminary Ruleset /etc/pf.conf

      set skip on lo0
      block all
      pass in proto tcp to port { 22 }
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass out inet proto icmp icmp-type { echoreq }
      

      Enregistrez et quittez le fichier.

      Vous créez une règle de saut définie pour le dispositif de bouclage car il n’a pas besoin de filtrer le trafic et risquerait d’amener votre serveur à un crawl. Vous ajoutez une règle pass out inet pour le protocole ICMP, qui vous permet d’utiliser l’utilitaire ping(8) pour le dépannage. L’option inet représente la famille d’adresses IPv4.

      L’ICMP est un protocole de messagerie polyvalent utilisé par les appareils en réseau pour divers types de communication. L’utilitaire ping, par exemple, utilise un type de message appelé echo request, que vous avez ajouté à votre liste icmp_type. Par mesure de précaution, vous n’autorisez que les types de messages dont vous avez besoin pour éviter que des appareils indésirables n’entrent en contact avec votre serveur. À mesure que vos besoins augmentent, vous pouvez ajouter d’autres types de messages à votre liste.

      Vous disposez désormais d’un règlement de fonctionnement qui fournit des fonctionnalités de base à la plupart des machines. Dans la section suivante, nous allons confirmer que tout fonctionne correctement en activant PF et en testant votre règlement préliminaire.

      Étape 2 – Test de votre règlement préliminaire

      Au cours de cette étape, vous testerez votre règlement préliminaire et ferez la transition de votre pare-feu dans le nuage à votre pare-feu PF, permettant à PF de prendre complètement le relais. Vous activerez votre règlement avec l’utilitaire pfctl, qui est l’outil de ligne de commande intégré de PF, et la principale méthode d’interface avec PF. 

      Les règlements de la PF ne sont rien d’autre que des fichiers texte, ce qui signifie que le chargement de nouveaux règlement n’implique aucune procédure délicate. Vous pouvez charger un nouveau règlement, et l’ancien est parti. Il est rarement, voire jamais, nécessaire de vider un règlement existant.

      FreeBSD utilise un réseau de scripts shell connu sous le nom de système rc pour gérer la façon dont les services sont démarrés au démarrage ; nous spécifions ces services dans divers fichiers de configuration rc. Pour les services globaux tels que PF, vous utilisez le fichier /etc/rc.conf. Comme les fichiers rc sont essentiels au bien-être d’un système FreeBSD, ils ne doivent pas être édités directement. A la place, FreeBSD fournit un utilitaire en ligne de commande connu sous le nom de sysrc, conçu pour vous aider à modifier ces fichiers en toute sécurité.

      Activons PF en utilisant l’utilitaire de ligne de commande sysrc :

      • sudo sysrc pf_enable="YES"
      • sudo sysrc pflog_enable="YES"

      Vérifiez ces changements en imprimant le contenu de votre fichier /etc/rc.conf :

      Vous verrez le résultat suivant :

      Output

      pf_enable="YES" pflog_enable="YES"

      Vous activez également le service pflog, qui, à son tour, active le démon pflogd pour se connecter à PF. Vous travaillerez sur la connexion dans une étape ultérieure.

      Vous spécifiez deux services globaux dans votre fichier /etc/rc.conf, mais ils ne s’initialiseront pas tant que vous n’aurez pas redémarré le serveur ou que vous ne les aurez pas démarrés manuellement. Redémarrez le serveur afin de pouvoir également tester votre accès SSH.

      Démarrez PF en redémarrant le serveur :

      La connexion sera interrompue. Donnez-lui quelques minutes pour mettre à jour.

      Maintenant, SSH est de retour sur le serveur :

      • ssh freebsd@your_server_ip

      Bien que vous ayez initialisé vos services PF, vous n’avez pas encore chargé votre règlement /etc/pf.conf, ce qui signifie que votre pare-feu n’est pas encore actif.

      Chargez le règlement avec pfctl :

      • sudo pfctl -f /etc/pf.conf

      S’il n’y a pas d’erreurs ou de messages, cela signifie que votre règlement ne contient pas d’erreurs et que le pare-feu est actif.

      Maintenant que PF fonctionne, vous pouvez détacher votre serveur de votre pare-feu dans le nuage. Cela peut se faire dans le panneau de contrôle de votre compte DigitalOcean en retirant votre Droplet du portail de votre pare-feu dans le nuage. Si vous utilisez un autre fournisseur de services en nuage, assurez-vous que ce que vous utilisez pour la protection temporaire est désactivé. Faire fonctionner deux pare-feu différents sur un serveur posera presque certainement des problèmes.

      Pour une bonne mesure, redémarrez votre serveur :

      Après quelques minutes, SSH revient sur votre serveur :

      • ssh freebsd@your_server_ip

      PF est maintenant votre pare-feu. Vous pouvez vous assurer qu’il fonctionne en accédant à certaines données avec l’utilitaire pfctl.

      Voyons quelques statistiques et compteurs avec pfctl -si :

      Vous passez devant les drapeaux -si, qui signifient show info. C’est l’une des nombreuses combinaisons de paramètres de filtrage que vous pouvez utiliser avec pfctl pour analyser les données concernant l’activité de votre pare-feu.

      Vous verrez les données tabulaires suivantes (les valeurs varient d’une machine à l’autre) :

      Output

      Status: Enabled for 0 days 00:01:53 Debug: Urgent State Table Total Rate current entries 5 searches 144 1.3/s inserts 11 0.1/s removals 6 0.1/s Counters match 23 0.2/s bad-offset 0 0.0/s fragment 0 0.0/s short 0 0.0/s normalize 0 0.0/s memory 0 0.0/s bad-timestamp 0 0.0/s congestion 0 0.0/s ip-option 0 0.0/s proto-cksum 0 0.0/s state-insert 0 0.0/s state-limit 0 0.0/s src-limit 0 0.0/s synproxy 0 0.0/s map-failed 0 0.0/s

      Comme vous venez d’activer votre ensemble de règles, vous ne verrez pas encore beaucoup d’informations. Cependant, ce résultat montre que PF a déjà enregistré 23 règles correspondantes, ce qui signifie que les critères de votre ensemble de règles ont été adaptés 23 fois. La sortie confirme également que votre pare-feu fonctionne.

      Votre règlement permet également au trafic sortant d’accéder à certains services essentiels de l’internet, y compris l’utilitaire ping.

      Vérifions la connectivité internet et le service DNS avec un ping contre google.com : 

      Depuis que vous avez lancé le drapeau du compte-c 3, vous verrez trois réponses de connexion réussies :

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Assurez-vous que vous pouvez accéder au dépôt pkgs avec la commande suivante :

      S’il y a des paquets à mettre à niveau, allez-y, mettez-les à niveau.

      Si ces deux services fonctionnent, cela signifie que votre pare-feu fonctionne et que vous pouvez maintenant continuer. Bien que votre ensemble de règles préliminaires offre une protection et des fonctionnalités, il reste un ensemble de règles élémentaires et pourrait bénéficier de quelques améliorations. Dans les autres sections, vous compléterez votre règlement de base et utiliserez certaines des fonctionnalités avancées de PF.

      Au cours de cette étape, vous vous appuierez sur l’ensemble de règles préliminaires pour compléter votre règlement de base. Vous réorganiserez certaines de vos règles et travaillerez avec des concepts plus avancés.

      Incorporation de macros et de tableaux

      Dans votre ensemble de règles préliminaires, vous avez codé en dur tous vos paramètres dans chaque règle, c’est-à-dire les numéros de port qui composent les listes. Cela peut devenir ingérable à l’avenir, en fonction de la nature de vos réseaux. Pour des raisons d’organisation, PF comprend des macros, des listes et des tableaux. Vous avez déjà inclus des listes directement dans vos règles, mais vous pouvez également les séparer de vos règles et les affecter à une variable à l’aide de macros.

      Ouvrez votre fichier pour transférer certains de vos paramètres dans des macros :

      Ajoutez maintenant le contenu suivant tout en haut du règlement :

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq }"
      . . .
      

      Modifiez vos anciennes règles SSH et ICMP avec vos nouvelles variables :

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 }
      . . .
      pass inet proto icmp icmp-type $icmp_types
      . . .
      

      Vos anciennes règles SSH et ICMP utilisent désormais des macros. Les noms des variables sont désignés par la syntaxe du signe du dollar de PF. Vous attribuez votre interface vtnet0 à une variable portant le même nom juste comme une formalité, ce qui vous donne la possibilité de la renommer à l’avenir si nécessaire. D’autres noms de variables courantes pour les interfaces publiques comprennent $pub_if ou $ext_if.

      Ensuite, vous instaurerez une table, qui est similaire à une macro, mais conçu pour contenir des groupes d’adresses IP. Créons une table pour les adresses IP non routables, qui jouent souvent un rôle dans les attaques par déni de service (DOS). Vous pouvez utiliser les adresses IP spécifiées dans la RFC6890, qui définit les registres d’adresses IP à usage spécifique. Votre serveur ne devrait pas envoyer ou recevoir de paquets à destination ou en provenance de ces adresses via l’interface publique.

      Créez cette table en ajoutant le contenu suivant directement sous la macro icmp_types :

      /etc/pf.conf

      . . .
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      . . .
      

      Ajoutez maintenant vos règles pour la table <rfc6890> sous la règle set skip on lo0 :

      /etc/pf.conf

      . . .
      set skip on lo0
      block in quick on egress from <rfc6890>
      block return out quick on egress to <rfc6890>
      . . .
      

      Vous introduisez ici l’option de retour, qui complète votre règle de blocage. Les paquets sont alors déposés et un message RST est envoyé à l’hôte qui a essayé d’établir ces connexions, ce qui est utile pour analyser l’activité de l’hôte.   Ensuite, vous ajoutez le mot-clé egress, qui trouve automatiquement la (les) route(s) par défaut sur une (des) interface(s) donnée(s). C’est généralement une méthode plus propre pour trouver des itinéraires par défaut, surtout avec des réseaux complexes. Le mot-clé quick exécute les règles immédiatement sans tenir compte du reste de l’ensemble des règles. Par exemple, si un paquet avec une adresse IP illogique tente de se connecter au serveur, vous voulez immédiatement interrompre la connexion et vous n’avez aucune raison de faire passer ce paquet par le reste du règlement.

      Protéger vos ports SSH

      Comme votre port SSH est ouvert au public, il est sujet à l’exploitation. L’un des signes d’alerte les plus évidents d’un agresseur est la quantité massive de tentatives de connexion. Par exemple, si la même adresse IP essaie de se connecter à votre serveur dix fois en une seconde, vous pouvez supposer que cela n’a pas été fait par des mains humaines, mais par un logiciel informatique qui a essayé de craquer votre mot de passe de connexion. Ces types d’exploits systématiques sont souvent appelés “attaques par force brute” et réussissent généralement si le serveur a des mots de passe faibles.

      Avertissement : Nous recommandons vivement l’utilisation d’une authentification par clé publique sur tous les serveurs. Consultez le tutoriel de DigitalOcean sur l’authentification par clé.

      PF dispose de fonctions intégrées pour gérer la force brute et d’autres attaques similaires. Avec PF, vous pouvez limiter le nombre de tentatives de connexion simultanées autorisées par un seul hôte. Si un hôte dépasse ces limites, la connexion sera interrompue et il sera banni du serveur. Pour ce faire, vous utiliserez le mécanisme de surcharge de PF qui gère une table d’adresses IP interdites.

      Modifiez votre ancienne règle SSH pour limiter le nombre de connexions simultanées à partir d’un seul hôte comme suit :

      /etc/pf.conf

      . . .
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      . . .
      

      Vous ajoutez l’option keep state qui vous permet de définir les critères d’état pour la table de surcharge. Vous passez le paramètre max-src-conn pour spécifier le nombre de connexions simultanées autorisées à partir d’un seul hôte par seconde, et le paramètre max-src-conn-rate pour spécifier le nombre de nouvelles connexions autorisées à partir d’un seul hôte par seconde. Vous spécifiez 15 connexions pour max-src-conn, et 3 connexions pour max-src-conn-rate. Si ces limites sont dépassées par un hôte, le mécanisme de surcharge ajoute l’IP source à la table <bruteforce>, ce qui les interdit au serveur. Enfin, l’option flush global supprime immédiatement la connexion.

      Vous avez défini une table de surcharge dans votre règle SSH, mais vous n’avez pas déclaré cette table dans votre règlement.

      Ajoutez la table <bruteforce> sous la macro icmp_types :

      /etc/pf.conf

      . . .
      icmp_types = "{ echoreq }"
      table <bruteforce> persist
      . . .
      

      Le mot-clé persist permet à une table vide d’exister dans le règlement. Sans lui, PF se plaindra qu’il n’y a pas d’adresses IP dans la table.

      Ces mesures garantissent que votre port SSH est protégé par un puissant mécanisme de sécurité. PF vous permet de configurer des solutions rapides pour vous protéger contre des formes d’exploitation désastreuses. Dans les sections suivantes, vous allez prendre des mesures pour nettoyer les paquets lorsqu’ils arrivent sur votre serveur.

      Assainir votre trafic

      Remarque : Les sections suivantes décrivent les principes fondamentaux de la suite de protocoles TCP/IP.   Si vous envisagez de créer des applications web ou des réseaux, il est dans votre intérêt de maîtriser ces concepts. Consultez le tutoriel Introduction à la terminologie, aux interfaces et aux protocoles de réseau de DigitalOcean.

      En raison de la complexité de la suite de protocoles TCP/IP et de la persistance d’acteurs malveillants, les paquets arrivent souvent avec des divergences et des ambiguïtés telles que des fragments d’IP qui se chevauchent, de fausses adresses IP, etc. Il est impératif que vous assainissiez votre trafic avant qu’il n’entre dans le système. Le terme technique pour ce processus est la normalisation.

      Lorsque les données circulent sur Internet, elles sont généralement divisées en petits fragments à leur source pour tenir compte des paramètres de transmission de l’hôte cible où elles sont réassemblées en paquets complets. Malheureusement, un intrus peut détourner ce processus de plusieurs façons qui vont au-delà de la portée de ce tutoriel. Cependant, avec PF, vous pouvez gérer la fragmentation avec une seule règle. PF comprend un mot-clé scrub qui normalise les paquets.

      Ajoutez le mot-clé scrub précédant directement votre règle block all : 

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      block all
      . . .
      

      Cette règle s’applique à l’épuration de tout le trafic entrant. Vous incluez l’option scrub in all fragment reassemble qui empêche les fragments d’entrer dans le système. Au lieu de cela, elles sont mises en cache en mémoire jusqu’à ce qu’elles soient réassemblées en paquets complets, ce qui signifie que vos règles de filtrage n’auront à faire face qu’à des paquets uniformes. Vous incluez également l’option max-mss 1440, qui représente la taille maximale du segment des paquets TCP réassemblés, également connue sous le nom de charge utile.   Vous spécifiez une valeur de 1440 octets, ce qui établit un équilibre entre la taille et les performances, laissant beaucoup de place pour les en-têtes.

      Un autre aspect important de la fragmentation est un terme connu sous le nom d’unité de transmission maximale (MTU). Les protocoles TCP/IP permettent aux appareils de négocier la taille des paquets pour établir des connexions. L’hôte cible utilise les messages ICMP pour informer l’IP source de son MTU, un processus connu sous le nom de découverte de chemin MTU. Le type de message ICMP spécifique concerne la destination inaccessible. Vous activerez la découverte du chemin MTU en ajoutant le type de message unreach à votre liste icmp_types.

      Vous utiliserez le MTU par défaut de votre serveur de 1500 octets qui peut être déterminé avec la commande ifconfig : 

      Vous verrez la sortie suivante qui inclut votre MTU actuelle :

      Output

      vtnet0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500 options=6c07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> . . .

      Mettez à jour la liste icmp_types pour y inclure le type de message de destination inaccessible :

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach}"
      . . .
      

      Maintenant que vous avez mis en place des politiques pour gérer la fragmentation, les paquets qui entrent dans votre système seront uniformes et cohérents. C’est souhaitable car il existe de nombreux appareils qui échangent des données sur l’internet.

      Vous allez maintenant vous efforcer d’éviter un autre problème de sécurité connu sous le nom de IP spoofing. Les attaquants changent souvent leurs IP sources pour faire croire qu’ils résident sur un nœud de confiance au sein d’une organisation. L’IP comprend une directive antispoofing pour le traitement des IPs de source usurpés Lorsqu’il est appliqué à une ou plusieurs interfaces spécifiques, l’antispoofing bloque tout le trafic provenant du réseau de cette interface (sauf s’il provient de cette interface). Par exemple, si vous appliquez l’antispoofing à une (des) interface(s) résidant au 5.5.5.1/24, tout le trafic du réseau 5.5.5.0/24 ne peut pas communiquer avec le système, sauf s’il provient de cette (ces) interface(s).

      Ajoutez le contenu surligné suivant pour appliquer l’antispoofing à votre interface vtnet0 :

      /etc/pf.conf

      . . .
      set skip on lo0
      scrub in
      antispoof quick for $vtnet0
      block all
      . . .
      

      Enregistrez et quittez le fichier.

      Cette règle antispoofing stipule que tout le trafic du (des) réseau(x) vtnet0 ne peut passer que par l’interface vtnet0, ou il sera immédiatement supprimé avec le mot-clé quick. Les mauvais éléments ne pourront pas se cacher dans le réseau de vtnet0 et communiquer avec d’autres nœuds. 

      Pour démontrer votre règle antispoofing, vous afficherez votre règlement à l’écran sous forme verbeuse. Les règles en PF sont généralement écrites sous une forme abrégée, mais elles peuvent également être écrites de manière verbeuse. Il n’est généralement pas pratique d’écrire les règles de cette manière, mais cela peut être utile à des fins de test.

      Imprimez le contenu de /etc/pf.conf en utilisant pfctl avec la commande suivante :

      • sudo pfctl -nvf /etc/pf.conf

      Cette commande pfctl prend les drapeaux -nvf, qui permettent d’imprimer le règlement et de le tester sans rien charger, ce qu’on appelle aussi un essai. Vous allez maintenant voir le contenu entier de /etc/pf.conf dans sa forme détaillée.

      Vous verrez quelque chose de similaire à la sortie suivante dans la partie antispoofing :

      Output

      . . . block drop in quick on ! vtnet0 inet from your_server_ip/20 to any block drop in quick on ! vtnet0 inet from network_address/16 to any block drop in quick inet from your_server_ip to any block drop in quick inet from network_address to any block drop in quick on vtnet0 inet6 from your_IPv6_address to any . . .

      Votre règle antispoofing a découvert qu’elle faisait partie du réseau your_server_ip/20. Il a également détecté que (pour l’exemple de ce tutoriel) le serveur fait partie d’un réseau adresse_réseau/16, et possède une adresse IPv6 supplémentaire. L’antispoofing empêche tous ces réseaux de communiquer avec le système, sauf si leur trafic passe par l’interface vtnet0. 

      Votre règle antispoofing est le dernier ajout à votre règlement de base. Dans l’étape suivante, vous lancerez ces changements et effectuerez quelques tests.

      Étape 4 – Tester votre règlement de base

      Au cours de cette étape, vous examinerez et testerez votre règlement de base pour vous assurer que tout fonctionne correctement. Il est préférable d’éviter de mettre en œuvre trop de règles à la fois sans les tester. La meilleure pratique consiste à commencer par l’essentiel, à développer progressivement et à remonter tout en modifiant la configuration.

      Voici votre règlement de base complet :

      Base Ruleset /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Assurez-vous que votre fichier /etc/pf.conf est identique au règlement de base complet ici avant de continuer. Puis, enregistrez et quittez le fichier.

      Vous disposez d’un règlement de base complet :

      • Une collection de macros qui peuvent définir les services et appareils clés.
      • Des politiques d’hygiène du réseau pour remédier à la fragmentation des paquets et aux adresses IP illogiques.
      • Une structure de filtrage de refus par défaut qui bloque tout et n’autorise que ce que vous spécifiez.
      • Accès SSH entrant avec des limites sur le nombre de connexions simultanées qui peuvent être effectuées par un hôte.
      • Des politiques de trafic sortant qui vous permettent d’accéder à certains services essentiels sur internet.
      • Les politiques de l’ICMP qui donnent accès à l’utilitaire ping et à la découverte du chemin MTU.

      Exécutez la commande pfctl suivante pour faire un essai :

      • sudo pfctl -nf /etc/pf.conf

      Vous passez les drapeaux -nf qui indiquent à pfctl d’exécuter le règlement sans le charger, ce qui entraînera des erreurs si quelque chose ne va pas.

      Maintenant, si vous ne rencontrez aucune erreur, chargez le règlement :

      • sudo pfctl -f /etc/pf.conf

      S’il n’y a pas d’erreurs, cela signifie que votre règlement de base est actif et fonctionne correctement. Comme précédemment dans le tutoriel, vous allez effectuer quelques tests sur votre ensemble de règles.

      Premier test pour la connectivité internet et le service DNS :

      Vous verrez le résultat suivant :

      Output

      PING google.com (172.217.0.46): 56 data bytes 64 bytes from 172.217.0.46: icmp_seq=0 ttl=56 time=2.088 ms 64 bytes from 172.217.0.46: icmp_seq=1 ttl=56 time=1.469 ms 64 bytes from 172.217.0.46: icmp_seq=2 ttl=56 time=1.466 ms --- google.com ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.466/1.674/2.088/0.293 ms

      Ensuite, vérifiez que vous atteignez le dépôt pkgs : 

      Encore une fois, améliorez les paquets si nécessaire.

      Enfin, redémarrez votre serveur :

      Donnez à votre serveur quelques minutes pour redémarrer. Vous avez achevé et mis en œuvre votre règlement de base, ce qui constitue une étape importante en termes de progrès. Vous êtes maintenant prêt à explorer certaines des fonctionnalités avancées de PF. Dans la prochaine étape, vous continuerez à prévenir les attaques par la force brute.

      Étape 5 – Gérer votre table de surcharge

      Avec le temps, la table de surcharge <bruteforce> se remplira d’adresses IP malveillantes et devra être nettoyé périodiquement. Il est peu probable qu’un attaquant continue à utiliser la même adresse IP, il est donc contre-intuitif de les stocker dans la table de surcharge pendant de longues périodes.

      Vous utiliserez pfctl pour effacer manuellement les adresses IP qui ont été stockées dans la table de surcharge pendant 48 heures ou plus avec la commande suivante :

      • sudo pfctl -t bruteforce -T expire 172800

      Vous verrez une sortie semblable à :

      Output

      0/0 addresses expired.

      Vous passez le drapeau -t bruteforce, qui signifie table bruteforce, et le drapeau -T, qui vous permet d’exécuter une poignée de commandes intégrées. Dans ce cas, vous dirigez la commandeexpire pour effacer toutes les entrées de -t bruteforce avec une valeur de temps représentée en secondes. Comme vous travaillez sur un nouveau serveur, il n’y a probablement pas encore d’adresses IP dans la table de surcharge.

      Cette règle fonctionne pour les solutions rapides, mais une solution plus robuste serait d’automatiser le processus avec cron, le planificateur de tâches de FreeBSD.   Créons plutôt un script shell qui exécute cette séquence de commandes.

      Créez un fichier de script shell dans le répertoire /usr/local/bin :

      • sudo vi /usr/local/bin/clear_overload.sh

      Ajoutez le contenu suivant au script shell :

      /usr/local/bin/clear_overload.sh

      #!/bin/sh
      
      pfctl -t bruteforce -T expire 172800
      

      Rendez le fichier exécutable avec la commande suivante :

      • sudo chmod 755 /usr/local/bin/clear_overload.sh

      Ensuite, vous allez créer une tâche cron. Il s’agit de tâches répétitives qui se déroulent selon une durée que vous spécifiez. Ils sont couramment utilisés pour les sauvegardes, ou tout processus qui doit s’exécuter à la même heure chaque jour. Vous créez des tâches cron avec des fichiers crontab. Veuillez consulter les pages du manuel pour en savoir plus surcron(8) et crontab(5). 

      Créez un fichier crontab pour l’utilisateur root ou racine avec la commande suivante :

      Ajoutez maintenant le contenu suivant au fichier crontab :

      crontab

      # minute    hour    mday    month   wday    command
      
        *             0     *       *     *     /usr/local/bin/clear_overload.sh
      

      Enregistrez et quittez le fichier.

      Remarque : Veuillez aligner chaque valeur sur l’entrée de table correspondante pour des raisons de lisibilité si les choses ne s’alignent pas correctement lorsque vous ajoutez le contenu.

      Cette tâche cron exécute le script clear_overload.sh tous les jours à minuit, en supprimant les adresses IP vieilles de 48 heures du tableau de surcharge <bruteforce>. Ensuite, vous ajouterez des ancres à votre règlement.

      Étape 6 – Introduction des ancres dans vos règlements

      Au cours de cette étape, vous introduisez des ancres, qui sont utilisées pour l’approvisionnement des règles dans le règlement principal, soit manuellement, soit à partir d’un fichier texte externe. Les ancres peuvent contenir des bribes de règles, des tables et même d’autres ancres, appelées ancres imbriquées. Montrons comment fonctionnent les ancres en ajoutant une table à un fichier externe, et en l’intégrant dans votre règlement de base. Votre table comprendra un groupe d’hôtes internes que vous voulez empêcher de se connecter au monde extérieur.

      Créez un fichier nommé /etc/blocked-hosts-anchor :

      • sudo vi /etc/blocked-hosts-anchor

      Ajoutez le contenu suivant au fichier :

      /etc/blocked-hosts-anchor

      table <blocked-hosts> { 192.168.47.1 192.168.47.2 192.168.47.3 }
      
      block return out quick on egress from <blocked-hosts>
      

      Enregistrez et quittez le fichier.

      Ces règles déclarent et définissent la table <blocked-hosts>, puis empêchent chaque adresse IP de la table <blocked-hosts> d’accéder aux services depuis le monde extérieur. Vous utilisez le mot-clé egress comme méthode privilégiée pour trouver l’itinéraire par défaut, ou la sortie vers internet.

      Vous devez encore déclarer l’ancre dans votre fichier /etc/pf.conf :

      Ajoutez maintenant les règles d’ancrage suivantes après la règle block all :

      /etc/pf.conf

      . . .
      block all
      anchor blocked_hosts
      load anchor blocked_hosts from "/etc/blocked-hosts-anchor"
      . . .
      

      Enregistrez et quittez le fichier.

      Ces règles déclarent les blocked_hosts et chargent les règles d’ancrage dans votre règlement principal à partir de /etc/blocked-hosts-anchorde l’entreprise. 

      Maintenant, initiez ces changements en rechargeant votre règlement avec pfctl :

      • sudo pfctl -f /etc/pf.conf

      S’il n’y a pas d’erreurs, cela signifie qu’il n’y a pas d’erreurs dans votre règlement et que vos modifications sont actives.

      Utilisez pfctl pour vérifier que votre ancre fonctionne :

      Le drapeau -s Anchors signifie show anchors (montrer les ancres). Vous verrez la sortie suivante :

      Output

      blocked_hosts

      L’utilitaire pfctl peut également analyser les règles spécifiques de votre ancre avec les drapeaux -a et -s : 

      • sudo pfctl -a blocked_hosts -s rules

      Vous verrez le résultat suivant :

      Output

      block return out quick on egress from <blocked-hosts> to any

      Une autre caractéristique des ancres est qu’elles vous permettent d’ajouter des règles à la demande sans avoir à recharger le règlement. Cela peut être utile pour les tests, les corrections rapides, les situations d’urgence, etc. Par exemple, si un hôte interne agit de manière particulière et que vous voulez l’empêcher d’établir des connexions vers l’extérieur, vous pouvez avoir une ancre en place qui vous permet d’intervenir rapidement depuis la ligne de commande.

      Ouvrons /etc/pf.conf et ajoutons une autre ancre :

      Vous nommerez l’ancre rogue_hosts, et la placerez sous la règle block all :

      /etc/pf.conf

      . . .
      block all
      anchor rogue_hosts
      . . .
      

      Enregistrez et quittez le fichier.

      Pour initier ces changements, rechargez le règlement avec pfctl : 

      • sudo pfctl -f /etc/pf.conf

      Encore une fois, utilisez pfctl pour vérifier que l’ancre est en marche :

      Cela donnera le résultat suivant :

      Output

      blocked_hosts rogue_hosts

      Maintenant que l’ancre est en marche, vous pouvez y ajouter des règles à tout moment. Testez ceci en ajoutant la règle suivante :

      • sudo sh -c 'echo "block return out quick on egress from 192.168.47.4" | pfctl -a rogue_hosts -f -'

      Ceci invoque la commande echo et son contenu de chaîne de caractères, qui est ensuite acheminé dans l’utilitaire pfctl avec le symbole |, où il est traité en une règle d’ancrage. Vous ouvrez une autre session shell avec la commande sh -c. En effet, vous établissez un conduit entre deux processus, mais vous avez besoin de privilèges sudo pour persister pendant toute la séquence de commande. Il existe plusieurs façons de résoudre ce problème ; ici, vous ouvrez un processus shell supplémentaire avec des privilèges sudo en utilisant sudo sh -c.

      Maintenant, utilisez à nouveau pfctl pour vérifier que ces règles sont actives :

      • sudo pfctl -a rogue_hosts -s rules

      Cela donnera le résultat suivant :

      Output

      block return out quick on egress inet from 192.168.47.4 to any

      L’utilisation des ancres est totalement situationnelle et souvent subjective. Comme toute autre caractéristique, il y a des avantages et des inconvénients à utiliser des ancres. Certaines applications telles que l’interface blacklistd avec les ancres par conception. Ensuite, vous vous concentrerez sur la journalisation avec PF, qui est un aspect essentiel de la sécurité du réseau. Votre pare-feu n’est pas utile si vous ne pouvez pas voir ce qu’il fait.

      Étape 7 – Enregistrer les activités de votre pare-feu

      Dans cette étape, vous travaillerez avec l’enregistrement PF, qui est géré par une pseudo-interface nommée pflog. La journalisation est activée au démarrage en ajoutant pflog_enabled=YES au fichier /etc/rc.conf, ce que vous avez fait à l’étape 2. Cela active le démon pflogd qui fait apparaître une interface nommée pflog0 et écrit les journaux au format binaire dans un fichier nommé /var/log/pflog. Les journaux peuvent être analysés en temps réel à partir de l’interface, ou lus dans le fichier /var/log/pflog avec l’utilitaire tcpdump(8).

      Accédez d’abord à certains journaux à partir du fichier /var/log/pflog :

      • sudo tcpdump -ner /var/log/pflog

      Vous passez les drapeaux -ner qui formatent la sortie pour la lisibilité, et spécifiez également un fichier à lire, qui dans votre cas est /var/log/pflog. 

      Vous verrez le résultat suivant :

      Output

      reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file)

      Dans ces premières étapes, il se peut qu’il n’y ait aucune donnée dans le fichier /var/log/pflog. Dans un court laps de temps, le fichier journal commencera à se développer.

      Vous pouvez également consulter les journaux en temps réel à partir de l’interface pflog0 en utilisant la commande suivante :

      Vous passez les drapeaux -nei, qui formatent également la sortie pour la lisibilité, mais cette fois-ci vous spécifiez une interface, qui dans votre cas est pflog0.

      Vous verrez le résultat suivant :

      Output

      tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes

      Vous verrez maintenant les connexions en temps réel. Si possible, effectuez un ping sur votre serveur à partir d’une machine distante et vous verrez les connexions se produire. Le serveur restera dans cet état jusqu’à ce que vous en sortiez.

      Pour sortir de cet état et revenir à la ligne de commande, appuyez sur CTRL + Z. 

      Il existe sur Internet une multitude d’informations sur le tcpdump(8), y compris le site officiel. 

      Accéder aux fichiers journaux avec pftop

      L’utilitaire pftop est un outil permettant de visualiser rapidement l’activité du pare-feu en temps réel. Son nom provient de l’utilitaire de pointe bien connu d’Unix.

      Pour l’utiliser, vous devez installer le paquet pftop :

      Maintenant, lancez le binaire pftop : 

      Cela produira le résultat suivant (vos IP seront différents) :

      Output

      PR DIR SRC DEST STATE AGE EXP PKTS BYTES tcp In 251.155.237.90:27537 157.225.173.58:22 ESTABLISHED:ESTABLISHED 00:12:35 23:59:55 1890 265K tcp In 222.186.42.15:25884 157.225.173.58:22 TIME_WAIT:TIME_WAIT 00:01:25 00:00:06 22 3801 udp Out 157.245.171.59:4699 67.203.62.5:53 MULTIPLE:SINGLE 00:00:14 00:00:16 2 227

      Création d’interfaces de journal supplémentaires

      Comme toute autre interface, plusieurs interfaces de journalisation peuvent être créées et nommées à l’aide d’un fichier /etc/hostname. Vous pouvez trouver cela utile à des fins d’organisation, par exemple si vous souhaitez enregistrer certains types d’activité séparément.

      Créer une interface de journalisation supplémentaire appelée pflog1 : 

      • sudo vi /etc/hostname.pflog1

      Ajoutez le contenu suivant au fichier /etc/hostname.pflog1 :

      /etc/hostname.pflog1

      up
      

      Activez maintenant le périphérique au moment du démarrage dans votre fichier /etc/rc.conf :

      • sudo sysrc pflog1_enable="YES"

      Vous pouvez maintenant surveiller et enregistrer l’activité de votre pare-feu. Cela vous permet de voir qui établit des connexions à votre serveur et les types de connexions effectuées.

      Tout au long de ce tutoriel, vous avez intégré certains concepts avancés dans votre ensemble de règles PF. Il est seulement nécessaire de mettre en œuvre des fonctionnalités avancées au fur et à mesure de vos besoins. Cela dit, dans la prochaine étape, vous reviendrez au règlement de base.

      Étape 8 – Retour à votre règlement de base

      Dans cette dernière section, vous reviendrez à votre règlement de base. C’est une étape rapide qui vous ramènera à un état de fonctionnalité minimaliste.

      Ouvrez le règlement de base avec la commande suivante :

      Supprimez le règlement actuel dans votre fichier et remplacez-le par le règlement de base suivant :

      /etc/pf.conf

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Enregistrez et quittez le fichier.

      Rechargez le règlement :

      • sudo pfctl -f /etc/pf.conf

      S’il n’y a pas d’erreurs de la commande, alors il n’y a pas d’erreurs dans votre règlement et votre pare-feu fonctionne correctement.

      Vous devez également désactiver l’interface pflog1 que vous avez créée. Comme vous ne savez peut-être pas encore si vous en avez besoin, vous pouvez désactiver pflog1 avec l’utilitaire sysrc : 

      • sudo sysrc pflog1_enable="NO"

      Supprimez maintenant le fichier /etc/hostname.pflog1 du répertoire /etc :

      • sudo rm /etc/hostname.pflog1

      Avant de vous déconnecter, redémarrez le serveur une fois de plus pour vous assurer que toutes vos modifications sont actives et persistantes :

      Attendez quelques minutes avant de vous connecter à votre serveur.

      Si vous souhaitez mettre en œuvre la PF avec un serveur web, voici un ensemble de règles pour ce scénario. Cet ensemble de règles constitue un point de départ suffisant pour la plupart des applications web.

      Simple Web Server Ruleset

      vtnet0 = "vtnet0"
      icmp_types = "{ echoreq unreach }"
      table <bruteforce> persist
      table <webcrawlers> persist
      table <rfc6890> { 0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16          
                        172.16.0.0/12 192.0.0.0/24 192.0.0.0/29 192.0.2.0/24 192.88.99.0/24    
                        192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24            
                        240.0.0.0/4 255.255.255.255/32 }
      
      set skip on lo0
      scrub in all fragment reassemble max-mss 1440
      antispoof quick for $vtnet0
      block in quick on $vtnet0 from <rfc6890>
      block return out quick on egress to <rfc6890>
      block all
      pass in on $vtnet0 proto tcp to port { 22 } 
          keep state (max-src-conn 15, max-src-conn-rate 3/1, 
              overload <bruteforce> flush global)
      pass in on $vtnet0 proto tcp to port { 80 443 } 
          keep state (max-src-conn 45, max-src-conn-rate 9/1, 
              overload <webcrawlers> flush global)
      pass out proto { tcp udp } to port { 22 53 80 123 443 }
      pass inet proto icmp icmp-type $icmp_types
      

      Cela crée une table de surcharge appelée <webcrawlers>, qui a une politique de surcharge plus libérale que votre port SSH basée sur les valeurs de max-src-conn 45 et max-src-conn-rate. C’est parce que toutes les surcharges ne sont pas le fait de mauvais acteurs. Elles peuvent également provenir de netbots non malveillants, ce qui vous permet d’éviter des mesures de sécurité excessives dans les ports 80 et 443. Si vous décidez de mettre en œuvre le règlement du serveur web, vous devez ajouter la table <webcrawlers> au fichier /etc/pf.conf, et supprimer les PA de la table périodiquement. Pour cela, reportez-vous à l’étape 5.

      Conclusion

      Dans ce tutoriel, vous avez configuré PF sous FreeBSD 12.1. Vous disposez maintenant d’un ensemble de règles de base qui peut servir de point de départ pour tous vos projets FreeBSD. Pour plus d’informations sur PF, consultez les pages de manuel pf.conf(5).

      Visitez notre page thématique sur FreeBSD pour plus de tutoriels et de questions-réponses.



      Source link