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 1411Shell 141Markdown 84Rust 832898 Definiciones

🧨 el curl de la distro no puede validar TLS: el capath no tiene hash-links

Al traer la primera imagen ajena, la caja falló con «curl failed to verify the legitimacy of the
server». El certificado del servidor estaba bien; lo que falta es de este lado:

    * CApath: /etc/ssl/certs
    * SSL certificate ... unable to get local issuer certificate (20)
    $ curl --cacert /etc/ssl/certs/ca-certificates.crt ...   → 200

El curl del corpus se compila con `--with-ca-path=/etc/ssl/certs` y SIN CAfile, y ese directorio
tiene un solo fichero: el bundle. Un capath necesita hash-links (`c_rehash`) — el ÍNDICE — y no los
hay. Los certificados están; el índice no.

Por qué faltan: la receta deja el hook `/etc/ca-certificates/update.d/certhash`, que en Alpine
ejecuta `apk` al instalar. **En takana no lo ejecuta nadie**: la distro proyecta artefactos, no corre
post-install. Todo presente, y el paso que lo conecta no existe.

Alcance: no es sólo `qorpa pull`. Es `install --repo https://…`, el mirror y cualquier curl/wget de
una caja instalada. No falla al construir ni al instalar: falla la primera vez que la máquina intenta
bajar algo. No se había visto porque el hub usa el curl de Artix.

Arreglado en la receta: los hash-links se generan EN EL BUILD (donde c_rehash y perl existen) y
viajan en el artefacto, con una guarda que falla ruidosamente si el rehash no produce ninguno.
Re-sella `ca-certificates`, raíz de `perfil.base`. Apaño mientras tanto: `CURL_CA_BUNDLE=…` (200).

Y el estado de qorpa en la caja: preflight de «BLOQUEA 1 · LIMITA 4» a «LIMITA 1» — qorpa movido a
/work (la raíz tenía 3 G), subuid provisionado y `setcap` aplicado a newuidmap/newgidmap SIN tocar el
artefacto del store (inodes distintos: en una caja instalada esos binarios son copias). El pull baja
y verifica el sha256, y muere al desempacar: el rootfs de Arch es `.tar.zst` y el `tar` de la imagen
es el de busybox. `qorpa pull` necesita `zstd -dc | tar -x` para `.zst`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn

88decb0498d300013d9f818a562b5dee1bdb0714 · por Sergio · (hace 1 mes) · padre 146ace3ce · ver el árbol en este commit

Delta semántico

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

2 archivos · +75 −0

diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md
index ed0239fd..54a51ef8 100644
--- a/docs/28-servidor-de-produccion.md
+++ b/docs/28-servidor-de-produccion.md
@@ -1353,6 +1353,59 @@ servicio vivo no tiene hoy camino a takana**. Las salidas son tres y hay que ele
 es para exactamente esto; (2) que ese servicio viva en otra máquina —`summa` ya lo hace, y su DNS lo
 demuestra—; o (3) que muera. Ninguna es técnica: es una decisión.
 
