🧨 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
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user