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>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
1 qillqakuna · +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: