#!/bin/sh # harkaq-farm-setup.sh — deja un worker de la granja listo para barrer con harkaq. # # La granja es el compilador continuo (SDD 16 §4.8), así que esto tiene que ser reproducible y # no un copy-paste. Idempotente: re-correrlo sobre un worker ya provisto no rompe nada. # # Precondición dura: la golden 408909310 (kernel 6.17 ⇒ Landlock ABI 7). Con la vieja (6.8, ABI 4) # el barrido correría y daría `SinEvidencia` en TODO — que es lo que D7 manda y lo que no sirve # para medir. Por eso lo primero que hace es verificar el ABI y abortar si no llega. set -eu IP="${1:?uso: harkaq-farm-setup.sh }" KEY="${SSH_KEY:-$HOME/.ssh/github5}" REMOTE="${REMOTE:-/opt/takana}" SSH="ssh -i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes" HERE="$(cd "$(dirname "$0")" && pwd)" echo "== 1/4 verificando el ABI (gate: >=7 o no hay evidencia)" abi=$($SSH "root@$IP" 'python3 -c " import ctypes; libc=ctypes.CDLL(\"libc.so.6\",use_errno=True) print(libc.syscall(444,None,0,1))"' 2>/dev/null | tr -d '\r') echo " kernel: $($SSH "root@$IP" uname -r 2>/dev/null) → Landlock ABI = $abi" if [ "${abi:-0}" -lt 7 ]; then echo " ABORTO: ABI $abi < 7 ⇒ el kernel no audita denegaciones. Todos los veredictos" echo " saldrían SinEvidencia. ¿El worker salió de la golden 408909310?" exit 4 fi echo "== 2/4 copiando y compilando las piezas" $SSH "root@$IP" "mkdir -p /root/.cache/harkaq $REMOTE/scripts/harkaq" scp -q -i "$KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ "$HERE"/harkaq-uapi.h "$HERE"/harkaq-audit.c "$HERE"/harkaq-exec.c \ "$HERE"/harkaq-policy.sh "$HERE"/harkaq-verdict.py "$HERE"/harkaq-suggest.py \ "$HERE"/harkaq-base-closure.py "$HERE"/fase2-barrido.sh \ "root@$IP:$REMOTE/scripts/harkaq/" # harkaq-uapi.h no es una comodidad: el worker tiene headers 6.8 sobre kernel 6.17 y NO define # ni AUDIT_LANDLOCK_ACCESS. Sin él el lector filtraría por un número que no conoce y vería cero # denegaciones — el falso `Hermetico` de D9, por headers viejos (§4.8). $SSH "root@$IP" "cd $REMOTE/scripts/harkaq && chmod +x *.sh *.py && gcc -O1 -Wall -o /root/.cache/harkaq/harkaq-audit harkaq-audit.c && gcc -O1 -Wall -static -o /root/.cache/harkaq/harkaq-exec harkaq-exec.c && echo ' compiladas ✓'" echo "== 3/4 derivando el runtime base DEL ROOTFS DEL WORKER" # El runtime base es POR ROOTFS (§4.3) — derivarlo del rootfs del worker, no copiar el del # laptop: los sonames de las libs (libz.so.1.3.2, …) dependen de la versión de Alpine que tenga. $SSH "root@$IP" "cd $REMOTE && python3 scripts/harkaq/harkaq-base-closure.py .dev-fs/alpine \ /bin/sh /bin/busybox /bin/bash /bin/coreutils /usr/bin/env 2>/dev/null \ > /root/.cache/harkaq/base.policy printf 'ro /usr/lib/os-release\n' >> /root/.cache/harkaq/base.policy # Sondas de compilador de Alpine: se DENIEGAN y se clasifican (D3). Concederlas dejaría a # zig/configure usar el gcc de Alpine por detrás — justo lo que la campaña matar-gcc caza. for p in /usr/bin/gcc /usr/bin/ldd /usr/bin/c89 /usr/bin/c99 /usr/bin/cpp /usr/bin/getent; do printf '# expect %s\n' \"\$p\" >> /root/.cache/harkaq/base.policy done echo \" runtime base: \$(grep -c '^ro ' /root/.cache/harkaq/base.policy) reglas + \$(grep -c '^# expect' /root/.cache/harkaq/base.policy) esperadas\"" echo "== 4/4 comprobando la cadena de evidencia de punta a punta" $SSH "root@$IP" "cd $REMOTE && cargo build -q -p takana-cli 2>/dev/null || true; ls target/debug/hammer >/dev/null 2>&1 && echo ' hammer-cli listo ✓' || echo ' OJO: falta target/debug/hammer (cargo build -p takana-cli)'" cat <