scieee AI-readable full text Open interactive document viewer

Análisis, documentación e implantación del analizador de red nftables en sistemas Linux

Rodríguez López, Francisco Javier

Abstract

Actualmente, la seguridad de la información y de nuestros equipos, ha ido cobrando más y más importancia. Ante este aumento en la concienciación sobre la importancia de nuestros datos surgen un sin fin de herramientas que nos permiten bastionar y securizar los sistemas. Este proyecto nace del desconocimiento de una nueva herramienta como es nftables, y busca aclarar aspectos acerca del comportamiento de esta, así como ejemplificar escenarios donde se pueda ver con detalle el uso de sus diferentes opciones, así como el comportamiento real de la misma (ya que en muchos casos dista bastante de la información imprecisa e inexacta que se encuentra en la red). También se busca dar respuesta no solo al funcionamiento e implementación de los módulos de nftables, sino estudiar su comportamiento en conjunción con los módulos NAT y Conntrack. El enfoque de este proyecto es práctico, por lo que cada explicación teórica, usará un escenario para ejemplificar y mostrar el uso de la misma. El proyecto se abordará con un enfoque ascendente, y se comenzará explicando las opciones básicas del mismo, así como su configuración, y se irá avanzando por los distintos temas, hasta finalizar abordando el uso de los módulos de esta.

Full text

Equation Chapter 1 Section 1 Trabajo Fin de Grado Grado en Ingeniería de las Telecomunicaciones Análisis, Documentación e Implantación del analizador de red nftables en sistemas Linux Autor: Francisco Javier Rodríguez López Tutor: Javier Muñoz Calle Dpto. Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2021 ii iii Trabajo Fin de Grado Grado en Ingeniería de las Telecomunicaciones Análisis, Documentación e Implantación del analizador de red nftables en sistemas Linux Autor: Francisco Javier Rodríguez López Tutor: Profesor titular Javier Muñoz Calle Dpto. de Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2021 iv v Trabajo Fin de Grado: Análisis, Documentación e Implantación del analizador de red nftables en sistemas Linux Autor: Francisco Javier Rodríguez López Tutor: Javier Muñoz Calle El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario: Acuerdan otorgarle la calificación de: Sevilla, 2021 El Secretario del Tribunal vi vii A mi familia A mi pareja A mis abuelos A mis amigos A mis maestros viii ix Agradecimientos En este punto, me gustaría agradecer a todas aquellas personas que me han apoyado y animado a cumplir esta meta de ser ingeniero en telecomunicaciones. Principalmente a mi familia, a mis padres y a mi hermana por estar ahí siempre que las cosas no salían como estaban previstas, por apoyarme y animarme a seguir adelante, por aguantar las noches programando y estudiando, por enseñarme los principios que hoy marcan mi día a día y por brindarme la posibilidad de estudiar esta carrera. Me faltan días para agradeceros todo lo que hacéis por mí. A mi pareja, sabes que, sin tí , esto no hubiera sido posible y que al igual que has estado para mí como pilar fundamental en mis días, yo estaré ahí siempre para tí. A mis telequitos, sin ustedes la salud mental la habría perdido hace mucho, gracias porque vuestros son los mejores recuerdos que tengo guardado en ese edificio de paredes rojas, por el apoyo y las regañinas. Porque todavía nos queda mucho por disfrutar y ahora es cuando comienza otra etapa. A mis grupo de los salesianos(los papitos), porque hacéis que los meses sean un poco menos malos y por el apoyo que habéis dado y aunque el trabajo nos lleve a ciudades distintas, siempre nos quedará discord, las quedadas y el LoL. A mi tutor Javier Muñoz Calle y a Pablo Neira, por guiarme por este proyecto tan complicado y aportar para que pudiera salir adelante. Y por último, pero no por ello menos importante, a dos personas que no han podido ver como se llegaba al final de este largo y duro camino, mis logros son también los vuestros. Gracias por que me disteis el regalo más bonito que se podía dar, el pasar tiempo a vuestro lado. Francisco Javier Rodríguez López Sevilla, 2021 xvi 6.1.1 Ejemplo de clasificación de estados 64 6.2 Connection tracking Linux 66 6.2.1 Entrada conntrack TCP 69 6.2.2 Entrada conntrack UDP 71 6.2.3 Entrada conntrack ICMP 72 6.2.4 Ejemplo de Seguimiento de Conexiones 75 6.3 TCP Conntrack 79 6.3.1 Ejemplo conntrack TCP. 80 6.3.2 Ejemplo conntrack TCP invalid. 90 6.4 UDP Conntrack 97 6.4.1 Ejemplo UDP conntrack. 98 6.5 ICMP Conntrack 102 6.5.1 Ejemplo ICMP conntrack. 102 6.5.2 Ejemplo ICMP conntrack reject. 106 6.6 Parámetros Conntrack 111 6.7 Helpers 115 6.8 Pruebas escenario con módulo ct (Connection Tracking) 129 6.8.1 Ejemplo mark 129 6.8.2 Ejemplo state 132 Traducción de direcciones (NAT) 137 7.1 Snat y Masquerade 137 7.1.1 Ejemplo Snat 137 7.1.2 Ejemplo Masquerade 144 7.2 Dnat y Redirect 147 7.2.1 Ejemplo Redirect 148 7.3 El módulo conntrack en NAT 151 7.3.1 Stateless NAT 151 7.3.2 Stateful NAT 156 7.4 Ejemplo Redirect en Prerouting 163 7.5 Ejemplo Redirect en Output 170 7.6 Ejemplo NAT Asimétrico 176 Filtrado de paquetes 185 8.1 Conjuntos Dinámicos 185 8.1.1 Ejemplo de port-knocking 186 8.2 Mapas Dinámicos 192 8.2.1 Ejemplo mapa direcciones IP 193 8.2.2 Ejemplo mapa protocolos 196 8.3 Medidas de tráfico 201 8.3.1 Limitación de ratio 201 8.3.2 Quotas 203 8.3.3 Contadores nombrados 206 8.4 Ejemplo lista negra 208 Conclusiones 213 9.1 Objetivos conseguidos 213 9.2 Futuras líneas de investigación 215 Anexo A - Tecnologías Usadas Y herramientas 217 VMWare 217 Wireshark y TCPdump 221 Hping3, Curl 222 Anexo B - Instalación Nftables 225 Instalación de dependencias 225 Instalación de Nftables 228 xvii Anexo C - Instalación Conntrack-Tools 231 Instalación dependencias de Conntrack-tools 231 Instalación de Conntrack-tools 232 Anexo D - Instalación y Configuración Firewalld 233 Instalación de dependencias Firewalld 233 Instalación de Firewalld 235 Configuración de Firewalld 236 Anexo E - Escenario 2 Equipos 243 Configuración del equipo PC1 244 Configuración del equipo Encaminador 246 Anexo F - Escenario 3 Equipos 249 Configuración del equipo PC1 250 Configuración del equipo PC2 252 Configuración del equipo Encaminador 255 Caso específico: Escenario NAT Asimétrico 258 Configuración del equipo Router NAT 259 Anexo G - CheatSheet Nftables 261 Línea de comandos CheatSheet 261 Módulos CheatSheet 263 Conntrack-Tools CheatSheet 269 Anexo H - Repaso Protocolos (TCP,UDP,ICMP) 271 Protocolo TCP (Transmission Control Protocol) 271 Cabecera TCP 271 Establecimiento de la conexión TCP 272 Cierre de la conexión TCP 273 Protocolo UDP (User Datagram Protocol) 275 Cabecera UDP 275 Protocolo ICMP (Internet Control Message Protocol) 276 Cabecera ICMP 276 Anexo I - Concepto Conexión 281 Protocolo orientado a conexión. 281 Socket de conexión. 281 Conexión en conntrack 282 Referencias 283 xviii xix ÍNDICE DE TABLAS Tabla 1 - Familias nftables 11 Tabla 2 - Tipos de cadenas 14 Tabla 3 - Enganches Netfilter 15 Tabla 4 - Prioridades de las cadenas 15 Tabla 5 - Acciones terminales reglas 22 Tabla 6 - Acciones no terminales 28 Tabla 7 - Zonas Firewalld 52 Tabla 8 - Puertos y servicios libvirt Firewalld 58 Tabla 9 - Estados conntrack 62 Tabla 10 - Campos de la entrada conntrack TCP 70 Tabla 11 - Campos de la entrada conntrack UDP 72 Tabla 12 - Campos de la entrada conntrack ICMP 74 Tabla 13 - Estados entradas conntrack 74 Tabla 14 - Valores por defecto estados TCP 79 Tabla 15 - Resumen paquetes TCP invalid 97 Tabla 16 - Variables configuración conntrack 114 Tabla 17 - Campos de la entrada conntrack expectation 125 Tabla 18 - Protocolos con helper en conntrack 129 Tabla 19 - Resumen escenario 2 equipos 243 Tabla 20 - Resumen escenario 3 equipos 249 Tabla 21 - Resumen escenario NAT asimétrico 258 Tabla 22 - CheatSheet comando table 261 Tabla 23 - CheatSheet comando chain 262 Tabla 24 - CheatSheet comando rule 262 Tabla 25 - CheatSheet módulo Ip 263 Tabla 26 - CheatSheet módulo TCP 264 Tabla 27 - CheatSheet módulo UDP 265 Tabla 28 - CheatSheet módulo ICMP 265 Tabla 29 - CheatSheet módulo ether 266 Tabla 30 - CheatSheet módulo ARP 266 Tabla 31 - CheatSheet módulo ct 267 Tabla 32 - CheatSheet módulo meta 269 xx Tabla 33 - CheatSheet Conntrack-Tools 269 Tabla 34 - Cabecera TCP 272 Tabla 35 - Cabecera UDP 275 Tabla 36 - ICMP Destination Unreachable 276 Tabla 37 - ICMP Redirect 277 Tabla 38 - ICMP Echo-request 277 Tabla 39 - ICMP Echo-reply 278 Tabla 40 - Tipo mensajes ICMP 279 xxi ÍNDICE DE FIGURAS Figura 2.1- Últimas versiones Herramientas Netfilter 3 Figura 2.2 - (Fortigate 60F) 5 Figura 3.1 - Versión del kernel 7 Figura 3.2 - Comprobación instalación 8 Figura 3.3 - Módulos cargados en el kernel 9 Figura 3.4 - Listar tablas 12 Figura 3.5 - Ejemplo 1 cadena usuario 17 Figura 3.6 - Resultado ejemplo 1 cadena usuario 18 Figura 3.7 - Ejemplo 2 cadena usuario 19 Figura 3.8 - Resultado Ejemplo 2 cadena usuario 20 Figura 3.9 - Iptables translate 22 Figura 3.10 - Ejemplo reject 23 Figura 3.11 - Resultado ejemplo reject 24 Figura 3.12 - Ejemplo return, accept y drop 26 Figura 3.13 - Resultado ejemplo return, accept y drop 27 Figura 3.14 - Ejemplo acción log 29 Figura 3.15 - Resultado del ejemplo log 30 Figura 3.16 - Ejemplo posición counter 31 Figura 3.17 - Resultado ejemplo posición counter 32 Figura 4.1 - Flow de paquetes de Nftables 33 Figura 4.2 - Bridge Flow 34 Figura 4.3 - ARP Flow 35 Figura 4.4 - IP Flow 35 Figura 4.5 - Armazón hooks escenario flow 37 Figura 4.6 - Reglas escenario flow 39 Figura 4.7 - Prueba ICMP PC1 escenario flow 39 Figura 4.8 - Nftrace ICMP local, entrada 40 Figura 4.9 - Nftrace ICMP local Salida 40 Figura 4.10 - Logs del ICMP local al pasar por los hooks 41 Figura 4.11 - Resumen camino ping a Encaminador 41 Figura 4.12 - Nftrace ICMP externo entrada 42 xxii Figura 4.13 - Logs del ICMP externo al pasar por los hooks 43 Figura 4.14 - Resumen camino ping a DNS Google 43 Figura 4.15 - Reglas escenario flow interfaz lo 45 Figura 4.16 - Nftrace ICMP req interfaz lo 45 Figura 4.17 - Nftrace ICMP rep interfaz lo 46 Figura 4.18 - Regla ingress interfaz lo 47 Figura 4.19 - Captura Wireshark interfaz lo 47 Figura 4.20 - Registro logs ICMP interfaz lo 48 Figura 4.21 - Resumen camino ping lo 48 Figura 5.1 - Estado servicio Firewalld 53 Figura 5.2 - Zonas definidas básicas 54 Figura 5.3 - Configuración zona Internal 55 Figura 5.4 - Arranque del servidor Apache 55 Figura 5.5 - Flujo conexión Apache (Internal) 56 Figura 5.6 - Página test Apache(Internal) 56 Figura 5.7 - Redirección de puertos (Internal) 57 Figura 5.8 - Reglas libvirt Firewalld 58 Figura 5.9 - Reglas zona Internal Firewalld 59 Figura 5.10 - Reglas forward Firewalld 59 Figura 6.1 - Puntos de clasificación de los paquetes con conntrack 63 Figura 6.2 - Estructura de cadenas y reglas del ejemplo de clasificación 65 Figura 6.3 - Contadores de las reglas del ejemplo de clasificación de estados 65 Figura 6.4 - Creación de las entradas conntrack 68 Figura 6.5 - Entrada conntrack TCP extendido 69 Figura 6.6 - Entrada conntrack UDP extendido 71 Figura 6.7 - Entrada conntrack ICMP extendido 72 Figura 6.8 - Estados entradas conntrack modo monitor 74 Figura 6.9 - Mostrar entradas conntrack 75 Figura 6.10 - Añadir regla counter en prerouting 76 Figura 6.11 - Reglas NAT escenario 2 equipos 76 Figura 6.12 - Tabla de conexiones con tuplas 76 Figura 6.13 - Conexiones con servidores web 77 Figura 6.14 - Entrada conexión con servidor trajano.us.es 77 Figura 6.15 - Flujo de conexión con servidor trajano 77 Figura 6.16 - Eliminación de tuplas 78 Figura 6.17 - Mostrar el número de entradas que tiene conntrack 78 Figura 6.18 - Estados TCP definidos en el código de Netfilter 79 Figura 6.19 - Estructura TCP conntrack 81 Figura 6.20 - Camino paquete TCP SYN 82 xxiii Figura 6.21 - Camino paquete TCP SYN-ACK 83 Figura 6.22 - Camino paquete TCP ACK 83 Figura 6.23 - Esquema estados conntrack TCP handshake 84 Figura 6.24 - Entradas conntrack paquete TCP 85 Figura 6.25 - Flow ejemplo TCP handshake conntrack 85 Figura 6.26 - Camino paquete TCP FIN-ACK PC1 85 Figura 6.27 - Camino paquete TCP FIN-ACK Encaminador 86 Figura 6.28 - Camino paquete TCP ACK cierre conexión 87 Figura 6.29 - Entradas conntrack cierre conexión TCP 87 Figura 6.30 - Esquema estados conntrack TCP close connection 88 Figura 6.31 - Flow ejemplo TCP cierre conexión conntrack 89 Figura 6.32 - Envejecimiento entrada conntrack 89 Figura 6.33 - Entradas conntrack del cierre de conexión del Encaminador 89 Figura 6.34 - Camino TCP PSH 92 Figura 6.35 - Camino TCP URG 93 Figura 6.36 - Camino TCP RST 93 Figura 6.37 - Camino TCP FIN 94 Figura 6.38 - Camino TCP ACK 94 Figura 6.39 - Camino TCP SYN 95 Figura 6.40 - Camino TCP SYN-ACK 96 Figura 6.41 - Entrada conntrack TCP-SYN 96 Figura 6.42 - Entrada conntrack TCP-ACK 97 Figura 6.43 - Camino de un paquete UDP 99 Figura 6.44 - Captura de paquete UDP 99 Figura 6.45 - Comando nslookup para consultar DNS 100 Figura 6.46 - Entradas conntrack paquete UDP 100 Figura 6.47 - Esquema estados conntrack UDP 101 Figura 6.48 - Camino paquetes conntrack UDP 101 Figura 6.49 - Captura echo-request y echo-reply ICMP conntrack 104 Figura 6.50 - Camino paquete echo-request 104 Figura 6.51 - Entradas conntrack creadas por comunicación ICMP 105 Figura 6.52 - Envío de paquete echo-reply 106 Figura 6.53 - Reglas reject de ICMP 107 Figura 6.54 - Paquete reject con estado related 108 Figura 6.55 - Respuesta de la regla reject 108 Figura 6.56 - Camino paquete echo-request ejemplo reject 109 Figura 6.57 - Camino paquete echo-reply generado por reject 109 Figura 6.58 - Evento conntrack del request del ejemplo reject 110 Figura 6.59 - Entrada conntrack del request del ejemplo reject 111 xxiv Figura 6.60 - Aumento del contador related de ICMP 111 Figura 6.61 - Valores parámetros conntrack en Encaminador 114 Figura 6.62 - Reglas para ct ftp-1 118 Figura 6.63 - Reglas para ct ftp-2 118 Figura 6.64 - Conexión FTP desde PC1 119 Figura 6.65 - Paquete TCP SYN flujo control FTP 120 Figura 6.66 - Paquete TCP SYN-ACK flujo control FTP 121 Figura 6.67 - Paquete TCP ACK flujo control FTP 122 Figura 6.68 - Entradas conntrack conexión flujo de control FTP. 122 Figura 6.69 - Campos de una entrada expectation conntrack 123 Figura 6.70 - Paquete TCP SYN flujo datos FTP 125 Figura 6.71 - Paquete TCP SYN-ACK flujo datos FTP 126 Figura 6.72 - Paquete TCP ACK flujo datos FTP 127 Figura 6.73 - Entradas conntrack ejemplo FTP 127 Figura 6.74 - Entrada conntrack en la tabla expect, ejemplo FTP 128 Figura 6.75 - Reglas ejemplo ct mark 131 Figura 6.76 - Ping PC1 ejemplo ct mark 131 Figura 6.77 - Flujo de conexión ejemplo ct mark 0x2 132 Figura 6.78 - Ruleset ejemplo ct state 133 Figura 6.79 - Flujo conexión servidor Apache 134 Figura 6.80 - Captura Tráfico conexión PC1 servidor Apache de Encaminador 134 Figura 6.81 - Petición a Google desde PC1 135 Figura 6.82 - Captura tráfico sin resolución DNS PC1 135 Figura 6.83 - Aumento de paquetes drop en la cadena forward 135 Figura 7.1 - Intento conexión trajano desde PC1 sin NAT 138 Figura 7.2 - Petición DNS lanzada por PC1 sin NAT en Encaminador 138 Figura 7.3 - Petición DNS de PC1 sale por Encaminador sin NAT 139 Figura 7.4 - Armazón ejemplo Snat y Dnat 140 Figura 7.5 - Regla Snat en Encaminador 140 Figura 7.6 - Paquete Req y Res DNS 141 Figura 7.7 - Paquete Req y Res DNS con Snat aplicado en Encaminador 141 Figura 7.8 - Conexión con Servidor web Trajano 142 Figura 7.9 - Captura ens38 Encaminador conexión Trajano con Snat completo 142 Figura 7.10 - Captura ens33 Encaminador conexión Trajano Snat completo 143 Figura 7.11 - Reglas y contadores Snat de Encaminador 143 Figura 7.12 - Captura ens38 Encaminador usando Masquerade 145 Figura 7.13 - Captura ens33 Encaminador usando Masquerade 145 Figura 7.14 - Nueva dirección IP ens33 con Masquerade 146 Figura 7.15 - Captura ens38 Encaminador con Masquerade nueva IP 146 xxv Figura 7.16 - Captura ens33 Encaminador con Masquerade nueva IP 147 Figura 7.17 - Reglas y contadores Masquerade de Encaminador 147 Figura 7.18 - Redirect de servidor Apache al de la máquina Encaminador 149 Figura 7.19 - Servidor Apache servido a PC2 con redirect en Encaminador 149 Figura 7.20 - Petición Apache de Encaminador puerto 80 con redirect de puerto 150 Figura 7.21 - Petición Apache de Encaminador puerto 452 con redirect de puerto 150 Figura 7.22 - Página web servida desde el puerto 452 de Encaminador con Redirect 151 Figura 7.23 - Camino Icmp-request Stateless NAT 154 Figura 7.24 - Camino Icmp-reply Stateless NAT 155 Figura 7.25 - Reglas y contadores Stateless NAT 156 Figura 7.26 - Carencia de tablas conntrack Stateless NAT 156 Figura 7.27 - Camino masquerade Stateful NAT 158 Figura 7.28 - Entrada conntrack NAT 159 Figura 7.29 - Trace para ver el cambio inverso de NAT 160 Figura 7.30 - Contadores para comprobar cambio inverso de NAT 160 Figura 7.31 - Argumento notrack y carencia de cadena nat 161 Figura 7.32 - Tras quitar argumento notrack, cadena prerouting tipo nat 162 Figura 7.33 - Camino ping PC1 redirect en prerouting 165 Figura 7.34 - Captura PC1 ping redirect en prerouting 166 Figura 7.35 - Entrada conntrack NAT ICMP redirect en prerouting 166 Figura 7.36 - Monitor conntrack NAT ICMP redirect en prerouting 166 Figura 7.37 - Camino TCP redirect en prerouting 167 Figura 7.38 - Monitor conntrack TCP redirect en prerouting 168 Figura 7.39 - Camino UDP redirect en prerouting 168 Figura 7.40 - Monitor conntrack UDP redirect prerouting 169 Figura 7.41 - Actualizada entrada UDP redirect en prerouting 169 Figura 7.42 - Estructura nftables Redirect en prerouting 170 Figura 7.43 - Estructura redirect en output 172 Figura 7.44 - Camino ICMP externo redirect en output 173 Figura 7.45 - Camino ICMP interno redirect en output 174 Figura 7.46 - Camino completo ICMP redirect en output 175 Figura 7.47 - Captura tráfico interfaz “lo”, redirect en output 176 Figura 7.48 - Entradas NAT conntrack , redirect en output 176 Figura 7.49 - Estructura nftables Encaminador, escenario asimétrico 179 Figura 7.50 - Regla Router NAT escenario asimétrico 180 Figura 7.51 - Captura interfaz ens37 PC1 escenario asimétrico 181 Figura 7.52 - Camino echo-request Encaminador en escenario asimétrico 181 Figura 7.53 - Captura interfaz ens39 Encaminador en escenario asimétrico 182 Figura 7.54 - Captura ens37 Router NAT escenario asimétrico 182 2 3. En este punto se estudiará el camino natural que siguen los paquetes tanto en la herramienta como en su trascurso por el núcleo de Linux. 4. El siguiente punto del trabajo pretenderá darnos una visión de qué son los managers, como funcionan y el análisis del uso básico de uno de ellos, en este caso el elegido ha sido Firewalld, del cual hablaremos más adelante. 5. Los siguientes tres puntos, se basarán en explicar y dar una visión amplia del uso de nftables con sus tres principales módulos/usos, el seguimiento de conexiones (conntrack), el filtrado de paquetes que atraviesen nuestro sistema firewall, y la traducción de direcciones (NAT). Esto lo conseguiremos mediante el planteamiento de escenarios de pruebas a través de los cuales pretendemos ampliar la visión del uso de los mismos, así como plantear ejemplos y pruebas que el lector podrá simular para comprobar el correcto funcionamiento, dando así la base que permita probar nuevas funcionalidades que puedan surgir en un futuro. La estructura de estos tres puntos será la siguiente: • Se realizará una primera aproximación al módulo a analizar, comandos, funcionalidades, etc… • Se planteará la creación de un escenario de pruebas el cuál se configurará paso a paso en los Anexos de este documento para crear la estructura general y en el capítulo correspondiente plantearemos los cambios más específicos. • Se hará la realización de pruebas sobre el mismo, adjuntando capturas de pantalla de la configuración de la herramienta, de los logs generados, así como del sniffer de paquetes. Como sniffer, se decide usar Wireshark, para realizar la captura de tráfico en el equipo Encaminador. 6. Y por último se incluirá un punto que contendrá las conclusiones sacadas de la realización de este proyecto, así como la opinión de la herramienta tras explorar a fondo el uso de la misma. A lo largo del proyecto, se realizan referencias a diferentes webs o pdfs, consultados para la investigación de este proyecto. En este punto , se debe hacer una advertencia y es que la mayoría de esos documentos o webs tiene una cantidad considerable de inexactitudes con respecto al funcionamiento de Netfilter o de su framework. Por ello se aconseja al lector que tome estas fuentes con cautela, ya que diferentes referencias pueden indicar comportamientos distintos de la misma herramienta. 1.3 Alcance y Objetivos El alcance de este proyecto busca desarrollar una guía que sirva como base para el entendimiento y puesta en funcionamiento de la herramienta nftables. Buscamos también la creación de escenarios de prueba que permitan comprender la actuación de las reglas, así como el análisis de los módulos más importantes de esta herramienta. Al ser nftables un proyecto que se encuentra vigente y que va actualizándose con cierta asiduidad, se ha determinado tomar una versión concreta de este y trabajar sobre ella, por lo cual, se dejará claro la versión de la herramienta usada, así como las versiones de compilación del kernel y de los sistemas operativos usados. Al ser un trabajo fin de grado, el análisis exhaustivo de la herramienta con su funcionalidad completa se escapa a los límites de este proyecto, por ello el objetivo, es que el lector tome esta guía como punto de partida para el entendimiento de Netfilter y de su framework Nftables, así como mostrarle ejemplos de los diferentes tipos de reglas y módulos que se pueden usar, basándonos en escenarios simples que no añadan complejidad a la comprensión del mismo. 3 ESTADO DEL ARTE Nftables es un proyecto que pertenece a Netfilter, el cual busca desarrollar el framework que será el sustituto de iptables. Ambos proyectos son herramientas que nos permiten tener en nuestro sistema Unix un firewall de paquetes de nivel 4 (capa de transporte). Actualmente la última versión estable lanzada de nftables es la 0.9.7 lanzada el 27 de octubre de 2020, mientras que la de iptables es la versión 1.8.6 lanzada el 31 de octubre de 2020 tal como se muestra en la Figura 2.1. Figura 2.1- Últimas versiones Herramientas Netfilter 2.1 Estado actual de la herramienta Ahora mismo la página de Netfilter nos indica que iptables está siendo reemplazada, y recomiendan la migración a su nueva herramienta nftables, así mismo, esto también ocurre con herramientas como ebtables[4] y arptables[5]. A pesar de esto, estas herramientas todavía reciben actualizaciones y parches de soporte, aunque como se indica, al estar marcadas como descontinuadas, los parches cada vez son menos frecuentas y piden la migración a su nueva herramienta, la cual engloba las funcionalidades de las herramientas anteriormente mencionadas. Aunque nftables es el sustituto natural y al que ya se recomienda su migración, existe una falta de documentación oficial de esta herramienta, situación que no ocurría con las herramientas anteriores como bien se puede comprobar. Este problema está siendo subsanado y se busca cada vez más documentar de forma más completa la wiki de la herramienta, la cual contiene explicaciones muy breves de algunos módulos, así como una descripción de las novedades que la herramienta incorpora en sus nuevas versiones. Este proyecto servirá del mismo modo para complementar y ampliar la información de la wiki. La wiki[6] además contiene una pequeña guía para instalar la herramienta mediante su código fuente, así como algunos ejemplos “cortos” de comandos y reglas para nftables. Nftables ya se encuentra disponible en las últimas versiones de los sistemas Unix. En S.O RedHat[7], el framework de nftables viene instalado de forma nativa, debido a que la gran mayoría de usuarios sigue usando iptables, esta viene con la implementación de la capa de adaptación, la cual permite escribir nuestras reglas en iptables y que esta se encargue de traducirlas a sintaxis de nftables. Pero, ¿a qué es debido que esté costando tanto la transición de iptables a nftables? 4 Tanto los usuarios como los desarrolladores de managers o herramientas de gestión de reglas, tienen su código preparado para trabajar con iptables, el hecho de que nftables abandone esa sintaxis para abrazar una más intuitiva, como es la usada por tcpdump, ha generado parte de rechazo. Este cambio de sintaxis, aunque resulte más amistoso para el usuario, implica la actualización de muchas herramientas, impidiendo que estas puedan actualizarse mediante el uso de parches, ya que en la mayoría de casos implica la creación de una nueva herramienta, partiendo de la generación de un nuevo código que acepte esta nueva sintaxis. Es por ello que managers ampliamente utilizados por la comunidad como Shorewall, Ipcop, Ipfire, han decidido no migrar. Existen otros proyectos que ya han comenzado la migración, permitiendo trabajar con iptables y nftables, un caso de estos es Suricata[9] y Firewalld[10], aunque como hemos mencionado anteriormente, carecen de explicaciones o información que ilumine esta transición, encontrándose la gran mayoría de sus documentos basados en iptables. Suricata apenas concede información acerca de la manipulación de reglas y creación de estas con nftables, de hecho, si accedemos a sus documentos y sus guías, en ellas aparece explicado con detalle el uso que se realiza con iptables y solo una primera aproximación con nftables. Lo mismo ocurre en este caso con Firewalld, a pesar de indicar que la herramienta puede trabajar de forma nativa con nftables, si accedemos a la documentación de la misma podemos darnos cuenta que toda la guía viene realizada en base a iptables y que apenas se encuentran menciones de nftables. Esta es una de las razones principales de la lenta migración que se está produciendo hacia esta nueva herramienta. 2.2 Estudio de Mercado En esta sección vamos a realizar el estudio de mercado de los firewalls en la actualidad. Debemos saber que, aunque nosotros usamos herramientas de software libre como puede ser iptables/ipsec/nftables etc…, no son las más usadas en ambientes profesionales o de negocios. Las grandes empresas suelen decantarse por equipos hardware que realizan la función de firewall y por código propietario antes que por software libre. Es por ello que, en la mayoría de los casos, es habitual encontrarnos con firewalls de empresas tales como Fortinet[12], Cisco[13], Zyxel[14], Palo Alto[15] etc… Esto se debe a que estas empresas ofrecen un mejor soporte y seguimiento del producto de lo que podemos obtener con herramientas de software libre. Es verdad que seguimos encontrándonos a estas herramientas en pequeños escenarios como pueden ser servidores de pequeñas empresas, laboratorios, clases etc…, pero lo normal, es que una empresa quiera cierta seguridad a la hora de proteger su entorno. A pesar de que con el software libre podemos conseguirlo, necesitamos de una buena configuración, la cual, requiere una buena inversión de tiempo. Los firewalls de empresas como las mencionadas anteriormente, ocultan la complejidad de la configuración y de la inversión de tiempo, que requieren los firewalls de software libre, es por ello que las empresas se decantan por esta solución, teniendo por contrapunto el costo de las mismas. Estos productos no suelen ser baratos y van desde precios tales como los 500 euros del producto más básico de Fortinet (Fortigate 60F), un dispositivo que nos permite administrar la seguridad de una red con un total de 10 puertos, hasta unos 6.459 euros por un equipo firewall de Cisco (ASR1000-2T). 5 Figura 2.2 - (Fortigate 60F) Por ello muchas empresas realizan auditorías para saber el nivel de seguridad necesario en sus redes y adaptar una solución acorde a las necesidades de esta. Estos equipos no solo proveen del sistema hardware, sino que cada uno tienen su propio sistema software para la inspección de paquetes, toma de decisiones, seguimiento de conexiones etc… En nuestro caso Netfilter provee una solución software (Nftables) que permite ser instalada en un equipo con una distribución Linux (Debian, Ubuntu, Kali, CentOS …) y hacer que este equipo funcione como firewall en nuestra red. Por lo cual, podemos observar, porqué este tipo de soluciones no son adoptadas por medianas/grandes empresas, que en su mayoría prefieren recurrir a soluciones más completas y que ya provean el equipo, dando un mayor soporte del que se puede conseguir con esta herramienta. 6 7 NFTABLES INTRODUCCIÓN En el siguiente capítulo se analizarán las partes que conforman la herramienta nftables, así como conocimientos que se deben aclarar acerca de cómo se realiza la obtención de los diferentes paquetes de red y comandos básicos para crear las estructuras, en las que más tarde se profundizará. Lo primero que se va a ver, es la instalación de la herramienta, en este apartado se explicará la instalación usando los repositorios de nuestro sistema Debian[16] y más adelante, en el “Anexo B - Instalación Nftables”, veremos la instalación desde código fuente para un sistema Debian. Se recomienda revisar del mismo el “Anexo H - Repaso Protocolos (TCP,UDP,ICMP)”, en el cual, se realiza un repaso de los conceptos básicos de los protocolos y sus mensajes. 3.1 Instalación Nftables La instalación de esta herramienta se llevará a cabo en el equipo Encaminador y a continuación se detallarán los pasos para realizarla, así como las comprobaciones de cada uno de los pasos para asegurarnos de que la instalación se realiza correctamente. 1. [Equipo:Encaminador - Usuario:dit] Para la instalación, lo primero que se debe realizar es la actualización del kernel, para ello se ejecutan los siguientes comandos: Equipo:Encaminador Usuario:dit $ sudo apt-get update $ sudo apt-get upgrade Con esto ya se tendrá el sistema actualizado, para comprobarlo se puede hacer uso del siguiente comando, el cual imprimirá la información del sistema y la versión de su kernel, pudiendo observar en la Figura 3.1 el resultado. Equipo:Encaminador Usuario:dit $ hostnamctl Figura 3.1 - Versión del kernel 8 En la Figura 3.1, se puede comprobar que se usa una distribución de Linux - Debian 18.04.5 y que la versión del kernel es 4.15.0-129-generic[17]. Una vez llegados a este punto, se tendrá que tener en cuenta las dependencias de la herramienta, que no son más que los módulos o las bibliotecas necesarias para el correcto funcionamiento de la misma. En este caso se debe tener instalados en el equipo los siguientes paquetes: • Libmnl [18]: Es una librería usada por Netfilter para el desarrollo de su framework, la cual tiene como principal ventaja, evitar la complejidad de las abstracciones a la hora de trabajar con los elementos del núcleo de Netfilter. Por lo que esta librería provee de los helpers necesarios para conseguir ese nivel de abstracción. • Libnftnl [19]: Esta librería provee de una API de bajo nivel a Netlinks, siendo esta librería la que permite la comunicación entre la API y el módulo de Netlinks. • Libgmp [20]: Es un paquete que nos permite operar con una librería matemática para la manipulación de enteros, flotantes, entre otros tipos de datos. • Libreadline [21]: Esta librería nos proporciona las funciones necesarias para que nuestro programa pueda interpretar los comandos escritos por la entrada estándar (la línea de comandos). Estas son las principales dependencias de la herramienta como se podrá ver en el “Anexo B - Instalación Nftables”, estas a su vez, dependen de otros módulos que deberemos descargar e instalar. Todo esto se encuentra indicado en su anexo. 2. [Equipo:Encaminador - Usuario:dit] Se procede entonces a la instalación usando repositorios. Equipo:Encaminador Usuario:dit $ sudo apt-get install nftables Una vez escrito el comando, se procederá a la instalación de nftables, se debe tener en cuenta que hay sistemas que ya traen de manera nativa esta herramienta instalada, en caso de que el sistema no la traiga, se procederá siguiendo estos sencillos pasos para instalar la herramienta en el sistema. 3. [Equipo:Encaminador - Usuario:dit] Para comprobar que la instalación se ha llevado a cabo correctamente, se hace uso del siguiente comando y se comprueba que la salida coincida con la mostrada (ver Figura 3.2). Equipo:Encaminador Usuario:root $ apt-cache policy nftables Figura 3.2 - Comprobación instalación 9 4. [Equipo:Encaminador - Usuario:dit] Una vez comprobado que se ha instalado, se tendrá que comprobar que los módulos se han cargado correctamente, para ello, se hace uso del siguiente comando. $ grep CONFIG_NFT_ /boot/config-[versión del kernel tengamos, en nuestro caso, 4.15.0-129-generic] Equipo:Encaminador Usuario:root $ grep CONFIG_NFT_ /boot/config-4.15.0-129-generic Figura 3.3 - Módulos cargados en el kernel En la Figura 3.3 se puede ver que los módulos principales se han cargado correctamente y que no hay ninguno que haya dado error o que presente alguna incompatibilidad con el sistema. Una vez realizada la instalación de la herramienta se procederá a comprobar su archivo de configuración. El archivo de configuración de nftables se encuentra en la ruta: /etc/nftables.conf . Este archivo permite guardar la estructura de tablas, cadenas y reglas que serán cargadas en el momento en el que se inicie el equipo. Por otra parte, para poder ver los módulos que se encuentran cargados actualmente en la herramienta se ha de usar el siguiente comando. Equipo:Encaminador Usuario:dit $ lsmod | grep nf_ 10 Con los módulos se pueden realizar dos operaciones, o cargarlos para ser usados o liberarlos. • [Equipo:Encaminador - Usuario:root] Para cargar un módulo concreto se usa el siguiente comando: Equipo:Encaminador Usuario:root $ modprobe nombre_módulo • [Equipo:Encaminador - Usuario:root] Para liberar un módulo concreto se usa el siguiente comando: Equipo:Encaminador Usuario:root $ rmmod nombre_módulo Llegados a este punto, se tendrá listo nftables, por lo que el siguiente paso será aprender a configurar su base, permitiendo así tener una estructura a partir de la cual poder crear las reglas que usará el sistema para trabajar con los paquetes. 3.2 Construcción básica nftables En este apartado se verá cómo preparar la estructura de tablas y cadenas para poder añadirle las reglas posteriormente. Lo primero que puede preguntarse alguien que comience con el uso de nftables es, por qué es necesario preparar una estructura inicial para usarla, cuando en iptables, bastaba con instalarla para comenzar a trabajar con ella. Y esto se debe a una explicación muy sencilla y es que en nftables no se tienen ni cadenas ni tablas definidas por defecto, de forma que depende totalmente del usuario el crearlas y configurarlas a su gusto para ser usadas. Esto representa un avance, pero conlleva un inconveniente y es que se debe conocer cómo se establecen las cadenas y tablas para poder usarlas convenientemente, en caso contrario, es posible que las reglas creadas no vean nunca tráfico o que estas tengan un comportamiento inesperado. Lo primero que se debe entender es el concepto de familias[22]. Las familias son las grandes agrupaciones en las cuales nftables divide el tráfico, es decir, dependiendo de la familia a la que se encuentre vinculada una tabla o cadena se podrá ver un tipo de tráfico u otro. Por ello se detalla las familias existentes en la Tabla 1. Familia Descripción ip Esta familia es la principal y ve todo el tráfico Ipv4 que le llegue. ip6 Esta familia permite centrarse solamente en aquel tráfico cuyo protocolo sea Ipv6. inet Esta familia se usa si se desea ver tanto tráfico Ipv4 como Ipv6. arp Esta familia, como su propio nombre indica, solo mostrará tráfico de tipo ARP. 11 bridge Esta familia solo muestra aquellos paquetes que atravesarían un switch, es decir, solamente llega a nivel 2. netdev Esta familia es especial, ya que permite trabajar con el tráfico que el driver de nuestra NIC acabe de pasar a la pila de red, de forma que esta familia será la primera en ver los paquetes del equipo. Esta familia es exclusiva de nftables y no tiene traducción en iptables. Tabla 1 - Familias nftables Como se acaba de comprobar, las familias no son más que los diferentes tipos de tráfico que se puede encontrar en nuestra red y la explicación del uso de las mismas se debe a que con iptables, solo se podía ver tráfico IP. Si se deseaba ver otro tipo de tráfico, se debía usar otras herramientas tales como ebtables, la cual permitía ver el tráfico bridge, o arptables, la cual mostraba el tráfico arp que llegaba hasta el equipo. Las familias nacen de la necesidad de agrupar todas las herramientas usadas con iptables para tratar diferentes tipos de tráfico en una sola herramienta. Una vez se ha entendido este punto se pasará a ver la sintaxis básica de la herramienta. Como ya se dijo anteriormente, la herramienta ha cambiado de sintaxis, por lo que los usuarios deben acostumbrarse a esta nueva manera de proceder. Siendo la sintaxis general de la herramienta de la siguiente forma: $ nft (Acciones) < Objeto > [Familia] < Nombre > [Opciones] • Acciones: Representa la acción que se desea realizar, ya sea crear, añadir, listar, eliminar etc… • Objeto: Representa el objeto o la parte sobre la cual se va a realizar la acción; una tabla, una cadena, una regla, un set… • Familia: Aquí es donde se decide el tipo de familia a la que pertenece el objeto y como se vio anteriormente, esta es la parte en la que define el tipo de tráfico que tratará en el sistema. • Nombre: El nombre que se le desea dar al objeto, como ya se vio con anterioridad, nftables no tiene ni cadenas ni tablas por defecto, así que pueden crearse y llamarse como el usuario desee. • Opciones: Aquí se describirán las opciones que se pueden realizar con el objeto. Estas dependerán de a qué objeto se le esté aplicando, pues no tiene las mismas opciones una tabla, una cadena, una regla etc… Se puede decir que esta es la estructura básica de un comando de nftables. A continuación, se verá la creación de una tabla, que es la unidad principal para crear las estructuras de reglas en nftables. 18 Figura 3.6 - Resultado ejemplo 1 cadena usuario Como se puede ver en la Figura 3.6, en el terminal 2 se han lanzado tres paquetes ICMP y el contador de la regla del terminal 1 muestra que ha aumentado de forma correspondiente a esta acción. Al ser la política por defecto accept se puede comprobar cómo el ping se completa. El camino que sigue el paquete ICMP es el siguiente : 1) El paquete ICMP es generado por el kernel, se toma la decisión de routing del mismo y llega a la cadena output de la tabla filter. 2) El paquete hace match con la regla de output ya que el protocolo de este es ICMP, por lo que su acción es jump a la cadena_usuario 3) En la cadena_usuario aumenta en 1 el contador que se ha creado y tras aumentarlo vuelve a la cadena desde la que saltó (output) 4) En la cadena output al no quedar más reglas, se toma como acción la que indica la política por defecto (accept). 5) El paquete continúa por postrouting y sale del equipo Encaminador. Ejemplo 2 cadena de usuario. Descripción del Ejemplo: En el siguiente ejemplo, se verá como discernir tráfico usando una cadena de usuario y de esta manera comprobar la utilidad principal de este tipo de cadenas. En el equipo Encaminador se tiene tráfico TCP, UDP e ICMP y se busca que el tráfico ICMP de salida que tenga como destino la IP: 8.8.8.8/32 ,sea denegado, mientras que el tráfico ICMP que tenga como destino la IP: 1.1.1.1/32 sea aceptado, pero además se busca saber el total de tráfico ICMP generado (sea o no aceptado) y la cantidad por separado de tráfico aceptado y denegado. Para evitar masificar con reglas la cadena base output, lo que se hace es utilizar la misma regla que en el ejemplo anterior y si el tráfico que atraviesa esta regla es de tipo ICMP, que salte a la cadena_usuario. 19 Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] En la cadena usuario se añadirán las reglas en el siguiente orden; 1) Se añade la regla de denegación de tráfico ICMP con destino a la IP: 8.8.8.8/32 y la contabilización de esta 2) Se añade la regla de aceptación de tráfico ICMP con destino a la IP: 1.1.1.1/32 y la contabilización de esta. Para ello se usa de base, el esquema del ejemplo anterior y se añaden las reglas tal y como se ha indicado, quedando el ruleset como aparece en la Figura 3.7: Equipo:Encaminador Usuario:root $ nft add rule inet filter cadena_usuario ip daddr 8.8.8.8/32 count drop $ nft add rule inet filter cadena_usuario ip daddr 1.1.1.1/32 count accept Figura 3.7 - Ejemplo 2 cadena usuario 2. [Equipo:Encaminador - Usuario:dit] Una vez creadas las reglas, se realizan los siguientes pasos. • Desde el terminal 1 se comprueba el ruleset de nftables. Equipo:Encaminador Usuario:root $ nft list ruleset • Desde el terminal 2 se realizan dos envíos ICMP con los siguientes comandos. Equipo:Encaminador Usuario:dit $ ping -c 3 1.1.1.1 $ ping -c 3 8.8.8.8 20 Figura 3.8 - Resultado Ejemplo 2 cadena usuario Como se puede ver en la Figura 3.8, se ha aceptado solo el tráfico de la IP: 1.1.1.1/32 mientras que el de la IP: 8.8.8.8/32 se ha denegado. Además, se puede observar cómo se ha contabilizado todo el tráfico ICMP y los datos de ambas IP’s por separado. El camino que sigue el paquete ICMP con destino 1.1.1.1 es el siguiente: 1) El paquete ICMP es generado por el kernel, se toma la decisión de routing(destino 1.1.1.1) del mismo y este llega a la cadena output de la tabla filter. 2) El paquete hace match con la regla de output ya que el protocolo de este es ICMP, por lo que su acción es jump a la cadena_usuario 3) En la cadena_usuario aumenta en 1 el contador de la primera regla y hace match con la tercera regla, aumentando el contador de esta y tomando la acción de accept sobre el paquete. 4) El paquete continúa por postrouting y sale del equipo Encaminador. El camino que sigue el paquete ICMP con destino 8.8.8.8 es el siguiente: 1) El paquete ICMP es generado por el kernel, se toma la decisión de routing(destino 8.8.8.8) del mismo y este llega a la cadena output de la tabla filter. 2) El paquete hace match con la regla de output ya que el protocolo de este es ICMP, por lo que su acción es jump a la cadena_usuario 3) En la cadena_usuario aumenta en 1 el contador de la primera regla y hace match con la segunda regla, aumentando el contador de esta y tomando la acción de drop sobre el paquete. Conclusión del ejemplo: Como se ha podido ver en los dos ejemplos anteriores, las cadenas de usuarios son usadas principalmente, para realizar el tratamiento de un tráfico específico en una cadena. La mayoría de ejemplos que se pueden encontrar de su uso, es para discernir tráfico por protocolos, por servicios(puerto destino) o en función de las direcciones de las cuales provenga el paquete, bien si este viene de la red interna, de Internet, de la DMZ etc… 21 3.2.3 Reglas básicas Ya se ha podido comprobar el funcionamiento de las tablas, las cadenas y sus enganches, por último, queda por comprender como funciona la creación de reglas dentro de nftables. En primer lugar, se verá cuál es la sintaxis de las reglas de nftables ya que, como se indicó en el comienzo de esta guía, esta se ha visto modificado con respecto a la usada en iptables. $ nft <acción> rule [<famiy>] <Nombre_tabla> <Nombre_cadena> [handle <value>] [<selectores>] [<acciones>] [comment "Comentario"] Esta es la sintaxis por defecto para las reglas. Debemos indicar que la tabla, la cadena y la familia a la que pertenece la regla, deberá coincidir con la de la cadena a la que se la añada. Si se desea en vez de añadir una regla, insertarla en una posición determinada, se usará la opción de handler. El handler [24] o manejador, no es más que un número que indica la posición de la regla dentro de la estructura de nftables, de esta forma, si se desea insertar una regla antes que otra ya creada, basta con indicar el handler que posee esa regla ya creada, para saber en qué punto se desea añadir la próxima regla. Los selectores son las opciones que proporcionan los módulos para especificar el tipo de tráfico que se desea tratar. La parte de las acciones, es donde se indica como se debe proceder con el tráfico que haya coincidido con nuestra regla, se verá que existen dos tipos de acciones, las terminales y las no terminales, las cuales se explicarán en este mismo punto. Y, por último, se da la opción de añadir un comentario para que quede constancia en el archivo, esto no es más que una explicación o indicación acerca de la regla. 3.2.3.1 Adaptación de reglas En el punto anterior, se ha visto la sintaxis que tiene nftables para crear una regla, pero esta herramienta también ofrece la opción de usar la capa de adaptación para traducir las reglas a sintaxis de nftables. Esta capa de adaptación no es más que una ayuda que permite traducir las reglas que usen la sintaxis de iptables, a sintaxis de nftables. Las opciones de traducción son: • Iptables-nft • Ip6tables-nft • Ebtables-nft • Arptables-nft Estos comandos que permiten traducir las reglas de iptables a nftables, se encargan de crear las tablas y cadenas necesarias para albergarlas, ocultando la complejidad de creación de estas al usuario. En la Figura 3.9, se puede observar un ejemplo de traducción de regla de iptables a nftables, usando la opción translate. 22 Figura 3.9 - Iptables translate En el punto de “Filtrado de paquetes”, se analizarán los módulos de nftables que permiten la inspección de los paquetes y los valores de estos. En este punto se analizarán las acciones que pueden realizar las reglas y los llamados objetos de estado. El seguimiento de conexiones también se verá en el punto de “Seguimiento de Conexiones(Conntrack)”. 3.2.3.2 Acciones terminales Como se ha comentado antes, las reglas tienen dos tipos de acciones, las que se consideran terminales y las no terminales. Las terminales son aquellas que ponen fin a la evaluación del paquete con respecto del resto de reglas, tomando una decisión de como se ha de proceder con el paquete/tráfico que ha coincidido con ella. Estas acciones quedan recogidas en la Tabla 5. Acciones terminales Descripción Accept Permite que el paquete sea aceptado. Drop Desecha el paquete y acaba la evaluación. Reject Rechaza el paquete y envía al origen del mismo un paquete de tipo ICMP informando de la acción. Si no se puede realizar la acción de reject por algún motivo, esta se toma como Drop. Queue Envía el paquete a una cola en el espacio de trabajo del usuario, acabando así la evaluación del resto de reglas. Continue Prosigue la evaluación con la siguiente regla de la cadena. Return Deja de evaluar las reglas de la cadena donde se encuentra y vuelve a la cadena desde la que se realiza el salto(jump). Si esta acción la colocamos en una cadena base, es igual que la acción Accept. Jump <chain> Salta a la cadena de usuario que se le especifique y al terminar la evaluación de reglas en la misma vuelve a la cadena base desde la que se realizó el salto. Goto <chain> Esta acción sirve para saltar a la cadena especificada, en la cual se terminará la evaluación del paquete sin volver a la cadena desde la que se realizó el salto. Tabla 5 - Acciones terminales reglas 23 3.2.3.2.1 Acción Reject A continuación, se podrá ver un ejemplo de estas acciones terminales. En el punto anterior, se ha visto el uso de jump y de cómo poder sacarle partido con las cadenas de usuarios, así como el uso de drop y accept dentro de las reglas de las mismas. En el siguiente ejemplo se mostrará el uso del reject de paquete, y el tipo de mensajes ICMP que este puede enviar. Ejemplo reject. Descripción del Ejemplo: En este ejemplo se realizará una prueba con el equipo Encaminador, en el cual se pretende que haga reject a todo el tráfico entrante cuyo puerto origen sea el 80. Se parte del ejemplo usado en “Cadena de usuario” y de la estructura creada en este. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Se añade la siguiente regla a nftables y se activa Wireshark para escuchar los paquetes en la interfaz “ens33”. Equipo:Encaminador Usuario:root $ nft add rule inet filter input tcp sport 80 reject with icmp type host-unreachable Con esta regla, se indica que cuando en la cadena input se reciba un paquete TCP, cuyo puerto de origen sea el 80, se descartará y se enviará un mensaje ICMP de tipo host unreachable de vuelta al origen. En la Figura 3.10, se puede ver la estructura de reglas usada. Figura 3.10 - Ejemplo reject 24 2. [Equipo:Encaminador - Usuario:dit] Desde el equipo Encaminador, se realiza una peticion a la web de trajano, cuya IP es: 193.147.162.130/32. Equipo:Encaminador Usuario:root $ curl 193.147.162.130 3. [Equipo:Encaminador - Usuario:root] Se accede a Wireshark para observar los paquetes generados. Figura 3.11 - Resultado ejemplo reject Como se puede ver en la Figura 3.11, se envían peticiones a la web de trajano, la cual, al ser un servidor HTTP recibirá estas en el puerto 80, cuando se recibe la respuesta del servidor, se descarta y se envía un mensaje ICMP de tipo 3 (Destination Unreachable) de vuelta al servidor de trajano. Camino de los paquetes en el ejemplo de reject. 1) Al usar curl, el kernel genera un paquete TCP SYN con dirección destino, la IP de Trajano. 2) El paquete cruza por los hooks de output y postrouting y sale del equipo. 3) Por ingress llega la respuesta del servidor de Trajano con el puerto origen 80. 4) El paquete cruza por prerouting y tras este se toma la decisión de routing, determinando que ese paquete se dirige a un proceso local y siguiendo su camino por el hook input. 5) Al llegar a input, se hace match con la regla que este contiene y se realiza el reject del paquete 6) El kernel genera un paquete ICMP, con destino, la dirección del servidor de trajano. 7) Este paquete llega a output y se le aplica la regla con la acción jump cadena_usuario 8) El paquete se contabiliza en la regla de counter y al no hacer match con ninguna de las otras reglas, se devuelve a la cadena output y se aplica la política por defecto(accept) 9) El paquete cruza por postrouting y sale del equipo. Conclusión del ejemplo: El uso de la acción reject, es usado sobre todo para tratar el tráfico de las redes internas, ya que como hemos visto, este envía un mensaje ICMP, indicándole al usuario que no se ha podido completar la petición realizada. Si esto mismo se hiciera para la red externa, estaríamos dando información al atacante, que normalmente no desearíamos dar, en este caso es preferible el uso de la acción drop. 25 Tipos de respuesta del reject: Se puede elegir entre distintos tipos de respuestas ICMP, a continuación, se proponen los diferentes tipos y los comandos para poder crear las reglas: • net-unreachable: Destination network unreachable $ nft add rule inet filter input tcp sport 80 reject with icmp type net-unreachable • host-unreachable: Destination host unreachable $ nft add rule inet filter input tcp sport 80 reject with icmp type host-unreachable • prot-unreachable: Destination protocol unreachable $ nft add rule inet filter input tcp sport 80 reject with icmp type prot-unreachable • port-unreachable: Destination port unreachable (this is the default) $ nft add rule inet filter input tcp sport 80 reject with icmp type port-unreachable • net-prohibited: Network administratively prohibited $ nft add rule inet filter input tcp sport 80 reject with icmp type net-prohibited • host-prohibited: Host administratively prohibited $ nft add rule inet filter input tcp sport 80 reject with icmp type host-prhohibited • admin-prohibited: Communication administratively prohibited $ nft add rule inet filter input tcp sport 80 reject with icmp type admin-prohibited 3.2.3.2.2 Acción Return, Accept y Drop En el siguiente ejemplo, se verá la acción terminal return, la cual, puede ser usada de dos formas distintas: • Si se invoca desde una cadena de usuario, en el momento en el que se llega a una regla con return, se para de procesar las reglas en esta y se vuelve a procesar las reglas de la cadena base desde la que se dio el salto y desde la regla en la que se dejó. • Si se invoca desde una cadena base, al no poder volver a una cadena anterior puesto que no es una cadena de usuario, se toma la acción como un accept. 26 Ejemplo return, accept y drop. Descripción del Ejemplo: En este ejemplo, se verá el uso de la acción return y como esta, ante un mismo tráfico, procesa unas reglas y otras no, como consecuencia de esta acción. Para ello, se crearán dos reglas a las cuales el tráfico pueda hacer match en la cadena_usuario, la primera tendrá como acción return, mientras que la segunda tendrá accept y en la cadena desde la que salten, estará otra regla en la cual también puede hacerse match y cuya acción será drop. En este ejemplo se partirá de la estructura creada en “Cadena de usuario”. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Se añaden las siguientes reglas a la estructura de nftables: 1) La primera regla se añade a la cadena_usuario , de forma que hace match si la dirección destino es la 2.2.2.2, se contabiliza y su acción es return. 2) La segunda regla se añade a la cadena_usuario , de forma que hace match si la dirección destino es la 2.2.2.2, se contabiliza y su acción es accept. 3) La tercera regla se añade a la cadena output, de forma que hace match si la dirección destino es la 2.2.2.2, se contabiliza y su acción es drop. Se puede ver en la Figura 3.12, como queda la estructura de nftables. Equipo:Encaminador Usuario:root $ nft add rule inet filter cadena_usuario ip daddr 2.2.2.2/32 counter return $ nft add rule inet filter cadena_usuario ip daddr 2.2.2.2/32 counter accept $ nft add rule inet filter output ip daddr 2.2.2.2/32 counter drop Figura 3.12 - Ejemplo return, accept y drop 27 2. [Equipo:Encaminador - Usuario:root] Se realiza un envío ICMP a la dirección IP: 2.2.2.2/32 en el terminal 2 y se comprueba si este es capaz de salir y el valor de los contadores en el terminal 1. • Terminal 1; Se muestra el ruleset de nftables. Equipo:Encaminador Usuario:root $ nft list ruleset • Terminal 2; Se realiza el ping a la dirección IP 2.2.2.2 Equipo:Encaminador Usuario:dit $ ping -c 3 2.2.2.2 Figura 3.13 - Resultado ejemplo return, accept y drop Como se puede ver en la Figura 3.13, el ping es incapaz de completarse y el contador de la regla que sigue a return permanece en 0, viendo como así la regla no continua su evaluación en la cadena de usuario. Camino del paquete ICMP generado en el ejemplo: 1) El paquete ICMP es generado por el kernel, se toma la decisión de routing (destino 2.2.2.2) del mismo y este llega a la cadena output de la tabla filter. 2) El paquete hace match con la regla de output ya que el protocolo de este es ICMP, por lo que su acción es jump a la cadena_usuario 3) En la cadena_usuario aumenta en 1 el contador de la primera regla y hace match con la cuarta regla, aumentando el contador de esta y tomando la acción de return sobre el paquete, de forma que este vuelve a la cadena desde la que saltó (output). 4) El paquete continua su camino con la siguiente regla a la del jump, de forma que hace match con la segunda regla y se toma la decisión de drop sobre el paquete. Conclusión del ejemplo: Una vez visto el ejemplo de uso de return y de las cadenas de usuario, podemos ver que trabajan muy bien en combinación, ya que podemos cortar el procesado de un paquete en una cadena de usuario, para darle un tratamiento más específico o más genérico en la cadena base. 34 Como se puede ver en la Figura 4.1, se ha dividido en 4 capas (Arp Layer, Bridge Layer, IP Layer y Application Layer) a través de las cuales, definimos los hooks que actúan en cada una de ellas y el tipo de familia a la que pertenecen. El camino que realiza un paquete, una vez que este llega y es tratado por el driver de nuestra NIC, es el indicado en la Figura 4.1. En este camino, el primer hook que se encuentra el paquete es ingress, el cual, pertenece a la familia netdev y que al ser el primer hook, nos permite realizar un tratamiento temprano de los paquetes, así como conseguir realizar bypass de los mismos usando las flowtable. Una vez el paquete atraviesa ingress, se plantea, si este ha entrado por el puerto de un bridge planteando una bifurcación de caminos. • En caso de que la respuesta a esta pregunta, sea SI, se entregará el paquete al hook prerouting de la familia bridge (Camino Bridge) • En caso contrario, se preguntará por el tipo de protocolo del paquete, según este sea ARP o IP se entregará al hook correspondiente de su familia (Camino ARP o Camino IP). 4.1.1 Camino Bridge Si el paquete ha entrado por un puerto bridge, se entregará al hook prerouting de la familia bridge y tras atravesarlo se tomará la bridge decision, en la cual se decidirá si el paquete es para nuestro equipo (ver Figura 4.2). • Si el paquete es para nuestro equipo, este es cursado por el hook input de bridge, el cual enlazará con el hook prerouting de la familia IP. • Si el paquete no es para nuestro equipo, seguirá su curso atravesando el hook forward de la familia bridge y por último el hook postrouting de la familia bridge, para finalmente, salir por egress. Figura 4.2 - Bridge Flow 4.1.2 Camino ARP En caso de que en la decisión de protocol type, el protocolo sea ARP, el paquete seguirá su camino pasando por el hook input de la familia ARP hasta llegar al Arp Handler que será el encargado de procesar este paquete (Figura 4.3). Si es nuestro equipo el que genera el paquete ARP, este nacerá del Arp Handler y cruzará a través del hook output de la familia ARP para salir finalmente por egress. 35 Figura 4.3 - ARP Flow 4.1.3 Camino IP En caso de que en la decisión de protocol type, el protocolo sea IP, el paquete seguirá su curso atravesando el hook prerouting de la familia IP. Tras esto, se tomará la decisión de enrutado, para saber si el paquete es para un proceso local o necesita ser encaminado, en caso de que nuestro equipo permita el forwarding. • Si el paquete es para un proceso local, tras la decisión de routing, este seguirá su curso por el hook input de la familia IP, hasta entregarse al proceso local en la capa de aplicación. • Si la decisión de enrutamiento, determina que el paquete no es para un proceso local y que el equipo permite el forwarding, este seguirá su curso por el hook forward y el hook postrouting de la familia IP, llegado a ese punto, se tomará la decisión de si sale por una interfaz bridge. o Si la interfaz de salida es bridge, el paquete continuará su viaje por el hook output y el hook postrouting de la familia bridge, hasta que finalmente salga por egress. o Si la interfaz de salida no es bridge, el paquete continuará su camino y saldrá por egress. Si el paquete es creado en un proceso local, este viajará hasta la capa IP, en la cual se tomará la decisión de enrutamiento y tras esta, el paquete seguirá su camino por el hook output y el hook postrouting de la familia IP, en este punto se tomará la misma decisión que en el camino anterior. o Si la interfaz de salida es bridge, el paquete continuará su viaje por el hook output y el hook postrouting de la familia bridge, hasta que finalmente salga por egress. o Si la interfaz de salida no es bridge, el paquete continuará su camino y saldrá por egress. Figura 4.4 - IP Flow Como se puede ver en la Figura 4.4, en el hook output, aparece un rombo con las siglas RD (Routing Decision) y es que, en estos hooks, ante el uso de reglas de tipo NAT o route, se realiza una reevaluación de la ruta, consultando de nuevo la tabla de routing, para ver si los cambios provocados por las reglas anteriores implican un cambio de ruta o de interfaz de salida. A continuación, se realizarán pruebas usando el escenario de dos equipos. 36 4.2 Escenario pruebas flow paquetes. Como se ha dicho, para este punto se usará el escenario de dos equipos, cuya configuración se encuentra en el “Anexo E - Escenario 2 Equipos”. 4.2.1 Ejemplo flow paquetes. Descripción del ejemplo: PC1 se encargará de generar el tráfico ICMP, que servirá para analizar el camino del paquete dentro del sistema de hooks. El equipo Encaminador, configurará las reglas de nftables, para poder realizar el seguimiento del paquete. Además, este debe usar dos terminales, uno desde el que se configurarán las reglas y otro para realizar la monitorización del paquete. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Se crea en Encaminador el esquema de tablas y cadenas que se usará para hacer las pruebas. Se crea la estructura de la tabla filter, que será la que contenga los hooks pertenecientes a la familia inet (prerouting, input, forward, output y postrouting). Equipo:Encaminador Usuario:root $ nft add table inet filter $ nft add 'chain inet filter prerouting { type filter hook prerouting priority -1 ; }' $ nft add 'chain inet filter postrouting { type filter hook postrouting priority 90 ; }' $ nft add 'chain inet filter input { type filter hook input priority 0 ; }' $ nft add 'chain inet filter output { type filter hook output priority 0 ; }' $ nft add 'chain inet filter forward { type filter hook forward priority 0 ; }' 2. [Equipo:Encaminador - Usuario:root] Se crea la tabla que contendrá los dos hooks de la familia ARP. Equipo:Encaminador Usuario:root $ nft add table arp filterarp $ nft add 'chain arp filterarp inputarp { type filter hook input priority 0 ; }' $ nft add 'chain arp filterarp outputarp { type filter hook output priority 0 ; }' 3. [Equipo:Encaminador - Usuario:root] Se crea la tabla que contendrá el hook de la familia netdev (ingress), como se puede ver, para poder crear la cadena para este hook es necesario que se especifique la interfaz en la cual escuchará el tráfico. 37 Equipo:Encaminador Usuario:root $ nft add table netdev filteringress $ nft add 'chain netdev filteringress ingress { type filter hook ingress device ens38 priority 0 ; }' 4. [Equipo:Encaminador - Usuario:root] Se comprueba que se hayan creado correctamente las reglas, imprimiendo el ruleset de nftables, como se puede ver en la Figura 4.5. Equipo:Encaminador Usuario:root $ nft list ruleset Figura 4.5 - Armazón hooks escenario flow 5. [Equipo:Encaminador - Usuario:root] A continuación se procede a crear las reglas. 1) Para realizar este seguimiento de los diferentes paquetes, se debe activar la marca nftrace, tanto en la cadena de output como en la de ingress. Por ello, se crea una regla en la tabla filteringress, la cual se activará si el protocolo del paquete es ICMP. Del mismo modo, se activa esta marca en el hook output de la familia IP, para poder realizar el seguimiento de los paquetes que sean generados en un proceso local. 2) Para poder realizar un correcto seguimiento del camino de los paquetes, se realizará en cada regla dos acciones no terminales. • Un log, con un prefijo que indique por qué regla se ha pasado. • Un counter, que lleve la cuenta de los paquetes que atraviesan esa regla. 38 Equipo:Encaminador Usuario:root #Se activa la marca nftrace en ingress y output $ nft add rule netdev filteringress ingress meta nftrace set 1 $ nft add rule inet' filter output ip protocol icmp meta nftrace set 1 ' #Se añaden las reglas que harán los logs en las cadenas arp $ nft add rule arp filterarp' inputarp log prefix "Entra ARP: " counter accept' $ nft add rule arp' filterarp outputarp meta nftrace set 1 ' $ nft add rule arp filterarp' outputarp log prefix "Sale ARP: " counter accept' #Se añade las reglas que harán los logs en las cadenas de filter $ nft add rule inet' filter output ip protocol icmp log prefix "Pasa por output-inet: " counter accept ' $ nft add rule inet' filter input ip protocol icmp log prefix "Pasa por input-inet: " counter accept ' $ nft add rule inet' filter prerouting ip protocol icmp log prefix "Pasa por pre-inet: " counter accept ' $ nft add rule inet' filter postrouting ip protocol icmp log prefix "Pasa por post-inet: " counter accept ' $ nft add rule inet' filter forward ip protocol icmp log prefix "Pasa por forward-inet: " counter accept ' 6. [Equipo:Encaminador - Usuario:root] Se muestra el ruleset de nftables, para comprobar que se han creado correctamente. En un segundo terminal, se activa el monitor de nftrace. En la Figura 4.6, se puede comprobar, como debe quedar la estructura de reglas y cadenas. Equipo:Encaminador Usuario:root #Terminal 1 $ nft list ruleset #Terminal 2 $nft monitor trace 39 Figura 4.6 - Reglas escenario flow 7. [Equipo:PC1 - Usuario:root] Desde PC1, se realizan pings para comprobar el camino que siguen los paquetes. 1) El primero de ellos tendrá como destino un proceso local, por ello se realiza el ping a la IP: 10.10.1.10, 2) El segundo, se usará para ver el forwarding, por ello se realiza el ping al DNS de Google, con IP: 8.8.8.8. La realización de los pings, puede comprobarse en la Figura 4.7. Equipo:PC1 Usuario:root $ ping -c 3 10.10.1.10 $ ping -c 3 8.8.8.8 Figura 4.7 - Prueba ICMP PC1 escenario flow 40 8. [Equipo:Encaminador - Usuario:root] Se procede a analizar los resultados de los logs y del monitor nftrace, del ping realizado al proceso local de Encaminador. Figura 4.8 - Nftrace ICMP local, entrada En la Figura 4.8, se puede ver que nftrace crea un ID de seguimiento de paquete (a9956702) y que el primer hook por el que pasa es ingress, que es el encargado de activar su marca. Camino del ICMP request hasta el proceso local: 1) El paquete ICMP req es recibido en la NIC de Encaminador y tras realizar las comprobaciones básicas de malformación, se entrega al hook ingress 2) En el hook ingress, se puede ver que se le aplica la regla de nftrace y se le asigna un identificador al paquete (a9956702), tras esto, se toma el veredicto de continue y se entrega al hook prerouting. 3) En el hook prerouting, se aplica la primera regla, la cual aumenta el contador de paquetes y guarda un log con el nombre “Pasa por pre-inet”, el veredicto del paquete es continue. 4) Se toma la decisión de routing sobre el paquete y se verifica que se dirige a un proceso local, por lo que este continua su camino por el hook input. 5) Al llegar al hook input, se aplica la primera regla, la cual aumenta el contador de esta en 1, y se guarda un log con el nombre “Pasa por input-inet”. 6) Tras esto se toma como veredicto accept y se entrega al proceso local. Se puede observar además, que entra por la interfaz ens38 y que tiene ID ICMP (12246). En la Figura 4.10, se pueden comprobar como las dos primeras entradas corresponden a los logs generados por los hooks de prerouting e input. 9. [Equipo:Encaminador - Usuario:root] Se procede a analizar los resultados de los logs y del monitor nftrace, de la respuesta al ping local generada por el equipo Encaminador. Figura 4.9 - Nftrace ICMP local Salida En la Figura 4.9, se puede ver que se realiza un nuevo seguimiento de un paquete ICMP, en este caso generado por el proceso local con el ID (7e137a80). 41 Camino del ICMP response, hasta que sale de Encaminador: 1) El paquete ICMP res, es generado por el proceso local como respuesta al request recibido. 2) El paquete llega al hook output donde se comienza a hacer el seguimiento del mismo, se le asigna el ID (7e137a80). 3) Tras activar la traza de nftrace del paquete, se le aplica la segunda regla, aumentando el contador de esta y generando un log con el nombre “pasa por out-inet”, siendo su veredicto continue. 4) El paquete llega al hook postrouting, donde hace match con la primera regla y genera un log con el nombre “pasa por post-inet”, siendo su veredicto accept. 5) El paquete sale por la NIC “ens38” camino a PC1. Se puede observar que el ID del paquete ICMP, es el mismo que el observado en la Figura 4.8, que seguía el camino de entrada, por lo que, se puede corroborar que este es la respuesta del paquete ICMP anterior. 10. [Equipo:Encaminador - Usuario:root] Se procede a analizar los logs del ping dirigido al proceso local del equipo Encaminador. Equipo:Encaminador Usuario:root $ cat /var/log/kern.log | grep Pasa En la Figura 4.10, se puede ver, como las entradas 3 y 4 coinciden con los logs que se han mencionado en el camino del paquete ICMP response. Figura 4.10 - Logs del ICMP local al pasar por los hooks La Figura 4.11, representa el camino del ping cuyo destino es un proceso local en Encaminador. Figura 4.11 - Resumen camino ping a Encaminador 42 11. [Equipo:Encaminador - Usuario:root] Se procede a analizar los resultados del monitor nftrace del ping dirigido al DNS de Google. Figura 4.12 - Nftrace ICMP externo entrada En la Figura 4.12, se puede comprobar el transcurso del paquete ICMP por los distintos hooks en su camino de forwarding. Camino del ICMP request hasta Google DNS: 1) El paquete ICMP req es recibido en la NIC de Encaminador y tras realizar las comprobaciones básicas de malformación, se entrega al hook ingress 2) En el hook ingress, se puede ver como se le aplica la regla de nftrace y se le asigna un identificador al paquete(b9dc1dbc), tras esto se toma el veredicto de continue y se entrega al hook prerouting. 3) En el hook prerouting se aplica la primera regla, la cual aumenta el contador de paquetes y guarda un log con el nombre “Pasa por pre-inet”, el veredicto del paquete es continue. 4) Se toma la decisión de routing sobre el paquete y se verifica que no es para un proceso local, por lo que este necesita ser encaminado, continuando así, su camino por el hook forward. 6) Al llegar al hook forward, se aplica la primera regla, la cual aumenta el contador de esta en 1, y se guarda un log con el nombre “Pasa por forward-inet” . 7) El paquete llega al hook postrouting, donde hace match con la primera regla, y genera un log con el nombre “Pasa por post-inet”, su veredicto es accept. 8) El paquete sale por la NIC “ens33” en dirección al DNS de Google. Se comprueba que nftrace le da el ID (b9dc1dbc) a este paquete, que su interfaz de entrada es ens38 y que el ID del ICMP es (12304). 12. [Equipo:Encaminador - Usuario:root] Se procede a analizar los logs del ping dirigido al DNS de Google. Equipo:Encaminador Usuario:root $ cat /var/log/kern.log | grep Pasa El camino de la respuesta es exactamente el mismo que el camino que ha recorrido el request, con la única salvedad de que request (entra por ens38 y sale por ens33) y res (entra por ens33 y sale por ens38). Esto puede observarse en los logs generados en la Figura 4.13. 43 Figura 4.13 - Logs del ICMP externo al pasar por los hooks Se debe distinguir entre los dos Id’s que pueden tener los paquetes, tales como los vistos en la Figura 4.12. Nftrace crea un ID para el paquete, que solo tiene sentido, entendido dentro de la estructura local de nftables de Encaminador, mientras que el segundo ID, es el propio del paquete ICMP y que viaja en la cabecera de este. La Figura 4.14 , representa el camino del ping al DNS de Google, el cual, se encamina, puesto que su destino está en una máquina pública y no en el equipo Encaminador. Figura 4.14 - Resumen camino ping a DNS Google Conclusión del ejemplo: Como se ha podido ver en los ejemplos, estos sirven para mostrar paso a paso los dos tipos de caminos que podemos encontrarnos en cualquier escenario: • Paquetes dirigidos a nuestro equipo; Los cuales atraviesan los siguientes hooks (ingress, prerouting, input, output y postrouting). • Paquetes que nuestro equipo debe encaminar; Los cuales atraviesan los siguientes hooks (ingress, prerouting, forward y postrouting). 50 51 MANAGERS En este capítulo, se analizará que es y cómo funciona, un manager de reglas con nftables. Los managers, son frontend que ayudan a administrar y configurar las reglas del firewall, en este caso de nftables. Estos tienen la capacidad de enmascarar la complejidad de la creación, distribución y mantenimiento de las reglas del framework de Netfilter. Actualmente los managers de reglas más conocidos, han dado su respuesta acerca de si van a migrar a esta nueva herramienta o por el contrario solo seguirán dando soporte a iptables. Nos encontramos en un escenario en el cual, la mayoría de las herramientas para manejo de reglas se encuentra actualmente migrando o con vistas de migrar en un futuro. Managers tan conocidos como; Ipfire[28], Shorewall o Ferm[29], han optado por no migrar y solo ofrecen su herramienta con soporte para iptables. La respuesta de estas, están basadas en que para ofrecer soporte a nftables, no basta con parchear la aplicación existente, sino que el cambio de sintaxis de la herramienta, exige la generación de una nueva herramienta para adaptarse a ella. Por otro lado, existen managers que han decidido migrar, pero todavía se encuentran en una fase temprana del proyecto, incluyendo solo parte de las funcionalidades que estos ofrecían con iptables, es el caso de Suricata y Firewalld, los cuales ya ofrecen la posibilidad de trabajar con nftables. Existe otro manager muy conocido como es Fail2ban, el cual ofrece soporte para nftables de manera nativa, pero está teniendo bastantes complicaciones en su desarrollo, provocando que los usuarios reporten una considerable cantidad de fallos en su Github. Con todo lo mencionado, e independientemente del estado de actualización en el que se encuentren, todas adolecen del mismo problema y es la falta de nueva documentación, que explique los cambios y la nueva forma de emplear estos managers. Por lo que para este punto, se ha decidido mostrar el uso de un manager que, aunque actualmente no tiene la funcionalidad al 100% con nftables, sí que se considera que cubre con solvencia áreas que antes se hacían con iptables, ese manager es Firewalld. 5.1 Firewalld Como se ha comentado anteriormente, Firewalld es un manager que nos permite gestionar las reglas de nftables. En este apartado, se explica su funcionamiento con ejemplos y se verán las reglas que este va creando en nftables. La instalación de esta herramienta es algo complejo debido a sus dependencias, por ello se explica en su totalidad en el “Anexo D - Instalación y Configuración Firewalld”. Lo que cabe destacar de este manager, es que la gestión de reglas las hace mediante el uso, de lo que él define como “zonas”[30]. 52 Estas zonas, no son más que agrupaciones de reglas que dependen del nivel de confianza que se le otorgue al tráfico de red. Firewalld trabaja con 9 zonas de confianza, las cuales van desde la menos confiable “drop” hasta la de mayor confianza, conocida como “trusted” La Tabla 7, recoge esas zonas y una breve descripción de cada una de ellas. Zona Descripción Drop Es la zona de menor confianza y en ella se realiza el drop de todos los paquetes que lleguen al equipo. Block Esta zona es parecida a Drop, con la diferencia de que en lugar de realizar el drop de los paquetes, lo que hace es un reject, informando al emisor con un mensaje ICMP. Public Es la más alta de las zonas de no confianza. En ella indicamos que no confiamos en los paquetes que recibimos, salvo que exista una regla específica que los permita. External Este tipo de zona se utiliza para realizar la traducción de direcciones del tráfico. De forma que nuestro equipo se comportará como frontera entre lo que considera zona privada y zona pública. En esta zona, al igual que en Public, desconfiamos del tráfico, salvo que existan reglas específicas. Internal Es la otra cara de la zona External, en ella entendemos que nos encontramos en nuestra zona privada y generalmente confiaremos en los paquetes que nos lleguen, estando ya algunos servicios permitidos de forma básica desde esta zona. DMZ Se usa para configurar zonas desmilitarizadas y al igual que Public, necesitamos reglas específicas para aceptar o denegar tráfico. Work Se usa para identificar un área de trabajo en la que confiamos, de forma que la mayoría de servicios se encuentran permitidos de forma básica en esta zona. Home La zona Home, es aquella en la que tenemos casi la totalidad de servicios disponibles para su acceso y solo unos pocos requieren reglas específicas para poder acceder. Trusted Es la Zona de mayor confianza y en él se encuentra permitido todo el tráfico. Tabla 7 - Zonas Firewalld 5.1.1 Escenario de Pruebas Ejemplo prueba manager. Para ejemplificar el uso de esta herramienta, se usará el escenario de dos equipos. La creación y configuración de este escenario se indica en el “Anexo E - Escenario 2 Equipos”. 53 Descripción del ejemplo: Como ejemplo, se configurará en el equipo Encaminador ambas tarjetas en zona Internal, que como se ha visto, usa una política restrictiva. En ella se habilitará el ping, los protocolos DNS[31], HTTP[32] y HTTPS y habilitaremos el puerto 80 para poder recibir peticiones por este. Para ello se activa el servicio httpd para que el servidor Apache[33] que se encuentra en el equipo Encaminador arranque y comience a escuchar peticiones TCP en el puerto 80. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Lo primero que se debe comprobar es el estado de servicio de Firewalld, para ello se usa el siguiente comando: Equipo:Encaminador Usuario:root $ service firewalld status Figura 5.1 - Estado servicio Firewalld En la Figura 5.1, se puede comprobar como el servicio se encuentra en estado running. Una vez comprobado que este se encuentra activo, se puede proceder con el resto de pasos. 2. [Equipo:Encaminador - Usuario:root] Los siguientes comandos, permitirán saber la zona en la que se encuentra nuestro equipo, así como las zonas que se encuentran activas. Equipo:Encaminador Usuario:root $ firewall-cmd --get-default-zone $ firewall-cmd --get-active-zones $ firewall-cmd --zone=public --list-all 54 Figura 5.2 - Zonas definidas básicas Se puede observar el resultado de los comandos anteriormente ejecutados en la Figura 5.2. 1) “--get-default-zone”, indica que zona es la que se encuentra activada por defecto. 2) “--get-active-zones” muestra las zonas que se encuentran activas y que por lo tanto, serán las que cursen el tráfico. En este caso, vemos como las zonas activas son : internal y libvirt, siendo la segunda de ellas una zona especial que se usa para interfaces virtuales. Este muestra también a que zona se encuentran asociadas nuestras NIC’s. Esto es así, porque por defecto, tenemos que asociar cada interfaz a una zona de confianza, cuyo equivalente en nftables sería, darle una política por defecto. 3) “--zone=public --list-all” podemos observar las propiedades de la zona public, la cual muestra; las interfaces asociadas, puertos permitidos, protocolos etc… 3. [Equipo:Encaminador - Usuario:root] Se procede a asociar las interfaces que van a ser usadas para que pertenezcan a la zona Internal. Equipo:Encaminador Usuario:root $ firewall-cmd --zone=internal --change-interface=ens37 $ firewall-cmd --zone=internal --change-interface=ens33 4. [Equipo:Encaminador - Usuario:root] A continuación, se habilita en la zona Internal el servicio HTTP y HTTPS con su puerto habilitado para la escucha. Equipo:Encaminador Usuario:root $ firewall-cmd --zone=internal --add-service=http --permanent $ firewall-cmd --zone=internal --add-service=https --permanent $ firewall-cmd --zone=internal --add-port=80/tcp --permanent $ firewall-cmd --zone=internal --add-port=80/udp --permanent 55 5. [Equipo:Encaminador - Usuario:root] Por último, se añaden servicios básicos de comunicación; Samba, DNS y SSH. Equipo:Encaminador Usuario:root $ firewall-cmd --permanent --zone=internal --add-service=samba $ firewall-cmd --permanent --zone=internal --add-service=dns $ firewall-cmd --permanent --zone=internal --add-service=ssh 6. [Equipo:Encaminador - Usuario:root] Una vez realizado esto, se procede a listar la configuración de la zona Internal con el siguiente comando. Equipo:Encaminador Usuario:root $ firewall-cmd --zone=internal --list-all Figura 5.3 - Configuración zona Internal Como se puede apreciar en la Figura 5.3, la configuración recoge todas las opciones que se le han indicado mediante los comandos anteriores. 7. [Equipo:Encaminador - Usuario:root] Se procede a arrancar el servidor Apache de la maquina Encaminador. Equipo:Encaminador Usuario:root $ service httpd start $ service httpd status Figura 5.4 - Arranque del servidor Apache 56 En la Figura 5.4, se comprueba que el servidor se encuentra levantado y activo. A continuación, se comprobará la conectividad, conectándose desde PC1 al servidor Apache del Encaminador. 8. [Equipo:PC1 - Usuario:root] Desde PC1, se intenta la conexión a la URL: http://10.10.1.20:80 Equipo:PC1 Usuario:root $ curl 10.10.1.20 Figura 5.5 - Flujo conexión Apache (Internal) Como se puede ver en las Figura 5.5 y Figura 5.6, a PC1 llegan los paquetes de conexión que sirven la página web de Apache, pudiendo comprobar que esta se muestra en el buscador. Figura 5.6 - Página test Apache(Internal) 57 9. [Equipo:Encaminador - Usuario:root] Una vez realizado este ejemplo, se probará a realizar una redirección de puertos, para ello, se añade la siguiente regla a la zona Internal. Equipo:Encaminador Usuario:root $firewall-cmd --zone="public" --add-forward port=port=100: \ proto=tcp:toport=80 Con esta regla, se habilita que se pueda llegar al Servidor Apache desde peticiones que se realicen al puerto 100 de la máquina Encaminador. 10. [Equipo:PC1 - Usuario:dit] Se realiza una nueva petición desde PC1, esta vez con la siguiente Url: http://10.10.1.20:100 y se recarga la página del buscador. Equipo:PC1 Usuario:root $ hping3 -S 10.10.1.20 -p 100 Figura 5.7 - Redirección de puertos (Internal) Como se puede ver en la Figura 5.7, el equipo PC1 lanza una petición a Encaminador con puerto destino 100, respondiéndonos y sirviendo la web de Apache. La aplicación de estas reglas y zonas de confianza, se hace posible gracias a que la herramienta trabaja de manera interna con la estructura de nftables. Para comprobar las reglas que Firewalld ha creado en nftables, basta con abrir un terminal, pasar a modo super usuario e indicar el siguiente comando. 11. [Equipo:Encaminador - Usuario:dit] Se comprueban las reglas creadas en nftables Equipo:Encaminador Usuario:dit $ sudo su $ nft list ruleset 58 Figura 5.8 - Reglas libvirt Firewalld En la Figura 5.8 se puede observar las reglas que Firewalld crea por defecto con respecto a interfaces virtuales. Estas interfaces se configuran de forma básica en la zona de confianza Home, por lo que permite acceso a la mayoría de servicios desplegados, estos servicios son: Puerto Servicio 67 UDP DHCP modo sin conexión 547 UDP DHCPv6 53 TCP/UDP DNS 22 TCP SSH 69 TCP/UDP TFTP Tabla 8 - Puertos y servicios libvirt Firewalld Como se puede ver en la Tabla 8, existe un servicio que tiene un tratamiento distinto, TFTP, esto se debe a que este protocolo opera con el puerto de control 69 TCP/UDP, pero el puerto de transferencia de datos es elegido por el usuario. Por ello sería complicado poder realizar el seguimiento de la conexión, cuando esta se produce en dos puertos con dos canales de comunicación distintos. Para evitar este tipo de problemas, se añade un helper de connection-tracking, el cual permitirá asociar el tráfico de los dos puertos como si fuesen un único flujo de tráfico. Este tipo de configuración se verá con detalle en el punto “6.7 Helpers”. El siguiente bloque de reglas que Firewalld crea, son las reglas de la zona de confianza con las que se ha elegido trabajar (ver Figura 5.9). 59 Figura 5.9 - Reglas zona Internal Firewalld Las reglas creadas en esta cadena se corresponden con la cadena input de la zona de confianza Internal. En ella se puede ver como se ha permitido el tráfico de; SSH, DHCP, Webmsg (9090), HTTP, TLS (443) y la entrada de comunicación de NetBIOS, la cual al igual que TFTP, usa dos canales (uno para control y otro para datos), es por este motivo, por el que se usa el helper. De esta manera permite realizar el seguimiento de la conexión, pese a usar dos puertos diferentes (2 flujos paralelos). Por último, se comprobará en la Figura 5.10, la creación de las reglas por defecto de forwarding y output. Figura 5.10 - Reglas forward Firewalld Al igual que en los casos anteriores, realiza el seguimiento de todas las conexiones permitidas o denegadas. Además, deniega una serie de direcciones Ipv6 que se consideran de entorno privado, o que son paquetes malformados que esperan recabar información de nuestro equipo. Este es el funcionamiento que tiene Firewalld para crear reglas nftables dependiendo de la zona de confianza asignada. También se ha podido comprobar que podemos aplicar reglas más específicas para aceptar o denegar tráfico. El archivo de configuración con todas las reglas creadas, así como la distribución de las cadenas y la tabla de Firewalld, están en el “Anexo D - Instalación y Configuración Firewalld”. Este manager también permite introducir reglas desde su propia línea de comandos. 66 Antes de pasar a ver cómo trabaja cada protocolo con el sistema de seguimiento de conexiones, se explicará, como funcionan las tuplas de conntrack, así como los datos que esta toma de cada protocolo para realizar el seguimiento de conexiones. 6.2 Connection tracking Linux Conntrack se encarga de adquirir y almacenar los datos necesarios de los paquetes, así como almacenarlos en una estructura que le permitirá discernir sus flujos de comunicación. De forma general, los datos que el módulo conntrack toma de nuestros paquetes son los siguientes: • Dirección origen y destino • Puerto origen y destino • Tipo de protocolo Si el protocolo es ICMP, los datos que almacena conntrack varían con respecto a los que se acaban de mencionar. Tomando conntrack los siguientes datos: • Dirección origen y destino • Tipo y Código del ICMP • ID del ICMP • Tipo de protocolo Además de estos datos, en la estructura de conexiones que mantiene conntrack, se observan otros campos que aportan información adicional: • El status de la conexión • El timeout de la tupla creada • La marca del flujo de comunicación • El flag de asegurado (ASSURED) • El flag de “sin respuesta”, el cual nos indica que solo se ha visto comunicación en una dirección (UNREPLIED) • El número de flujos que hacen referencia a esa entrada (use) Una vez vistos los datos básicos, que conntrack toma de nuestros paquetes, se procederá a ver qué es y como se crean las tuplas de los diferentes flujos de conexión [40]. Se han explicado los datos y la máquina de estados de Netfilter, falta indicar como se organiza la tabla de conexiones y su funcionamiento en conjunto con el kernel. Para poder trabajar con la tabla de conexiones, Netfilter se basa en 4 funciones, estas funciones son; • La creación del flujo de conexión • La inspección de los paquetes de un flujo • La manipulación de los paquetes fragmentados 67 • El uso de helpers [41]. La tabla de conexiones, se divide en particiones llamadas “buckets”[42] y cada una de estas particiones está formada por una lista doblemente enlazada, en la que cada miembro es una tupla de tipo hash. Para cada conexión, se tienen 2 tuplas distintas. • Una tupla que representa los datos en la dirección originaria de la conexión (aquella que la inicia) • Una segunda tupla con los datos de la respuesta. Cada una de las tuplas, contiene la información relevante de la conexión. Se debe entender, que la conexión a la que se refiere el sistema, es distinta al concepto de conexión de un protocolo como puede ser TCP. Mientras que TCP es un protocolo que se encuentra orientado a conexiones, lo que connection tracking conoce como “connection”, no es más que la representación de un flujo de datos con origen y destino, el cual puede usar un protocolo orientado o no, a conexión (TCP o UDP entre otros). Esta explicación viene detallada en el “Anexo I - Concepto Conexión” . Como se ha comentado anteriormente, la unidad más importante de este módulo son las tuplas, las cuales se usan para representar flujos unidireccionales de comunicación. Esta estructura contiene las uniones, en las cuales se guardan los datos que resultan de interés para realizar el seguimiento de dicho flujo. Las diferentes uniones, son las estructuras en las cuales se almacenan los valores de las cabeceras de los siguientes protocolos: TCP, UDP, ICMP, DCCP[43] y SCTP[44]. Estas estructuras, independientes para cada protocolo, guardan la información que se considera única para identificar un paquete, es por ello, que, si se realiza el seguimiento de un paquete TCP o UDP, guardará los puertos origen y destino, mientras que en caso de realizar el seguimiento de paquetes ICMP, guardará el tipo, el código, así como también su identificador. Además de estos valores, conntrack necesita también conocer información específica de los protocolos, de capa 3 y capa 4 que tenga el paquete. Es de esta manera, por la cual el módulo de conntrack, toma los datos de los paquetes que atraviesan los hooks de Netfilter, para después organizarlos en estructuras dentro de una tupla. Para evitar la complejidad de mantener todos los datos de cada paquete guardado en cada una de las tuplas del sistema, conntrack usa lo que se denomina como tupla hash, la cual consiste en realizar el hash de los valores de las estructuras, guardando en la tupla este valor hash. Las dos tuplas hash (una para cada dirección de conexión) se guardan en una estructura que se denomina como “nf_conn”[45]. Las entradas creadas o actualizadas con las que trabaja el módulo conntrack, se pueden imprimir por pantalla usando la herramienta conntrack-tool. Una vez visto el funcionamiento de conntrack y como este, guarda la información y crea las tuplas, se procederá a ver en qué puntos crea estas entradas. Como se ha visto en el punto “Máquina de estados.”, los paquetes se clasifican dentro del hook prerouting y del hook output, cabría preguntarse si las entradas de conntrack son creadas en estos mismos puntos. La respuesta es no. Las entradas en la tabla de conntrack se crean en el hook input y en el hook postrouting, con un valor de prioridad máximo. Si recordamos como funciona la prioridad, “Prioridades de las Cadenas”, el valor máximo representa la última prioridad a ejecutar, por lo que esta, es la última operación que tiene lugar en el hooks input y en el hook postrouting. 68 Figura 6.4 - Creación de las entradas conntrack En la Figura 6.4, se puede observar los puntos en los cuales se crean las entradas de conntrack, estos se encuentran marcados con un número, se procede a explicar el significado de las mismas: 1) Si tenemos un paquete, cuyo destino es un proceso local de la máquina, este entrar por la NIC del equipo, será procesado por el hook ingress y el hook prerouting, se tomará la decisión de encaminamiento del mismo y al ser para la máquina local, este se procesará por el hook input. Dentro de este hook, la entrada se creará en el valor de prioridad máximo, es decir, en la última acción que se realice dentro del hook input y antes de pasar el paquete al proceso local. 2) Si tenemos un paquete cuyo destino no es un proceso local, sino que este, ha de ser encaminado, tras la decisión de routing, viajará por el hook forward y el hook postrouting, siendo en este último y con valor de prioridad máxima donde se creará la entrada. Este punto también sirve para crear o actualizar las entradas de los paquetes generados por el proceso local. Conntrack-tools, es la encargada de imprimirnos la información que antes podía comprobarse en la ruta “/proc/net/ip_conntrack”[46], la cual se encontraba muy limitada, ya que solo permitía imprimir las entradas existentes de la tabla conntrack. Conntrack-tool y su herramienta conntrack, permiten ahora , no solo imprimir esa información, sino manejarla( actualizarla, crear una entrada, borrar una entrada etc…). En caso de que se desee ver las entradas del módulo conntrack, se debe usar el siguiente comando: Equipo:Encaminador Usuario:root $ conntrack -L Conntrack, también ofrece una opción que permite imprimir la tabla, con la misma salida, que la impresa por “/proc/net/ip_conntrack”. Equipo:Encaminador Usuario:root $ conntrack -L -o extended Una vez visto el comando, se pasará a indicar los diferentes campos que conforman una entrada TCP, UDP e ICMP. 69 6.2.1 Entrada conntrack TCP Figura 6.5 - Entrada conntrack TCP extendido Analizamos la información mostrada en la Figura 6.5 (Entrada TCP): 1) Para comenzar, se tiene el protocolo de capa 3, que en este caso es el ipv4 2) Representación de este protocolo de forma numérica decimal, el valor en este caso es “2”. 3) Se tiene la información del protocolo de capa 4, el cual se puede ver que es TCP 4) Representación del número de este protocolo en notación decimal “6”. 5) Después viene el tiempo de vida restante para dicha entrada: en la Figura 6.5 se puede observar que a esta entrada de conexión le quedan 111 segundos, los cuales, irán disminuyendo hasta que se vea más tráfico perteneciente a dicha conexión. Cuando llegue nuevo tráfico, el contador de esta entrada, se establece de nuevo a su valor por defecto. 6) El siguiente dato, es la información del estado actual en que se encuentra la entrada. En este caso se puede comprobar que la tupla se encuentra en el estado TIME_WAIT. El valor interno de una conexión es ligeramente distinto a los empleados externamente por nftables. El valor TIME_WAIT indica que se encuentra esperando tráfico para esa entrada en concreto, este tipo de estados depende del protocolo que se esté usando y se verán en el punto específico de cada protocolo. 7) Dirección IP de origen del paquete de petición. 8) Dirección IP de destino del paquete de petición. 9) Puerto de origen del paquete de petición. 10) Puerto de destino del paquete de petición. 11) Pasados estos 4 campos, encontramos el valor de un flag, en la Figura 6.5, el valor de esta es 0. Este flag indica que solo se ha visto tráfico en una dirección y se denomina UNREPLIED. 12) Dirección IP de origen de la respuesta. 13) Dirección IP de destino de la respuesta. 14) Puerto de origen de la respuesta. 15) Puerto de destino de la respuesta. 16) En caso de haber visto tráfico en ambas direcciones, se borra el valor del flag UNREPLIED y se sustituye por uno que se encuentra en el antepenúltimo valor de la entrada, “ASSURED”, el cual indica que se ha visto tráfico en ambos sentidos. Este flag nos indica que la entrada se encuentra asegurada y que ante un llenado de todas las entradas de conntrack esta no se borrará, al contrario de lo que ocurriría con la entrada cuyo flag es “UNREPLIED”. 17) Mark, nos da la marca de ese flujo de comunicación. 18) Use, nos indica el número de usos de ese entrada de flujo. Como se puede comprobar en la Figura 6.5, para crear los datos de la entrada pertenecientes a la respuesta, 70 conntrack toma las direcciones de origen y destino y los invierte con respecto a los vistos en el comienzo de la entrada, lo mismo ocurre con los puertos de origen y destino que también se encuentran invertidos respecto a los anteriores. Tabla de parámetros de una entrada conntrack TCP 1º Protocolo de capa 3 ipv4 2º Numeración protocolo capa 3 (Decimal) 2 3º Protocolo de capa 4 TCP 4º Numeración protocolo capa 4 (Decimal) 6 5º Timeout de la entrada (Duración) 111 6º State interno de la entrada TIME_WAIT 7º IP origen (original) 10.10.1.20 8º IP destino (original) 10.10.1.10 9º Puerto origen (original) 54662 10º Puerto destino (original) 80 11º Flag UNREPLIED 0 12º IP origen (reply) 10.10.1.10 13º IP destino (reply) 10.10.1.20 14º Puerto origen (reply) 80 15º Puerto destino (reply) 54662 16º Flag ASSURED 1 17º Marca de la conexión 2 18º Use de la entrada 1 Tabla 10 - Campos de la entrada conntrack TCP En la Tabla 10, se pueden observar los diferentes valores que tienen los campos de la entrada TCP de conntrack. 71 6.2.2 Entrada conntrack UDP Figura 6.6 - Entrada conntrack UDP extendido Analizamos la información mostrada en la Figura 6.6 (Entrada UDP): 1) Para comenzar, se tiene el protocolo de capa 3, que en este caso es el ipv4 2) Representación de este protocolo de forma numérica decimal, el valor en este caso es “2”. 3) Se tiene la información del protocolo de capa 4, el cual se puede ver que es UDP 4) Representación del número de este protocolo en notación decimal “17”. 5) Después viene el tiempo de vida restante para dicha entrada, en la Figura 6.6 se puede observar que a esta entrada de conexión le quedan 24 segundos, los cuales, irán disminuyendo hasta que se vea más tráfico perteneciente a dicha conexión. Cuando llegue nuevo tráfico, el contador de esta entrada se establece de nuevo a su valor por defecto. 6) Dirección IP de origen del paquete de petición. 7) Dirección IP de destino del paquete de petición. 8) Puerto de origen del paquete de petición. 9) Puerto de destino del paquete de petición. 10) Pasados estos 4 campos, podemos encontrarnos el valor de un flag , en la Figura 6.6 el valor de esta es 0. Este flag indica que solo se ha visto tráfico en una dirección y se denomina UNREPLIED. 11) Dirección IP de origen de la respuesta. 12) Dirección IP de destino de la respuesta. 13) Puerto de origen de la respuesta. 14) Puerto de destino de la respuesta. 15) Mark, nos da la marca de ese flujo de comunicación. 16) Use, nos indica el número de usos de ese entrada de flujo. Tabla de parámetros de una entrada conntrack UDP 1º Protocolo de capa 3 ipv4 2º Numeración protocolo capa 3 (Decimal) 2 3º Protocolo de capa 4 UDP 4º Numeración protocolo capa 4 (Decimal) 17 5º Timeout de la entrada 24 72 (Duración) 6º IP origen (original) 192.168.106.137 7º IP destino (original) 8.8.8.8 8º Puerto origen (original) 52565 9º Puerto destino (original) 53 10º Flag UNREPLIED 0 11º IP origen (reply) 8.8.8.8 12º IP destino (reply) 192.168.106.137 13º Puerto origen (reply) 53 14º Puerto destino (reply) 52565 15º Marca de la conexión 0 16º Use de la entrada 1 Tabla 11 - Campos de la entrada conntrack UDP En la Tabla 11, se pueden observar los diferentes valores que tienen los campos de la entrada UDP de conntrack. 6.2.3 Entrada conntrack ICMP Figura 6.7 - Entrada conntrack ICMP extendido Analizamos la información mostrada en la Figura 6.7 (Entrada ICMP): 1) Para comenzar, se tiene el protocolo de capa 3, que en este caso es el ipv4 . 2) Representación de este protocolo de forma numérica decimal, el valor en este caso es “2”. 3) Se tiene la información del protocolo de capa 4, el cual se puede ver que es ICMP 4) Representación del número de este protocolo en notación decimal “1”. 5) Después viene el tiempo de vida restante para dicha entrada, en la Figura 6.7 se puede observar que a esta entrada de conexión le quedan 28 segundos, los cuales, irán disminuyendo hasta que se vea más tráfico perteneciente a dicha conexión. Cuando llegue nuevo tráfico, el contador de esta entrada se establece de nuevo a su valor por defecto. 6) Dirección IP de origen del paquete de petición. 7) Dirección IP de destino del paquete de petición. 8) Tipo ICMP del paquete de petición. 73 9) Código ICMP del paquete de petición. 10) ID ICMP del paquete de petición Pasados estos 5 campos, podemos encontrarnos el valor de un flag , en la Figura 6.7 el valor de esta es 0. Este flag indica que solo se ha visto tráfico en una dirección y se denomina UNREPLIED. 11) Dirección IP de origen de la respuesta. 12) Dirección IP de destino de la respuesta. 13) Tipo ICMP del paquete de respuesta. 14) Código ICMP del paquete de respuesta. 15) ID ICMP del paquete de respuesta. 16) Mark, nos da la marca de ese flujo de comunicación. 17) Use, nos indica el número de usos de ese entrada de flujo. 17) Tabla de parámetros de una entrada conntrack 1º Protocolo de capa 3 ipv4 2º Numeración protocolo capa 3 (Decimal) 2 3º Protocolo de capa 4 ICMP 4º Numeración protocolo capa 4 (Decimal) 1 5º Timeout de la entrada (Duración) 28 6º IP origen (original) 192.168.106.137 7º IP destino (original) 216.58.215.131 8º Tipo ICMP (original) 8 9º Código ICMP (original) 0 10º ID ICMP (original) 2854 11º Flag UNREPLIED 0 12º IP origen (reply) 216.58.215.131 13º IP destino (reply) 192.168.106.137 14º Tipo ICMP (reply) 0 15º Código ICMP (reply) 0 16º ID ICMP (reply) 2854 74 17º Marca de la conexión 0 18º Módulos que usan la entrada 1 Tabla 12 - Campos de la entrada conntrack ICMP En la Tabla 12, se pueden observar los diferentes valores que tienen los campos de la entrada ICMP de conntrack. Una vez se ha visto los distintos tipos de entradas que podemos tener y los campos que las conforman, pasaremos a ver el uso de conntrack en modo monitor, con la opción -E. Equipo:Encaminador Usuario:root $ conntrack -E En caso de usarlo así, debemos indicar que existen unos estados específicos que veremos a continuación. Figura 6.8 - Estados entradas conntrack modo monitor En la Figura 6.8, se pueden ver los 3 valores de estados que aparecen al comienzo de la entrada; NEW, UPDATE y DESTROY, estos estados se encuentran descritos en la Tabla 13. Estos valores a diferencia de los vistos en la Tabla 9, no representan el estado de un paquete, sino que representan el estado de una entrada dentro de conntrack. Estado Descripción NEW Este estado nos indica que la entrada acaba de crearse dentro de conntrack. Por lo que, al crearse esta entrada, entendemos que el paquete que la ha creado, ha atravesado el hook input si su destino es la máquina local o el hook postrouting si este ha sido encaminado por el equipo. Estos paquetes son los primeros pertenecientes a un nuevo flujo de comunicación que ve conntrack. Esta entrada se caracteriza porque siempre tendrá activado el flag UNREPLIED. UPDATE Este estado nos indica que se ha actualizado una entrada ya existente en conntrack. La actualización, se da cada vez que se ve un paquete perteneciente a un flujo de comunicación prexistente. DESTROY Este estado, se da cuando expira el temporizador que tiene la entrada de conntrack y nos indica, que esa entrada se ha borrado del sistema. Tabla 13 - Estados entradas conntrack 75 6.2.4 Ejemplo de Seguimiento de Conexiones Descripción del ejemplo: En este ejemplo, se busca mostrar el uso básico de la herramienta conntrack, de forma que se pueda monitorizar los eventos de las entradas de esta, así como ver y buscar por un determinado patrón en las entradas que tenga guardadas. Para realizar este ejemplo, se usará el escenario de dos equipos “Anexo E - Escenario 2 Equipos”. La instalación de conntrack-tools [47] [48], se especifica en el “Anexo C - Instalación Conntrack-Tools”. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Se comprueba que la tabla de conntrack se encuentra vacía con el siguiente comando y se observa si la salida coincide con la mostrada en la Figura 6.9. Equipo:Encaminador Usuario:root $ conntrack -L Figura 6.9 - Mostrar entradas conntrack Como se puede observar en la Figura 6.9, se encuentra inicialmente vacía, para que nuestro módulo comience a guardar las conexiones, es imprescindible que el tráfico sea procesado por algún hook de nftables. 2. [Equipo:Encaminador - Usuario:root] Para comenzar a ver las entradas de conntrack, basta con añadir una regla que contabilice el tráfico y se vuelve a comprobar la tabla de conexiones. Equipo:Encaminador Usuario:root $ nft add table ip filter $ nft add chain ip filter prerouting { type filter hook prerouting priority 0 ; } $ nft add rule ip filter prerouting counter 3. [Equipo:Encaminador - Usuario:root] Para que PC1 pueda comunicarse con máquinas públicas a través de Encaminador, se añaden las siguientes reglas. Equipo:Encaminador Usuario:root $ nft add table ip nat $ nft add chain ip nat prerouting { type nat hook prerouting priority 0 ; } $ nft add chain ip nat postrouting { type nat hook postrouting priority 100 ; } $ nft add rule ip nat prerouting ip daddr 192.168.106.128 dnat to 10.10.1.20 $ nft add rule ip nat postrouting ip saddr 10.10.1.0/24 counter masquerade 82 5. [Equipo:Encaminador - Usuario:root] En Encaminador, se abren dos terminales adicionales con el usuario root: • En el primero de ellos, se realizará la monitorización del paso de los paquetes por las reglas de nftables • En el segundo de ellos, colocaremos conntrack en modo evento, de forma que muestre todos los eventos que se produzcan durante la comunicación. Equipo:Encaminador Usuario:root #Terminal 1 $ nft monitor trace #Terminal 2 $ conntrack -E --event-mask ALL 6. [Equipo:PC1 - Usuario:root] Desde PC1, se usa el siguiente comando para pedir la página web del servidor Apache de Encaminador. Equipo:PC1 Usuario:root $ curl 10.10.1.10 7. [Equipo:Encaminador - Usuario:root] Se observa la salida mostrada en el terminal con el monitor activado, en el cual, se puede ver el camino del paquete TCP que llega al equipo Encaminador por la interfaz “ens38”, este paquete tiene activado el flag SYN. Figura 6.20 - Camino paquete TCP SYN En la Figura 6.20, se puede observar el camino del paquete TCP SYN. Camino del paquete TCP SYN: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38”. 2) Tras realizar las comprobaciones básicas del mismo, la NIC le pasa el paquete a la cadena filteringress, la cual, activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter, (este pasa por la cadena nat pero no se le aplica ninguna regla). 4) En prerouting, hace match con la regla que realiza la cuenta de paquetes, cuyo estado es new 83 (En el punto anterior de este capítulo , se vio que la categorización de este estado tiene lugar en este hook, en una etapa temprana de procesado). 5) El veredicto del paquete es continue, por lo que se procede a consultar el encaminamiento del mismo. 6) Al ser un paquete cuyo destino es el proceso local, continua su camino hacia el hook input. 7) Antes de salir del hook input y siendo su veredicto continue, se crea la entrada con el estado NEW en conntrack. 8. [Equipo:Encaminador - Usuario:root] Se observa la salida mostrada en el terminal con el monitor activado, en este, se puede ver el camino del paquete TCP generado por el proceso local, el cual responde con un paquete SYN-ACK que sale por la interfaz “ens38” como se puede ver en la Figura 6.21. Figura 6.21 - Camino paquete TCP SYN-ACK Camino del paquete TCP SYN-ACK: 1) El paquete TCP SYN ACK es generado por el proceso local y antes de llegar a output se consulta la tabla de encaminamiento. 2) Tras comprobar su encaminamiento, el paquete llega al hook output donde se le activa nftrace. 3) El veredicto de output es continue y el paquete sigue su curso hacia postrouting 4) Antes de salir del hook postrouting se actualiza la entrada que el paquete TCP SYN había creado en conntrack, siendo el nuevo estado de la entrada UPDATE. 9. [Equipo:Encaminador - Usuario:root] Por último, PC1 responde con un paquete TCP con el flag ACK activado y de esta manera queda establecida la conexión TCP. Figura 6.22 - Camino paquete TCP ACK 84 Camino del paquete TCP ACK: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38” 2) Tras realizar las comprobaciones básicas del mismo, la NIC le pasa el paquete a la cadena filteringress, la cual activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting, hace match con la regla que realiza la cuenta de paquetes cuyo estado es established. 5) El veredicto del paquete es continue, por lo que se procede a consultar el encaminamiento del mismo. 6) Al ser un paquete, cuyo destino es el proceso local, continua su camino hacia el hook input. 7) Antes de salir del hook input y siendo su veredicto continue, se actualiza la entrada con el estado UPDATE en conntrack. Figura 6.23 - Esquema estados conntrack TCP handshake En la Figura 6.23, se puede observar un esquema del transcurso de los paquetes de apertura de conexión TCP y los distintos estados que estos toman. Los estados en negro, pertenecen a la categorización que realiza conntrack en el hook prerouting y hook output, Tabla 9, mientras que aquellos que aparecen en color rojo, son los estados internos de TCP que se ven en la Figura 6.18, los cuales, adjudica conntrack en los puntos de creación/actualización de entradas en el hook input y hook postrouting. Este es el transcurso del paquete por las diferentes reglas, pero el paso por el hook input y el hook postrouting, actualizan el sistema de seguimiento de conexiones, produciendo que; 1) Al llegar el paquete SYN, se añada una nueva entrada con el estado interno de TCP SYN_SENT (línea 1 Figura 6.24 ). 2) Cuando el proceso local de Encaminador recibe el paquete SYN, este envía un mensaje de respuesta a PC1 con el SYN-ACK, al cruzar este mensaje por el hook postrouting, se actualiza la entrada de conntrack con el estado interno de TCP SYN_RECV, además, al haber visto 85 tráfico ya en ambos sentidos, se pone a 0 el valor del flag UNREPLIED de la entrada (línea 2 Figura 6.24). 3) Por último, cuando PC1 recibe este paquete, contestará con el ACK visto en la Figura 6.22, de forma de que al llegar este paquete al hook input, se volvería a actualizar la entrada de conntrack y el valor de su estado interno pasaría a ser ESTABLISHED. Se activaría el flag de ASSURED, puesto que la conexión estaría establecida y en caso de que se llenara la memoria de conntrack, no se busca que se borre esa entrada, por lo que se marca como asegurada (línea 3 Figura 6.24). Figura 6.24 - Entradas conntrack paquete TCP En la Figura 6.25 se puede ver el flow del handshake de TCP descrito en este ejemplo. Figura 6.25 - Flow ejemplo TCP handshake conntrack A continuación, se analizará dentro del mismo ejemplo el cierre de la conexión que tiene lugar una vez la web ha sido servida. Se sigue viendo la salida de los dos terminales abiertos en el equipo Encaminador. El cierre de conexión se realiza mediante el intercambio de 3 mensajes (muy parecido al handshake). 10. [Equipo:Encaminador - Usuario:root] Se observa la salida mostrada en el terminal con el monitor activado, en el cual, se puede ver el camino del paquete TCP que llega al equipo Encaminador por la interfaz “ens38”, este paquete tiene activado los flags FIN y ACK (Figura 6.26). Figura 6.26 - Camino paquete TCP FIN-ACK PC1 86 Camino del paquete TCP FIN: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38”. 2) Tras realizar las comprobaciones básicas del mismo, la NIC pasa el paquete a la cadena filteringress, la cual activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting, hace match con la regla que realiza la cuenta de paquetes cuyo estado es established. 5) El veredicto del paquete es continue, por lo que se procede a consultar el encaminamiento del mismo. 6) Al ser un paquete cuyo destino es el proceso local, continua su camino hacia el hook input. 7) Antes de salir del hook input y siendo su veredicto continue, se actualiza la entrada con el estado UPDATE en conntrack, segunda línea de la Figura 6.29. 11. [Equipo:Encaminador - Usuario:root] Se observa la salida mostrada en el terminal con el monitor activado, en el cual se puede ver el camino del paquete TCP generado por el proceso local, el cual responde con un paquete FIN-ACK que sale por la interfaz “ens38” como se puede ver en la Figura 6.27. Figura 6.27 - Camino paquete TCP FIN-ACK Encaminador Camino del paquete TCP FIN-ACK: 1) El paquete TCP FIN ACK es generado por el proceso local y antes de llegar a output se consulta la tabla de encaminamiento. 2) Tras comprobar su encaminamiento, el paquete llega al hook output donde se activa nftrace. 3) El veredicto de output es continue y el paquete sigue su curso hacia postrouting 4) Antes de salir del hook postrouting, se actualiza la entrada que el paquete TCP FIN había creado en conntrack, siendo el nuevo estado de la entrada UPDATE, tercera línea de la Figura 6.29. 12. [Equipo:Encaminador - Usuario:root] Por último, PC1 responde con un paquete TCP con el flag ACK activado y de esta manera queda cerrada la conexión TCP. 87 Figura 6.28 - Camino paquete TCP ACK cierre conexión Camino del paquete TCP ACK: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38”. 2) Tras realizar las comprobaciones básicas del mismo, la NIC pasa el paquete a la cadena filteringress, la cual activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting, hace match con la regla que realiza la cuenta de paquetes cuyo estado es established. 5) El veredicto del paquete es continue, por lo que se procede a consultar el encaminamiento del mismo. 6) Al ser un paquete cuyo destino es el proceso local, continua su camino hacia el hook input. 7) Antes de salir del hook input y siendo su veredicto continue, se actualiza la entrada con el estado UPDATE en conntrack, cuarta línea de la Figura 6.29 Figura 6.29 - Entradas conntrack cierre conexión TCP 88 Figura 6.30 - Esquema estados conntrack TCP close connection En la Figura 6.30, se puede observar un esquema del transcurso de los paquetes para cerrar la conexión TCP y los distintos estados que estos toman. Los estados en negro, pertenecen a la categorización que realiza conntrack en el hook prerouting y hook output, Tabla 9, mientras que aquellos que aparecen en color rojo, son los estados internos de TCP que se ven en la Figura 6.18, los cuales adjudica conntrack en los puntos de creación/actualización de entradas en el hook input y hook postrouting. 1) Podemos ver, como la entrada tenía como estado ESTABLISHED, de forma que al enviar PC1 el paquete con el flag FIN y al pasar este por el hook input, la entrada se actualiza a su estado FIN_WAIT, el cual indica que se espera el cierre de la conexión. 2) Encaminador envía su paquete TCP con los flags FIN y ACK, al pasar este por el hook postrouting, se actualiza la entrada con el estado LAST_ACK, indicando que lo último que falta para cerrar la conexión es recibir el ACK del cliente, de forma que al recibir este paquete, PC1 enviará el último ACK para cerrar la conexión. 3) Al llegar este paquete al hook input, se actualiza la entrada y su estado pasa a ser TIME_WAIT. Este estado tiene una duración por defecto de 2 min, por lo que este tiempo se emplea para que todos los paquetes que han tenido problemas y que han sufrido algún tipo de retardo o que se encuentren en un buffer de procesado, puedan atravesar igualmente el conjunto de reglas, incluso después de que la conexión se haya cerrado. Este tiempo se puede considerar como una especie de “tiempo de guarda”, que permita que todos los paquetes lleguen a su destino de forma correcta en caso de que la red tenga algún tipo de congestión. En la Figura 6.31, se puede ver el flow del cierre de conexión TCP que se ha descrito en este ejemplo. 89 Figura 6.31 - Flow ejemplo TCP cierre conexión conntrack 13. [Equipo:Encaminador - Usuario:root] Si se intenta ver las entradas de conntrack, veremos que solo se encuentra la entrada con el estado TIME_WAIT y si se lanza varias veces la consulta, se puede ver como el temporizador va decrementándose, hasta que la entrada desaparece (Figura 6.32). Equipo:Encaminador Usuario:root $ conntrack -L # Se espera un par de segundos $ conntrack -L # Se espera un par de segundos $ conntrack -L Figura 6.32 - Envejecimiento entrada conntrack Debemos hacer una puntualización en este ejemplo ya que tiene una excepción de estados. o En este ejemplo, el paquete FIN-ACK, ha llegado por la cadena input, de forma que los estados que se usarán para el cierre de la conexión son: (FIN_WAIT, LAST_ACK, TIME_WAIT). o En caso de que el paquete FIN_ACK, sea visto primero por el hook postrouting, los estados serían los vistos en la Figura 6.33, ( FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT). Figura 6.33 - Entradas conntrack del cierre de conexión del Encaminador Conclusión del ejemplo: De este ejemplo, se pueden obtener dos imágenes muy importantes, la Figura 6.23 y la Figura 6.30, las cuales muestran el proceso de apertura y cierre de una conexión TCP, indicando los estados TCP, así como la categorización que se realiza de los paquetes usados en este proceso. Estos ejemplos tienen especial importancia para un administrador de red, ya que muestran de forma 90 clara y detallada, el camino seguido por cada paquete y los cambios producidos en los estados de las entradas conntrack. Debemos tener en cuenta, que conntrack realiza un mantenimiento de estados de los equipos finales, es decir, no es capaz de mantener una entrada con el estado del emisor y otra con la del receptor, sino que la misma entrada presenta los cambios y los estados en los que se encuentra la comunicación de ambos equipos finales. Sería un buen punto de trabajo para el futuro, que este mantenimiento de estados se realizase de forma independiente según emisor y receptor, ya que, en casos específicos, podemos encontrarnos con que el estado de uno de ellos, difiera del otro, esto puede ser producido por pérdidas, retrasos de la red etc… Como se ha mencionado anteriormente, en muchos escritos se puede ver que el primer paquete que atraviesa nftables, es el que crea la entrada de conntrack y esto no es así. Para que conntrack cree una entrada de TCP, el paquete que este debe ver es de apertura de conexión, en caso contrario, considerará que el estado de ese paquete es INVALID, puesto que no puede crear una entrada al no ser un paquete de apertura de conexión y tampoco se puede asociar a un flujo existente, por lo que se categoriza como inválido. 6.3.2 Ejemplo conntrack TCP invalid. Descripción del Ejemplo: Desde PC1, probaremos a generar paquetes TCP de distintos tipos. En Encaminador, se activará la monitorización de eventos TCP, viendo así, cuáles de ellos son capaces de crear una entrada en conntrack, además se usarán reglas para poder ver que paquetes se categorizan como inválidos. Para este ejemplo, se parte de la base creada en el ejemplo anterior, el cual usa el escenario de 2 equipos “Anexo E - Escenario 2 Equipos”. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Para el ejemplo de TCP, se crea una tabla filter y otra ingress. Equipo:Encaminador Usuario:root $ nft add table ip filter $ nft add table netdev ingress 2. [Equipo:Encaminador - Usuario:root] Se crean los siguientes grupos de cadenas: 1) Tabla filter: cadenas prerouting, input, forward, postrouting y output. 2) Tabla ingress: cadena ingr Equipo: Encaminador Usuario:root $ nft add chain ´ip filter prerouting { type filter hook prerouting priority 0 ; }´ $ nft add chain ´ip filter postrouting { type filter hook postrouting priority 0 ; }´ $ nft add chain ´ip filter input { type filter hook input priority 0 ; }´ 91 $ nft add chain ´ip filter forward { type filter hook forward priority 0 ; }´ $ nft add chain ´ip filter output { type filter hook output priority 0 ; }´ $ nft add 'chain netdev ingress ingr { type filter hook ingress device ens38 priority 0 ; }' 3. [Equipo:Encaminador - Usuario:root] Se crean las siguientes reglas: 1) Regla en la cadena prerouting de filter, para paquetes TCP cuyo state sea invalid. 2) Regla en la cadena prerouting de filter, para paquetes TCP cuyo state sea new. 3) Regla en la cadena prerouting de filter, para paquetes TCP cuyo state sea established. 4) Regla en la cadena ingr de ingress, para activar la marca nftrace de los paquetes TCP. Equipo: Encaminador Usuario:root #Reglas tabla filter $ nft add rule ip filter prerouting ip protocol tcp ct state invalid counter continue $ nft add rule ip filter prerouting ip protocol tcp ct state new counter continue $ nft add rule ip filter prerouting ip protocol tcp ct state established counter continue #Regla tabla netdev $ nft add rule netdev ingress ip protocol tcp nftrace set 1 4. [Equipo:Encaminador - Usuario:root ] En el equipo Encaminador, se abre un terminal y se coloca conntrack en modo monitor, usando la opción para mostrar todos los eventos. En otro terminal se abre el monitor de nftrace. Equipo:Encaminador Usuario:root #Terminal 1 $ conntrack -E --event-mask ALL #Terminal 2 $ nft monitor trace 5. [Equipo:PC1 - Usuario:root] Desde PC1, se realiza el envío de diferentes paquetes TCP con el comando hping3. Equipo:PC1 Usuario:root #Flag PUSH $ hping3 -c 1 -P 10.10.1.10 -p 80 #Flag URGENT $ hping3 -c 1 -U 10.10.1.10 -p 80 #Flag RESET 98 6.4.1 Ejemplo UDP conntrack. Descripción del Ejemplo: Para realizar el ejemplo con UDP, se partirá de la estructura creada en “TCP Conntrack”, la cual se basa en el “Anexo E - Escenario 2 Equipos”. En este ejemplo; • PC1 generará consultas al DNS mediante el uso del comando nslookup • Encaminador será el encargado de aplicar las reglas de nftables, así como de observar las entradas del módulo conntrack y de monitorizar el paso del paquete por las diferentes reglas. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root ] A las reglas vistas anteriormente, se le añade la siguiente regla en la cadena post de la tabla nat, puesto que, al salir a una red distinta, necesitamos aplicarle masquerade al paquete que se va a encaminar. Equipo:Encaminador Usuario:root $ nft add rule ip nat post ip saddr 10.10.1.20 counter masquerade 2. [Equipo:Encaminador - Usuario:root ] Se abren dos terminales en el equipo encaminador, además se abre Wireshark y se pone a escuchar en la interfaz “ens38”. • Terminal 1: Se abre conntrack en modo monitor de eventos, usando la opción de mostrar todos los eventos. • Terminal 2: Se abre un monitor de reglas nftables. Equipo:Encaminador Usuario:root #Terminal 1 $ conntrack -E --event-mask ALL #Terminal 2 $ nft monitor trace 3. [Equipo:PC1 - Usuario:root ] Se usa el comando nslookup desde PC1, para pedir la dirección de la web trajano. Equipo:PC1 Usuario:root $ nslookup trajano.us.es 4. [Equipo:Encaminador - Usuario:root ] Se observa en el monitor de reglas, el camino del paquete de petición al servidor DNS 8.8.8.8 y la captura de Wireshark realizada. 99 Figura 6.43 - Camino de un paquete UDP En la Figura 6.43 se puede ver el camino del paquete UDP enviado por PC1: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38”. 2) Tras realizar las comprobaciones básicas del mismo, la NIC pasa el paquete a la cadena filteringress, la cual activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting se procesa el paquete y en una fase temprana se clasifica con state NEW, su veredicto es continue, por lo que continúa con su procesado. 5) Se consulta el encaminamiento del paquete, determinando que este ha de ser encaminado. 6) Al tener que ser encaminado, el paquete continúa su camino por el hook forward, siendo aquí su veredicto continue. 7) El paquete llega al hook postrouting, donde antes de abandonar el equipo, se le aplica la regla de NAT y se realiza el masquerade, cambiando su IP origen por la de la interfaz “ens33” del equipo Encaminador. En este punto se crea también la entrada de conntrack con estado NEW, en la cual se recoge los datos del paquete UDP. En la Figura 6.44 se puede ver, como se realiza la petición de IP al servidor DNS, de forma que la petición del paquete entra por la interfaz “ens38” y sale por la interfaz “ens33” después de haberle realizado el masquerade para que pueda salir al exterior. Figura 6.44 - Captura de paquete UDP 100 5. [Equipo:PC1 - Usuario:root ] En el equipo PC1, se observa la salida del comando nslookup y se comprueba el éxito de la petición DNS. La respuesta del servidor DNS viene de vuelta y llega al equipo PC1, indicándole la IP del servidor de trajano.us.es, tal como se puede ver en la Figura 6.45 Figura 6.45 - Comando nslookup para consultar DNS 6. [Equipo:Encaminador - Usuario:root ] En el equipo Encaminador, se revisan las entradas que se han ido creando en conntrack. En la Figura 6.46 podemos ver, que ante el paquete UDP de petición al servidor DNS, se crea en conntrack, una entrada con la categoría NEW y con el flag UNREPLIED activado. Al recibir la respuesta y que esta cruce por el hook postrouting, se actualiza la entrada anterior y se elimina el flag que indicaba que el flujo de datos no había visto respuesta. En la Figura 6.46 también se puede ver la entrada que imprime conntrack al consultar su listado y podemos ver el valor de los campos indicados en el primer punto de este capítulo. Figura 6.46 - Entradas conntrack paquete UDP En la Figura 6.47, se puede observar un resumen del estado que asigna conntrack al paquete UDP conforme se produce la comunicación con el servidor DNS. 101 Figura 6.47 - Esquema estados conntrack UDP En la Figura 6.48 se puede observar el camino que hace cada uno de los dos paquetes de UDP que ve Encaminador (pregunta y respuesta). Figura 6.48 - Camino paquetes conntrack UDP Conclusión del ejemplo: De este ejemplo, cabe destacar el estudio de la Figura 6.47 y Figura 6.48, ya que en ellas reside la base conceptual del ejemplo, mostrando los estados que obtienen los paquetes UDP durante su transmisión, así como visualizando el camino que estos siguen a través de los hooks de Netfilter. A diferencia de TCP, con este protocolo no tenemos paquetes que no abran o no puedan ser asociados a una entrada conntrack. 102 6.5 ICMP Conntrack Con el protocolo ICMP, ocurre los mismo que con el protocolo UDP visto anteriormente, ambos, son protocolos que no están orientados a la conexión, pero como ya se comentó anteriormente, esto no supone ningún impedimento para poder realizar el seguimiento de su flujo de comunicación. Como también se dijo anteriormente, no todos los tipos de paquetes son capaces de crear una entrada de conntrack, de forma que si el primer paquete que esta ve, es de tipo echo request, creará la entrada con la categoría NEW, mientras que si el paquete es de tipo echo-reply y conntrack no tiene ninguna entrada anterior con la que poder asociarlo, lo marcará como invalid. Se recomienda la revisión del anexo de protocolos, en especial, el punto “Protocolo ICMP (Internet Control Message Protocol)” [54]. 6.5.1 Ejemplo ICMP conntrack. Descripción del ejemplo: Para realizar los ejemplos de este punto, se usará el escenario de tres equipos “Anexo F - Escenario 3 Equipos”. • PC1 será el encargado de generar el tráfico ICMP, bien con el comando ping o usando hping3. • Encaminador será el encargado de usar nftables y de visualizar las entradas de conntrack, así como monitorizar el camino del paquete a través de la estructura de tablas y cadenas de Netfilter. • PC2 será el encargado de recibir ciertas peticiones y de probar el caso del reject. Análisis del ejemplo: 1. [Equipo:Encaminador - Usuario:root] Para el ejemplo de ICMP, se crea una tabla filter, una tabla nat y otra netdev. Equipo:Encaminador Usuario:root $ nft add table ip nat $ nft add table ip filter $ nft add table netdev filteringress 2. [Equipo:Encaminador - Usuario:root] Se crean los siguientes grupos de cadenas: 1) Tabla filter: cadenas prerouting, input, forward, postrouting y output. 2) Tabla nat: cadenas prerouting y postrouting. 3) Tabla netdev: cadena filteringress. Equipo: Encaminador Usuario:root $ nft add chain ´ip nat prerouting { type nat hook prerouting priority -1 ; }´ $ nft add chain ´ip nat postrouting { type nat hook postrouting priority -1 ; }´ 103 $ nft add chain ´ip filter prerouting { type filter hook prerouting priority -1 ; }´ $ nft add chain ´ip filter postrouting { type filter hook postrouting priority -1 ; }´ $ nft add chain ´ip filter input { type filter hook input priority -1 ; }´ $ nft add chain ´ip filter forward { type filter hook forward priority 0 ; }´ $ nft add chain ´ip filter output { type filter hook output priority -1 ; }´ $ nft add chain ´ip filter prerouting { type filter hook prerouting priority -1 ; }´ $ nft add 'chain netdev filteringress ingress { type filter hook ingress device ens38 priority 0 ; }' 3. [Equipo:Encaminador - Usuario:root] Se crean las siguientes reglas: 1) En la cadena filteringress, se añade una regla que active nftrace para todo el tráfico entrante. 2) En la cadena prerouting de filter, se añade una regla que contabilice el tráfico ICMP cuyo state sea invalid. 3) En la cadena postrouting de nat, se añade una regla para contabilizar y realizar el masquerade al tráfico cuya IP origen sea la de PC1. Equipo: Encaminador Usuario:root $ nft add rule netdev filteringress nftrace set 1 $ nft add rule ip filter prerouting ip protocol tcp ct state invalid counter continue $ nft add rule ip nat postrouting ip saddr 10.10.1.20 counter masquerade 4. [Equipo:Encaminador - Usuario:root ] Se abren dos terminales en el equipo Encaminador: • Terminal 1: Se abre conntrack en modo monitor de eventos, usando la opción de mostrar todos los eventos. • Terminal 2: Se abre un monitor de reglas nftables. Equipo:Encaminador Usuario:root #Terminal 1 $ conntrack -E --event-mask ALL #Terminal 2 $ nft monitor trace 5. [Equipo:PC1 - Usuario:root ] Se abre Wireshark y se pone a escuchar en la interfaz “ens37”. 6. [Equipo:PC1 - Usuario:root ] Se lanza un ICMP echo-request desde PC1 hacia la dirección de PC2. Equipo: PC1 Usuario: root $ ping -c 1 172.168.0.20 104 7. [Equipo:PC1 - Usuario:root ] Se comprueba la salida de Wireshark. Como se puede comprobar en las Figura 6.49 y Figura 6.50, la petición de echo request llega a Encaminador y este la encamina hacia PC2 saliendo el paquete por la interfaz “ens39”. Al recibir el echo request, PC2 responde con el echo-reply y al llegar a Encaminador, este lo encamina hacia PC1, el cual recibe la respuesta y da por completado el ping. Figura 6.49 - Captura echo-request y echo-reply ICMP conntrack 8. [Equipo:Encaminador - Usuario:root ] Se comprueba la salida del monitor de nftrace. Esta salida puede verse en la Figura 6.50. Figura 6.50 - Camino paquete echo-request En la Figura 6.50, se puede ver el camino del paquete ICMP enviado por PC1 hacia PC2: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38”. 2) Tras realizar las comprobaciones básicas del mismo, la NIC pasa el paquete a la cadena filteringress, la cual activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting, se procesa y en una fase temprana se clasifica el paquete con state NEW, su veredicto es continue, por lo que se continua con su procesado. 5) Se consulta el encaminamiento del paquete, determinando que este ha de ser encaminado hacia PC2. 105 6) Al tener que ser encaminado, el paquete continúa su camino por el hook forward, siendo aquí su veredicto continue. 7) El paquete llega al hook postrouting, donde, antes de abandonar el equipo se le aplica la regla de NAT y se realiza el masquerade, cambiando su IP origen por la de la interfaz “ens39” del equipo Encaminador. En este punto, se crea también la entrada de conntrack con estado NEW, en la cual, se recogen los datos del paquete ICMP. El paquete echo-reply, realiza el mismo camino que el realizado por el request, categorizando este paquete como ESTABLISHED en el hook prerouting y actualizando la entrada de conntrack cuando este cruza por el hook postrouting, camino a PC1. 9. [Equipo:Encaminador - Usuario:root ] Se comprueba la salida del monitor de conntrack. Esta salida puede verse en la Figura 6.51. Figura 6.51 - Entradas conntrack creadas por comunicación ICMP La primera entrada, la cual podemos ver con el estado NEW y el flag UNREPLIED activado, se crea cuando el paquete icmp-request, cruza el hook postrouting de Encaminador , dirigiéndose hacia PC2. La actualización de la entrada, tiene lugar cuando el paquete icmp-reply, cruza el hook postrouting de Encaminador, dirigiéndose así hacia PC1, en este momento también se pone a 0 el flag de UNREPLIED 10. [Equipo:PC1 - Usuario:root ] Ahora se comprobará las salidas del monitor de nftrace y de conntrack, enviando un icmp-request hacia PC2, en lugar de un icmp-reply. Equipo: PC1 Usuario: root #-C indica el tipo de ICMP y -K el código ICMP $ hping3 -1 -C 0 -K 0 172.168.0.20 11. [Equipo:Encaminador - Usuario:root ] Se comprueba la salida del monitor de nftrace y de conntrack. Observamos, que no se crea la entrada en conntrack y que al ser este un paquete de respuesta y no tener flujo asociado ni poder crearlo, su estado es el de inválido, tal y como se puede comprobar en la Figura 6.52. En la Figura 6.52 se puede ver el camino del paquete ICMP reply enviado por PC1 hacia PC2: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38” 2) Tras realizar las comprobaciones básicas del mismo, la NIC le pasa el paquete a la cadena filteringress, la cual activa la marca de seguimiento del paquete. 3) El veredicto en filteringress es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting se procesa y en una fase temprana, se clasifica el paquete con state INVALID, 106 ya que no puede crear una entrada dentro de conntrack, ni tampoco existe entrada a la que poder asociar ese paquete. 5) Se consulta el encaminamiento del paquete, determinando que este ha de ser encaminado hacia PC2. 6) Al tener que ser encaminado, el paquete continua su camino por el hook forward, siendo aquí su veredicto continue. 7) El paquete llega al hook postrouting, al ser INVALID, este no entra en la cadena NAT, por lo que al no realizársele el masquerade, la respuesta nunca llega a PC1. Figura 6.52 - Envío de paquete echo-reply Conclusión del ejemplo: Este ejemplo, sirve para comprobar que la afirmación que se puede observar en numerosas guías y sitios web, la cual, asegura que las respuestas pueden crear una entrada en conntrack, es falsa. Por ello, es importante que un administrador de red tenga en cuenta, que estos paquetes necesitan estar asociados a un flujo con entrada en conntrack, en caso contrario, el estado de los mismos será invalid. También sirve para comprobar el camino que realizan los paquetes ICMP, tanto de petición como de respuesta a lo largo del sistema de Netfilter. 6.5.2 Ejemplo ICMP conntrack reject. Descripción del ejemplo: Para el siguiente ejemplo, se creará una regla que realice el reject del tráfico ICMP para la máquina local de PC2, de forma que se podrá ver como se crea la entrada de conntrack, así como el state related del paquete generado por ICMP reject, viendo como se considera, que pertenece al flujo creado por el echo-request de PC1. 107 Para este ejemplo, se usará el escenario de 3 equipos “Anexo F - Escenario 3 Equipos” y se partirá de las reglas creadas en el “Ejemplo ICMP conntrack.”. Análisis del ejemplo: 1. [Equipo:PC2 - Usuario:root ] Se debe crear una estructura de nftables en PC2 y añadir la siguientes reglas. • Una tabla filter con las cadenas de prerouting e input. • Añadir tres reglas en la cadena input, una por cada tipo de tráfico que realice su reject. Equipo:PC2 Usuario:root #Creación de tabla y cadenas $ nft add table ip filter $ nft add chain ip´ filter pre { type filter hook prerouting priority 0 ; }´ $ nft add chain ip´ filter input { type filter hook input priority 0 ; }´ #Creación de reglas $ nft add rule ip filter input ip protocol udp reject with icmp type net-unreachable $ nft add rule ip filter input ip protocol tcp reject with icmp type net-unreachable $ nft add rule ip filter input ip protocol icmp reject with icmp type net-unreachable 2. [Equipo:PC2 - Usuario:root ] Se comprueba que la estructura de reglas de PC2 se corresponde con la vista en la Figura 6.53. Equipo:PC2 Usuario:root $ nft list ruleset Figura 6.53 - Reglas reject de ICMP 3. [Equipo:Encaminador - Usuario:root ] En Encaminador, se añade la siguiente regla para poder ver si el paquete tiene el estado de related, de forma que la estructura de nftables queda como se puede ver en la Figura 6.54 114 _stream de transmisión. Tabla 16 - Variables configuración conntrack Si se usa el siguiente comando, se puede ver los valores por defecto de todos los campos explicados anteriormente (ver Figura 6.61). Equipo:Encaminador Usuario:root $ sysctl net.netfilter | grep conntr Figura 6.61 - Valores parámetros conntrack en Encaminador 115 6.7 Helpers Como hemos visto anteriormente, conntrack realiza el seguimiento de flujos de comunicación y para ello, usa ciertos parámetros para poder identificar estos flujos. Existen protocolos que no solo usan un único canal de comunicación, sino que usan varios, uno de ellos para control y otro para la transferencia de datos (protocolos multi-flow). Por ello, usamos lo que se denomina “helpers”, que no son más que unos módulos de ayuda que nos permiten asociar el tráfico de dos flujos distintos a una misma comunicación. Un ejemplo es el protocolo FTP, el cual usa el puerto 21 para conectarse al servidor e intercambiar información de control y el puerto 20 para el intercambio de datos si se usa en modo activo, en modo pasivo, este usa un algoritmo por el cual, calcula el puerto origen y destino siendo estos superiores al puerto 1024. De esta forma, asocia el flujo de intercambio de datos al de control, que es el primero que sea crea. Descripción del ejemplo. En este ejemplo se realizará la prueba de una conexión FTP, en la cual se usará el helper correspondiente para ver el camino de los paquetes y que estados se le asignan a cada uno de estos. Para ello, se usará el escenario de 2 equipos “Anexo E - Escenario 2 Equipos”. • PC1 se encargará de realizar la petición al servidor FTP, cuya dirección IP de la máquina pública es: 35.163.228.146 • Encaminador, será el encargado de realizar el routing de los paquetes, así como de monitorizar las reglas y entradas de conntrack. Análisis del ejemplo. 1. [Equipo:Encaminador - Usuario:root ] Lo primero que debemos hacer es cargar tanto el helper de FTP como el helper de NAT FTP. • El helper de FTP, sirve para poder asociar los dos flujos que se abren (datos y control), a la misma comunicación. • El helper de NAT FTP, permite que, aunque se realice NAT de la conexión FTP, podamos ver la conexión en conntrack y no aparezca como invalid. Equipo:Encaminador Usuario:root $ modprobe nf_conntrack_ftp $ modprobe nf_nat_ftp 2. [Equipo:Encaminador - Usuario:root] Pasamos a continuación a crear las tablas de nftables que se usarán en este ejemplo. • Una tabla nat de tipo ip. • Una tabla filter de tipo ip. • Una tabla ingress de tipo netdev. 116 Equipo:Encaminador Usuario:root $ nft add table ip nat $ nft add table ip filter $ nft add table netdev ingress 3. [Equipo:Encaminador - Usuario:root] Se crean los siguientes grupos de cadenas: 1) Tabla filter: cadenas prerouting, input, forward, postrouting y output. 2) Tabla nat: cadenas pre y post. 3) Tabla ingress: cadenas ingr y ens33. Equipo: Encaminador Usuario:root #Cadenas de tabla nat $ nft add chain ´ip nat pre { type nat hook prerouting priority -10 ; }´ $ nft add chain ´ip nat post { type nat hook postrouting priority 10 ; }´ #Cadenas de tabla filter $ nft add chain ´ip filter prerouting { type filter hook prerouting priority 0 ; }´ $ nft add chain ´ip filter postrouting { type filter hook postrouting priority 0 ; }´ $ nft add chain ´ip filter input { type filter hook input priority 0 ; }´ $ nft add chain ´ip filter forward { type filter hook forward priority 0 ; }´ $ nft add chain ´ip filter output { type filter hook output priority 0 ; }´ #Cadenas de tabla ingress $ nft add 'chain netdev ingress ingr { type filter hook ingress device ens38 priority 0 ; }' $ nft add 'chain netdev ingress ens33 { type filter hook ingress device ens33 priority 0 ; }' 4. [Equipo:Encaminador - Usuario:root] Se crean las siguientes reglas: 1) En la cadena ingr, se añade una regla que active nftrace para todo el tráfico entrante. 2) En la cadena ens33, se añade una regla que active nftrace para todo el tráfico entrante. 3) En la cadena prerouting de filter, se añade una regla que contabilice el tráfico cuyo state sea new. 4) En la cadena prerouting de filter, se añade una regla que contabilice el tráfico cuyo state sea related. 5) En la cadena prerouting de filter, se añade una regla que contabilice el tráfico cuyo state sea established. 6) En la cadena prerouting de filter, se añade una regla que contabilice el tráfico cuyo state sea 117 invalid. 7) En la cadena forward de filter, se añade una regla que contabilice el tráfico cuyo state sea new, established o related. 8) En la cadena postrouting de nat, se añade una regla para contabilizar y realizar el masquerade al tráfico cuya IP origen sea la de PC1. Equipo:Encaminador Usuario:root #Reglas tabla ingress $ nft add rule netdev ingress ingr meta nftrace set 1 counter $ nft add rule netdev ingress ens33 meta nftrace set 1 counter #Reglas tabla filter $ nft add rule ip filter prerouting ct state new continue $ nft add rule ip filter prerouting ct state established continue $ nft add rule ip filter prerouting ct state related continue $ nft add rule ip filter prerouting ct state invalid continue $ nft add rule ip 'filter prerouting ct state { new, estbalished, related } continue' #Regla tabla nat $ nft add rule ip nat post ip saddr 10.10.1.20 counter masquerade 5. [Equipo:Encaminador - Usuario:root] Una vez cargado los módulos y creada la estructura de tablas y cadenas de nftables, pasamos a crear el Stateful object de tipo ct helper, que nos ayude a realizar el seguimiento de la conexión FTP. Equipo:Encaminador Usuario:root $ nft add' ct helper ip filter ftp { type "ftp" protocol tcp ; } ' 6. [Equipo:Encaminador - Usuario:root] Una vez creado el objeto de tipo helper, pasamos a crear su regla en la cadena forward. En la cadena forward de filter, se añade una regla que contabilice el tráfico TCP cuyo puerto destino sea el 21 y se le asigna el helper “ftp”, por último, se añade un contador a esta regla. Equipo:Encaminador Usuario:root $ nft add rule ip filter' forward tcp dport ftp ct helper set "ftp" counter accept ' 7. [Equipo:Encaminador - Usuario:root] Listamos el ruleset de nftables. Podemos ver la salida del comando en las Figura 6.62 y Figura 6.63. Equipo:Encaminador Usuario:root $ nft list ruleset 118 Figura 6.62 - Reglas para ct ftp-1 Figura 6.63 - Reglas para ct ftp-2 8. [Equipo:Encaminador - Usuario:root ] Se abren dos terminales en el equipo Encaminador: • Terminal 1: Se abre conntrack en modo monitor de eventos, usando la opción de mostrar todos los eventos. • Terminal 2: Se abre un monitor de reglas nftables. • Terminal 3: Se abre un monitor de conntrack para visualizar la tabla expect, en la cual, se añadirá la entrada de expectación de la comunicación con FTP. Equipo:Encaminador Usuario:root #Terminal 1 $ conntrack -E --event-mask ALL #Terminal 2 $ nft monitor trace #Terminal 3 $ nft conntrack -E expect 119 9. [Equipo:PC1 - Usuario:root ] Pasamos a realizar la conexión con el servidor FTP desde PC1, para ello usaremos el siguiente comando. Se indican además las credenciales para conectar con el servidor FTP. Una vez conectado al servidor, se procederá a realizar la subida de un fichero, en nuestro caso, usamos un index.html de prueba. Equipo:PC1 Usuario:root $ ftp ftp.dlptest.com # Usuario: dlpuser # Password: rNrKYTX9g7z3RgJRmxWuGHbeu #Ya nos encontramos conectados al servidor, ahora subimos el archivo $put index.html Podemos observar en la Figura 6.64, la salida de los comandos anteriormente mencionados, así como de la conexión en modo pasivo que se realiza para subir el archivo index.html. Figura 6.64 - Conexión FTP desde PC1 Como se puede ver en la Figura 6.64, se han marcado dos números de la conexión en modo pasivo. Estos números, son los que indican el puerto que abre el servidor FTP. Para obtener el valor del puerto se hace la siguiente operación (4*256 + 24 = 1048), por lo que ya sabremos que la conexión con el servidor, se realizará en el puerto 1048. 10. [Equipo:Encaminador - Usuario:root ] En Encaminador, observamos la salida del monitor de nftrace para ver como se establece la conexión del flujo de control. A continuación, veremos los tres paquetes TCP que utiliza PC1 para establecer la conexión de control con el servidor FTP. 120 Figura 6.65 - Paquete TCP SYN flujo control FTP En la Figura 6.65, se puede ver el camino del paquete TCP SYN enviado desde PC1 al servidor FTP: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38” 2) Tras realizar las comprobaciones básicas del mismo, la NIC le pasa el paquete a la cadena ingr, la cual activa la marca de seguimiento del paquete. 3) El veredicto en ingr es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting se procesa y en una fase temprana se clasifica el paquete con state NEW, su veredicto es continue, por lo que se continúa con su procesado. 5) Se consulta el encaminamiento del paquete, determinando que este ha de ser encaminado hacia el servidor FTP. 6) Al tener que ser encaminado, el paquete continúa su camino por el hook forward, donde hace match con la regla que inspecciona si el paquete tiene el state NEW, ESTABLISHED o RELATED. Además, hace match con la segunda regla, en la cual se activa el uso del helper de FTP para este flujo de comunicación y siendo el veredicto de esta cadena continue. 7) El paquete llega al hook postrouting, donde, antes de abandonar el equipo se le aplica la regla de NAT y se le realiza masquerade, cambiando su IP origen por la de la interfaz “ens33” del equipo Encaminador. En este primer paquete, se puede ver que el puerto usado por PC1 es el 34598, mientras que el del servidor es el 21. 121 Figura 6.66 - Paquete TCP SYN-ACK flujo control FTP En la Figura 6.66, se puede ver el camino del paquete TCP SYN-ACK enviado desde el servidor FTP a PC1: 1) El paquete sale de la máquina pública(servidor FTP) y llega a Encaminador por la interfaz “ens33” 2) Tras realizar las comprobaciones básicas del mismo, la NIC le pasa el paquete a la cadena ens33, la cual activa la marca de seguimiento del paquete. 3) El veredicto en ens33 es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting se procesa y en una fase temprana se clasifica el paquete con state ESTABLISHED, su veredicto es continue, por lo que se continúa con su procesado. 5) Se consulta el encaminamiento del paquete, determinando que este ha de ser encaminado hacia PC1. 6) Al tener que ser encaminado, el paquete continúa su camino por el hook forward, donde hace match con la regla que inspecciona si el paquete tiene el state NEW, ESTABLISHED o RELATED. Además, hace match con la segunda regla, en la cual se activa el uso del helper de FTP para este flujo de comunicación y siendo el veredicto de esta cadena continue. 7) El paquete llega al hook postrouting y sale de Encaminador hacia PC1 por la interfaz “ens38”. 122 Figura 6.67 - Paquete TCP ACK flujo control FTP En la Figura 6.67, se puede ver el camino del paquete TCP ACK enviado desde PC1 al servidor FTP, y con el cual, queda establecida la conexión de control entre ambos equipos: 1) El paquete sale de PC1 y llega a Encaminador por la interfaz “ens38” 2) Tras realizar las comprobaciones básicas del mismo, la NIC le pasa el paquete a la cadena ingr, la cual activa la marca de seguimiento del paquete. 3) El veredicto en ingr es continue, por lo que el paquete continúa su camino hacia la cadena prerouting de filter. 4) En prerouting se procesa y en una fase temprana se clasifica el paquete con state ESTABLISHED, su veredicto es continue, por lo que se continúa con su procesado. 5) Se consulta el encaminamiento del paquete, determinando que este ha de ser encaminado hacia el servidor FTP. 6) Al tener que ser encaminado, el paquete continua su camino por el hook forward, donde hace match con la regla que inspecciona si el paquete tiene el state NEW, ESTABLISHED o RELATED. Además, hace match con la segunda regla, en la cual se activa el uso del helper de FTP para este flujo de comunicación y siendo el veredicto de esta cadena continue. 8) El paquete llega al hook postrouting y sale de Encaminador hacia el servidor FTP por la interfaz “ens33”. 11. [Equipo:Encaminador - Usuario:root ] En Encaminador, observamos la salida del monitor de conntrack para ver como se han creado las entradas del flujo de control. Figura 6.68 - Entradas conntrack conexión flujo de control FTP. 123 En la Figura 6.68, vemos como se han creado las entradas del flujo de control de FTP. Estas entradas tienen en común, que usan el helper ftp. 1) La primera entrada con el estado TCP SYN_SENT, se crea cuando el paquete TCP SYN enviado por PC1 hacia el servidor FTP, cruza el hook postrouting para salir del equipo Encaminador. Esta entrada tiene activado el flag UNREPLIED. 2) La entrada se actualiza con el estado TCP SYN_RECV, cuando el paquete TCP SYN-ACK enviado por el servidor FTP hacia PC1, cruza el hook postrouting para salir del equipo Encaminador. Se elimina también el flag UNREPLIED de la entrada. 3) Por último, la entrada se vuelve a actualizar con el estado TCP ESTABLISHED, cuando el paquete TCP ACK enviado por PC1 hacia el servidor FTP cruza el hook postrouting, para salir del equipo Encaminador. En esta entrada se marca la conexión con el flag ASSURED. Antes de pasar a ver el siguiente punto, se debe explicar que es una “expectación”[55] y como funciona. En este ejemplo, como se ha visto en la Figura 6.64, se comunica que puerto se va a utilizar para el flujo de datos de la comunicación FTP. Nosotros hemos añadido el helper a las reglas que tengan como puerto TCP destino el 21. Al comunicar el puerto usado para el flujo de datos, conntrack crea en su tabla expect, una entrada de expectación. Este tipo de entradas, es usada para las conexiones que usan helper, es decir, aquellas que son multi-flow. En esta expectación, indicamos que se espera la creación de una entrada, que guardará relación con una entrada ya existente en conntrack (esta entrada es conocida como entrada maestra) y de la que solo conocemos algunos datos. Una vez se ve el primer paquete que coincida con los campos de la entrada de expectación, esta es borrada y se crea una nueva entrada en conntrack, que estará relacionada, con la entrada denominada maestra. A continuación, se verán las partes de una entrada expectation. Figura 6.69 - Campos de una entrada expectation conntrack Analizamos la información mostrada en la Figura 6.69 (Entrada conntrack expectation): 1) Para comenzar, se tiene el estado de la entrada conntrack, en este caso NEW. 2) Valor del timeout de ese tipo de expectación, el valor por defecto para una expectación FTP es de 300 segundos. 3) Información decimal del protocolo usado, como se puede ver, el valor 6 hace referencia al protocolo TCP. 4) Dirección origen de la expectación, en esta figura vemos que se espera que el origen sea la IP de PC1. 5) Dirección destino de la expectación, en esta figura vemos que se espera que el destino sea la IP del servidor FTP. 6) Puerto origen de la expectación, el 0 que se puede ver, significa que puede usarse cualquier puerto origen. 226 3. [Equipo:Encaminador - Usuario:root] Instalación de Bison. Equipo:Encaminador Usuario:root $ git clone https://git.savannah.gnu.org/git/bison.git $ cd bison $ sh autogen.sh $ ./configure $ make $ make install $ cd .. 4. [Equipo:Encaminador - Usuario:root] Instalación de Flex. Equipo:Encaminador Usuario:root $ wget http://prdownloads.sourceforge.net/flex/flex- 2.5.33.tar.gz? /download $ tar -xvzf flex-2.5.33.tar.gz $ cd flex-2.5.33 $ sh autogen.sh $ ./configure --prefix=/usr/local/flex $ make $ make install $ cd .. 5. [Equipo:Encaminador - Usuario:root] Instalación de Asciidoc. Equipo:Encaminador Usuario:root $ git clone https://github.com/asciidoc/asciidoc-py3 asciidoc- 9.0.4 $ cd asciidoc-9.0.4 $ sh autogen.sh $ ./configure $ make $ make install $ cd .. 6. [Equipo:Encaminador - Usuario:root] Instalación de Libgmp. Equipo:Encaminador Usuario:root $ wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.xz $ tar xvf gmp-6.1.2.tar.xz $ cd gmp-6.1.2 $ ./configure --prefix=/usr/local/gmp/6_1_2 $ make $ make install 227 7. [Equipo:Encaminador - Usuario:root] Instalación de Libreadline. Equipo:Encaminador Usuario:root $ wget ftp://ftp.gnu.org/gnu/readline/readline-8.0.tar.gz $ tar xvfz readline-8.0.tar.gz $ cd readline-8.0 $ ./configure --prefix=/usr/local/readline/8_0 $ make $ make install 8. [Equipo:Encaminador - Usuario:root] Comprobación de dependencias. Una vez hemos llegado a este punto, comprobamos que tenemos instaladas las dependencias necesarias para poder instalar el paquete de nftables sin que salte ningún aviso ni error. Para ello comprobamos con las siguientes órdenes si los paquetes se encuentran instalados (Figura B.1 y Figura B.2) Equipo:Encaminador Usuario:root $ dpkg -l | grep libmn $ dpkg -l | grep libnft $ dpkg -l | grep bison $ dpkg -l | grep flex Figura B.1 - Librerías nft(1) Equipo:Encaminador Usuario:root $ dpkg -l | grep readlin $ dpkg -l | grep libgm Figura B.2 - Librerías nft(2) 228 Instalación de Nftables La mayoría de las anteriores dependencias, son librerías que ayudan a la interpretación de las reglas y al manejo de las mismas, ya que el núcleo de Netfilter viene por defecto instalado en las distribuciones. A continuación, pasamos a descargar el framework de nftables. 1. [Equipo:Encaminador - Usuario:root] Instalación de Nftables. Equipo:Encaminador Usuario:root $ git clone git://git.netfilter.org/nftables $ cd nftables $ sh autogen.sh $ ./configure $ make $ make install 2. Comprobación de instalación Comprobamos que el paquete ha sido instalado, para ello hacemos uso del siguiente comando (Figura B.3). Equipo:Encaminador Usuario:root $ dpkg -l | grep nftables Figura B.3 - nft instalado 3. [Equipo:Encaminador - Usuario:root] Cargar módulo nftables. Una vez lo hayamos comprobado, cargamos su módulo Equipo:Encaminador Usuario:root $ modprobe nf_tables Con esto, ya tendríamos instalada nuestra herramienta en la distribución. 4. [Equipo:Encaminador - Usuario:root] Revisar estado del servicio. Para comprobarlo revisamos el estado del servicio, introduciendo el siguiente comando y comprobando que el resultado es similar al mostrado en la Figura B.4. Equipo:Encaminador Usuario:dit $ service nftables status 229 Figura B.4 - Servicio nft 230 231 ANEXO C - INSTALACIÓN CONNTRACK-TOOLS En este anexo se explica el proceso de instalación de Conntrack-tools. Lo primero que tenemos que realizar es la actualización de la lista de paquetes. Equipo:Encaminador Usuario:dit $ sudo su $ apt-get update $ apt-upgrade Una vez realizado, instalamos las dependencias de Conntrack-tools. Instalación dependencias de Conntrack-tools 1. [Equipo:Encaminador - Usuario:root] Instalación de Libnetlink. Equipo:Encaminador Usuario:root $ wget http://www.netfilter.org/projects/libnfnetlink/files \ /libnfnetlink-0.0.11.tar.bz2 $ tar xvf libnfnetlink-0.0.11.tar.bz2 $ cd libnfnetlink-0.0.11 $ ./configure $ make $ make install 2. [Equipo:Encaminador - Usuario:root] Instalación de Libnetfilter_conntrack. Equipo:Encaminador Usuario:root $ wget http://www.netfilter.org/projects/ libnetfilter_conntrack/ \ files/libnetfilter_conntrack-1.0.8.tar.bz2 $ tar xvf libnetfilter_conntrack-1.0.8.tar.bz2 $ cd libnetfilter_conntrack-1.0.8 $ ./configure $ make $ make install 3. [Equipo:Encaminador - Usuario:root] Comprobar módulos. Para comprobar que están instalados los módulos necesarios, usamos el siguiente comando y comprobamos que su resultado es el mostrado en la Figura C.1. Equipo:Encaminador Usuario:root $ lsmod | grep conn 232 Figura C.1 - Módulos Conntrack-tools Instalación de Conntrack-tools Por último, instalamos Conntrack-tools. 1. [Equipo:Encaminador - Usuario:root] Instalación de Conntrack-tools. Equipo:Encaminador Usuario:root $ wget http://www.netfilter.org/projects/conntrack-tools/ \ files/conntrack-tools-1.4.6.tar.bz2 $ tar xvjf conntrack-tools-1.4.6.tar.bz2 $ cd conntrack-tools-1.4.6 $ ./configure $ make $ make install 2. [Equipo:Encaminador - Usuario:root] Comprobación de la instalación. Para comprobar que este se ha instalado correctamente, ejecutamos el siguiente comando con la opción -L, para que nos muestre la tabla de flujos de conexión, que deberá estar vacía (Figura C.2). Equipo:Encaminador Usuario:root $ conntrack -L Figura C.2 - Conntrack-tools instalado 233 ANEXO D - INSTALACIÓN Y CONFIGURACIÓN FIREWALLD En este anexo, veremos cómo se realiza la instalación de Firewalld mediante el código fuente. La primera dependencia con la que nos encontramos es desktop-file-utils. Este paquete nos permite trabajar con una base de datos tipo MIME, usando como entrada la línea de comandos. Dado que las zonas de Firewalld son guardadas en estas bases, necesitamos este paquete para no obtener error a la hora de intentar configurarlas desde la línea de comandos. Repositorio: Equipo:Encaminador Usuario:dit $ sudo apt-get update $ sudo apt-get install desktop-file-utils Instalación de dependencias Firewalld 1. [Equipo:Encaminador - Usuario:root] Instalación de Desktop-File-Utils. Equipo:Encaminador Usuario:root $ mkdir firewall-dependencias $ cd firewall-dependencias $ wget ftp https://www.freedesktop.org/software/desktop- \ file-utils/releases/desktop-file-utils-0.26.tar.xz.sha256sum $ tar xvfz file-utils-0.26.tar.xz $ cd file-utils-0.26 $ ./configure $ make $ make install $ cd .. 2. [Equipo:Encaminador - Usuario:root] Instalación de Gettext. Este paquete es el encargado de ofrecernos las herramientas de programación que necesita nuestro frontend (Firewalld). 1) Gextext por repositorio: Equipo:Encaminador Usuario:dit $ sudo apt-get update $ sudo apt-get install gettext 234 2) Gettext por código fuente: Equipo:Encaminador Usuario:root $ wget ftp https://ftp.gnu.org/pub/gnu/gettext/gettext- 0.21.tar.gz $ tar xvfz gettext-0.21.tar.gz $ cd gettext-0.21 $ ./configure $ make $ make install $ cd .. 3. [Equipo:Encaminador - Usuario:root] Instalación de Intltool. La siguiente dependencia a instalar consta de varios sub-paquetes, es por ello que elegimos instalarla mediante el uso de repositorios, para evitar la complejidad del código fuente. Repositorio: Equipo:Encaminador Usuario:dit $ sudo apt-get update $ sudo apt-get install intltool Se deben instalar las siguientes opciones de cmake-extras: • Cmake • Cmake-data • Libcurl4 • Libjsonpp1 • Librhash0 • Libuv1 4. [Equipo:Encaminador - Usuario:root] Instalación de Glib. La siguiente dependencia se llama glib, y en caso de instalarla por repositorio deberemos indicar su nombre tal y como se indica a continuación, mientras que, si se instala desde código fuente por git , bastará con usar los comandos indicados. 1) Glib2 por repositorio. Equipo:Encaminador Usuario:dit $ sudo apt-get update $ sudo apt-get install libntrack-glib2 235 2) Glib2 por código fuente. Equipo:Encaminador Usuario:root $ git clone https://gitlab.gnome.org/GNOME/glib $ cd glib $ ./configure $ make $ make install $ cd .. Existen 3 dependencias más, pero entendemos que si se usa la distribución indicada ya vienen de base, aun así, se indica a continuación por si en algún caso no estuviesen. • Docbook • Libxslt • Ebtables • Ipsec El motivo de instalar ipsec y ebtables es que la funcionalidad de firewalld todavía no es completa, por lo que alguno de sus módulos todavía trabaja con iptables. Una vez seguido los pasos anteriores procederemos a instalar firewalld. Instalación de Firewalld 1. [Equipo:Encaminador - Usuario:root] Instalación de Firewalld. Equipo:Encaminador Usuario:root $ wget ftp https://github.com/firewalld/firewalld/releases/ \ download/v0.9.3/firewalld-0.9.3.tar.gz $ tar xvfz firewalld-0.9.3.tar.gz $ cd firewalld-0.9.3 $ ./configure $ make $ make install $ cd .. 2. [Equipo:Encaminador - Usuario:root] Comprobar servicio Firewalld. A continuación, para comprobar que el funcionamiento es correcto, que está cargado y que lo tenemos corriendo en nuestro equipo, introducimos el siguiente comando. Comprobaremos que la salida producida se corresponde con las vistas en la Figura D.1 y Figura D.2. Equipo:Encaminador Usuario:dit #Estado del servicio $ systemctl start firewalld $ systemctl enable firewalld 242 } chain nat_POST_internal { jump nat_POST_internal_pre jump nat_POST_internal_log jump nat_POST_internal_deny jump nat_POST_internal_allow jump nat_POST_internal_post } } 243 ANEXO E - ESCENARIO 2 EQUIPOS Figura E.1 - Esquema escenario 2 equipos Este es el escenario que se plantea para usar dos equipos (Figura E.1). Consta de un primer equipo, que será el cliente (PC1) y es el encargado de realizar las peticiones y generar tráfico de red y segundo equipo servidor (Encaminador) en el cual tendremos las herramientas de firewall para tratar el tráfico. En la Tabla 19, se recoge un cuadro resumen, con los sistemas operativos, las interfaces y las direcciones Ip usadas en este escenario. Notación S.O usado Interfaz IP/Mask PC1 CentOS 8 Ens37 10.10.1.20/24 Encaminador Debian- Stretch Ens38 Ens33 10.10.1.10/24 192.168.106.128/24 Tabla 19 - Resumen escenario 2 equipos 244 A continuación, se detallarán tanto los comandos para configurar el entorno, como los archivos de configuración listos para sustituirlos en los equipos. Todos los comandos que se van a indicar están ejecutados con el superusuario root. Configuración del equipo PC1 Comandos configuración PC1 Equipo:PC1 Usuario:root $ ip address flush dev ens37 $ ip link set ens37 down $ ip address add 10.10.1.20/24 dev ens37 $ ip link set ens37 up $ ip neigh flush all $ ip address ls dev ens37 $ service network restart La configuración puede realizarse con los comandos indicados o bien modificando el archivo ifcfg correspondiente en la ruta /etc/sysconfig/network-scripts/ y dejando su contenido de la siguiente forma. [root@localhost dit]# cat /etc/sysconfig/network-scripts/ifcfg-ens37- 1 HWADDR=00:0C:29:62:ED:AD TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none IPADDR=10.10.1.20 PREFIX=24 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV4_DNS_PRIORITY=100 IPV6INIT=yes IPV6_AUTOCONF=no IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy IPV6_DNS_PRIORITY=100 NAME=ens37 UUID=98f4a976-7f4d-4708-9505-6cb0ee7024a5 DEVICE=ens37 ONBOOT=yes Tras realizar las configuraciones indicadas pueden observarse las siguientes salidas. • La Figura E.2 muestra el contenido del archivo ifcfg de PC1 Equipo:PC1 Usuario:root $ cat /etc/sysconfig/network-scripts/ifcfg-ens37-1 245 • La Figura E.3 muestra la salida del comando ip address. Equipo:PC1 Usuario:root $ ip addr • La Figura E.4 muestra la salida del comando ip route. Equipo:PC1 Usuario:root $ ip route Figura E.2 - Archivo ifcfg de PC1 (escenario 2 equipos) Figura E.3 - IP address PC1 (escenario 2 equipos) 246 Figura E.4 - IP route PC1 (escenario 2 equipos) Configuración del equipo Encaminador Pasamos a continuación a realizar la configuración del equipo Encaminador. Comandos de configuración Encaminador Equipo:Encaminador Usuario:root $ ip address flush dev ens38 $ ip link set ens38 down $ ip address add 10.10.1.10/24 dev ens38 $ ip link set ens38 up $ ip neigh flush all $ ip address ls dev ens38 $ service network restart Arrancamos también los siguientes servicios. Equipo:Encaminador Usuario:root $ service nftables start $ service firewalld stop $ service httpd start La configuración puede realizarse con los comandos indicados o bien modificando el archivo interfaces correspondiente en la ruta /etc/network/ y dejando su contenido de la siguiente forma. root@linux:/home/dit# cat /etc/network/interfaces # interfaces(5) file used by ifup(8) and ifdown(8) #auto lo #iface lo inet loopback # iface ens38 inet static address 10.10.1.10 netmask 255.255.255.0 network 10.10.1.0 broadcast 10.10.1.255 dns-nameServer 8.8.8.8 8.8.4.4 Si usamos este segundo método, una vez cargado el archivo tenemos que usar los siguientes comandos para que la interfaz se recargue y tome su nueva configuración. 247 Equipo:Encaminador Usuario:root $ ifdown ens38 $ ifup ens38 Se puede comprobar la configuración, observando las salidas de las siguientes figuras. • La Figura E.5 muestra el contenido del archivo interfaces de Encaminador Equipo:Encaminador Usuario:root $ cat /etc/network/interfaces • La Figura E.6 muestra la salida del comando ip address. Equipo:Encaminador Usuario:root $ ip addr • La Figura E.7 muestra la salida del comando ip route. Equipo:Encaminador Usuario:root $ ip route Figura E.5 - Archivo interfaces Encaminador (escenario 2 equipos) 248 Figura E.6 - IP address Encaminador (escenario 2 equipos) Figura E.7 - IP route (escenario 2 equipos) 249 ANEXO F - ESCENARIO 3 EQUIPOS Figura F.1 - Esquema escenario 3 equipos Este es el escenario que se plantea para usar tres equipos (Figura F.1). Consta de un primer equipo que será el Pc de la red privada (PC1) y que tiene un servidor Apache escuchando en su puerto 80. Un equipo servidor (Encaminador) en el cual tendremos las herramientas de firewall para tratar el tráfico, así como otro servidor Apache en escucha en el puerto 80 y por último tenemos un Pc cliente (PC2), el cual está en la red pública, y que será el encargado de generar tráfico de red. En la Tabla 20, se recoge un cuadro resumen, con los sistemas operativos, las interfaces y las direcciones IP usadas en este escenario. Notación S.O usado Interfaz IP/Mask PC1 CentOS 8 Ens37 10.10.1.20/24 PC2 CentOS 8 Ens37 172.168.0.20/24 Encaminador Debian- Stretch Ens38 Ens33 Ens39 10.10.1.10/24 192.168.106.128/24 172.168.0.10/24 Tabla 20 - Resumen escenario 3 equipos 250 A continuación, se detallarán tanto los comandos para configurar el entorno, como los archivos de configuración listos para sustituirlos en los equipos. Todos los comandos que se van a indicar están ejecutados con el superusuario root. Configuración del equipo PC1 Comandos de configuración PC1: Equipo:PC1 Usuario:root $ ip address flush dev ens37 $ ip link set ens37 down $ ip address add 10.10.1.20/24 dev ens37 $ ip link set ens37 up $ ip neigh flush all $ ip address ls dev ens37 $ service network restart $ service httpd start La configuración puede realizarse con los comandos indicados o bien modificando el archivo ifcfg correspondiente en la ruta /etc/sysconfig/network-scripts/ y dejando su contenido de la siguiente forma. [root@localhost dit]# cat /etc/sysconfig/network-scripts/ifcfg-ens37- 1 HWADDR=00:0C:29:62:ED:AD TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none IPADDR=10.10.1.20 PREFIX=24 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV4_DNS_PRIORITY=100 IPV6INIT=yes IPV6_AUTOCONF=no IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy IPV6_DNS_PRIORITY=100 NAME=ens37 UUID=98f4a976-7f4d-4708-9505-6cb0ee7024a5 DEVICE=ens37 ONBOOT=yes 251 Tras realizar las configuraciones indicadas pueden observarse las siguientes salidas. • La Figura F.2 muestra el contenido del archivo ifcfg de PC1 Equipo:PC1 Usuario:root $ cat /etc/sysconfig/network-scripts/ifcfg-ens37-1 • La Figura F.3 muestra la salida del comando ip address. Equipo:PC1 Usuario:root $ ip addr • La Figura F.4 muestra la salida del comando ip route. Equipo:PC1 Usuario:root $ ip route Figura F.2 - Archivo ifcfg de PC1 (escenario 3 equipos) 258 Caso específico: Escenario NAT Asimétrico El escenario de NAT asimétrico es un caso puntual en el que se usará el escenario de 3 equipos y se añadirá un cuarto equipo por el cual se enviará el tráfico de respuesta de PC2 (Figura F.11). La configuración de este escenario como bien se ha dicho, parte de la base del escenario de 3 equipos - (Anexo F - Escenario 3 Equipos). La configuración del cuarto equipo “Router NAT” es la siguiente: Figura F.11 - Esquema escenario NAT asimétrico En la Tabla 21 se recoge un cuadro resumen, con los sistemas operativos, las interfaces y las direcciones Ip usadas en este escenario. Notación S.O usado Interfaz Ip/Mask PC1 CentOS 8 Ens37 10.10.1.20/24 PC2 CentOS 8 Ens37 172.168.0.20/24 Encaminador Debian- Stretch Ens38 Ens33 Ens39 10.10.1.10/24 192.168.106.128/24 172.168.0.10/24 Router NAT CentOS 8 Ens37 Ens38 10.10.1.30/24 172.168.0.40/24 Tabla 21 - Resumen escenario NAT asimétrico 259 Configuración del equipo Router NAT Comandos de configuración Router NAT Equipo:Router NAT Usuario:root $ ip address flush dev ens38 $ ip link set ens38 down $ ip address add 10.10.1.30/24 dev ens37 $ ip link set ens38 up $ ip neigh flush all $ ip address ls dev ens38 $ ip address flush dev ens39 $ ip link set ens39 down $ ip address add 172.168.0.400/24 dev ens38 $ ip link set ens39 up $ ip neigh flush all $ ip address ls dev ens39 $ service network restart La configuración puede realizarse con los comandos indicados o bien modificando el archivo ifcfg correspondiente en la ruta /etc/sysconfig/network-scripts/ y dejando su contenido de la siguiente forma. [root@localhost dit]# cat /etc/sysconfig/network-scripts/ifcfg-ens37 HWADDR=00:0C:29:08:2E:23 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none IPADDR=10.10.1.30 PREFIX=24 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens37 UUID=e07385a5-adcd-4c23-a426-812daa776be8 ONBOOT=yes [root@localhost dit]# cat /etc/sysconfig/network-scripts/ifcfg-ens38 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=none 260 IPADDR=172.168.0.40 PREFIX=24 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens38 UUID=861b6eb7-85a9-419e-ad9b-0e6aa4e2db15 ONBOOT=yes HWADDR=00:0C:29:08:2E:2D • La Figura F.12 muestra la salida del comando ip address. Equipo:Encaminador Usuario:root $ ip addr • La Figura F.13 muestra la salida del comando ip route. Equipo:Encaminador Usuario:root $ ip rou Figura F.12 - Ip address (Router NAT) Figura F.13 - Ip route (Router NAT) 261 ANEXO G - CHEATSHEET NFTABLES Línea de comandos CheatSheet Comando Opciones Descripción/Ejemplo table add Añadir una tabla nueva nft add table inet tabla_pru delete Borrar una tabla nft delete table inet tabla_pru flush Borrar el contenido de una tabla nft flush table inet tabla_pru list Listar una tabla (se recomienda usar la opción -a o -n) -a: muestra el handle -n: muestra el número de la regla nft list table inet tabla_pru -a nft list table inet tabla_pru -n Tabla 22 - CheatSheet comando table Comando Opciones Descripción/Ejemplo chain add Crear una cadena nueva nft add chain inet tabla_pru cadena_pru { type filter hook input priority 0 ; policy drop ; } nft add chain arp tabla_pru cadena_arp { type filter hook prerouting priority -300 ; policy accept ; } create Solo crea la nueva cadena si esta no existe nft create chain inet tabla_pru cadena_new { type filter hook output priority 100 ; policy accept ; } delete Borrar una cadena nft delete chain inet tabla_pru cadena_new 262 list Listar una cadena nft list chain inet tabla_pru cadena_new flush Limpiar el contenido de una cadena nft flush chain inet tabla_pru cadena_new rename Renombrar una cadena nft rename chain inet tabla_pru cadena_new cadena2 Tabla 23 - CheatSheet comando chain Comando Opciones Descripción/Ejemplo rule add Añadir una regla nueva tras la última existente nft add rule inet tabla_pru cadena_pru accept insert Insertar una regla en una posición de la cadena determinada. Para ver las posiciones de las reglas se usa la opción -n al listar una cadena. nft insert rule inet tabla_pru cadena_pru <posicion> accept replace Reemplazar una regla existente por otra nueva. Para saber el número de handle cuando listemos una cadena se usa la opción -a nft replace rule inet tabla_pru cadena_pru <n_handle> accept delete Borrar una regla nft delete rule inet tabla_pru cadena_pru <n_handle> Tabla 24 - CheatSheet comando rule 263 Módulos CheatSheet Módulo Opciones Descripción /Ejemplo ip length Valor de longitud total del paquete nft add rule inet tabla_pru cadena_pru ip length 260 accept id Ip ID del paquete nft add rule inet tabla_pru cadena_pru ip id !=20 accept ttl TTL (time to live) del paquete nft add rule inet tabla_pru cadena_pru ip ttl { 74-128 } accept protocol Protocolo de capa superior que lo encapsula nft add rule inet tabla_pru cadena_pru ip protocol { icmp, udp, tcp } accept saddr Dirección origen nft add rule inet tabla_pru cadena_pru ip saddr 192.168.1.0/24 daddr Dirección destino nft add rule inet tabla_pru cadena_pru ip daddr 192.168.1.10 accept version Versión del paquete IP nft add rule inet tabla_pru cadena_pru ip version 6 drop checksum Checksum de la cabecera IP nft add rule inet tabla_pru cadena_pru ip checksum 1260 accept Tabla 25 - CheatSheet módulo Ip 264 Módulo Opciones Descripción /Ejemplo tcp dport Puerto destino del paquete TCP nft add rule inet tabla_pru cadena_pru tcp dport != 10-19 drop sport Puerto origen del paquete TCP nft add rule inet tabla_pru cadena_pru tcp sport { 80, 8080 } accept sequence Secuencia del paquete TCP nft add rule inet tabla_pru cadena_pru tcp sequence 1 accept ackseq Secuencia del paquete TCP-ACK nft add rule inet tabla_pru cadena_pru tcp ackseq 1 accept flags Flags del paquete TCP nft add rule inet tabla_pru cadena_pru tcp flags { fin, syn, ack } accept checksum Checksum del paquete TCP nft add rule inet tabla_pru cadena_pru tcp checksum 1000 drop Tabla 26 - CheatSheet módulo TCP Módulo Opciones Descripción /Ejemplo udp dport Puerto destino paquete UDP nft add rule inet tabla_pru cadena_pru udp dport 80 accept sport Puerto origen paquete UDP nft add rule inet tabla_pru cadena_pru udp sport != 8080 accept length Longitud total del paquete UDP nft add rule inet tabla_pru cadena_pru udp length 100-200 accept 265 checksum Checksum del paquete UDP nft add rule inet tabla_pru cadena_pru udp checksum 1280 drop Tabla 27 - CheatSheet módulo UDP Módulo Opciones Descripción /Ejemplo icmp type Tipo del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp type { echo-reply, echo-request, routersolicitation } accept code Código del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp code != 4 accept id Id del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp code != 4 accept sequence Secuencia del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp sequence 1-4 accept checksum Checksum del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp checksum != { 1000, 999, 000 } accept mtu (Maximun Transfer Unit) del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp mtu 100-1264 accept gateway Gateway de salida del paquete ICMP nft add rule inet tabla_pru cadena_pru icmp gateway 10.10.1.30 drop Tabla 28 - CheatSheet módulo ICMP 266 Módulo Opciones Descripción /Ejemplo ether saddr Mac de origen del paquete nft add rule inet tabla_pru cadena_pru ether saddr 00:5f:60:0c:ab:e4 accept type Ethertype del paquete nft add rule inet tabla_pru cadena_pru ether type vlan drop Tabla 29 - CheatSheet módulo ether Módulo Opciones Descripción /Ejemplo arp ptype Tipo del payload del paquete ARP nft add rule arp tabla_pru cadena_arp arp ptype 0x200 accept htype Tipo de cabecera del paquete ARP nft add rule arp tabla_pru cadena_arp arp htype 1 drop hlen Longitud de la cabecera ARP nft add rule arp tabla_pru cadena_arp arp hlen != { 0, 999, 664 } accept plen Longitud del payload ARP nft add rule arp tabla_pru cadena_arp arp plen 100-500 accept operation Tipo de operación del paquete ARP nft add rule arp tabla_pru cadena_arp arp operation { nak, inreplay, request, reply } accept Tabla 30 - CheatSheet módulo ARP 267 Módulo Opciones Descripción /Ejemplo ct state Estado que asigna el módulo ct nft add rule inet tabla_pru cadena_pru ct { new, established, related } accept direction Dirección del paquete referente a la conexión(original/reply) nft add rule inet tabla_pru cadena_pru ct direction { original, reply } accept status Estado interno de la conexión nft add rule inet tabla_pru cadena_pru ct status { reply, assured, confirmed } accept mark Marca de la conexión nft add rule inet tabla_pru cadena_pru ct mark set 1 accept nft add rule inet tabla_pru cadena_pru ct mark != 1 drop helper Helper para conexiones de 2 flujos nft add ct helper inet tabla_pru ftp { type "ftp" protocol tcp ; } saddr/daddr Dirección origen y destino (original/reply) nft add rule inet tabla_pru cadena_pru ct original saddr 10.10.1.10 accept nft add rule inet tabla_pru cadena_pru ct reply saddr 204.160.24.50 drop protocol Protocolo del paquete de la conexión (original/reply) nft add rule inet tabla_pru cadena_pru ct original protocol icmp drop nft add rule inet tabla_pru cadena_pru ct reply protocol tcp accept proto-dts proto-src Puerto origen/destino del paquete de la conexión (original/reply) nft add rule inet tabla_pru cadena_pru ct original proto-dts 80 accept nft add rule inet tabla_pru cadena_pru ct reply proto-src 21 drop Tabla 31 - CheatSheet módulo ct 274 Figura H.2 - Cierre conexión TCP 1) El cliente envía al servidor un segmento TCP con el bit del flag FIN a 1, con este bit a 1 se le indica al servidor que se desea cerrar la sesión que se tiene establecida con él. 2) El servidor responde al cliente con un segmento TCP con los bits de los flags FIN y ACK a 1. El flag FIN indica al cliente que queremos cerrar la sesión que está establecida con él, mientras que el flag ACK se usa para asentir el mensaje que ha recibido del cliente en la fase 1. 3) El cliente responde al segmento TCP FIN-ACK que recibe del servidor con un segmento TCP ACK para dar el asentimiento de este último, en este punto el cliente cierra su sesión. 4) El servidor lo recibe y cierra su sesión, quedando así cerrada la conexión TCP. Para más información del protocolo, puede consultarse su referencia (RFC 1323). 275 Protocolo UDP (User Datagram Protocol) UDP son las siglas de “Protocolo de Datagramas de Usuario”, el cual se encuentra definido en la RFC 768 y su unidad básica recibe el nombre de datagrama. Este protocolo opera en el nivel 4 del modelo TCP/IP, basándose para ello en el protocolo IP de capa 3. UDP a diferencia de TCP, no es un protocolo orientado a conexión, puesto que no necesita realizar una fase de establecimiento de conexión, sino que puede realizar directamente el envío de datos. Este protocolo tampoco ofrece ni la confirmación de paquetes ni el control de flujo que si proporciona TCP, por lo que los mecanismos de seguridad tienen que ser ofrecidos por protocolos de otras capas. Este protocolo es usado, sobre todo, en entornos en los que los requisitos de retardo son muy estrictos, como pueden ser flujos de video o audio en streaming, entre otros. Los protocolos más conocidos de capa de Aplicación que se basan en UDP son: DHCP y DNS (existen más protocolos, pero indicamos los dos más usados). A continuación, se verá la cabecera usada por UDP. Cabecera UDP 0 1 2 3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Puerto origen Puerto destino Longitud mensaje Checksum Tabla 35 - Cabecera UDP En la Tabla 35, se puede observar la composición de una cabecera UDP, a continuación, se dará una breve explicación de cada campo, los campos con un color de fondo distinto representan campos opcionales de UDP. • Puerto origen: Este campo es optativo, e identifica el puerto del proceso emisor (16 bits). • Puerto destino: Identifica el puerto del proceso receptor (16 bits). • Longitud del mensaje: Identifica el tamaño en octetos del mensaje, incluyendo la cabecera UDP y el campo datos (16 bits). • Checksum: Este campo es optativo y se usa para comprobar la integridad del mensaje, tenemos que hacer una apreciación y es que este checksum, usa para calcularse, campos de la cabecera UDP y de la cabecera IP (16 bits). UDP carece de flags , por lo que no existe distinción entre tipos de mensajes. Para más información del protocolo puede consultarse su referencia (RFC 768). 276 Protocolo ICMP (Internet Control Message Protocol) ICMP son las siglas de “Protocolo de Control de Mensajes de Internet”, el cual se encuentra definido en la RFC 792. Este protocolo opera en el nivel 3 del modelo TCP/IP, aunque también se apoya en el protocolo Ip que pertenece a su misma capa. Este protocolo a diferencia de TCP y UDP no busca intercambiar información entre aplicaciones de usuarios, ya que su cometido es el de gestionar los mensajes de error cuando estos ocurren sobre IP. En este apartado se verá la cabecera usada por ICMP según el tipo de mensaje, así como los mensajes más comunes que podemos encontrar en este protocolo. Cabecera ICMP Antes de pasar a ver los tipos de cabecera se realizará una breve introducción al significado de los campos de estas. • Tipo ICMP: Identifica el tipo de mensaje, existen 18 tipos de mensajes, los cuales pueden verse reflejados en la Tabla 40. (8 bits) • Código ICMP: Dentro de un tipo de mensaje ICMP el código sirve para especificar un tipo de mensaje en concreto, los diferentes valores del código pueden comprobarse en la Tabla 40. (8bits) • Checksum: Suma de comprobación para comprobar la integridad del mensaje. (16 bits) • Identificador ICMP: Identifica un flujo de transmisión ICMP, sirve para poder asociar las preguntas con las respuestas (16 bits). • Número de Secuencia: Identifica la posición del mensaje dentro de un flujo con un identificador ICMP concreto (16 bits). Destination Unreachable 0 1 2 3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Tipo ICMP Código ICMP Checksum Identificador ICMP Número de secuencia Tabla 36 - ICMP Destination Unreachable • Tipo ICMP: En este tipo de mensajes, el valor de este campo es siempre 3. • Código ICMP: Puede tomar distintos valores según el tipo de mensaje, estos valores pueden comprobarse en la Tabla 40, yendo desde el valor 0 hasta el 15. 277 Este tipo de mensajes sirven para avisar de una situación de error, existen situaciones muy diversas en las que estos pueden producirse y cada una de ellas tiene su propio tipo de mensaje, aunque todas tienen en común el mismo punto y es que no se ha conseguido acceder al destino que se ha solicitado. Redirect 0 1 2 3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Tipo ICMP Código ICMP Checksum Sin uso Tabla 37 - ICMP Redirect • Tipo ICMP: En este tipo de mensajes el valor de este campo es siempre 5. • Código ICMP: Puede tomar distintos valores según el tipo de mensaje, estos valores pueden comprobarse en la Tabla 40 , yendo desde el valor 0 hasta 3. Este tipo de mensajes es el utilizado por los routers cuando reciben un paquete que deben encaminar y quieren comunicarle al emisor, que existe otra ruta más corta hacia el destino que no pasa por ellos. Echo-request 0 1 2 3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Tipo ICMP Código ICMP Checksum Identificador ICMP Número de secuencia Tabla 38 - ICMP Echo-request • Tipo ICMP: En este tipo de mensajes, el valor de este campo es siempre 8. • Código ICMP: En este tipo de mensajes, el valor del campo es siempre 0. Estos mensajes se usan para solicitar a otro equipo que nos devuelva los mismos datos que nosotros le enviamos previamente. 278 Echo-reply 0 1 2 3 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Tipo ICMP Código ICMP Checksum Identificador ICMP Número de secuencia Tabla 39 - ICMP Echo-reply • Tipo ICMP: En este tipo de mensajes, el valor de este campo es siempre 0. • Código ICMP: En este tipo de mensajes, el valor del campo es siempre 0. Estos mensajes se usan como respuesta a los mensajes echo-request. A continuación, se detallará en la Tabla 40 los diferentes valores de tipos y códigos que pueden tener los mensajes ICMP, así como indicar si son mensajes de pregunta o de respuesta. Tipo Código Descripción del Código Mensaje Pregunta Mensaje Respuesta 0 - Echo Reply 0 Echo Reply X 3 - Destination Unreachable 0 Destination network unreachable X 1 Destination host unreachable X 2 Destination protocol unreachable X 3 Destination port unreachable X 4 Fragmentation required X 5 Source route failed X 6 Destination network unknown X 7 Destination host unknown X 8 Source host isolated X 9 Network administratively prohibited X 10 Host administratively prohibited X 11 Network unreacheable for ToS X 12 Host unreacheable for ToS X 13 Communication administratively prohibited X 279 14 Host precedence Violation X 15 Precedence cutoff in effect X 4 - Source Quench 0 Source quench X 5 - Redirect Message 0 Redirect Datagram for the Network X 1 Redirect Datagram for the Host X 2 Redirect Datagram for the ToS and Network X 3 Redirect Datagram for the ToS and Host X 8 - Echo Request 0 Echo request X 11 - Time Exceeded 0 TTL expired in transit X 1 Fragment reassembly time exceeded X 12 - Parameter Problem 0 Pointer indicates the error X 1 Missing required option X 2 Bad length X 13 - Timestamp Request 0 Timestamp Request (obsoleto) X 14 -Timestamp Reply 0 Timesamp Reply (obsoleto) X 15 - Information Request 0 Information Request (obsoleto) X 16 - Information Reply 0 Information Reply (obsoleto) X 17- Address mask request 0 Address mask request X 18 - Address mask reply 0 Address mask reply X Tabla 40 - Tipo mensajes ICMP Para más información del protocolo, puede consultarse su referencia (RFC 792) 280 281 ANEXO I - CONCEPTO CONEXIÓN En este anexo se estudiará el concepto de conexión, el cuál es necesario entender para poder abordar el capítulo 6, Seguimiento de Conexiones(Conntrack). Se planteará el concepto de conexión desde el punto de vista de un socket, de un protocolo y de conntrack, explicando que entiende cada uno de ellos por conexión, para finalmente aclarar como debe ser entendida en este punto. Comenzaremos explicando que es un protocolo orientado a conexión. Protocolo orientado a conexión. Existen dos tipos de protocolos, aquellos que están orientados a conexión y los que no lo están. Un protocolo orientado a conexión es aquel que identifica el flujo de tráfico con un identificador de conexión, en lugar de hacerlo por las direcciones del emisor y el receptor. Para lograr que se pueda identificar el flujo de conexión, el protocolo establece que antes del envío de datos tendrá lugar una fase de negociación de la comunicación, en la cual, se verificarán datos como la alcanzabilidad, la disponibilidad etc… y una vez se ha dado esta fase inicial y acordados los términos para la transmisión de datos, comenzará la comunicación, identificando todos los paquetes de esta dentro del mismo flujo. Este flujo de comunicación tiene lugar entre el emisor y el receptor y sirve para identificar a todos los paquetes que se intercambien. ( Protocolo TCP (Transmission Control Protocol) ) Aquellos protocolos que no realizan esta fase inicial de negociación se conocen como protocolos no orientados a conexión. ( Protocolo UDP (User Datagram Protocol) ) Socket de conexión. Un socket es una representación abstracta de un punto de comunicación, que permite establecer un canal de comunicación entre dos rutinas o programas. Existen dos tipos de sockets, aquellos que son de conexión(sockets de flujo) y los que no son de conexión(socket de datagramas). Un socket que no está orientado a conexión o socket de datagrama solo guarda su dirección Ip y el puerto en el cual este se encuentra abierto. Mientras que un socket orientado a conexión o socket de flujo guarda la pareja de datos de Ip/puerto origen/destino. En este caso los sockets de conexión tienen un concepto parecido al visto en el protocolo orientado a conexión, ya que este busca identificar un flujo de información entre un origen y un destino de los cuales guarda sus datos. Podemos tener sockets de conexión para TCP y también para UDP. Debemos entender que al hablar de socket de conexión, lo estamos haciendo a nivel del S.O, es decir, que UDP a pesar de ser un protocolo no orientado a conexión y no establecer una fase preliminar de negociación, si puede a nivel de kernel, emplear un socket de conexión, el cual guarda información del origen y del destino. 282 Conexión en conntrack Una vez visto el concepto de conexión de los sockets y de los protocolos, pasaremos a ver que entiende conntrack por conexión. La definición de conntrack, es módulo de seguimiento de conexiones, esta idea puede llevar a pensar que solamente realiza el seguimiento de protocolos orientados a conexión (TCP) y no es así. La definición de flujo de conexión para conntrack, no es más que un flujo de datos, es decir, este módulo realiza el seguimiento de un flujo de datos que va desde un origen hasta un destino. Es por esto, que conntrack muestra entradas de conexión de protocolos como UDP, TCP o ICMP, sin importar si son o no son protocolos orientados a conexión. Este concepto de conexión es parecido al usado por los sockets, ya que como se ha visto, existen sockets de conexión UDP, que simplemente guardan información de la comunicación entre el origen y el destino. Pues conntrack se basa en la misma idea. Cuando llega un paquete, conntrack mira en su cabecera su dirección Ip y puerto, tanto origen como destino y con esos datos es capaz de guardar entradas que realicen el seguimiento de paquetes que pertenezcan a ese flujo de datos. Un [1]paquete pertenece a un flujo de datos siempre y cuando sus direcciones Ip y puertos origen/destino, coincidan con los que almacene conntrack en sus entradas. Existe una excepción y es el protocolo ICMP, ya que este carece de puertos, por lo que para realizar el seguimiento de un flujo de datos ICMP, se usa la dirección Ip origen y destino, así como el tipo y el código de ICMP y su Id. Cada uno de estos protocolos y los datos que conntrack toma de ellos, se verán en profundidad en los puntos dedicados a estos, dentro del capítulo 6. Conntrack usa otro concepto, el de conexiones relacionadas (RELATED). Una conexión RELATED, no es más que un flujo de datos que está relacionado con otro flujo que ya se encuentra registrado en el sistema. Para entender este concepto se puede poner como ejemplo una conexión FTP pasiva. El flujo de datos de control que se intercambia al principio de la comunicación establece una entrada en conntrack, que tiene IP/puerto origen/destino, pero en el modo pasivo, para el envío de datos se usan puertos distintos, a pesar de que las direcciones Ip son las mismas. En ese caso y mediante la ayuda de unos módulos llamados helpers (un concepto que se verá en el punto 6.7 Helpers) es capaz de identificar ese nuevo flujo de datos con distinto puerto, como un flujo asociado al ya existente en la máquina y que fue abierto por el intercambio de datos de control. Una vez explicado, que entiende cada uno de estos puntos por conexión, se puede abordar el capítulo de Seguimiento de Conexiones(Conntrack). Como resumen final diremos que cuando conntrack hable de seguimiento de conexiones o de flujo de conexión, se estará refiriendo a un flujo de datos o flujo de comunicación. 283 REFERENCIAS [1] Netfilter, “The netfilter org project”. 2019. [Online]. Available: http://nftables.org/ [2] Netfilter, “Iptables project”. 2019. [Online]. Available: http://www.netfilter.org/projects/iptables/index.html [3] Linux, “Linux Forum”. 2020. [Online]. Available: https://www.linux.org/ [4] Netfilter, “Ebtables”. 2004. [Online]. Available: https://ebtables.netfilter.org/ [5] Netfilter, “Arptables man page”. 2019. [Online]. Available: https://linux.die.net/man/8/arptables [6] Netfilter, “Wiki Nftables”. 2020. [Online]. Available: https://wiki.nftables.org/wikinftables/index.php/Main_Page [7] RedHat, “RedHat packages”. 2016. [Online]. Available: https://access.redhat.com/errata/RHEA-2016:2558 [8] Sourceforge, “Shorewall no migration”. 2016. [Online]. Available: https://sourceforge.net/p/shorewall/ mailman/message/35492188/ [9] Suricata, “Suricata user guide”. 2017. [Online]. Available: https://fossies.org/linux/suricata/doc/userguide/userguide.pdf [10] RedHat, “Firewalld with nftables”. 2018. [Online]. Available: https://developers.redhat. com/blog/2018/08/10/ firewalld-the-future-is-nftables/ [11] Sourceforge, “Suricata no migration”. 2017. [Online]. Available: https://sourceforge.net/p/shorewall/mailman/ message/35492188/ [12] Fortinet, “Fortinet Firewall”. 2020. [Online]. Available: https://www.fortinet.com/lat [13] Cisco, “Cisco Firewall”. 2020. [Online]. Available: https://www.cisco.com/c/es_es/products/security/ firewalls/index.html [14] Zyxel, “Zyxel Firewall”. 2020. [Online]. Available: https://www.zyxel.com/es/es/products_services/smb-security_firewalls.shtml?t=c