receta: squid 7.7 entra al corpus — y el `--export-dynamic` que desactivaba el estático
`b3:54070b26…`, 8,8 M, **estático de verdad** (binario y los tres helpers), y probado con la CONFIG REAL de produccion: parsea sin FATAL, tunela `CONNECT claude.ai` y `CONNECT api.anthropic.com` con TCP_TUNNEL/200, y su `basic_ncsa_auth` lee el `passwd` de los tres usuarios (control negativo: con una clave mala contesta `ERR Wrong password`). Es la respuesta definitiva a lo de ayer: el proxy se levanto primero en una jaula qorpa porque estaba EN USO y eso lo destrabo en minutos, pero squid es C++ y el lab lo construye. La diferencia con php-fpm importa: PHP no queremos que entre al corpus, squid si. ⚠ LA FUENTE NO SALE DE squid-cache.org: esa URL devuelve **200 con una pagina HTML de 8985 bytes**, no el tarball. Pinear su sha256 habria anclado la receta a una pagina de error. Va el release de GitHub, que ademas trae `configure` ya generado. 🧨 EL MURO, y es del lab: el primer sellado salio con `usr/sbin/squid` **dinamico y `NEEDED libc.so`** mientras sus helpers salian estaticos — o sea inerte en cualquier imagen sin cargador ([[needed-colgante-libstdcxx]]) pese a `link = "static"`. La cadena: `squid_LDFLAGS` trae `-export-dynamic` (para modulos eCAP, que estan apagados) ⇒ **el wrapper del lab quita `-static` de cualquier enlace que mencione `--export-dynamic`**, a proposito, para poder enlazar las `.so` dlopen-ables de Python y companhia. Y no alcanza con sacarlo de la variable: **libtool lo vuelve a anhadir solo** en cuanto hay un `-dlopen`. Se vacia `export_dynamic_flag_spec` en el `libtool` GENERADO (local al build, sin tocar la fuente) y con guarda: si el campo no aparece, aborta — un `sed` que no acierta deja pasar el problema y el binario sale dinamico sin que nada falle. ⚠⚠ Y `-dlopen force` NO sobra, aunque lo parezca: vaciar `squid_LDFLAGS` entero rompe el enlace con `undefined symbol: lt__PROGRAM__LTX_preloaded_symbols`, que emite el propio libtool **porque hay un `-dlopen`**. De los dos flags, el que estorba es uno solo. Distinguirlos costo un build; adivinar cuesta lo mismo y no ensenha nada. Declarado en `perfil.servidor` como paquete Y en `servicios`, con su `[[user]] proxy` y su `[[service]]` (SDD 30) — que comprueba la config del sitio y la cuenta, y sale 78 nombrando cual falta en vez de dejar un bucle de reinicios. El hash NO cambio al declararlos: `[[user]]` y `[[service]]` estan fuera de `hash_inputs`. 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.
2 qillqakuna · +130 −1
- docs/state/targets.toml +7 −1
- recipes/squid.toml +123 −0
diff --git a/docs/state/targets.toml b/docs/state/targets.toml
index e6087034..c6d170ff 100644
--- a/docs/state/targets.toml
+++ b/docs/state/targets.toml
@@ -1346,6 +1346,12 @@ paquetes = [
# sale 78 si el repo no existe. Una caja que se inventa su identidad soberana al arrancar es peor
# que una caja sin peer.
"minga",
+ # `squid` (2026-09-15): el proxy de salida de gioser, que es lo que la mudanza tiene que PRODUCIR
+ # como receta y no sólo mover (§6.2). Es un servicio con gente encima —tres usuarios autenticados
+ # y 40 IPs en la ACL— y hasta hoy corría sobre binarios de Artix que nadie sabría reconstruir.
+ # Su config (el `squid.conf`, el `passwd` y las dos ACL) es dato del SITIO y viaja con la mudanza,
+ # no con el paquete: el servicio arranca sólo si está, y si no sale 78 diciéndolo.
+ "squid",
# `rust-toolchain-bin` (2026-09-14): el compilador de Rust. Va en `servidor` y NO en `base` por
# tamaño —799 M— y porque una imagen de escritorio no compila nada; la caja que sirve el repo y
# construye sí. Es el paso 1 de tres: prebuilt ajeno (`foreign`) para desbloquear hoy; luego rustc
@@ -1403,4 +1409,4 @@ paquetes = [
# `gitea` en `/etc/passwd`— y sale con 78 si falta alguna. Es a propósito: las dos vienen con los
# datos de la mudanza, y un gitea que arranca sin su config ofrece el asistente de «crear
# administrador» a quien pase. Hasta que la mudanza traiga ambas, este servicio NO levanta y lo dice.
-servicios = ["sshd", "gitea", "caddy", "minga"]
+servicios = ["sshd", "gitea", "caddy", "minga", "squid"]
diff --git a/recipes/squid.toml b/recipes/squid.toml
new file mode 100644
index 00000000..4d246b7d
--- /dev/null
+++ b/recipes/squid.toml
@@ -0,0 +1,123 @@
+# squid 7.7 — el proxy de salida (forward proxy) con autenticación básica y ACLs por IP.
+#
+# ── POR QUÉ ENTRA AL CORPUS (SDD 28 §6.2 y §6.27) ──────────────────────────────────────────────
+# Es uno de los servicios que la mudanza de gioser tiene que PRODUCIR como receta, no sólo mover:
+# en la caja vieja corre sobre binarios de Artix y nadie sabría reconstruirlo. El 2026-09-15 se
+# levantó primero dentro de una jaula `qorpa` porque estaba en uso —`CONNECT api.anthropic.com` y
+# `claude.ai` en el minuto anterior— y eso lo destrabó en minutos; esta receta es la respuesta
+# definitiva, y cuando esté proyectada la instancia se tira. La diferencia con `php-fpm`, que se
+# queda enjaulado para siempre, es que squid es C++ y el lab lo construye.
+#
+# ── LA FUENTE VIENE DE GITHUB, Y NO ES CAPRICHO ────────────────────────────────────────────────
+# `https://www.squid-cache.org/Versions/v7/squid-7.7.tar.xz` **devuelve 200 con una página HTML de
+# 8985 bytes**, no el tarball. Un `sha256` sobre eso habría quedado pineado a una página de error,
+# que es la forma más tonta de anclar una fuente. El release de GitHub sí trae el tarball de
+# distribución (con `configure` ya generado: no hace falta autoreconf ni autotools del lab).
+# La URL es locator y no entra en `hash_inputs` (ADR 0013 §1) ⇒ espejarla después es gratis.
+#
+# ── LAS PERILLAS, Y POR QUÉ CADA GRUPO ─────────────────────────────────────────────────────────
+# · `--enable-auth-basic=NCSA` y nada más de auth: la config de producción usa exactamente
+# `basic_ncsa_auth` contra un fichero `passwd`. Negotiate/NTLM/Digest arrastran krb5, SASL y LDAP.
+# · `--without-openssl`: el proxy no hace ssl-bump ni `https_port`; un `CONNECT` es un túnel ciego y
+# no necesita TLS de este lado. Menos superficie y una dep menos.
+# · `--disable-arch-native`: el default ya es ese, y se escribe igual porque es la perilla que
+# hornearía la ISA del builder — el SIGILL en otra CPU que ya costó una vez (ver la nota de
+# `-mcpu=baseline` en el sandbox).
+# · `--disable-eui` / `--disable-snmp` / `--disable-wccp*` / `--disable-htcp` / `--disable-icap-client`:
+# protocolos de red que este proxy no habla. `eui` además quiere las cabeceras de ARP del sistema.
+# · `--disable-translation`: las páginas de error localizadas se GENERAN con `po2html`, que el lab
+# no trae. El inglés sale igual.
+name = "squid"
+version = "7.7"
+license = "GPL-2.0-or-later"
+
+[source]
+tarball = "https://github.com/squid-cache/squid/releases/download/SQUID_7_7/squid-7.7.tar.xz"
+sha256 = "e3bd613b91b1c498ec2992276063342a85cd6edddd5521294e04f44bc055da9b"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "static"
+# Split de la info de depuración (SDD 23): squid sin strip son decenas de megas de DWARF.
+strip_debug = true
+
+[build.phases]
+configure = '''
+./configure --build=$CBUILD --host=$CHOST --prefix=/usr \
+ --sysconfdir=/etc/squid --libexecdir=/usr/lib/squid --datadir=/usr/share/squid \
+ --localstatedir=/var --with-logdir=/var/log/squid --with-swapdir=/var/cache/squid \
+ --with-pidfile=/run/squid.pid --with-default-user=proxy \
+ --disable-arch-native --disable-strict-error-checking --disable-translation \
+ --enable-auth-basic=NCSA --disable-auth-digest --disable-auth-negotiate --disable-auth-ntlm \
+ --disable-external-acl-helpers --disable-url-rewrite-helpers --disable-storeid-rewrite-helpers \
+ --disable-log-daemon-helpers --disable-security-cert-validators --disable-security-cert-genrators \
+ --disable-icap-client --disable-snmp --disable-wccp --disable-wccpv2 --disable-eui --disable-htcp \
+ --without-openssl --without-gnutls --without-nettle --without-cap --without-systemd \
+ --without-ldap --without-sasl --without-gss --without-mit-krb5 --without-heimdal-krb5 \
+ --without-tdb --without-cppunit
+# ⚠ EL `libtool` GENERADO AÑADE `--export-dynamic` SOLO, y eso desactiva el enlace estático.
+# Ver la nota larga de `compile`: el wrapper del lab quita `-static` de cualquier enlace que
+# mencione `--export-dynamic`, y libtool lo añade por su cuenta en cuanto hay un `-dlopen` —o sea
+# que no alcanza con sacarlo de `squid_LDFLAGS`. Se vacía la plantilla en el `libtool` generado,
+# que es local a este build y no toca la fuente. Con guarda: si el campo no aparece, ABORTA, porque
+# un `sed` que no acierta deja pasar el problema y el binario sale dinámico sin que nada falle.
+grep -q '^export_dynamic_flag_spec=' libtool || {
+ echo 'squid: el libtool generado no declara export_dynamic_flag_spec — revisar antes de sellar' >&2
+ exit 1
+}
+sed -i 's|^export_dynamic_flag_spec=.*|export_dynamic_flag_spec=|' libtool
+'''
+# ── DOS COSAS EN LA LÍNEA DE ENLACE, Y LA SEGUNDA SÓLO SE VE MIRANDO EL BINARIO ────────────────
+# `-all-static`: squid enlaza CON LIBTOOL, que lee el `-static` del lab como «preferí mis `.a`» y
+# NO como flag del enlazador ⇒ `link = "static"` se ignoraría en silencio y el binario saldría
+# dinámico. Es el patrón de curl/jq/parted, y la trampa está medida en
+# [[link-static-mentira-libtool]]. Va también en `install` porque libtool RELINKEA al instalar.
+#
+# ⚠ `squid_LDFLAGS=`: el `Makefile.am` de squid declara `squid_LDFLAGS = -export-dynamic -dlopen
+# force` (línea 562) para los módulos de eCAP, que acá están apagados. Y **el wrapper del lab quita
+# `-static` de cualquier enlace que mencione `--export-dynamic`** —a propósito, para que las
+# extensiones `.so` de Python y compañía se puedan enlazar—, así que ese flag de squid desactivaba
+# el estático del proyecto entero. MEDIDO: el primer sellado dio un `squid` **dinámico con
+# `NEEDED libc.so`** mientras sus helpers salían estáticos, lo que además lo hace inerte en
+# cualquier imagen sin cargador ([[needed-colgante-libstdcxx]]). Redefinir la variable por línea de
+# comandos es la vía de automake para anular flags por-objetivo sin parchear la fuente.
+#
+# ⚠⚠ Y se queda `-dlopen force`, que parecía sobrar: vaciar la variable ENTERA rompe el enlace con
+# `undefined symbol: lt__PROGRAM__LTX_preloaded_symbols`. Ese símbolo lo emite el propio libtool en
+# el `squidS.o` que genera **porque hay un `-dlopen`**, y `libltdlc.a` lo referencia siempre. O sea:
+# de los dos flags, el que estorba es `-export-dynamic` y el otro es estructural. Sale una sola
+# medición distinguirlos, y adivinar cuesta un build entero.
+compile = 'make -j"$(nproc)" LDFLAGS="-all-static -no-pie" squid_LDFLAGS="-dlopen force"'
+install = 'make DESTDIR=/out install LDFLAGS="-all-static -no-pie" squid_LDFLAGS="-dlopen force"'
+
+[deps]
+build = ["binutils"]
+
+# ── LA CUENTA (SDD 30) ──────────────────────────────────────────────────────────────────────────
+# Un proxy que atiende la red pública no corre como root: squid baja de privilegio al usuario que
+# le fijó `--with-default-user`. Si la cuenta no existe, el `setuid` falla y squid muere; por eso el
+# servicio de abajo lo comprueba y sale 78 nombrándolo, en vez de dejar un bucle de reinicios.
+[[user]]
+name = "proxy"
+uid = 968
+home = "/var/cache/squid"
+
+# ── EL SERVICIO QUE ESTE PAQUETE TRAE (SDD 30) ──────────────────────────────────────────────────
+# Fuera de `hash_inputs`: declarar esto NO re-hashea squid.
+#
+# ⚠ La CONFIG no viene acá y es a propósito: `squid.conf`, el `passwd` de los usuarios y las ACL de
+# IPs son datos del SITIO —en gioser son 412 K con tres cuentas y 40 IPs autorizadas— y viajan con
+# la mudanza, no con el paquete. El servicio arranca sólo si están, y lo dice.
+#
+# ⚠ `-N` (sin daemonizar) porque el supervisor es arje: un servicio que se va a segundo plano deja
+# al init cuidando un proceso que ya murió. `-YC` es lo que corría en gioser y se conserva.
+[[service]]
+label = "squid"
+id = "01M2EKDA00SQ7D5X2KB9WHNT4P"
+exec = "/bin/busybox"
+argv = ["sh", "-c", "test -f /etc/squid/squid.conf || { echo 'squid: falta /etc/squid/squid.conf — es config del SITIO (con su `passwd` y sus ACL), viene con la mudanza y no con el paquete' >&2; exit 78; }; /bin/grep -q '^proxy:' /etc/passwd || { echo 'squid: no existe el usuario `proxy` en /etc/passwd y squid NO se queda como root' >&2; exit 78; }; mkdir -p /var/log/squid /var/cache/squid; chown proxy:proxy /var/log/squid /var/cache/squid; exec /usr/sbin/squid -YC -f /etc/squid/squid.conf -N"]
+envp = [["PATH", "/usr/bin:/bin"], ["HOME", "/var/cache/squid"], ["USER", "proxy"]]
+networking = "full"
+cgroup = "arje.slice/squid"
+restart = { initial_ms = 1000, max_ms = 30000 }