diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md index 22e4e825..f1944be5 100644 --- a/docs/28-servidor-de-produccion.md +++ b/docs/28-servidor-de-produccion.md @@ -1890,6 +1890,51 @@ Su guarda sale **78 nombrando el fichero** si el reglaset no está, en vez de de filtrar creyendo que está protegida: *un cortafuegos ausente y uno vacío se ven igual desde afuera hasta que alguien prueba*. +### 6.33 🧨 EL CORTAFUEGOS BANEÓ A LOS USUARIOS DEL PROXY — y squid nunca se cayó *(2026-09-16)* + +El usuario preguntó si el proxy estaba caído. **No lo estaba**: el ente `squid` llevaba horas +`corriendo` con `↻ 0`, escuchando en `:1137` y contestando `407` a quien preguntara. Lo que estaba +caído era **el acceso**: el cortafuegos que puse ayer estaba baneando a los usuarios autorizados. + +La prueba, en una línea: **`154.197.1.2` —una IP que está en la ACL de squid, o sea gente con +contraseña— apareció en `@ban4`**. Y el contador del ban iba en **38.246 paquetes tirados**. + +#### La causa no es la tasa: es la RÁFAGA + + tcp dport 1137 ct state new add @ban4 { ip saddr timeout 300s limit rate over 300/minute burst 5 packets } drop + +`burst 5` significa «tolero cinco conexiones por encima del promedio». **Un navegador o un agente +detrás de un proxy abre decenas de CONNECT en el mismo instante**, aunque su promedio sea bajísimo: +seis de golpe y ya estás en el set. Y como **`@ban4` es UN SOLO set consultado antes que todo**, +caer por el puerto del proxy te tira también el web y el git. + +⚠ El tipo del cortafuegos ya traía el campo (`rafaga`, default 5) con un comentario que decía +«para un servicio web va alto (100-200)». Otra vez: **leí el `.ron` de ejemplo y no el tipo**. + +#### Lo que se hizo, en orden de urgencia + +1. **`nft flush set … ban4/ban6`** — servicio restaurado en el acto. +2. **Los usuarios del proxy a `confiables`**: la misma lista que la ACL de squid (21 IPs + 5 redes). + Un proxy que autentica no necesita que el kernel le cuente las conexiones a un usuario conocido; + lo que el ban tiene que parar son las fuentes DESCONOCIDAS. +3. **`rafaga` por servicio, según su clientela**: ssh 5 · git 20 · web 100 · **proxy 200**. Y el + proxy pasa a `1200/min` con ban de 60 s: red de contención contra un flood, no control de uso. +4. Control después: **cero autorizados en el set**, 24 baneados (escáneres, que es lo que se quiere), + y tráfico real pasando — `154.194.14.37 … CONNECT api.deepseek.com:443 sigma`, 298 K tunelados. + +⚠⚠ **Y un fallo de método que casi lo tapa: `nft -f` SUMA a la tabla existente.** Cargué el reglaset +corregido encima del viejo y quedaron **30 reglas**: las viejas ADELANTE, así que los `confiables` +nuevos no llegaban a evaluarse nunca. Se vio contando (`grep -c dport` daba 30 y no 15) y mirando +qué `saddr` salía primero. Por eso `cortafuegos apply-input` **borra la tabla antes de cargar** — +usar `nft -f` a pelo se saltea esa mitad. + +#### Lo que esto enseña del cortafuegos como herramienta + +Un cortafuegos correcto y un cortafuegos usable no son lo mismo, y la diferencia **no se ve al +aplicarlo**: las reglas cargan, el `nft -c` pasa, los sitios responden, y el daño aparece sólo cuando +un cliente REAL hace lo que los clientes reales hacen. El único control que lo habría cazado antes es +el que no corrí: **una ráfaga de conexiones desde una IP que NO esté en `confiables`**. + ## 7. Reusar los scripts que ya existen, y no escribir de nuevo Pedido explícito del usuario. El inventario de lo que ya hace el trabajo: diff --git a/scripts/servidor/cortafuegos-entrada.ron b/scripts/servidor/cortafuegos-entrada.ron index 1c674b43..257086d7 100644 --- a/scripts/servidor/cortafuegos-entrada.ron +++ b/scripts/servidor/cortafuegos-entrada.ron @@ -30,6 +30,27 @@ "204.168.193.248", // dev.gioser.net: el worker de la granja. "154.197.1.13", + + // ── LOS USUARIOS DEL PROXY, Y ESTO NO ES OPCIONAL (2026-09-16) ──────────────────────── + // Es la MISMA lista que la ACL de squid (`/etc/squid/allowed_ssh_users.acl`): gente + // autorizada, con contraseña, que el cortafuegos baneó igual. Medido: `154.197.1.2` —que + // está en esa ACL— apareció en `@ban4` y perdió el proxy ENTERO. + // + // La causa es la mecánica del ban, no la tasa: la regla es `limit rate over N/minute burst + // 5 packets`, y **el burst de 5 no lo aguanta ningún cliente real** — un navegador o un + // agente abre decenas de CONNECT a la vez. Y como `@ban4` es UN SOLO set consultado antes + // que todo, caer por el puerto del proxy te tira también el web y el git. + // + // Un proxy con autenticación no necesita que el kernel le cuente las conexiones a un + // usuario conocido: lo que el ban tiene que parar son las fuentes DESCONOCIDAS. + "154.197.1.2", "154.197.1.7", "186.94.250.208", + "190.206.193.88", "190.206.212.233", "190.206.214.18", "190.206.215.35", + "190.206.246.187", "190.206.249.243", "190.206.254.167", "190.206.58.77", + "190.52.108.181", "200.84.33.134", "200.84.43.251", "200.84.55.166", + "200.93.92.169", "201.208.13.192", "201.208.211.104", "201.208.25.223", + "201.209.132.56", "201.211.110.96", "181.225.47.111", + "186.167.0.0/16", "190.72.0.0/16", "190.74.0.0/16", "190.77.0.0/16", + "45.234.60.0/24", ], drop_estados_invalidos: true, icmp_echo_por_seg: 10, @@ -44,6 +65,9 @@ conexiones_max: 10, nuevas_por_min: 5, ban_timeout_seg: 600, + // 5 está bien acá: una sesión ssh no abre veinte conexiones de golpe, y el operador + // está en `confiables` de todos modos. + rafaga: 5, ), ( puerto: 2345, @@ -54,6 +78,8 @@ conexiones_max: 20, nuevas_por_min: 15, ban_timeout_seg: 600, + // un `git clone` abre varias a la vez. + rafaga: 20, ), ( puerto: 80, @@ -62,6 +88,7 @@ conexiones_max: 200, nuevas_por_min: 60, ban_timeout_seg: 600, + rafaga: 100, ), ( puerto: 443, @@ -69,7 +96,10 @@ descripcion: "https — los siete dominios mudados", conexiones_max: 200, nuevas_por_min: 120, - ban_timeout_seg: 600, + // ⚠ Una página con 30 recursos son 30 conexiones nuevas EN UN INSTANTE. Con la ráfaga + // por defecto (5) un navegador normal se banea solo — el mismo defecto que sacó del aire + // al proxy el 2026-09-16, un piso más abajo. + rafaga: 100, ), ( puerto: 1137, @@ -79,8 +109,17 @@ // CONNECT nuevo. Un límite pensado para ssh acá BANEA A UN USUARIO LEGÍTIMO, que es // peor que no tener regla — el abuso que esto para es un flood, no un navegador. conexiones_max: 300, - nuevas_por_min: 300, - ban_timeout_seg: 300, + // ⚠ 1200/min y ban CORTO: acá el ban es una red de contención contra un flood de una + // fuente DESCONOCIDA, no un control de uso. Los usuarios de verdad están en + // `confiables` y no llegan nunca a esta regla. Con 300/min y `burst 5` se baneaba solo + // un cliente normal. + nuevas_por_min: 1200, + ban_timeout_seg: 60, + // ⚠⚠ LA RÁFAGA ES LO QUE LO ROMPIÓ, no la tasa. `limit rate over N/minute burst 5` + // banea a quien abre 6 conexiones DE GOLPE aunque su promedio sea bajísimo, y un agente + // o un navegador detrás de un proxy abre decenas. Medido: `154.197.1.2` —autorizado, con + // contraseña— terminó en `@ban4` y perdió el proxy entero. + rafaga: 200, ), ], )