tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Definiciones

me dejé afuera de la caja: 20 minutos caída, y las tres causas encadenadas

Crear una cuenta tiró el servidor. Ninguna de las tres causas era la que parecía:

1. La caja NUNCA tuvo /etc/shadow. Crearlo con todas las cuentas bloqueadas (!) hizo que sshd
   RECHAZARA LA LLAVE de root: este sshd no acepta login por llave de una cuenta bloqueada. La forma
   correcta acá es la vieja — el hash en el campo 2 de /etc/passwd, sin shadow.
2. La caja NO reinicia por ACPI: `hcloud server reboot` no hizo nada (arje-zero no atiende la señal).
   La única forma de reiniciarla desde fuera es `reset`, que es un corte de energía.
3. Y ese corte dejó el reglaset del cortafuegos a MEDIO ESCRIBIR — 5 KB de NULs: ext4 journaló el
   tamaño y los datos nunca llegaron al disco. Un fichero medio escrito con `policy drop` y sin los
   `accept` es exactamente una caja que arranca, corre todo y no deja entrar a nadie.
   ⇒ después de escribir algo que el arranque necesita, `sync` ANTES de cualquier reset.

Lo que el rodeo destapó y vale más que el susto:
 · EL CORTAFUEGOS NO SE APLICABA EN NINGÚN ARRANQUE (su card sale 78 si nft -c falla, y con el
   fichero corrupto fallaba siempre): la caja llevaba días arrancando SIN FILTRAR, en silencio.
   Reparado, el arranque ya deja 21 reglas dport, comprobado tras reiniciar.
 · netup es DHCP-only y falló dos veces; se le añadió al init una IP estática de respaldo con la
   forma de Hetzner (/32 + puerta scope link)… que no corría, porque su guarda miraba /sys y el init
   NO MONTA /sys. El diagnóstico que lo probó hubo que escribirlo a FICHERO: sin red, el log tiene
   que estar en el disco.
 · el mapa real de particiones: sda2 root · sda3 state · sda4 work · sdb store.

El costo, sin adornos: ~20 minutos de caída de los ocho dominios y tres resets duros, uno de ellos
disparado por mí a los 400 s mientras la caja estaba haciendo su trabajo. En esta caja cada
diagnóstico remoto cuesta un ciclo de 6-8 minutos: el primero conviene gastarlo en dejar evidencia
en disco, no en probar una corazonada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

a3e891a601a84633b1959486dd46c9c08a4788f3 · por Sergio · (hace 1 mes) · padre e7b77ff65 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

1 archivos · +64 −0

diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md
index 16355a8e..c48db244 100644
--- a/docs/28-servidor-de-produccion.md
+++ b/docs/28-servidor-de-produccion.md
@@ -2912,6 +2912,70 @@ repo vive en `/opt/takana` ⇒ **el índice por ruta no coincide**. Se resuelve
 directorio a `-opt-takana` o dándole al repo la misma ruta; hasta entonces el agente arranca sin su
 memoria del proyecto aunque los 733 ficheros estén en disco.
 
+### 6.51 🔥 Me dejé afuera de la caja — 20 minutos caída, y tres causas encadenadas *(2026-09-17)*
+
+Crear una cuenta de usuario tiró el servidor de producción. Queda escrito entero porque **ninguna de
+las tres causas era la que parecía**, y las tres siguen ahí para quien venga.
+
+#### 1. `/etc/shadow` no existía, y crearlo cerró el SSH de root
+
+La caja nunca tuvo `/etc/shadow`: todas las cuentas llevan `x` en `/etc/passwd` y entran por llave.
+Para darle contraseña a `sergio` creé el fichero con **todas las cuentas bloqueadas (`!`)** y la suya
+con su hash. Efecto inmediato: **`ssh` de root empezó a dar `Permission denied (publickey)`** con la
+misma llave de siempre. Este `sshd` **rechaza la llave de una cuenta cuyo hash está bloqueado**.
+
+⇒ La forma correcta acá es la vieja: **el hash va en el campo 2 de `/etc/passwd`** y no hay
+`/etc/shadow`. Así quedó, y así funciona `su - sergio`.
+
+#### 2. La caja NO reinicia por ACPI
+
+Con el SSH cerrado, `hcloud server reboot` (ACPI) **no hizo absolutamente nada**: arje-zero no
+atiende esa señal. La web siguió sirviendo como si nada. Para un mantenimiento remoto eso importa:
+**la única forma de reiniciar esta caja desde fuera es `reset`, que es un corte de energía.**
+
+#### 3. Y el corte de energía dejó el cortafuegos a medio escribir — eso fue lo que la aisló
+
+Tras el `reset` la caja **arrancaba** —los logs de arje lo probaban: gitea y caddy escribiendo— pero
+**nadie llegaba**. La causa, encontrada mirando el fichero:
+
+```
+  $ head -c 90 /etc/takana/cortafuegos-entrada.nft | od -c
+  0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
+```
+
+**El reglaset era TODO NULs.** Se había escrito minutos antes del corte: ext4 journaló el tamaño y
+los datos nunca llegaron al disco. Un fichero de 5 KB de ceros — o, peor y más probable en el primer
+arranque, **medio fichero válido**: la tabla con `policy drop` y las reglas de `accept` cortadas.
+Eso es exactamente una caja que arranca, corre todo, y no deja entrar a nadie.
+
+⇒ **Después de escribir algo que el arranque necesita, `sync` ANTES de cualquier `reset`.** Y el
+corolario amargo: un `reset` no es un `reboot`, y lo que se perdió no avisa.
+
+#### Lo que el rodeo destapó, y vale más que el susto
+
+- **El cortafuegos NO se estaba aplicando en ningún arranque.** Su card sale 78 si `nft -c` falla, y
+  con el fichero corrupto fallaba siempre: la caja llevaba días **arrancando sin filtrar**, en
+  silencio, porque «no aplicar nada» es su modo seguro y nadie mira un 78 en un log de boot.
+  Reparado el fichero, ahora el arranque deja **21 reglas `dport`**, comprobado tras un reinicio.
+- **`netup` es DHCP-only y falló dos veces seguidas** («sin respuesta DHCP (tipo 2)»). Una caja con
+  IP fija no debería depender de que el DHCP conteste: si no contesta no hay segundo intento, y el
+  síntoma —desde fuera— es idéntico al de una máquina que no bootea. Se le añadió al init una
+  **dirección estática de respaldo** con la forma que pide Hetzner (IP `/32` + puerta `scope link`).
+- **Esa red de respaldo no corría**: su guarda era `[ -d /sys/class/net/eth0 ]` y el init **no monta
+  `/sys`**. El diagnóstico que lo probó tuvo que escribirse a FICHERO, porque `/dev/kmsg` no
+  sobrevive al reinicio y sin red no hay forma de mirar. *Cuando no hay red, el log tiene que estar
+  en el disco.*
+- Del rescate salió el mapa real de particiones, que no era el que yo creía:
+  `sda2 hammer-root` · `sda3 hammer-state` · `sda4 hammer-work` · `sdb hammer-store`.
+
+#### El costo, dicho sin adornos
+
+**~20 minutos de caída** de los ocho dominios, cuatro ciclos rescate↔sistema y tres `reset` duros —
+uno de ellos, el que corrompió el fichero, disparado por mí a los 400 s de espera **mientras la caja
+estaba haciendo su trabajo**. La lección que queda no es «hay que tener cuidado»: es que **en esta
+caja el diagnóstico remoto cuesta un ciclo de 6 a 8 minutos**, así que conviene gastar el primero en
+dejar evidencia en disco antes que en probar una corazonada.
+
 ## 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: