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 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

⎇ main scripts/labnet.sh Shell · 88 siq'ikuna · 4.3 KB Ñawpa willay ch'uya

crates/netup: red mínima Rust-nativa (Etapa C pieza 5) 6886f810b · sergio ·

1#!/bin/sh
2# labnet.sh — lab de red para probar `netup` (y luego OpenSSH) in-VM con DHCP/DNS/NAT REALES, sin poner
3# la VM en la LAN física (el host sale por WiFi, que no se puede bridgear a L2).
4#
5# Modelo TAP DIRECTO (sin bridge): para UNA VM no hace falta bridge. El host pone su IP en el tap
6# (192.168.100.1/24) y corre dnsmasq escuchando ahí; la VM y el host son pares L2 sobre el tap. Esto
7# evita la sutileza del Linux bridge (broadcast entregado localmente desde un puerto con skb_iif =
8# puerto, que el SO_BINDTODEVICE de dnsmasq al bridge no matchea ⇒ no recibía el DISCOVER).
9#
10# Da DHCP+DNS reales (dnsmasq) + salida a internet por NAT hacia el uplink. Ejercita exactamente los
11# code paths de netup: netlink real, DHCP DISCOVER/OFFER/REQUEST/ACK reales, ruta + DNS reales.
12#
13# REQUIERE ROOT.  Levantar:  sudo sh scripts/labnet.sh up        Bajar:  sudo sh scripts/labnet.sh down
14# El tap queda owned por $LAB_USER ⇒ QEMU (no-root) lo abre.
15#
16# Variables: TAP (def hmtap0)  SUBNET (def 192.168.100)  UPLINK (def wlan0)
17#            LAB_USER (dueño del tap, def $SUDO_USER)  DNS_UP (upstream DNS, def 192.168.1.1)
18set -eu
19TAP="${TAP:-hmtap0}"
20SUBNET="${SUBNET:-192.168.100}"
21UPLINK="${UPLINK:-wlan0}"
22LAB_USER="${LAB_USER:-${SUDO_USER:-root}}"
23DNS_UP="${DNS_UP:-192.168.1.1}"
24PIDF="/run/hmdnsmasq.pid"
25
26[ "$(id -u)" = 0 ] || { echo "labnet: requiere root (sudo sh scripts/labnet.sh $*)" >&2; exit 1; }
27
28fw_clean() {  # quita las reglas "hmlab" que insertamos en el firewall del host
29    for ch in input forward; do
30        while h=$(nft -a list chain inet filter "$ch" 2>/dev/null | awk '/comment "hmlab"/{print $NF; exit}'); [ -n "${h:-}" ]; do
31            nft delete rule inet filter "$ch" handle "$h" 2>/dev/null || break
32        done
33    done
34}
35
36up() {
37    echo "==> tap $TAP ($SUBNET.1/24, owner $LAB_USER) — modelo tap directo, sin bridge"
38    # auto-limpieza de estado viejo (bridge de versiones previas + tap que pudo quedar enslaved)
39    ip link del hmbr0 2>/dev/null || true
40    ip link del "$TAP" 2>/dev/null || true
41    ip tuntap add dev "$TAP" mode tap user "$LAB_USER"
42    ip addr replace "$SUBNET.1/24" dev "$TAP"
43    ip link set "$TAP" up
44
45    echo "==> forwarding + NAT (nftables) $SUBNET.0/24 → $UPLINK"
46    sysctl -wq net.ipv4.ip_forward=1
47    nft list table ip hmnat >/dev/null 2>&1 || nft add table ip hmnat
48    nft flush table ip hmnat
49    nft add chain ip hmnat hmpost '{ type nat hook postrouting priority 100 ; }'
50    nft add rule ip hmnat hmpost ip saddr "$SUBNET.0/24" oifname "$UPLINK" masquerade
51
52    # El host tiene su PROPIO firewall (inet filter, policy drop en input/forward). Insertamos accepts
53    # ACOTADOS al tap del lab DENTRO de inet filter (al tope, vía `insert`), reversibles por su comment
54    # "hmlab". input: el DISCOVER llega a dnsmasq. forward: el NAT VM→internet pasa.
55    if nft list chain inet filter input >/dev/null 2>&1; then
56        echo "==> permitir $TAP en el firewall del host (inet filter input/forward)"
57        fw_clean
58        nft insert rule inet filter input   iifname "$TAP" accept comment "hmlab"
59        nft insert rule inet filter forward iifname "$TAP" accept comment "hmlab"
60        nft insert rule inet filter forward oifname "$TAP" accept comment "hmlab"
61    fi
62
63    echo "==> dnsmasq (DHCP $SUBNET.50-150 + DNS→$DNS_UP) en $TAP"
64    [ -f "$PIDF" ] && kill "$(cat "$PIDF")" 2>/dev/null || true
65    dnsmasq --interface="$TAP" --bind-interfaces --except-interface=lo \
66        --dhcp-range="$SUBNET.50,$SUBNET.150,12h" --dhcp-authoritative \
67        --dhcp-option=3,"$SUBNET.1" --dhcp-option=6,"$SUBNET.1" \
68        --listen-address="$SUBNET.1" --no-resolv --server="$DNS_UP" \
69        --dhcp-leasefile=/tmp/hmdnsmasq.leases \
70        --pid-file="$PIDF" --log-dhcp --log-facility=/tmp/hmdnsmasq.log
71    chmod 644 /tmp/hmdnsmasq.log /tmp/hmdnsmasq.leases 2>/dev/null || true
72    echo "==> listo. QEMU: -netdev tap,id=n0,ifname=$TAP,script=no,downscript=no -device e1000,netdev=n0"
73}
74
75down() {
76    echo "==> teardown"
77    [ -f "$PIDF" ] && kill "$(cat "$PIDF")" 2>/dev/null && rm -f "$PIDF" || true
78    nft delete table ip hmnat 2>/dev/null || true
79    fw_clean
80    ip link del "$TAP" 2>/dev/null || true
81    echo "==> red del lab desmontada"
82}
83
84case "${1:-}" in
85    up) up ;;
86    down) down ;;
87    *) echo "uso: sudo sh scripts/labnet.sh {up|down}" >&2; exit 1 ;;
88esac