censar: «no existe» y «no puedo mirar» se confundían — 572 M invisibles, y el censo de hoy
El censo ya tenía tres estados a propósito (`ausente` / `sin_permiso` / `ok`), pero el tercero sólo se detectaba sobre la PROPIA ruta: cuando el que no deja pasar es un ANCESTRO, `[ -e "$p" ]` contesta que no existe y la ruta caía en `ausente`, que el censo descarta sin decir nada. Medido en gioser: `/root/.local` es 0700 ⇒ un censo corrido como `sergio` daba `/root/.local/bin` por AUSENTE. Como root son 572 M de binarios puestos a mano que ningún paquete provee — justo la clase que la mudanza no puede reconstruir. Arreglado: si un ancestro existe y no es atravesable, el estado es `sin_permiso`. Probado en los dos sentidos, que es lo que separa un guardián de un adorno: ancestro 0700 de otro dueño → sin_permiso (sale en el ⚠ del resumen) ruta que NO existe de verdad → ausente (no se reporta) ← el control que tiene que pasar Con el arreglo, el censo sin privilegio pasa de 2 rutas ciegas a 13, entre ellas el home entero de `artix`, que antes no figuraba de ninguna manera. Y el §6.34 con el estado MEDIDO de la mudanza hoy: de los 29 dominios queda UNO sirviéndose desde gioser (`sergio.gioser.net`); los otros seis vivos ya contestan 200 contra 2.29.29.217. El rescate del §6.20 sigue coincidiendo bit a bit con cuatro de los seis procesos que corren desde un inodo borrado, y los otros dos tienen en disco una versión más nueva. Lo que queda abierto son los pasos 6 y 7: el montón de daemons propios (shuma, willay, pacha, tejido, tupu, matilda…) y los datos. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1964,6 +1964,86 @@ aplicarlo**: las reglas cargan, el `nft -c` pasa, los sitios responden, y el da
|
||||
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`**.
|
||||
|
||||
### 6.34 📋 Censo del 2026-09-16: queda UN vhost — y el censo sin privilegio no veía 572 M
|
||||
|
||||
Censo fresco de gioser (`censar.py --local --probe-dns`, sólo lee), para saber **qué falta de
|
||||
verdad** en vez de arrastrar la lista del 11.
|
||||
|
||||
```
|
||||
servicios vivo 23 · no-declarado 17 · declarado-muerto 81 · descartados 6
|
||||
dominios apunta-aca 1 · ya-mudado 6 · fosil-sin-dns 7
|
||||
datos /home 25 G (copiar 27 G) · /var/lib 8,1 G · /opt 1,2 G · /var/www 288 M
|
||||
```
|
||||
|
||||
**De los 29 dominios del Caddyfile sólo UNO sigue sirviéndose desde gioser: `sergio.gioser.net`.**
|
||||
Comprobado desde fuera, resolución + HTTP, no por el fichero de config:
|
||||
|
||||
| dominio | resuelve a | HTTP |
|
||||
|---|---|---|
|
||||
| `tawasuyu.net` · `gioser.net` · `git.tawasuyu.net` · `takana.gioser.net` · `hifas.gioser.net` · `api.sergio.gioser.net` | `2.29.29.217` | 200 |
|
||||
| `gitea.gioser.net` | `2.29.29.217` | 301 |
|
||||
| **`sergio.gioser.net`** | **`204.168.193.248` (gioser)** | 200 |
|
||||
| `api.summa.gioser.net` | `154.197.1.2` (otra máquina) | — |
|
||||
| `terapeuta.ec`, `andino.ec`, `api.sigma…` y 4 más | **sin DNS** | — |
|
||||
|
||||
⇒ la lista de «tres vhosts» del §9 quedó vieja: `gioser.net` y `tawasuyu.net` ya están mudados
|
||||
(§6.26) con su origen vivo a propósito. **Lo único que ata el DNS a gioser es la consola de `sergio`.**
|
||||
|
||||
#### El rescate del §6.20 sigue vigente — y caduca de verdad
|
||||
|
||||
Seis procesos corren hoy desde un **inodo borrado**. Cuatro tienen su copia en
|
||||
`work/mudanza/rescate/` y el sha256 del `/proc/<pid>/exe` vivo **coincide bit a bit** con lo
|
||||
rescatado el 12. Los otros dos (`/usr/local/bin/tejido` y `/usr/local/bin/shuma-daemon`) **no están
|
||||
en el rescate**, pero en disco hay una versión **más nueva** de cada uno (hoy 11:13 y 14:20): no se
|
||||
perdió nada porque el usuario los está reconstruyendo. La lección es la del §6.20 y no cambió: *ese
|
||||
paso caduca, y quién caducó se ve mirando `/proc`, no el directorio*.
|
||||
|
||||
#### 🕳️ Y el hallazgo del día: `-e` contesta «no existe» cuando lo que pasa es «no puedo mirar»
|
||||
|
||||
El censo tiene tres estados a propósito (`ausente` / `sin_permiso` / `ok`) porque un `ls` sin
|
||||
permiso se lee igual que un directorio vacío. Pero el tercer estado sólo se detectaba **sobre la
|
||||
propia ruta**: cuando el que no deja pasar es un **ANCESTRO**, `[ -e "$p" ]` contesta que no, y la
|
||||
ruta caía en `ausente` — que el censo **descarta sin decir nada**.
|
||||
|
||||
```
|
||||
/root/.local drwx------ root root ← 0700
|
||||
/root/.local/bin 572 M de binarios a mano que NINGÚN paquete provee
|
||||
```
|
||||
|
||||
Corrido como `sergio`, el censo decía que `/root/.local/bin` no existe. Corrido como root, son
|
||||
**572 M** de exactamente la clase que la mudanza no puede reconstruir: binarios puestos a mano.
|
||||
Arreglado —si un ancestro existe y no es atravesable, el estado es `sin_permiso`— y probado en los
|
||||
dos sentidos, que es lo que distingue un guardián de un adorno:
|
||||
|
||||
```
|
||||
ancestro 0700 de otro dueño → sin_permiso (y sale en el ⚠ del resumen)
|
||||
ruta que NO existe de verdad → ausente (y NO se reporta) ← el control que tiene que pasar
|
||||
```
|
||||
|
||||
Con el arreglo, el censo como `sergio` pasa de **2 rutas ciegas a 13** — entre ellas el home entero
|
||||
de `artix`, que antes no figuraba de ninguna manera. **El censo se corre como root**; la lista de
|
||||
ciegas es el recibo de lo que una corrida sin privilegio no puede ver.
|
||||
|
||||
#### Lo que queda, y por qué no lo decide el programa
|
||||
|
||||
Descontados los que ya se decidieron (§6.30: `qdrant`, `act_runner`, `fail2ban` mueren) y los que
|
||||
provee el init del destino, lo que sigue vivo en gioser es **un montón de daemons de tawasuyu que
|
||||
ningún paquete provee** — binarios a mano en `/usr/local/bin` (1,2 G) y `~/.local/bin` (765 M + 572 M
|
||||
en el home de root):
|
||||
|
||||
```
|
||||
shuma-daemon · shuma-gateway (:7378) la consola de sergio.gioser.net — el único vhost que queda
|
||||
willay-daemon · willay-crosscheck · tejido (:4102,:33097) · pacha · pacha-secretos
|
||||
matilda · tupu · thasnuna · sandokan-watch · openclaw · zeroclaw
|
||||
puerta-f6e393ffbef3999e (:34221,:44961) binario de test en target/debug, BORRADO del disco
|
||||
webhook-deploy.py
|
||||
```
|
||||
|
||||
`planear.py --revisar` los saca con su motivo, pero **la decisión es del usuario y el programa no la
|
||||
va a inventar**: son las herramientas propias del usuario, no servicios de un catálogo. Y los
|
||||
**datos** tampoco se recomiendan solos (§3): `/home` son 25 G que incluyen 6,8 G de `.claude` y
|
||||
1,3 G de binarios sueltos.
|
||||
|
||||
## 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:
|
||||
@@ -2040,9 +2120,12 @@ receta usa uno.
|
||||
### Lo que falta para el cutover, en este orden
|
||||
|
||||
⚠ **La lista de abajo es del 2026-09-11 y los pasos 1-5 YA ESTÁN** (gitea mudado y sirviendo, §6.14;
|
||||
estáticos mudados, §6.18; fósiles barridos, §6.19; `api.sergio` mudado, §6.25). El estado vigente de
|
||||
la mudanza está en la tabla del final de §6.25; lo que sigue vivo en gioser son **tres vhosts**
|
||||
(`sergio` con su `/shuma`, `gioser.net`/`www`, `tawasuyu.net`) y los servicios del censo.
|
||||
estáticos mudados, §6.18; fósiles barridos, §6.19; `api.sergio` mudado, §6.25; `tawasuyu.net` y
|
||||
`gioser.net` mudados, §6.26; squid, §6.27-28; hora, latido y rotación, §6.29; cortafuegos, §6.31-33).
|
||||
|
||||
**El estado vigente está medido en el §6.34 (2026-09-16), y es más corto de lo que decía esta lista:
|
||||
queda UN solo vhost sirviéndose desde gioser — `sergio.gioser.net` — y el montón de daemons propios
|
||||
del usuario que ningún paquete provee.** Los pasos 6 y 7 son lo único que sigue abierto.
|
||||
|
||||
|
||||
1. **Actualizar la caja a la imagen nueva** (gitea + `arjectl` + las cuentas de `[[user]]`).
|
||||
|
||||
@@ -592,6 +592,14 @@ def fuera_de_git(t):
|
||||
«no hay nada» de lo que no pudo mirar. Por eso hay `sin_permiso`, que es un dato distinto y va
|
||||
al resumen: lo ausente se descarta, lo no mirado se vuelve a mirar con quien pueda.
|
||||
|
||||
⚠ Y el tercer estado hay que buscarlo TAMBIÉN hacia arriba (2026-09-16). La primera versión sólo
|
||||
lo detectaba cuando la ruta se podía *stat*ear pero no listar; cuando el que no deja pasar es un
|
||||
ANCESTRO, `[ -e ]` contesta que no existe y la ruta caía en `ausente`, que el censo descarta sin
|
||||
decir nada. Medido en gioser: `/root/.local` es 0700, así que un censo corrido como `sergio`
|
||||
reportaba `/root/.local/bin` como si no estuviera — **572 M de binarios puestos a mano que
|
||||
ningún paquete provee**, justo la clase que la mudanza no puede reconstruir. Corriendo como
|
||||
root aparecen. Ahora, si un ancestro existe y no es atravesable, el estado es `sin_permiso`.
|
||||
|
||||
Todo en UNA sola llamada (un script generado) y no una por ruta: por SSH, N rutas × M homes son
|
||||
decenas de conexiones y el censo tarda más que el trabajo que describe.
|
||||
"""
|
||||
@@ -610,10 +618,21 @@ def fuera_de_git(t):
|
||||
q = shlex.quote(ruta)
|
||||
prog.append(
|
||||
f'p={q}; '
|
||||
'if [ ! -e "$p" ]; then st=ausente; '
|
||||
'elif [ -f "$p" ]; then st=fichero; '
|
||||
'elif ls -1 "$p" >/dev/null 2>&1; then st=ok; '
|
||||
'else st=sin_permiso; fi; '
|
||||
# `-e` responde NO tanto para «no está» como para «no puedo mirar»: si un ANCESTRO no es
|
||||
# atravesable, el test falla igual que si la ruta no existiera. Medido: /root/.local es
|
||||
# 0700, y un censo corrido como `sergio` daba /root/.local/bin por AUSENTE — 572 M de
|
||||
# binarios a mano que ningún paquete provee, desaparecidos en silencio del censo.
|
||||
'if [ -e "$p" ]; then '
|
||||
' if [ -f "$p" ]; then st=fichero; '
|
||||
' elif ls -1 "$p" >/dev/null 2>&1; then st=ok; '
|
||||
' else st=sin_permiso; fi; '
|
||||
'else '
|
||||
' st=ausente; d=${p%/*}; '
|
||||
' while [ -n "$d" ]; do '
|
||||
' if [ -e "$d" ]; then [ -x "$d" ] || st=sin_permiso; break; fi; '
|
||||
' d=${d%/*}; '
|
||||
' done; '
|
||||
'fi; '
|
||||
'sz=$(timeout 20 du -shx "$p" 2>/dev/null | cut -f1); '
|
||||
'printf "P\t%s\t%s\t%s\n" "$p" "$st" "${sz:-?}"; '
|
||||
'[ "$st" = ok ] && ls -1 "$p" 2>/dev/null | head -20 | sed "s/^/E\t/"; '
|
||||
@@ -920,8 +939,8 @@ def resumen(c):
|
||||
if ciegos:
|
||||
# Un `ls` sin permiso se lee IGUAL que un directorio ausente. Decirlo es la diferencia
|
||||
# entre «no hay nada» y «no pude mirar», y sólo una de las dos se puede descartar.
|
||||
print(f" ⚠ {len(ciegos)} ruta(s) EXISTEN y el censo no pudo leerlas "
|
||||
f"(corré el censo como su dueño o con privilegio):")
|
||||
print(f" ⚠ {len(ciegos)} ruta(s) que el censo NO PUDO MIRAR — no es lo mismo que "
|
||||
f"ausentes (corré el censo como su dueño o con privilegio):")
|
||||
for f in ciegos:
|
||||
print(f" {f['path']}")
|
||||
if c["datos"]:
|
||||
|
||||
Reference in New Issue
Block a user