Reglas de firewall
Cómo crea y gestiona el bouncer las reglas del firewall de RouterOS.
Reglas que escribe el daemon
Sección titulada «Reglas que escribe el daemon»El bouncer no escribe una regla por tabla. Escribe un bloque ordenado por chain, y escribe ese bloque una vez por cada familia de protocolo habilitada: firewall.ipv4.enabled y firewall.ipv6.enabled valen true por defecto, así que la configuración de partida construye dos veces cada regla de aquí abajo, contra crowdsec-banned para IPv4 y contra crowdsec6-banned para IPv6. También se construye un bloque por cada entrada de firewall.filter.chains y firewall.raw.chains; añade una chain ahí y el bloque completo se repite en ella.
Dentro de un bloque el orden es fijo —whitelist, contador, denegación— y el bloque solo se mueve a su posición cuando ya existen todas sus reglas, de modo que RouterOS nunca evalúa un bloque a medio construir.
Se crean por defecto
Sección titulada «Se crean por defecto»8 reglas en el router con la configuración de partida: 4 tipos de regla × 2 familias de protocolo.
Contador de filtersolo cuenta
Cuenta cada paquete que la chain de filter entrega al bloque del bouncer, que es lo que informan las métricas de bytes y paquetes procesados.
/ip/firewall/filter add chain=input action=passthrough comment="crowdsec-bouncer:filter-input-counting-v4 @cs-routeros-bouncer"/ipv6/firewall/filter add chain=input action=passthrough comment="crowdsec-bouncer:filter-input-counting-v6 @cs-routeros-bouncer"Se crea por defecto. Depende de
metrics.track_processed(por defectotrue).No coincide con ninguna address-list ni toma ninguna decisión —passthrough solo incrementa contadores—, y por eso mismo parece una regla suelta en el router.
Atributos que solo aparecen si se configuran:
in-interface(firewall.block_input.interface),in-interface-list(firewall.block_input.interface_list)Denegación de filterdescarta
Descarta el tráfico entrante cuya dirección de origen está en la address-list de baneados, después de que se haya ejecutado el connection tracking.
/ip/firewall/filter add chain=input action=drop src-address-list=crowdsec-banned comment="crowdsec-bouncer:filter-input-input-v4 @cs-routeros-bouncer"/ipv6/firewall/filter add chain=input action=drop src-address-list=crowdsec6-banned comment="crowdsec-bouncer:filter-input-input-v6 @cs-routeros-bouncer"Se crea por defecto. Depende de
firewall.filter.enabled(por defectotrue).Si firewall.deny_action se establece en reject, esta regla rechaza en lugar de descartar, e incluye reject-with cuando hay uno configurado.
Atributos que solo aparecen si se configuran:
connection-state(firewall.filter.connection_state),in-interface(firewall.block_input.interface),in-interface-list(firewall.block_input.interface_list),reject-with(firewall.reject_with),log(firewall.log),log-prefix(firewall.log_prefix)Contador de rawsolo cuenta
Cuenta cada paquete que la chain de raw entrega al bloque del bouncer y alimenta las mismas métricas de procesados que su gemela de filter.
/ip/firewall/raw add chain=prerouting action=passthrough comment="crowdsec-bouncer:raw-prerouting-counting-v4 @cs-routeros-bouncer"/ipv6/firewall/raw add chain=prerouting action=passthrough comment="crowdsec-bouncer:raw-prerouting-counting-v6 @cs-routeros-bouncer"Se crea por defecto. Depende de
metrics.track_processed(por defectotrue).Igual que el contador de filter, no coincide con ninguna address-list; sus contadores son los que hacen que «evaluados» y «descartados» sean dos cifras distintas.
Atributos que solo aparecen si se configuran:
in-interface(firewall.block_input.interface),in-interface-list(firewall.block_input.interface_list)Denegación de rawdescarta
Descarta los orígenes baneados antes del connection tracking, que es el punto más barato de RouterOS para deshacerse de una avalancha.
/ip/firewall/raw add chain=prerouting action=drop src-address-list=crowdsec-banned comment="crowdsec-bouncer:raw-prerouting-input-v4 @cs-routeros-bouncer"/ipv6/firewall/raw add chain=prerouting action=drop src-address-list=crowdsec6-banned comment="crowdsec-bouncer:raw-prerouting-input-v6 @cs-routeros-bouncer"Se crea por defecto. Depende de
firewall.raw.enabled(por defectotrue).Las reglas raw de RouterOS no pueden rechazar, así que firewall.deny_action: reject se escribe aquí como drop: es la única regla cuya acción no sigue esa opción.
Atributos que solo aparecen si se configuran:
in-interface(firewall.block_input.interface),in-interface-list(firewall.block_input.interface_list),log(firewall.log),log-prefix(firewall.log_prefix)
Las dos reglas passthrough de contador son las que ninguna versión anterior de esta página listaba, y son la razón de que un router con la configuración de partida muestre ocho reglas del bouncer donde la documentación describía cuatro. Las crea metrics.track_processed, cuyo valor predeterminado es true.
Una regla de contador no coincide con ninguna address-list, no lleva src-address-list y no toma ninguna decisión: passthrough en RouterOS se limita a incrementar los contadores de bytes y paquetes de la regla y seguir adelante. Es intencionado: el bouncer lee esos contadores para informar de cuánto tráfico han evaluado sus chains, que es el denominador de cuánto se ha descartado. Y también es la razón de que, revisando el router a simple vista, la regla parezca exactamente una regla suelta que alguien olvidó. No lo es.
metrics.track_processed se consulta por su cuenta, no por detrás de metrics.enabled, cuyo valor predeterminado es false. Un router cuyo bouncer no expone ningún endpoint de métricas sigue llevando las dos reglas de contador, contando en silencio para nadie. Establecer metrics.track_processed: false las elimina y, con ellas, las métricas crowdsec_bouncer_processed_*; los contadores de descartes, que salen de las propias reglas de denegación, no se ven afectados.
Solo se crean si una opción las pide
Sección titulada «Solo se crean si una opción las pide»Whitelist de filteracepta
Acepta el tráfico de una address-list que tú controlas antes de que ninguna regla del bouncer pueda descartarlo, de modo que un origen que has avalado nunca queda bloqueado por una decisión de CrowdSec.
/ip/firewall/filter add chain=input action=accept src-address-list=crowdsec-whitelist comment="crowdsec-bouncer:filter-input-whitelist-v4 @cs-routeros-bouncer"/ipv6/firewall/filter add chain=input action=accept src-address-list=crowdsec-whitelist comment="crowdsec-bouncer:filter-input-whitelist-v6 @cs-routeros-bouncer"No se crea por defecto. Requiere
firewall.block_input.whitelist(por defectosin definir).Va primera en el bloque a propósito: RouterOS evalúa la chain de arriba abajo, así que un accept colocado después del drop no se alcanzaría nunca.
Atributos que solo aparecen si se configuran:
connection-state(firewall.filter.connection_state),in-interface(firewall.block_input.interface),in-interface-list(firewall.block_input.interface_list),log(firewall.log),log-prefix(firewall.log_prefix)Whitelist de rawacepta
La misma exención que la whitelist de filter, un paso antes en la cadena de procesado, para que un origen avalado tampoco se descarte antes del connection tracking.
/ip/firewall/raw add chain=prerouting action=accept src-address-list=crowdsec-whitelist comment="crowdsec-bouncer:raw-prerouting-whitelist-v4 @cs-routeros-bouncer"/ipv6/firewall/raw add chain=prerouting action=accept src-address-list=crowdsec-whitelist comment="crowdsec-bouncer:raw-prerouting-whitelist-v6 @cs-routeros-bouncer"No se crea por defecto. Requiere
firewall.block_input.whitelist(por defectosin definir).La tabla raw no tiene connection tracking, así que esta regla nunca lleva connection-state aunque firewall.filter.connection_state esté configurado.
Atributos que solo aparecen si se configuran:
in-interface(firewall.block_input.interface),in-interface-list(firewall.block_input.interface_list),log(firewall.log),log-prefix(firewall.log_prefix)Bloqueo de outputdescarta
Impide que el propio router inicie tráfico hacia un destino baneado; es la única regla aquí que coincide por destino y no por origen.
/ip/firewall/filter add chain=output action=drop dst-address-list=crowdsec-banned comment="crowdsec-bouncer:filter-output-output-v4 @cs-routeros-bouncer"/ipv6/firewall/filter add chain=output action=drop dst-address-list=crowdsec6-banned comment="crowdsec-bouncer:filter-output-output-v6 @cs-routeros-bouncer"No se crea por defecto. Requiere
firewall.block_output.enabled(por defectofalse).Su bloque no recibe regla de contador, por lo que el tráfico de salida nunca aparece en las métricas de procesados.
Atributos que solo aparecen si se configuran:
src-address (negated)(firewall.block_output.passthrough_v4),src-address-list (negated)(firewall.block_output.passthrough_v4_list),out-interface(firewall.block_output.interface),out-interface-list(firewall.block_output.interface_list),reject-with(firewall.reject_with),log(firewall.log),log-prefix(firewall.log_prefix)
Flujo de creación de reglas
Sección titulada «Flujo de creación de reglas»Al arrancar, el bouncer sigue esta secuencia:
-
Comprobar si existen reglas
Busca reglas gestionadas por el bouncer comparando el patrón del comentario.
-
Reutilizar o crear
Una regla cuyo comentario exacto ya está en el router se adopta, no se duplica; lo que falte se crea.
-
Colocar el bloque en la posición configurada
Coloca el bloque gestionado según el
rule_placementefectivo para ese protocolo y tabla: arriba, abajo, una posición numérica de RouterOS o un comentario ancla.
Colocación de reglas
Sección titulada «Colocación de reglas»El bouncer coloca las reglas relacionadas como bloques ordenados. Un bloque de input típico incluye las siguientes reglas en orden: whitelist (si está configurada), counting (si las métricas de procesados están habilitadas) y después la regla de deny/reject. La colocación se realiza cuando ya existen todas las reglas del bloque, de modo que el orden interno se mantiene estable.
La colocación es local a cada menú. Un bloque de filter se posiciona dentro de /ip firewall filter o /ipv6 firewall filter; un bloque de raw se posiciona dentro de /ip firewall raw o /ipv6 firewall raw.
El bouncer puede colocar su bloque gestionado (las reglas relacionadas que crea y mueve juntas) arriba, abajo, en una posición numérica de print de RouterOS, o relativa a un comentario existente perteneciente a otra regla. Si el bloqueo de salida está habilitado, el bloque de output se mueve con el mismo orden interno. Por defecto, el bouncer reutiliza la misma estrategia de colocación para IPv4 e IPv6. Las anulaciones por tabla y por protocolo pueden enviar los bloques de filter, raw, IPv4 e IPv6 a ubicaciones distintas. La precedencia es: colocación global, anulación global de tabla, anulación de protocolo y, por último, anulación de tabla del protocolo.
La colocación se calcula sobre los candidatos: todas las reglas que ya están en ese menú y cuyo comentario no lleva la firma @cs-routeros-bouncer. Las reglas del propio bouncer quedan fuera de esa cuenta, así que una position numérica significa el mismo lugar esté o no el bloque ya en el router. El diagrama siguiente es el mecanismo completo, reintentos incluidos: cada peldaño que falla cae al siguiente, y el último peldaño siempre es dejar el bloque donde RouterOS lo añadió. La colocación nunca aborta el arranque.
Dos peldaños merecen una segunda lectura. El reintento es por candidata, no por intento: cuando RouterOS rechaza mover el bloque delante de una regla —una regla dinámica o integrada, por ejemplo— el bouncer apunta a la regla siguiente y vuelve a intentarlo, y por eso un bloque top puede acabar unas posiciones más abajo de lo que su nombre sugiere. Y fallback solo existe para las estrategias por comentario: una position numérica más allá del final no tiene ancla que fallar, así que simplemente se añade al final.
El movimiento tampoco es atómico para todo el bloque. Cada regla se mueve por separado, en el orden del bloque, así que un fallo a mitad de camino puede dejar el bloque partido alrededor del destino; el orden lo completa la siguiente pasada de colocación.
| Estrategia | Comportamiento |
|---|---|
top | Mueve el bloque antes de la primera regla utilizable que no sea del bouncer. Si RouterOS rechaza la posición, por ejemplo antes de reglas dinámicas o integradas, el bouncer reintenta con posiciones inferiores. |
bottom | Deja las reglas recién creadas añadidas al final. |
position | Requiere position y usa la numeración de print de RouterOS empezando en cero, excluyendo las reglas existentes del bouncer. Las posiciones fuera de rango se añaden al final. |
before_comment | Mueve el bloque antes de la primera regla no perteneciente al bouncer cuyo comentario coincide con el ancla configurada. |
after_comment | Mueve el bloque después del ancla coincidente insertándolo antes de la siguiente regla no perteneciente al bouncer; si el ancla es la última, el bloque se queda añadido al final. |
La colocación por comentario usa fallback (top por defecto, o bottom) cuando el ancla no existe o no puede usarse. La position numérica ignora fallback porque una posición fuera de rango implica de forma natural añadir al final.
Identificación de reglas
Sección titulada «Identificación de reglas»Las reglas se identifican mediante un comentario estructurado:
{prefix}:{type}-{chain}-{direction}-{protocol} @cs-routeros-bouncer| Parte | Valores |
|---|---|
prefix | Configurable mediante comment_prefix (por defecto: crowdsec-bouncer) |
type | filter o raw |
chain | input, forward, prerouting, output |
direction | input, output, whitelist o counting |
protocol | v4 o v6 |
RouterOS imprime el comentario encima de la regla a la que pertenece, así que el bloque gestionado completo se ve con una sola consulta:
/ip/firewall/filter print where comment~"crowdsec"# 0 ;;; crowdsec-bouncer:filter-input-counting-v4 @cs-routeros-bouncer# chain=input action=passthrough# 1 ;;; crowdsec-bouncer:filter-input-input-v4 @cs-routeros-bouncer# chain=input action=drop src-address-list=crowdsec-bannedLimpieza y lo que queda atrás
Sección titulada «Limpieza y lo que queda atrás»Cuando el bouncer recibe SIGTERM o SIGINT:
-
Eliminar las reglas
Se elimina toda regla de firewall creada por el bouncer, incluidas las de contador.
-
No tocar las address-lists
Las entradas de las address-lists no se eliminan. Expiran mediante el timeout de MikroTik con el que se escribieron, que es la duración de la decisión de CrowdSec que las creó.
Este diseño implica que la protección continúa después de detener el bouncer, durante lo que le quede de timeout a cada entrada, y que un reinicio rápido nunca deja el router desprotegido en ese intervalo. También implica que no hay que ejecutar ningún borrado masivo al apagar.