+### 6.22 🧨 El `curl` de la distro NO PUEDE VALIDAR TLS — y por eso nada se baja por HTTPS
+
+Al ir a traer la primera imagen ajena (`qorpa pull`), la caja falló con `curl failed to verify the
+legitimacy of the server`. El certificado del servidor estaba bien; lo que falta es de este lado:
+
+```
+* CApath: /etc/ssl/certs
+* SSL certificate ... unable to get local issuer certificate (20)
+$ curl --cacert /etc/ssl/certs/ca-certificates.crt ...   → 200
+```
+
+El `curl` del corpus está compilado **con `--with-ca-path=/etc/ssl/certs` y sin CAfile**, y ese
+directorio contiene **un solo fichero**: el bundle. Un *capath* necesita **hash-links**
+(`c_rehash`) — el índice — y no los hay. Los certificados están, el índice no.
+
+**Por qué faltan**: `recipes/ca-certificates.toml` deja escrito el hook
+`/etc/ca-certificates/update.d/certhash`, que en Alpine ejecuta `apk` al instalar. **En takana no lo
+ejecuta nadie**: la distro proyecta artefactos, no corre post-install. Es la misma familia que
+[[subcomando-sin-driver]] — todo presente, y el paso que lo conecta no existe.
+
+**Alcance**: no es sólo `qorpa pull`. Es `takana install --repo https://…`, el mirror, y cualquier
+`curl`/`wget` de un script en una caja instalada. **No falla al construir ni al instalar: falla la
+primera vez que la máquina intenta bajar algo.** Nadie lo había visto porque el hub usa el `curl` de
+Artix.
+
+**Arreglado en la receta**: los hash-links se generan **en el build** —donde `c_rehash` y perl ya
+existen— y viajan dentro del artefacto, con una guarda que **falla ruidosamente si el rehash no
+produce ninguno**. Re-sella `ca-certificates`, que es raíz de `perfil.base`.
+
+**Apaño mientras tanto**, para invocaciones puntuales: `CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt`
+(comprobado: 200).
+
+### 6.23 `qorpa` en la caja: preflight en verde, y el segundo muro es `tar`
+
+Con el backend de `sergio` sin camino a musl (§6.21), la salida elegida es **qorpa**. Estado medido
+en la caja:
+
+| paso | resultado |
+|---|---|
+| userns anidado · overlayfs sin privilegios | ✅ ya estaban |
+| **disco** | ❌→✅ `/var/lib/hammer` vive en la raíz (3 G) ⇒ `qorpa` **se movió a `/work`** (62 G) por symlink |
+| `subuid`/`subgid` | ❌→✅ rango escrito para root |
+| `newuidmap`/`newgidmap` sin capability | ❌→✅ `setcap` aplicado — **y el artefacto del store NO se tocó** (inodes distintos: en una caja instalada esos binarios son copias, no hardlinks) |
+| veredicto del preflight | **de «BLOQUEA 1 · LIMITA 4» a «LIMITA 1»** |
+| `qorpa pull` de Arch bootstrap | baja y **verifica el sha256**, y falla al desempacar |
+
+El segundo muro: el rootfs de Arch es `.tar.zst` y **el `tar` de la imagen es el de busybox**, que no
+lo entiende — el mismo tropiezo que ya costó el lab (`tar: unrecognized option: zstd`). `zstd` SÍ
+está instalado. ⇒ `qorpa pull` tiene que descomprimir con `zstd -dc | tar -x` cuando el archivo es
+`.zst`, en vez de dárselo entero a `tar`. Es un arreglo pequeño en el CLI, y hasta entonces la
+alternativa es una imagen `.tar.gz` (Ubuntu base) — que además obliga a reinstalar las deps del venv,
+porque el de gioser trae extensiones de **CPython 3.14** y Ubuntu 24.04 lleva 3.12.
+
 ## 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/recipes/ca-certificates.toml b/recipes/ca-certificates.toml
index 327a4a64..986fb770 100644
--- a/recipes/ca-certificates.toml
+++ b/recipes/ca-certificates.toml
@@ -65,6 +65,28 @@ make install DESTDIR="/out"
 		exec /usr/bin/c_rehash /etc/ssl/certs
 	EOF
 	chmod +x "/out"/etc/ca-certificates/update.d/certhash
+
+	# ── LOS HASH-LINKS, HECHOS EN EL BUILD (2026-09-14) ──────────────────────────────────────
+	# En Alpine ese hook de arriba lo ejecuta `apk` al instalar. **Acá no lo ejecuta nadie**: takana
+	# proyecta artefactos, no corre post-install. Resultado medido en la caja de producción: el
+	# `curl` de la distro está compilado con `--with-ca-path=/etc/ssl/certs` y SIN CAfile, así que
+	# mira un directorio que sólo tiene el bundle — y **no puede validar ningún certificado**:
+	#
+	#     * CApath: /etc/ssl/certs
+	#     * SSL certificate ... unable to get local issuer certificate (20)
+	#
+	# No falla al construir ni al instalar: falla la primera vez que la caja intenta bajar algo por
+	# HTTPS (`qorpa pull`, `install --repo https://…`, el mirror). Con `--cacert` el mismo curl da
+	# 200, que es la prueba de que los certificados están y lo que falta es el ÍNDICE.
+	#
+	# Se generan acá, donde `c_rehash` y perl existen, y viajan dentro del artefacto.
+	cp "/out"/usr/share/ca-certificates/*.crt "/out"/etc/ssl/certs/ 2>/dev/null || true
+	c_rehash "/out"/etc/ssl/certs >/dev/null 2>&1 || /usr/bin/c_rehash "/out"/etc/ssl/certs >/dev/null 2>&1 || true
+	# Falla ruidosamente si el rehash no produjo NADA: un capath sin enlaces es exactamente el bug
+	# que esto viene a cerrar, y sellarlo en silencio lo devolvería intacto.
+	n=$(find "/out"/etc/ssl/certs -name '*.0' | wc -l)
+	[ "$n" -gt 0 ] || { echo "ca-certificates: c_rehash no generó hash-links en /etc/ssl/certs" >&2; exit 1; }
+	echo "ca-certificates: $n hash-links en el capath"
 }
 _abuild_phase
 '''