diff --git a/2026/2026-09-19--goa-regio-ng-login-health+monitoring.md b/2026/2026-09-19--goa-regio-ng-login-health+monitoring.md deleted file mode 100644 index 25b8b23..0000000 --- a/2026/2026-09-19--goa-regio-ng-login-health+monitoring.md +++ /dev/null @@ -1,38 +0,0 @@ -# 2026-09-19 — GOA single-CTR: login-health + monitoring - -## Why - -`koopa-login-health` FAIL×3 on dead `taler-hacktivism*` + WARN `koopa-tor-relay`. -Live stack is **`goa-regio-ng`** (pasta 9010–9015) + host **`tor.service`** (ORPort 8080). - -## Live SoT (hernani@koopa) - -| Piece | Detail | -|-------|--------| -| GOA CTR | `goa-regio-ng` — image `localhost/goa-regio-ng:empty-current` | -| Scripts | `~/scripts/taler-shared/goa-regio-ng/` · `goa-all-in-one.sh` | -| Bak | `~/backups/goa/current` | -| Landings | host `/var/www/*-landing/` + `~/goa-landing-deploy` · Caddy outside CTR | -| Tor | host `tor.service` — **not** container `koopa-tor-relay` | -| Forgejo | `:9024/:9200` · edge Caddy `:9000/:9001` | - -## Repo changes (magikoopa, no push yet) - -**koopa-admin-log** -- `scripts/login-health/`: CRITICAL/EXPECT → `goa-regio-ng` (+ forgejo); drop legacy + tor-relay; host `tor.service` check; probes 9010–9012 -- delete `host/overview/{LIVE,services}.*` · delete `configs/tor/*` -- rewrite `host/tor/README.md` · shorten README / ports / koopa-setup / login-health README -- ISSUES I-07 → host Tor SoT - -**elelmon + taler-monitoring** (EQ scripts mirrored) -- BANK=EX=MER=`goa-regio-ng`; drop nginx-in-bank; host stats.json fallback -- `check_{server,inside,urls,versions,e2e,sanity}.sh` · `metrics.sh` · `lib.sh` · docs - -## Verify (after deploy on koopa — Freigabe) - -```bash -koopa-login-health show -v -# expect: goa-regio-ng OK · no taler-hacktivism* · tor.service OK|WARN -``` - -STATE dir name `taler-hacktivism-monitoring` kept (host-agent path, not CTR). diff --git a/ISSUES.md b/ISSUES.md index d23c743..efb5921 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -12,7 +12,7 @@ Stand **2026-07-18** (koopa, live). Keine Secrets. | [I-04](#i-2026-07-16-04) | low | open | Stray `kind_taussig` | | [I-05](#i-2026-07-16-05) | low | open | Alte exited Podman-Container | | [I-06](#i-2026-07-16-06) | low–medium | open | Nym HTTP API `*:9080` | -| [I-07](#i-2026-07-16-07) | medium | **fixed** | Tor = host `tor.service` (not container) | +| [I-07](#i-2026-07-16-07) | medium | **fixed** | Tor host vs `koopa-tor-relay` | | [I-08](#i-2026-07-17-08) | medium | open | Landing-stats → standalone `taler-landing-stats` | | [I-09](#i-2026-07-18-09) | high | open | Monitoring-HTML öffentlich: Caddy/www (code 21) | @@ -134,18 +134,24 @@ Hinweis: `nym-node` startet intern mit `--http-bind-address [::]:8080` (Containe ### I-2026-07-16-07 -**Tor = host `tor.service` (ORPort 8080)** -Severity: medium · Host: koopa · Status: **fixed** (SoT 2026-09) +**`koopa-tor-relay` vs host `tor.service` (Port-Clash)** +Severity: medium · Host: koopa · Status: **fixed** 2026-07-16 -**Live:** host **`tor.service`** · ORPort **8080** · ControlPort **9051** · non-exit. -Legacy CTR `koopa-tor-relay` / `configs/tor/` removed from inventory (git history keeps them). +**War:** Nach Reboot crash-loopte `koopa-tor-relay` — Host-`tor.service` hielt **8080**/**9051**. +**Soll:** nur Container (`KoopaRelay`, ORPort **8080**, VeciGate WAN→koopa:8080). + +**Fix:** Host-Tor gestoppt/disabled; ggf. hängenden Prozess gekillt; User-Unit: ```bash -systemctl status tor +sudo systemctl disable --now tor +sudo systemctl mask tor # optional +systemctl --user enable --now container-koopa-tor-relay.service ss -lntp | grep -E '8080|9051' -# login-health: WARN if tor.service not active +podman ps --filter name=koopa-tor-relay ``` +**Live (nach Fix):** Host-`tor` inactive/disabled; `koopa-tor-relay` Up; 8080 + 127.0.0.1:9051 vom Relay-Prozess. + --- ### I-2026-07-17-08 @@ -171,4 +177,4 @@ Severity: medium · Host: koopa · Status: open · **TODO (noch nicht umsetzen a - Prod-Container mit Boot-Autostart: Up - Taler-Ports 9010–9015 antworten (401/302 OK) - Linger=yes, container-*-Units enabled -- Tor-OR: host `tor.service` (I-07) +- Tor-OR: Container-Pfad (I-07 fixed) diff --git a/README.md b/README.md index 916b125..031eff9 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ Ops log and config mirror for host **koopa** (openSUSE Tumbleweed). ## FIND / setup entry -Plain file **`koopa-setup`** — lab + host pointers (goa-regio-ng, ports, daylogs). Start there. +Plain file **`koopa-setup`** — lab + host pointers (mytops-local, regio-ng, +ports, daylogs). Start there before hunting under `configs/` / `2026/`. ## Open issues @@ -24,35 +25,78 @@ Plain file **`koopa-setup`** — lab + host pointers (goa-regio-ng, ports, daylo Hosted on **Forgejo rootless** (this host). See `2026/2026-07-10--admin-log-origin-forgejo.md`. +## FIND / setup entry + +Plain file **`koopa-setup`** — lab + host pointers (mytops-local, regio-ng, +ports, daylogs). Start there before hunting under `configs/` / `2026/`. + ## Layout ``` koopa-setup # FIND: lab/host setup pointers -host/ # openSUSE host-level (caddy, tor, systemd, …) -configs/ # mirrored app configs (caddy, forgejo, …) -scripts/ # login-health, GOA helpers, … - login-health/ # SSH login snapshot - taler-shared/goa-regio-ng/ # live GOA SoT +host/ # openSUSE host-level config + overview + overview/services.md # graphical service map + systemd/ firewalld/ caddy/ network/ +configs/ # mirrored app configs (caddy, taler, forgejo, …) + taler-hacktivism/ # merchant container taler-hacktivism + taler-hacktivism-bank/ # bank container (image …-banking) + taler-exchange/ # exchange conf (inside ansible container) + taler-exchange-ansible/ # container taler-hacktivism-exchange-ansible + forgejo/ # rootless git.hacktivism.ch + castopod/ bonfire/ lemmy/ prime/ # compose mirrors (no secret values) + tops/ # koopa-tops-ng1…ng3 + autostart unit + tor/ # KoopaRelay ORPort 8080 +scripts/ # merchant, exchange, monitoring helpers + taler-merchant/ # merchant-model start scripts + taler-exchange/ # same model; archive/ = greenfield bootstrap 2026/ # day logs + dated topic notes ``` -## Live GOA + public stack +## Live containers (podman) -| Name | Role | Host ports | -|------|------|------------| -| **`goa-regio-ng`** | bank + exchange + merchant (one CTR, pasta) | **9010–9012** APIs · **9013–9015** landings (host nginx) | +**Authoritative snapshot of host koopa:** [`host/overview/LIVE.md`](host/overview/LIVE.md) (refreshed from live). + +| Name (podman) | Role | Host port | +|---------------|------|-----------| +| `taler-hacktivism` | merchant | **9010** (+ landing **9015**) | +| **`taler-hacktivism-exchange-ansible`** | exchange (Ansible/systemd) | **9011** (+ landing **9014**) | +| `taler-hacktivism-bank` | libeufin-bank (GOA) | **9012** (+ landing **9013**) | +| `koopa-castopod` (+ mariadb/redis) | Castopod | **9020** | +| `koopa-bonfire` (+ postgres) | Bonfire | **9021** | +| `koopa-lemmy-proxy` (+ lemmy/ui/pictrs/db) | Lemmy | **9026** | +| `koopa-prime-jellyfin` | Jellyfin | **9022** | +| `koopa-prime-qbittorrent` | qBittorrent | **9023** | | `koopa-forgejo` (+ postgres) | Forgejo rootless | **9024** + SSH **9200** | -| `koopa-castopod` / bonfire / lemmy / decidim / … | optional apps | **9020+** | -| `koopa-tops-ng1`…`ng3` | static nginx | **9090–9092** | -| host **`tor.service`** | Tor relay | ORPort **8080** · ControlPort **9051** | +| `koopa-tops-ng1` … `ng3` | static nginx | **9090**–**9092** | -Start GOA: `scripts/taler-shared/goa-regio-ng/` · bak `~/backups/goa/current` · landings `~/goa-landing-deploy`. -Edge: Caddy **9000/9001** → 127.0.0.1 backends. -Login snapshot: `scripts/login-health/` (`koopa-login-health`). +Start model (Taler merchant/bank): **root** `start_base_services_*` → `/usr/local/bin/start_*.sh`. +Start model (exchange): `~/ansible-taler-exchange/` → `run-container-koopa.sh` + `deploy-hacktivism-goa.sh`. +Start model (user apps): `hernani` → `cd ~/koopa-* && podman-compose up -d`. +Start model (tops): user unit `container-koopa-tops.service` (linger). +Public hosts: `taler.` / `exchange.` / `bank.` / `castopod.` / `bonfire.` / `prime.` / `bt.` / **`git.hacktivism.ch`** / `lemmy.` / `tops.ng1`–`ng3`.hacktivism.ch +(Caddy → 9010–9015 / 9020–**9026** / **9090–9092**; git-SSH host **9200** direct). + +Service **details**: `configs/taler-hacktivism*`, `configs/taler-exchange*`, `configs/forgejo/`, `configs/tops/`, `scripts/*`. +Host-wide picture: **`host/overview/services.md`**. Port table: **`configs/ports.md`**. -Tor: **`host/tor/README.md`**. Router: **`../vecigate-admin-log`**. -**Benchmarks:** `benchmarks/` -**Forgejo:** `2026/2026-07-10--forgejo-rootless.md` → https://git.hacktivism.ch/ +**Benchmarks** (drive from the local machine, measure on koopa): **`benchmarks/`** +→ amount ladder: `benchmarks/amount-ladder/`. + +**Exchange snapshot/restore (GOA, local images only):** +→ `2026/2026-07-09--exchange-snapshot-and-restore.md` + +**Exchange `/keys` + Wire + bank account (diagram):** +`configs/taler-exchange/README.md` (section “/keys, Wire and Account”). + +**Castopod (stack/accounts/boot — not podcast content):** +`2026/2026-07-09--castopod-content.md` → https://castopod.hacktivism.ch/ + +**Bonfire FEDERATE + guest public (2026-07-10):** +`2026/2026-07-10--bonfire-federate.md` → https://bonfire.hacktivism.ch/ +(ground zero: `2026/2026-07-09--bonfire-ground-zero.md`) + +**Forgejo rootless (git.hacktivism.ch, no free registration, SSH :9200):** +`2026/2026-07-10--forgejo-rootless.md` → https://git.hacktivism.ch/ diff --git a/configs/ports.md b/configs/ports.md index 70288db..36ccd88 100644 --- a/configs/ports.md +++ b/configs/ports.md @@ -1,4 +1,4 @@ -# Port map (koopa) +# Port map (see also host/overview/services.md) | Port | Role | |------|------| @@ -7,43 +7,45 @@ | 443 | systemd `https-proxy.socket` → Caddy **9001** | | 9000 | Caddy HTTP + ACME webroot | | 9001 | Caddy HTTPS (vhosts) | -| **9010** | `goa-regio-ng` merchant API (HTTPS in CTR) | -| **9011** | `goa-regio-ng` exchange | -| **9012** | `goa-regio-ng` libeufin-bank | -| **9013–9015** | bank / exchange / merchant public landings (host nginx) | -| 9020 | `koopa-castopod` → `castopod.hacktivism.ch` | -| 9021 | `koopa-bonfire` → `bonfire.hacktivism.ch` | -| 9022 | `koopa-prime` (Jellyfin) → `prime.hacktivism.ch` | -| 9023 | qBittorrent → `bt.hacktivism.ch` | -| **9024** | `koopa-forgejo` (HTTP) → **`git.hacktivism.ch`** | -| **9025** | `koopa-paivana` → `paivana.hacktivism.ch` | -| **9026** | `koopa-lemmy-proxy` → `lemmy.hacktivism.ch` | -| **9027** | `koopa-decidim` → `decidim.hacktivism.ch` | -| **9028** | `koopa-paivana-silverbullet` → `silverbullet.hacktivism.ch` | -| **9029** | `koopa-paivana-galene` → `galene.hacktivism.ch` | -| **9030** | `koopa-paivana-cryptpad` → `cryptpad.hacktivism.ch` | -| **9031** | `koopa-paivana-meet` → `meet.hacktivism.ch` | -| **9032** | `koopa-bbb-front` → `bbb.hacktivism.ch` | -| **9200** | Forgejo git-SSH (host-direct; not Caddy) | -| 9090–9092 | `koopa-tops-ng1`…`ng3` → `tops.ng{1,2,3}.hacktivism.ch` | -| **8080** | host `tor.service` ORPort | -| **9051** | host Tor ControlPort (loopback) | +| 9010 | podman `taler-hacktivism` (merchant) | +| 9011 | podman **`taler-hacktivism-exchange-ansible`** (exchange) | +| 9012 | podman `taler-hacktivism-bank` (libeufin-bank) | +| 9013–9015 | bank / exchange / merchant public landings | +| 9020 | podman `koopa-castopod` → Caddy `castopod.hacktivism.ch` | +| 9021 | podman `koopa-bonfire` → Caddy `bonfire.hacktivism.ch` | +| 9022 | podman `koopa-prime` (Jellyfin) → Caddy `prime.hacktivism.ch` | +| 9023 | podman qBittorrent → Caddy `bt.hacktivism.ch` | +| **9024** | podman **`koopa-forgejo`** (HTTP) → Caddy **`git.hacktivism.ch`** | +| **9025** | podman **`koopa-paivana`** (portal paywall) → Caddy **`paivana.hacktivism.ch`** | +| **9026** | podman **`koopa-lemmy-proxy`** → Caddy **`lemmy.hacktivism.ch`** | +| **9027** | podman **`koopa-decidim`** → Caddy **`decidim.hacktivism.ch`** | +| **9028** | podman **`koopa-paivana-silverbullet`** → Caddy **`silverbullet.hacktivism.ch`** (app backend `172.17.0.1:19128`) | +| **9029** | podman **`koopa-paivana-galene`** → Caddy **`galene.hacktivism.ch`** (app backend `172.17.0.1:19129`; UDP 10000–10099 still Galene) | +| **9030** | podman **`koopa-paivana-cryptpad`** → Caddy **`cryptpad.hacktivism.ch`** (edge backend `172.17.0.1:19130`) | +| **9031** | podman **`koopa-paivana-meet`** → Caddy **`meet.hacktivism.ch`** (app backend `172.17.0.1:19131`) | +| **9032** | podman **`koopa-bbb-front`** (Ubuntu) → Caddy **`bbb.hacktivism.ch`** | +| **9200** | podman **Forgejo git-SSH** (host-direct; not Caddy) | +| 9090–9092 | podman `koopa-tops-ng1` … `ng3` → Caddy `tops.ng{1,2,3}.hacktivism.ch` | +| 8080 | Tor ORPort | VeciGate: WAN **80→9000**, WAN **443→9001**. -Public apps: Caddy on **9001** → 127.0.0.1:{9010–9015, 9020–9032, 9090–9092}. -Git SSH needs **9200/tcp** if exposed to WAN. +Public apps: Caddy vhosts on **9001** → 127.0.0.1:{9010–9015, 9020–9032, 9090–9092}. +Git SSH needs separate NAT/firewall **9200/tcp** if exposed to WAN. +Meet/Galene/BBB media UDP is separate from these HTTP ports. | UDP range | Role | |-----------|------| -| **10000–10099/udp** | Galene WebRTC | +| **10000–10099/udp** | **Galene** WebRTC (host publish + planned VeciGate DNAT → koopa) | +| (TBD) | Meet JVB / BBB media — allocate when Phase‑2 / full BBB leaves park | -| Extra | Role | -|-------|------| -| **1789** | `koopa-nym` mixnet | -| **1790** | `koopa-nym` verloc | -| **9080** | `koopa-nym` HTTP API | -| **9180** | lab `goa-regio-ng` HTTP (loopback; `configs/lab-local/`) | -| **9322** | lab `goa-regio-ng` SSH/ansible (loopback) | -| **8288** | lab `mytops-local` HTTP (loopback) | - -login-health inventory: `scripts/login-health/koopa-login-health.sh`. +| **1789** | podman **`koopa-nym`** mixnet (nym.com nym-node) | +| **1790** | podman **`koopa-nym`** verloc | +| **9080** | podman **`koopa-nym`** HTTP API (mapped from container 8080; Tor keeps **8080**) | +| **9180** | lab **`goa-regio-ng`** HTTP (loopback only; see `configs/lab-local/`) | +| **9322** | lab **`goa-regio-ng`** SSH/ansible (loopback only) | +| **8288** | lab **`mytops-local`** HTTP (loopback only) | +| **19000** | optional nym entry WS (gateway mode) | +| **51822/udp** | optional nym WireGuard (dVPN path) | +| **9180** | lab **`goa-regio-ng`** HTTP (loopback only; see `configs/lab-local/`) | +| **9322** | lab **`goa-regio-ng`** SSH/ansible (loopback only) | +| **8288** | lab **`mytops-local`** HTTP (loopback only) | diff --git a/configs/tor/Containerfile b/configs/tor/Containerfile new file mode 100644 index 0000000..0e1fb31 --- /dev/null +++ b/configs/tor/Containerfile @@ -0,0 +1,18 @@ +# koopa-tor-relay — Tor non-exit relay +# Process is NOT root: debian-tor remapped to uid/gid 1000 for rootless +# podman + host volumes (~/koopa-tor-relay/{data,log} owned by hernani). +# Recreate container with: --user 1000:1000 --userns=keep-id (see README). +FROM docker.io/library/debian:stable-slim +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update \ + && apt-get install -y --no-install-recommends tor nyx ca-certificates tor-geoipdb \ + && rm -rf /var/lib/apt/lists/* \ + && mkdir -p /var/lib/tor /var/log/tor \ + && groupmod --gid 1000 debian-tor \ + && usermod --uid 1000 --gid 1000 debian-tor \ + && chown -R debian-tor:debian-tor /var/lib/tor /var/log/tor \ + && chmod 700 /var/lib/tor +EXPOSE 8080 9051 +USER debian-tor:debian-tor +ENTRYPOINT ["/usr/bin/tor"] +CMD ["-f", "/etc/tor/torrc", "--runasdaemon", "0"] diff --git a/configs/tor/README.md b/configs/tor/README.md new file mode 100644 index 0000000..4f618f6 --- /dev/null +++ b/configs/tor/README.md @@ -0,0 +1,64 @@ +# Tor relay — koopa (`KoopaRelay`) + +Live: **podman** container **`koopa-tor-relay`** (rootless hernani, `--network host`). +Host layout: `~/koopa-tor-relay/{torrc,data,log,build}`. +Mirror in this repo: `configs/tor/`. + +| Setting | Value | +|---------|--------| +| Nickname | `KoopaRelay` | +| Fingerprint | `02C7EECCDF7814FBA2DB1CBAED000D06E8A32EE8` | +| ORPort | **8080** (IPv4 + IPv6; VeciGate WAN DNAT → koopa:8080) | +| ControlPort | **127.0.0.1:9051** | +| ExitRelay | **0** (non-exit) | +| SocksPort | **0** | +| MyFamily | `52BB94DDC1292F950CF728708AC48523E018A718` | +| Bandwidth* | 2000 MBytes rate/burst | +| Image | `localhost/koopa-tor-relay:latest` (Debian stable + tor + nyx) | +| Process user | **non-root** `debian-tor` remapped to **uid/gid 1000** (`USER` in image) | +| Rootless note | recreate with `--user 1000:1000 --userns=keep-id` so `~/koopa-tor-relay/data` (hernani) stays writable | + +## Files + +| File | Role | +|------|------| +| `torrc` | Active policy (mounted read-only into container) | +| `Containerfile` | Image build (tor, nyx, tor-geoipdb); **not** root process | +| `create-container.sh` | Recreate container non-root + host net + volume mounts | +| `migrate-identity.sh` | One-shot copy of `/var/lib/tor` → container data (same identity) | +| `container-koopa-tor-relay.service` | systemd --user unit template | +| `torrc.minimal` / `torrc.sample` | Distro templates (reference) | + +## Ops + +```bash +# build image + recreate non-root container (as hernani) +cd ~/koopa-tor-relay/build # or configs/tor mirror +podman build -t localhost/koopa-tor-relay:latest -f Containerfile . +./create-container.sh # or: bash configs/tor/create-container.sh +podman start koopa-tor-relay +systemctl --user enable --now container-koopa-tor-relay.service + +# status +podman ps --filter name=koopa-tor-relay +podman exec koopa-tor-relay id # expect uid=1000(debian-tor) +systemctl --user status container-koopa-tor-relay +ss -lntp | grep -E '8080|9051' +tail -f ~/koopa-tor-relay/log/notices.log + +# monitor +podman exec -it koopa-tor-relay nyx +``` + +### Cutover (host package → container) + +1. `sudo systemctl stop tor && sudo systemctl disable tor` (prefer `mask` so it never returns) +2. `sudo ~/koopa-tor-relay/migrate-identity.sh` (or copy of this script) +3. `podman start koopa-tor-relay` / user unit enable +4. Confirm fingerprint and ORPort reachability + +Do **not** run host `tor.service` and the container at the same time. + +Monitoring helpers: `scripts/monitoring/tor_*.sh`. +Firewall: `configs/firewalld/public-ports.md` (**8080/tcp**). +Router: `../vecigate-admin-log` (WAN :8080 → koopa). diff --git a/configs/tor/container-koopa-tor-relay.service b/configs/tor/container-koopa-tor-relay.service new file mode 100644 index 0000000..051b56e --- /dev/null +++ b/configs/tor/container-koopa-tor-relay.service @@ -0,0 +1,28 @@ +# container-koopa-tor-relay.service +# Install on koopa as hernani: +# mkdir -p ~/.config/systemd/user +# cp configs/tor/container-koopa-tor-relay.service ~/.config/systemd/user/ +# systemctl --user daemon-reload +# systemctl --user enable --now container-koopa-tor-relay.service +# Requires: loginctl enable-linger hernani (root, once) +# +# autogenerated by Podman 5.8.3 (paths are host-specific; regenerate if container id changes) + +[Unit] +Description=Podman container-koopa-tor-relay.service +Documentation=man:podman-generate-systemd(1) +Wants=network-online.target +After=network-online.target +RequiresMountsFor=/run/user/1000/containers + +[Service] +Environment=PODMAN_SYSTEMD_UNIT=%n +Restart=always +TimeoutStopSec=70 +ExecStart=/usr/bin/podman start koopa-tor-relay +ExecStop=/usr/bin/podman stop -t 10 koopa-tor-relay +ExecStopPost=/usr/bin/podman stop -t 10 koopa-tor-relay +Type=forking + +[Install] +WantedBy=default.target diff --git a/configs/tor/create-container.sh b/configs/tor/create-container.sh new file mode 100755 index 0000000..2f7156a --- /dev/null +++ b/configs/tor/create-container.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Recreate koopa-tor-relay as non-root (uid 1000) under rootless podman keep-id. +# Run as hernani on koopa (not root). Stops/removes existing container first. +set -euo pipefail + +NAME=koopa-tor-relay +IMAGE="${TOR_IMAGE:-localhost/koopa-tor-relay:latest}" +BASE="${KOOPA_TOR_BASE:-$HOME/koopa-tor-relay}" + +if [[ ! -f "$BASE/torrc" ]]; then + echo "ERROR: missing $BASE/torrc" >&2 + exit 1 +fi +mkdir -p "$BASE/data" "$BASE/log" +# Host ownership: hernani (uid 1000) ↔ container debian-tor (uid 1000) via keep-id +chmod 700 "$BASE/data" 2>/dev/null || true + +if podman ps -a --format '{{.Names}}' | grep -qx "$NAME"; then + podman stop "$NAME" 2>/dev/null || true + podman rm "$NAME" +fi + +podman create \ + --name "$NAME" \ + --replace \ + --network host \ + --user 1000:1000 \ + --userns keep-id \ + --restart unless-stopped \ + -v "$BASE/torrc:/etc/tor/torrc:ro" \ + -v "$BASE/data:/var/lib/tor:Z" \ + -v "$BASE/log:/var/log/tor:Z" \ + --label org.hacktivism.service=tor \ + --label org.hacktivism.container=koopa-tor-relay \ + --label org.hacktivism.managed_by=koopa-admin \ + "$IMAGE" + +echo "created $NAME (user 1000:1000, userns=keep-id, host net)" +echo "start: podman start $NAME # or systemctl --user start container-koopa-tor-relay" diff --git a/configs/tor/migrate-identity.sh b/configs/tor/migrate-identity.sh new file mode 100755 index 0000000..344fddd --- /dev/null +++ b/configs/tor/migrate-identity.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copy host Tor identity → container data. Works with: sudo ./migrate-identity.sh +set -euo pipefail + +if [[ "$(id -u)" -ne 0 ]]; then + exec sudo -H "$0" "$@" +fi + +OWNER="${SUDO_USER:-hernani}" +if [[ "$OWNER" == root ]]; then OWNER=hernani; fi +BASE="$(getent passwd "$OWNER" | cut -d: -f6)/koopa-tor-relay" +SRC=/var/lib/tor +DST="$BASE/data" + +if [[ ! -d "$BASE" ]]; then + echo "ERROR: missing $BASE" >&2 + exit 1 +fi +if systemctl is-active --quiet tor 2>/dev/null; then + echo "ERROR: stop host tor first: systemctl stop tor" >&2 + exit 1 +fi +if command -v podman >/dev/null 2>&1; then + if runuser -u "$OWNER" -- podman ps --format "{{.Names}}" 2>/dev/null | grep -qx koopa-tor-relay; then + echo "ERROR: stop container first: podman stop koopa-tor-relay" >&2 + exit 1 + fi +fi + +echo "Copying $SRC → $DST (identity keys as $OWNER)…" +mkdir -p "$DST" +rsync -aHAX --delete "$SRC"/ "$DST"/ +chown -R "${OWNER}:${OWNER}" "$DST" +chmod 700 "$DST" + +echo "--- fingerprint ---" +[[ -f "$DST/fingerprint" ]] && cat "$DST/fingerprint" || echo "(no fingerprint file yet)" +[[ -f "$DST/fingerprint-ed25519" ]] && cat "$DST/fingerprint-ed25519" || true +echo "OK — $DST ready. Then: podman start koopa-tor-relay" diff --git a/configs/tor/torrc b/configs/tor/torrc new file mode 100644 index 0000000..63cd8cf --- /dev/null +++ b/configs/tor/torrc @@ -0,0 +1,16 @@ +# KoopaRelay — active policy (podman koopa-tor-relay, host network) +# Live paths: ~/koopa-tor-relay/{torrc,data,log} on koopa +Log notice file /var/log/tor/notices.log +Nickname KoopaRelay +ContactInfo info+koopa@hacktivism.ch +# dual-stack ORPort (IPv4 + IPv6) +ORPort 8080 +ControlPort 127.0.0.1:9051 +ExitRelay 0 +SocksPort 0 +MyFamily 52BB94DDC1292F950CF728708AC48523E018A718 +BandwidthRate 2000 MBytes +BandwidthBurst 2000 MBytes +RelayBandwidthRate 2000 MBytes +RelayBandwidthBurst 2000 MBytes +DataDirectory /var/lib/tor diff --git a/configs/tor/torrc.minimal b/configs/tor/torrc.minimal new file mode 100644 index 0000000..a05f52c --- /dev/null +++ b/configs/tor/torrc.minimal @@ -0,0 +1,192 @@ +## Configuration file for a typical Tor user +## Last updated 9 October 2013 for Tor 0.2.5.2-alpha. +## (may or may not work for much older or much newer versions of Tor.) +## +## Lines that begin with "## " try to explain what's going on. Lines +## that begin with just "#" are disabled commands: you can enable them +## by removing the "#" symbol. +## +## See 'man tor', or https://www.torproject.org/docs/tor-manual.html, +## for more options you can use in this file. +## +## Tor will look for this file in various places based on your platform: +## https://www.torproject.org/docs/faq#torrc + +## Tor opens a socks proxy on port 9050 by default -- even if you don't +## configure one below. Set "SocksPort 0" if you plan to run Tor only +## as a relay, and not make any local application connections yourself. +#SocksPort 9050 # Default: Bind to localhost:9050 for local connections. +#SocksPort 192.168.0.1:9100 # Bind to this address:port too. + +## Entry policies to allow/deny SOCKS requests based on IP address. +## First entry that matches wins. If no SocksPolicy is set, we accept +## all (and only) requests that reach a SocksPort. Untrusted users who +## can access your SocksPort may be able to learn about the connections +## you make. +#SocksPolicy accept 192.168.0.0/16 +#SocksPolicy reject * + +## Logs go to stdout at level "notice" unless redirected by something +## else, like one of the below lines. You can have as many Log lines as +## you want. +## +## We advise using "notice" in most cases, since anything more verbose +## may provide sensitive information to an attacker who obtains the logs. +## +## Send all messages of level 'notice' or higher to /var/log/tor/notices.log +#Log notice file /var/log/tor/notices.log +## Send every possible message to /var/log/tor/debug.log +#Log debug file /var/log/tor/debug.log +## Use the system log instead of Tor's logfiles +#Log notice syslog +## To send all messages to stderr: +#Log debug stderr + +## Uncomment this to start the process in the background... or use +## --runasdaemon 1 on the command line. This is ignored on Windows; +## see the FAQ entry if you want Tor to run as an NT service. +#RunAsDaemon 1 + +## The directory for keeping all the keys/etc. By default, we store +## things in $HOME/.tor on Unix, and in Application Data\tor on Windows. +#DataDirectory /var/lib/tor + +## The port on which Tor will listen for local connections from Tor +## controller applications, as documented in control-spec.txt. +#ControlPort 9051 +## If you enable the controlport, be sure to enable one of these +## authentication methods, to prevent attackers from accessing it. +#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C +#CookieAuthentication 1 + +############### This section is just for location-hidden services ### + +## Once you have configured a hidden service, you can look at the +## contents of the file ".../hidden_service/hostname" for the address +## to tell people. +## +## HiddenServicePort x y:z says to redirect requests on port x to the +## address y:z. + +#HiddenServiceDir /var/lib/tor/hidden_service/ +#HiddenServicePort 80 127.0.0.1:80 + +#HiddenServiceDir /var/lib/tor/other_hidden_service/ +#HiddenServicePort 80 127.0.0.1:80 +#HiddenServicePort 22 127.0.0.1:22 + +################ This section is just for relays ##################### +# +## See https://www.torproject.org/docs/tor-doc-relay for details. + +## Required: what port to advertise for incoming Tor connections. +#ORPort 9001 +## If you want to listen on a port other than the one advertised in +## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as +## follows. You'll need to do ipchains or other port forwarding +## yourself to make this work. +#ORPort 443 NoListen +#ORPort 127.0.0.1:9090 NoAdvertise + +## The IP address or full DNS name for incoming connections to your +## relay. Leave commented out and Tor will guess. +#Address noname.example.com + +## If you have multiple network interfaces, you can specify one for +## outgoing traffic to use. +# OutboundBindAddress 10.0.0.5 + +## A handle for your relay, so people don't have to refer to it by key. +#Nickname ididnteditheconfig + +## Define these to limit how much relayed traffic you will allow. Your +## own traffic is still unthrottled. Note that RelayBandwidthRate must +## be at least 20 KB. +## Note that units for these config options are bytes per second, not bits +## per second, and that prefixes are binary prefixes, i.e. 2^10, 2^20, etc. +#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps) +#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps) + +## Use these to restrict the maximum traffic per day, week, or month. +## Note that this threshold applies separately to sent and received bytes, +## not to their sum: setting "4 GB" may allow up to 8 GB total before +## hibernating. +## +## Set a maximum of 4 gigabytes each way per period. +#AccountingMax 4 GB +## Each period starts daily at midnight (AccountingMax is per day) +#AccountingStart day 00:00 +## Each period starts on the 3rd of the month at 15:00 (AccountingMax +## is per month) +#AccountingStart month 3 15:00 + +## Administrative contact information for this relay or bridge. This line +## can be used to contact you if your relay or bridge is misconfigured or +## something else goes wrong. Note that we archive and publish all +## descriptors containing these lines and that Google indexes them, so +## spammers might also collect them. You may want to obscure the fact that +## it's an email address and/or generate a new address for this purpose. +#ContactInfo Random Person +## You might also include your PGP or GPG fingerprint if you have one: +#ContactInfo 0xFFFFFFFF Random Person + +## Uncomment this to mirror directory information for others. Please do +## if you have enough bandwidth. +#DirPort 9030 # what port to advertise for directory connections +## If you want to listen on a port other than the one advertised in +## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as +## follows. below too. You'll need to do ipchains or other port +## forwarding yourself to make this work. +#DirPort 80 NoListen +#DirPort 127.0.0.1:9091 NoAdvertise +## Uncomment to return an arbitrary blob of html on your DirPort. Now you +## can explain what Tor is if anybody wonders why your IP address is +## contacting them. See contrib/tor-exit-notice.html in Tor's source +## distribution for a sample. +#DirPortFrontPage /etc/tor/tor-exit-notice.html + +## Uncomment this if you run more than one Tor relay, and add the identity +## key fingerprint of each Tor relay you control, even if they're on +## different networks. You declare it here so Tor clients can avoid +## using more than one of your relays in a single circuit. See +## https://www.torproject.org/docs/faq#MultipleRelays +## However, you should never include a bridge's fingerprint here, as it would +## break its concealability and potentionally reveal its IP/TCP address. +#MyFamily $keyid,$keyid,... + +## A comma-separated list of exit policies. They're considered first +## to last, and the first match wins. If you want to _replace_ +## the default exit policy, end this with either a reject *:* or an +## accept *:*. Otherwise, you're _augmenting_ (prepending to) the +## default exit policy. Leave commented to just use the default, which is +## described in the man page or at +## https://www.torproject.org/documentation.html +## +## Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses +## for issues you might encounter if you use the default exit policy. +## +## If certain IPs and ports are blocked externally, e.g. by your firewall, +## you should update your exit policy to reflect this -- otherwise Tor +## users will be told that those destinations are down. +## +## For security, by default Tor rejects connections to private (local) +## networks, including to your public IP address. See the man page entry +## for ExitPolicyRejectPrivate if you want to allow "exit enclaving". +## +#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more +#ExitPolicy accept *:119 # accept nntp as well as default exit policy +#ExitPolicy reject *:* # no exits allowed + +## Bridge relays (or "bridges") are Tor relays that aren't listed in the +## main directory. Since there is no complete public list of them, even an +## ISP that filters connections to all the known Tor relays probably +## won't be able to block all the bridges. Also, websites won't treat you +## differently because they won't know you're running Tor. If you can +## be a real relay, please do; but if not, be a bridge! +#BridgeRelay 1 +## By default, Tor will advertise your bridge to users through various +## mechanisms like https://bridges.torproject.org/. If you want to run +## a private bridge, for example because you'll give out your bridge +## address manually to your friends, uncomment this line: +#PublishServerDescriptor 0 + diff --git a/configs/tor/torrc.sample b/configs/tor/torrc.sample new file mode 100644 index 0000000..7be6773 --- /dev/null +++ b/configs/tor/torrc.sample @@ -0,0 +1,257 @@ +## Configuration file for a typical Tor user +## Last updated 28 February 2019 for Tor 0.3.5.1-alpha. +## (may or may not work for much older or much newer versions of Tor.) +## +## Lines that begin with "## " try to explain what's going on. Lines +## that begin with just "#" are disabled commands: you can enable them +## by removing the "#" symbol. +## +## See 'man tor', or https://www.torproject.org/docs/tor-manual.html, +## for more options you can use in this file. +## +## Tor will look for this file in various places based on your platform: +## https://support.torproject.org/tbb/tbb-editing-torrc/ + +## Tor opens a SOCKS proxy on port 9050 by default -- even if you don't +## configure one below. Set "SOCKSPort 0" if you plan to run Tor only +## as a relay, and not make any local application connections yourself. +#SOCKSPort 9050 # Default: Bind to localhost:9050 for local connections. +#SOCKSPort 192.168.0.1:9100 # Bind to this address:port too. + +## Entry policies to allow/deny SOCKS requests based on IP address. +## First entry that matches wins. If no SOCKSPolicy is set, we accept +## all (and only) requests that reach a SOCKSPort. Untrusted users who +## can access your SOCKSPort may be able to learn about the connections +## you make. +#SOCKSPolicy accept 192.168.0.0/16 +#SOCKSPolicy accept6 FC00::/7 +#SOCKSPolicy reject * + +## Logs go to stdout at level "notice" unless redirected by something +## else, like one of the below lines. You can have as many Log lines as +## you want. +## +## We advise using "notice" in most cases, since anything more verbose +## may provide sensitive information to an attacker who obtains the logs. +## +## Send all messages of level 'notice' or higher to /var/log/tor/notices.log +#Log notice file /var/log/tor/notices.log +## Send every possible message to /var/log/tor/debug.log +#Log debug file /var/log/tor/debug.log +## Use the system log instead of Tor's logfiles +#Log notice syslog +## To send all messages to stderr: +#Log debug stderr + +## Uncomment this to start the process in the background... or use +## --runasdaemon 1 on the command line. This is ignored on Windows; +## see the FAQ entry if you want Tor to run as an NT service. +#RunAsDaemon 1 + +## The directory for keeping all the keys/etc. By default, we store +## things in $HOME/.tor on Unix, and in Application Data\tor on Windows. +#DataDirectory /var/lib/tor + +## The port on which Tor will listen for local connections from Tor +## controller applications, as documented in control-spec.txt. +#ControlPort 9051 +## If you enable the controlport, be sure to enable one of these +## authentication methods, to prevent attackers from accessing it. +#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C +#CookieAuthentication 1 + +############### This section is just for location-hidden services ### + +## Once you have configured a hidden service, you can look at the +## contents of the file ".../hidden_service/hostname" for the address +## to tell people. +## +## HiddenServicePort x y:z says to redirect requests on port x to the +## address y:z. + +#HiddenServiceDir /var/lib/tor/hidden_service/ +#HiddenServicePort 80 127.0.0.1:80 + +#HiddenServiceDir /var/lib/tor/other_hidden_service/ +#HiddenServicePort 80 127.0.0.1:80 +#HiddenServicePort 22 127.0.0.1:22 + +################ This section is just for relays ##################### +# +## See https://community.torproject.org/relay for details. + +## Required: what port to advertise for incoming Tor connections. +#ORPort 9001 +## If you want to listen on a port other than the one advertised in +## ORPort (e.g. to advertise 443 but bind to 9090), you can do it as +## follows. You'll need to do ipchains or other port forwarding +## yourself to make this work. +#ORPort 443 NoListen +#ORPort 127.0.0.1:9090 NoAdvertise +## If you want to listen on IPv6 your numeric address must be explicitly +## between square brackets as follows. You must also listen on IPv4. +#ORPort [2001:DB8::1]:9050 + +## The IP address or full DNS name for incoming connections to your +## relay. Leave commented out and Tor will guess. +#Address noname.example.com + +## If you have multiple network interfaces, you can specify one for +## outgoing traffic to use. +## OutboundBindAddressExit will be used for all exit traffic, while +## OutboundBindAddressOR will be used for all OR and Dir connections +## (DNS connections ignore OutboundBindAddress). +## If you do not wish to differentiate, use OutboundBindAddress to +## specify the same address for both in a single line. +#OutboundBindAddressExit 10.0.0.4 +#OutboundBindAddressOR 10.0.0.5 + +## A handle for your relay, so people don't have to refer to it by key. +## Nicknames must be between 1 and 19 characters inclusive, and must +## contain only the characters [a-zA-Z0-9]. +## If not set, "Unnamed" will be used. +#Nickname ididnteditheconfig + +## Define these to limit how much relayed traffic you will allow. Your +## own traffic is still unthrottled. Note that RelayBandwidthRate must +## be at least 75 kilobytes per second. +## Note that units for these config options are bytes (per second), not +## bits (per second), and that prefixes are binary prefixes, i.e. 2^10, +## 2^20, etc. +#RelayBandwidthRate 100 KBytes # Throttle traffic to 100KB/s (800Kbps) +#RelayBandwidthBurst 200 KBytes # But allow bursts up to 200KB (1600Kb) + +## Use these to restrict the maximum traffic per day, week, or month. +## Note that this threshold applies separately to sent and received bytes, +## not to their sum: setting "40 GB" may allow up to 80 GB total before +## hibernating. +## +## Set a maximum of 40 gigabytes each way per period. +#AccountingMax 40 GBytes +## Each period starts daily at midnight (AccountingMax is per day) +#AccountingStart day 00:00 +## Each period starts on the 3rd of the month at 15:00 (AccountingMax +## is per month) +#AccountingStart month 3 15:00 + +## Administrative contact information for this relay or bridge. This line +## can be used to contact you if your relay or bridge is misconfigured or +## something else goes wrong. Note that we archive and publish all +## descriptors containing these lines and that Google indexes them, so +## spammers might also collect them. You may want to obscure the fact that +## it's an email address and/or generate a new address for this purpose. +## +## If you are running multiple relays, you MUST set this option. +## +#ContactInfo Random Person +## You might also include your PGP or GPG fingerprint if you have one: +#ContactInfo 0xFFFFFFFF Random Person + +## Uncomment this to mirror directory information for others. Please do +## if you have enough bandwidth. +#DirPort 9030 # what port to advertise for directory connections +## If you want to listen on a port other than the one advertised in +## DirPort (e.g. to advertise 80 but bind to 9091), you can do it as +## follows. below too. You'll need to do ipchains or other port +## forwarding yourself to make this work. +#DirPort 80 NoListen +#DirPort 127.0.0.1:9091 NoAdvertise +## Uncomment to return an arbitrary blob of html on your DirPort. Now you +## can explain what Tor is if anybody wonders why your IP address is +## contacting them. See contrib/tor-exit-notice.html in Tor's source +## distribution for a sample. +#DirPortFrontPage /etc/tor/tor-exit-notice.html + +## Uncomment this if you run more than one Tor relay, and add the identity +## key fingerprint of each Tor relay you control, even if they're on +## different networks. You declare it here so Tor clients can avoid +## using more than one of your relays in a single circuit. See +## https://support.torproject.org/relay-operators/multiple-relays/ +## However, you should never include a bridge's fingerprint here, as it would +## break its concealability and potentially reveal its IP/TCP address. +## +## If you are running multiple relays, you MUST set this option. +## +## Note: do not use MyFamily on bridge relays. +#MyFamily $keyid,$keyid,... + +## Uncomment this if you want your relay to be an exit, with the default +## exit policy (or whatever exit policy you set below). +## (If ReducedExitPolicy, ExitPolicy, or IPv6Exit are set, relays are exits. +## If none of these options are set, relays are non-exits.) +#ExitRelay 1 + +## Uncomment this if you want your relay to allow IPv6 exit traffic. +## (Relays do not allow any exit traffic by default.) +#IPv6Exit 1 + +## Uncomment this if you want your relay to be an exit, with a reduced set +## of exit ports. +#ReducedExitPolicy 1 + +## Uncomment these lines if you want your relay to be an exit, with the +## specified set of exit IPs and ports. +## +## A comma-separated list of exit policies. They're considered first +## to last, and the first match wins. +## +## If you want to allow the same ports on IPv4 and IPv6, write your rules +## using accept/reject *. If you want to allow different ports on IPv4 and +## IPv6, write your IPv6 rules using accept6/reject6 *6, and your IPv4 rules +## using accept/reject *4. +## +## If you want to _replace_ the default exit policy, end this with either a +## reject *:* or an accept *:*. Otherwise, you're _augmenting_ (prepending to) +## the default exit policy. Leave commented to just use the default, which is +## described in the man page or at +## https://support.torproject.org/relay-operators +## +## Look at https://support.torproject.org/abuse/exit-relay-expectations/ +## for issues you might encounter if you use the default exit policy. +## +## If certain IPs and ports are blocked externally, e.g. by your firewall, +## you should update your exit policy to reflect this -- otherwise Tor +## users will be told that those destinations are down. +## +## For security, by default Tor rejects connections to private (local) +## networks, including to the configured primary public IPv4 and IPv6 addresses, +## and any public IPv4 and IPv6 addresses on any interface on the relay. +## See the man page entry for ExitPolicyRejectPrivate if you want to allow +## "exit enclaving". +## +#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports on IPv4 and IPv6 but no more +#ExitPolicy accept *:119 # accept nntp ports on IPv4 and IPv6 as well as default exit policy +#ExitPolicy accept *4:119 # accept nntp ports on IPv4 only as well as default exit policy +#ExitPolicy accept6 *6:119 # accept nntp ports on IPv6 only as well as default exit policy +#ExitPolicy reject *:* # no exits allowed + +## Uncomment this if you want your exit relay to reevaluate its exit policy on +## existing connections when the exit policy is modified. +#ReevaluateExitPolicy 1 + +## Bridge relays (or "bridges") are Tor relays that aren't listed in the +## main directory. Since there is no complete public list of them, even an +## ISP that filters connections to all the known Tor relays probably +## won't be able to block all the bridges. Also, websites won't treat you +## differently because they won't know you're running Tor. If you can +## be a real relay, please do; but if not, be a bridge! +## +## Warning: when running your Tor as a bridge, make sure than MyFamily is +## NOT configured. +#BridgeRelay 1 +## By default, Tor will advertise your bridge to users through various +## mechanisms like https://bridges.torproject.org/. If you want to run +## a private bridge, for example because you'll give out your bridge +## address manually to your friends, uncomment this line: +#BridgeDistribution none + +## Configuration options can be imported from files or folders using the %include +## option with the value being a path. This path can have wildcards. Wildcards are +## expanded first, using lexical order. Then, for each matching file or folder, the following +## rules are followed: if the path is a file, the options from the file will be parsed as if +## they were written where the %include option is. If the path is a folder, all files on that +## folder will be parsed following lexical order. Files starting with a dot are ignored. Files +## on subfolders are ignored. +## The %include option can be used recursively. +#%include /etc/torrc.d/*.conf + diff --git a/host/hernani-home.md b/host/hernani-home.md deleted file mode 100644 index 3cbd806..0000000 --- a/host/hernani-home.md +++ /dev/null @@ -1,31 +0,0 @@ -# hernani@koopa — home layout (SoT paths) - -Terse map after GOA single-CTR. Live moves on koopa need Freigabe. - -## GOA - -| Path | Role | -|------|------| -| `~/scripts/taler-shared/goa-regio-ng/` | restore / all-in-one helpers (admin-log SoT) | -| `~/goa-regio-ng-scripts/` | optional live copy of helpers | -| `~/backups/goa/current` | CTR bak for restore | -| `~/goa-landing-deploy/` | host landings → `/var/www/*-landing/` | -| CTR `goa-regio-ng` | pasta **9010–9015**; landings+Caddy outside CTR | - -## Monitoring state (not a CTR) - -| Path | Role | -|------|------| -| `~/.local/state/taler-hacktivism-monitoring/` | elelmon/taler-monitoring host-agent state dir name (legacy string OK) | - -## Tor - -Host `tor.service` — ORPort **8080**, ControlPort **9051**. No `~/…/tor-relay` CTR. - -## Other CTRs (unchanged) - -Forgejo / social / media: see `configs/ports.md`. Inventory: `koopa-login-health`. - -## Magikoopa laptop (ops junk) - -Prefer under `$HOME/git/` + `$HOME/Archives/`; do not leave `/tmp/commit-*`, `/tmp/goa-*`, or loose `~/*.asc` / screenshots as SoT. diff --git a/host/overview/LIVE.md b/host/overview/LIVE.md new file mode 100644 index 0000000..11120be --- /dev/null +++ b/host/overview/LIVE.md @@ -0,0 +1,119 @@ +# Live inventory — koopa (2026-07-13) + +Snapshot of **what runs on host koopa** (openSUSE Tumbleweed). No secrets. + +Refresh command ideas: + +```bash +hostname; date -R +podman ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}' +systemctl is-active caddy +systemctl --user is-active container-koopa-tor-relay +systemctl --user is-active container-koopa-nym +ss -lntp | grep -E '90[0-9]{2}|9200|8080|9080|1789' +``` + +## Host + +| Item | Value | +|------|--------| +| Hostname | `koopa` | +| Role | App host behind VeciGate (WAN :80→9000, :443→9001) | +| Edge | Caddy **9000/9001**, systemd socket proxies **80/443** | +| Tor | **podman `koopa-tor-relay`** (host net) ORPort **8080** dual-stack, ControlPort **127.0.0.1:9051** — not host `tor.service` | + +## Running podman containers + +| Name | Image | Ports (host) | Public site | +|------|--------|--------------|-------------| +| `taler-hacktivism` | `localhost/taler-hacktivism-live:landing` | **9010**, **9015** | `taler.hacktivism.ch` | +| **`taler-hacktivism-exchange-ansible`** | `localhost/taler-hacktivism-exchange-ansible:landing` | **9011**, **9014** | `exchange.hacktivism.ch` | +| `taler-hacktivism-bank` | **`localhost/taler-hacktivism-banking:live`** | **9012**, **9013** | `bank.hacktivism.ch` | +| `koopa-castopod` (+ mariadb, redis) | `castopod/castopod:1` | **9020** | `castopod.hacktivism.ch` | +| `koopa-bonfire` (+ postgres) | `bonfire:1.0.5-social-amd64` | **9021** | `bonfire.hacktivism.ch` | +| `koopa-prime-jellyfin` | `linuxserver/jellyfin:10.10.7` | **9022** | `prime.hacktivism.ch` | +| `koopa-prime-qbittorrent` | `linuxserver/qbittorrent:5.0.4` | **9023**, **6881** | `bt.hacktivism.ch` | +| `koopa-forgejo` (+ postgres) | `forgejo:11-rootless` | **9024**, **9200** | `git.hacktivism.ch` | +| **`koopa-paivana`** (+ upstream) | `localhost/koopa-paivana:latest` | **9025** | `paivana.hacktivism.ch` | +| `koopa-lemmy-proxy` (+ lemmy, ui, pictrs, db) | `lemmy:0.19.20` | **9026** | `lemmy.hacktivism.ch` | +| `koopa-decidim` (+ postgres, redis, sidekiq) | `decidim/decidim:0.30.8` | **9027** | `decidim.hacktivism.ch` | +| **`koopa-tor-relay`** | `localhost/koopa-tor-relay:latest` | **8080**, **9051** (host net) | Tor OR (non-exit) | +| **`koopa-nym`** | `localhost/koopa-nym:latest` | **9080**, **1789**, **1790** (+ opt. WG) | Nym mixnet node (nym.com) | +| `koopa-tops-ng1` | `nginx` | **9090** | `tops.ng1.hacktivism.ch` | +| `koopa-tops-ng2` | `nginx` | **9091** | `tops.ng2.hacktivism.ch` | +| `koopa-tops-ng3` | `nginx` | **9092** | `tops.ng3.hacktivism.ch` | + +### Naming note (exchange) + +Live exchange container is **`taler-hacktivism-exchange-ansible`** (not `taler-hacktivism-exchange-ansible` / not without `-ansible`). +Managed from **`/home/hernani/ansible-taler-exchange/`** (see `configs/taler-exchange-ansible/`). + +## Caddy vhosts → backends + +| Host | Backend | +|------|---------| +| `taler.hacktivism.ch` | 9010 (API) + 9015 (`/intro`) | +| `exchange.hacktivism.ch` | 9011 + 9014 (`/intro`) | +| `bank.hacktivism.ch` | 9012 + 9013 (`/intro`, terms, privacy) | +| `castopod.hacktivism.ch` | 9020 | +| `bonfire.hacktivism.ch` | 9021 | +| `prime.hacktivism.ch` | 9022 | +| `bt.hacktivism.ch` | 9023 | +| `git.hacktivism.ch` | 9024 (HTTP); git-SSH **9200** host-direct | +| `paivana.hacktivism.ch` | 9025 (paivana-httpd GOA paywall) | +| `lemmy.hacktivism.ch` | 9026 | +| `decidim.hacktivism.ch` | 9027 | +| `tops.ng1.hacktivism.ch` | 9090 | +| `tops.ng2.hacktivism.ch` | 9091 | +| `tops.ng3.hacktivism.ch` | 9092 | + +Config: `/etc/caddy/Caddyfile` (mirror `configs/caddy/Caddyfile`). + +## Paths on host (`hernani`) + +| Path | Role | +|------|------| +| `~/ansible-taler-exchange/` | Ansible + scripts for exchange-ansible container | +| `~/koopa-castopod/` | Castopod compose | +| `~/koopa-lemmy/` | Lemmy compose | +| `~/koopa-decidim/` | Decidim compose | +| `~/koopa-bonfire/` | Bonfire compose + gitbot | +| `~/koopa-prime/` | Jellyfin + qBittorrent | +| `~/koopa-forgejo/` | Forgejo rootless | +| `~/koopa-paivana/` | Paivana paywall (`koopa-paivana`) | +| `~/koopa-tops/` | tops.ng1–ng3 (`koopa-tops-ng*`) | +| `~/koopa-caddy/` | Caddyfile working tree on host | +| `~/koopa-tor-relay/` | Tor relay container (torrc, data/identity, log) | +| `~/koopa-nym/` | Nym nym-node (nym.com mixnet / NymVPN network) | + +## Start models + +| Stack | How | +|-------|-----| +| Taler merchant/bank | root `start_base_services_*` → service user → `/usr/local/bin/start_*.sh` | +| Exchange (GOA) | `~/ansible-taler-exchange/run-container-koopa.sh` then `deploy-hacktivism-goa.sh` | +| User apps | `cd ~/koopa-* && podman-compose up -d` | +| Lemmy | user units `container-koopa-lemmy-db` + `container-koopa-lemmy` (linger) | +| Decidim | user units `container-koopa-decidim-db` + `container-koopa-decidim` (linger) | +| tops (ng1–ng3) | user unit `container-koopa-tops.service` (linger) | + +## Config mirrors in this repo (`configs/`) + +| Live container | Git path | +|----------------|----------| +| `taler-hacktivism` | `configs/taler-hacktivism/` | +| `taler-hacktivism-bank` (image **…-banking**) | `configs/taler-hacktivism-bank/` | +| `taler-hacktivism-exchange-ansible` | `configs/taler-exchange-ansible/` + conf in `configs/taler-exchange/` | +| `koopa-tops-ng1` … `ng3` | `configs/tops/` | + +## Related docs in this repo + +| Topic | Doc | +|-------|-----| +| Ports | `configs/ports.md` | +| Diagram | `host/overview/services.md` | +| Exchange Ansible (koopa) | `configs/taler-exchange-ansible/` | +| Forgejo | `2026/2026-07-10--forgejo-rootless.md` | +| Bonfire public feeds | `configs/bonfire/public-feeds.md` | +| Castopod content | `2026/2026-07-09--castopod-content.md` | +| Decidim | `2026/2026-08-17--decidim.md` · `configs/decidim/` | diff --git a/host/overview/services.md b/host/overview/services.md new file mode 100644 index 0000000..6c72548 --- /dev/null +++ b/host/overview/services.md @@ -0,0 +1,110 @@ +# Service overview — koopa + +**Live container/port inventory:** [`LIVE.md`](LIVE.md) (state as observed on host). + +Diagram + +```mermaid +flowchart TB + subgraph Internet + Client[Client IPv4/IPv6] + end + + subgraph VeciGate["VeciGate (MikroTik)"] + DNAT80["DNAT :80 → koopa:9000"] + DNAT443["DNAT :443 → koopa:9001"] + DNATSSH["DNAT :23235 → koopa:22"] + DNATTOR["DNAT :8080 → koopa:8080"] + end + + subgraph Host["openSUSE host koopa"] + subgraph Edge["Edge on host"] + S80["systemd http-proxy.socket :80"] + S443["systemd https-proxy.socket :443"] + CaddyHTTP["Caddy :9000 HTTP\nACME + redirect"] + CaddyHTTPS["Caddy :9001 HTTPS"] + FW["firewalld public\n9000,9001,80,8080,ssh"] + end + + subgraph Podman["podman rootless (hernani)"] + Merch["taler-hacktivism\n:9010"] + Exch["taler-hacktivism-exchange-ansible\n:9011"] + Bank["taler-bank-hacktivism\n:9012"] + Castopod["koopa-castopod\n:9020"] + Bonfire["koopa-bonfire\n:9021"] + Prime["koopa-prime jellyfin\n:9022"] + BT["qbittorrent\n:9023"] + Forgejo["koopa-forgejo ROOTLESS\n:9024 HTTP / :9200 SSH"] + Paivana["koopa-paivana\n:9025"] + Lemmy["koopa-lemmy-proxy\n:9026"] + Decidim["koopa-decidim\n:9027"] + end + + Tor["tor ORPort :8080"] + SSH["sshd :22"] + end + + Client --> DNAT80 --> CaddyHTTP + Client --> DNAT443 --> CaddyHTTPS + Client --> DNATSSH --> SSH + Client --> DNATTOR --> Tor + + S80 --> CaddyHTTP + S443 --> CaddyHTTPS + + CaddyHTTP -->|"/.well-known"| ACME["/var/www/acme"] + CaddyHTTP -->|other| Redir[301 HTTPS] + CaddyHTTPS -->|taler.hacktivism.ch| Merch + CaddyHTTPS -->|exchange.hacktivism.ch| Exch + CaddyHTTPS -->|bank.hacktivism.ch| Bank + CaddyHTTPS -->|castopod.hacktivism.ch| Castopod + CaddyHTTPS -->|bonfire.hacktivism.ch| Bonfire + CaddyHTTPS -->|prime.hacktivism.ch| Prime + CaddyHTTPS -->|bt.hacktivism.ch| BT + CaddyHTTPS -->|git.hacktivism.ch| Forgejo + CaddyHTTPS -->|paivana.hacktivism.ch| Paivana + CaddyHTTPS -->|lemmy.hacktivism.ch| Lemmy + CaddyHTTPS -->|decidim.hacktivism.ch| Decidim +``` + +## Port table + +| Port | Listener | Backend / notes | +|------|----------|-----------------| +| 22 | sshd | LAN; WAN via 23235 | +| 80 | systemd socket | → 127.0.0.1:**9000** | +| 443 | systemd socket | → 127.0.0.1:**9001** | +| 9000 | caddy | HTTP + ACME | +| 9001 | caddy | HTTPS vhosts | +| 9010 | podman | **merchant** nginx | +| 9011 | podman | **exchange** httpd | +| 9012 | podman | **bank** libeufin | +| 9020 | podman | **castopod** | +| 9021 | podman | **bonfire** | +| 9022 | podman | **jellyfin** (prime) | +| 9023 | podman | **qbittorrent** (bt) | +| **9024** | podman | **forgejo** HTTP → `git.hacktivism.ch` | +| **9025** | podman | **paivana** → `paivana.hacktivism.ch` | +| **9026** | podman | **lemmy** → `lemmy.hacktivism.ch` | +| **9027** | podman | **decidim** → `decidim.hacktivism.ch` | +| **9200** | podman | **forgejo** git-SSH (host-direct) | +| 9090–9092 | podman | **tops** `koopa-tops-ng1`…`ng3` | +| 8080 | tor | ORPort | + +Full port notes: `configs/ports.md`. + +## Service index (details elsewhere) + +| Service | Detail docs | +|---------|-------------| +| Caddy | `host/caddy/`, `configs/caddy/` | +| firewalld | `host/firewalld/` | +| systemd proxies | `host/systemd/` | +| Merchant container | `configs/taler-hacktivism/`, `scripts/taler-merchant/` | +| Exchange container | `configs/taler-exchange/`, `scripts/taler-exchange/` | +| **Forgejo rootless** | `configs/forgejo/`, `2026/2026-07-10--forgejo-rootless.md` | +| Paivana paywall | `configs/paivana/` | +| tops (`koopa-tops-ng*`) | `configs/tops/` | +| Tor relay (`koopa-tor-relay` podman) | `configs/tor/`, `host/tor/` | +| Tor monitoring scripts | `scripts/monitoring/` | +| VeciGate NAT | `../vecigate-admin-log/ip/firewall/nat/` | diff --git a/host/overview/services.txt b/host/overview/services.txt new file mode 100644 index 0000000..a37748b --- /dev/null +++ b/host/overview/services.txt @@ -0,0 +1,24 @@ + Internet + | + +-------------+-------------+ + | VeciGate | + | :80→9000 :443→9001 | + | :23235→22 :8080→8080 | + +-------------+-------------+ + | + koopa 192.168.100.95 + | + +----------------------+----------------------+ + | | | + systemd Caddy other + :80 → 9000 :9000 HTTP sshd :22 + :443 → 9001 :9001 HTTPS tor :8080 + | | + +----------+-----------+ + | + +-------+--------+ + | | + :9010 merchant :9011 exchange + (nginx TLS) (httpd TCP) + | | + unix sock postgres/secmods diff --git a/host/tor/README.md b/host/tor/README.md index 138d11d..18643b5 100644 --- a/host/tor/README.md +++ b/host/tor/README.md @@ -1,13 +1,28 @@ # Tor on koopa -**Runtime:** host **`tor.service`** (not a podman container). -**Ports:** ORPort **8080** · ControlPort **9051** (loopback). -**Non-exit** relay (`ExitRelay 0`). +**Runtime:** podman **`koopa-tor-relay`** (not host `tor.service`). +**Config mirror:** `configs/tor/` (`torrc`, Containerfile, migrate script, `create-container.sh`, user unit). +**Data/identity:** `~/koopa-tor-relay/data` (same keys as former `/var/lib/tor`). +**Process:** non-root **uid 1000** (`debian-tor`); recreate via `configs/tor/create-container.sh` after image rebuild. + +| Port | Bind | Role | +|------|------|------| +| **8080** | `0.0.0.0` + `[::]` | ORPort (dual-stack) | +| **9051** | `127.0.0.1` | ControlPort (nyx / stem) | + +Non-exit relay (`ExitRelay 0`, `SocksPort 0`). + +### Root checklist ```bash -systemctl status tor -ss -lntp | grep -E '8080|9051' +sudo systemctl disable --now tor +sudo systemctl mask tor +# linger already required for rootless user units: +# sudo loginctl enable-linger hernani ``` -login-health: WARN if `tor.service` not active. -Legacy `koopa-tor-relay` / `configs/tor/` removed from live inventory (git history keeps them). +### User unit + +```bash +systemctl --user enable --now container-koopa-tor-relay.service +``` diff --git a/koopa-setup b/koopa-setup index 7d1832e..0a18930 100644 --- a/koopa-setup +++ b/koopa-setup @@ -14,18 +14,14 @@ configs/ports.md 2026/2026-09-04--mytops-local-podman.md # outward: ~/git/mytops-admin-log → git switch mytops-local -## goa-regio-ng (live GOA on koopa) +## goa-regio-ng -# single CTR goa-regio-ng · pasta 9010–9015 · landings host-side -# SoT: scripts/taler-shared/goa-regio-ng/ · bak ~/backups/goa/current 2026/2026-09-04--goa-backup-regio-ng.md -configs/ports.md -scripts/login-health/ +# outward: ~/src/regio-local/ ## host map -configs/ports.md +host/overview/ configs/caddy/ -host/tor/README.md SECRETS.md ISSUES.md diff --git a/scripts/login-health/README.md b/scripts/login-health/README.md index 1f48387..0003217 100644 --- a/scripts/login-health/README.md +++ b/scripts/login-health/README.md @@ -1,81 +1,115 @@ # login-health — status on SSH login (koopa) -SSH login shows a short **pre-collected** snapshot: Forgejo, GOA (`goa-regio-ng`), Caddy edge, host Tor, rest of inventory. +When you **SSH into koopa**, show a short **pre-collected** health snapshot so you see whether **git.hacktivism.ch** (Forgejo), Taler GOA, Caddy edge, and the rest of the LIVE inventory are up. -Inventory: `configs/ports.md` + this script’s arrays (not `host/overview/`). +Inventory source: `host/overview/LIVE.md`, `configs/ports.md`. -## New / changed services +## New / changed services (mandatory) -Same package: +Whenever a **new service** is added on koopa (or ports/vhosts change), update **in the same work package**: 1. `koopa-login-health.sh` — `EXPECT_CONTAINERS`, `PROBES`, critical vs optional -2. `configs/ports.md` -3. Deploy → `~/.local/bin/koopa-login-health` on koopa (no git commit on koopa) -4. `koopa-login-health collect` +2. `host/overview/LIVE.md` + `configs/ports.md` (and `services.md` if the diagram changes) +3. Deploy script to `~/.local/bin/koopa-login-health` on koopa (laptop commits/pushes; **no git commit on koopa**) +4. `koopa-login-health collect` so the next SSH login is not stale -Workflow: `koopa-services-health`. +Grok workflows: `koopa-services-health` (inventory drift) + `commit-rules` (planning rule 10). ## Design: no probes at login -| Path | What | -|------|------| -| **user timer** (5 min + after boot) | `collect` — podman, Caddy, Tor, loopback HTTP → snapshot | -| **SSH / bashrc** | `show` only — cat snapshot | +| Path | What runs | +|------|-----------| +| **systemd user timer** (every **5 min** + soon after boot) | `koopa-login-health collect` — podman, Caddy, loopback HTTP, write snapshot | +| **SSH / bashrc** | `koopa-login-health show` only — **cat** last snapshot (milliseconds, no curl/podman) | -State: `~/.local/state/koopa-login-health/` (`status.compact` / `.verbose` / `.meta`). -Stale if older than `KOOPA_HEALTH_STALE_SEC` (default 900). +Snapshot files (`XDG_STATE_HOME`, default `~/.local/state/koopa-login-health/`): + +| File | Content | +|------|---------| +| `status.compact` | login view (WARN/FAIL + overall) | +| `status.verbose` | full line list | +| `status.meta` | `overall=`, `collected_at=` (unix), RFC date | + +If the snapshot is older than **`KOOPA_HEALTH_STALE_SEC`** (default **900** = 15 min), `show` prints a **stale** warning (timer likely down). ## Login must never break -`KOOPA_HEALTH_FROM_LOGIN=1` → exit 0 · `timeout 2s` · `|| true` · `bash -n` on install. +| Guard | What it does | +|-------|----------------| +| **show only** | bashrc never runs `collect` | +| **`KOOPA_HEALTH_FROM_LOGIN=1`** | always exit 0 | +| **`timeout 2s`** | wall cap to cat a few KB | +| **`\|\| true` / `set +e`** | hook cannot abort the shell | +| **`bash -n`** on install | refuse a broken bashrc hook | + Skip: `KOOPA_SKIP_HEALTH=1 ssh koopa` ## What you see ```text -koopa health koopa Sat, 19 Sep 2026 … +koopa health koopa Wed, … git.hacktivism.ch = Forgejo :9024/:9200 · edge Caddy :9000/:9001 - OK all critical checks passed (… ok) -overall: OK ok=… warn=0 fail=0 + OK all critical checks passed (42 ok) +overall: OK ok=42 warn=0 fail=0 + checked: Wed, … (3m ago) [timer snapshot; not live at login] ``` -## Checks (collect only) +## Checks (on collect only) | Area | What | |------|------| | Edge | `caddy.service`, proxy sockets | -| Tor | host `tor.service` (ORPort 8080 / ControlPort 9051) — WARN if down | | Listen | critical + optional ports | -| Podman | `goa-regio-ng`, forgejo, optional apps | -| HTTP | loopback backends (2s curl) | +| Podman | LIVE container names | +| HTTP | loopback backends (2s curl, parallel) | | Git SSH | TCP `:9200` | -**Critical** (FAIL): `goa-regio-ng`, `koopa-forgejo`, edge/ports **9010–9012**, **9024**, **9200**. -**Optional** (WARN): castopod, bonfire, lemmy, decidim, prime, bt, paivana, tops, nym. +**Critical** (→ overall FAIL): merchant, exchange, bank, forgejo, edge/critical ports. +**Optional** (→ WARN): castopod, bonfire, lemmy, decidim, prime, bt, paivana, tops, tor, nym. -GOA = single CTR `goa-regio-ng` (pasta **9010–9015**). Landings **9013–9015** host-side (`~/goa-landing-deploy`). -Legacy `taler-hacktivism*` / `koopa-tor-relay` are not expected. +Collect also checks **linger** and that Lemmy/Decidim user units are **enabled** (reboot survival). Read-only. No restarts, no secrets. -## Install (koopa as `hernani`) +## Install (on koopa as `hernani`) ```bash cd ~/src/koopa/koopa-admin-log ./scripts/login-health/install-login-health.sh +``` + +Installs binary, user units, bashrc hook, enables timer, runs one collect. + +Linger (so the timer runs after reboot without an open SSH session): + +```bash sudo loginctl enable-linger hernani ``` ## Manual ```bash -koopa-login-health -koopa-login-health show -v -koopa-login-health collect +koopa-login-health # show compact snapshot +koopa-login-health show -v # verbose snapshot +koopa-login-health show -q # overall (+ stale note) +koopa-login-health collect # refresh now (same as the timer unit) +systemctl --user start koopa-login-health.service systemctl --user status koopa-login-health.timer ``` +## Uninstall + +```bash +systemctl --user disable --now koopa-login-health.timer +rm -f ~/.config/systemd/user/koopa-login-health.{service,timer} +systemctl --user daemon-reload +rm -f ~/.local/bin/koopa-login-health +# remove marked block in ~/.bashrc +rm -rf ~/.local/state/koopa-login-health +``` + ## Related -- `configs/ports.md` · `host/tor/README.md` (host Tor) +- Grok workflow `koopa-services-health` (laptop public HTTPS + generated mon pages) +- `scripts/taler-sanity/check_stack-health.sh` (deeper Taler, often root) - units: `configs/systemd/user/koopa-login-health.{service,timer}` diff --git a/scripts/login-health/koopa-login-health.sh b/scripts/login-health/koopa-login-health.sh index 80ebdbc..309a782 100755 --- a/scripts/login-health/koopa-login-health.sh +++ b/scripts/login-health/koopa-login-health.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # koopa-login-health — read-only GOA/koopa service health. -# Inventory: configs/ports.md + arrays below (goa-regio-ng single CTR). +# Inventory: koopa-admin-log host/overview/LIVE.md (+ ports.md). # # Architecture: # collect — run probes, write snapshot (systemd user timer; NOT on login) @@ -138,12 +138,16 @@ do_show() { # ---------- COLLECT: probes → write snapshot ---------- CRITICAL_CONTAINERS=( - goa-regio-ng + taler-hacktivism + taler-hacktivism-exchange-ansible + taler-hacktivism-bank koopa-forgejo ) EXPECT_CONTAINERS=( - goa-regio-ng + taler-hacktivism + taler-hacktivism-exchange-ansible + taler-hacktivism-bank koopa-castopod koopa-bonfire koopa-lemmy-proxy @@ -152,6 +156,7 @@ EXPECT_CONTAINERS=( koopa-prime-qbittorrent koopa-forgejo koopa-paivana + koopa-tor-relay koopa-nym koopa-tops-ng1 koopa-tops-ng2 @@ -162,6 +167,7 @@ OPTIONAL_CONTAINERS=( koopa-prime-jellyfin koopa-prime-qbittorrent koopa-nym + koopa-tor-relay koopa-tops-ng1 koopa-tops-ng2 koopa-tops-ng3 @@ -262,12 +268,6 @@ do_collect() { else record FAIL "caddy.service is ${caddy_st} (edge HTTPS)" fi - tor_st=$(systemctl is-active tor 2>/dev/null || echo unknown) - if [ "${tor_st}" = "active" ]; then - record OK "tor.service active" - else - record WARN "tor.service is ${tor_st} (host ORPort/ControlPort)" - fi for sock in http-proxy.socket https-proxy.socket; do st=$(systemctl is-active "${sock}" 2>/dev/null || echo unknown) if [ "${st}" = "active" ] || [ "${st}" = "listening" ]; then