diff --git a/2026/2026-09-07--git-meta-origin-forgejo.md b/2026/2026-09-07--git-meta-origin-forgejo.md new file mode 100644 index 0000000..d795832 --- /dev/null +++ b/2026/2026-09-07--git-meta-origin-forgejo.md @@ -0,0 +1,55 @@ +# `$HOME/git/` meta-repo origin on git.hacktivism.ch (2026-09-07) + +## Remote + +| Item | Value | +|------|--------| +| Host | **Forgejo rootless** `https://git.hacktivism.ch/` | +| Repo | **hernani/git** (meta-repo: non-secret globals only) | +| Visibility | **private** (`DEFAULT_PRIVATE` template is public — create with `private:true`) | +| Default branch | `main` | +| SSH clone (FQDN form) | `git@git.hacktivism.ch:hernani/git.git` | +| SSH URL (API form) | `ssh://git@git.hacktivism.ch:9200/hernani/git.git` | +| Local tree | `$HOME/git/` (`PATH[git-root]`) | + +Unauth HTTPS browse of a private repo → **404** (expected). + +## Local setup (done 2026-09-07 ~14:21) + +```bash +cd "$HOME/git" +git remote add origin git@git.hacktivism.ch:hernani/git.git +git push -u origin main +``` + +SSH Host `git.hacktivism.ch`: `HostName 127.0.0.1`, `Port 9200`, `User git`, `ProxyJump hernani@koopa`, `IdentityFile ~/.ssh/id_ed25519`. + +## Create via One-Shot-Token (on koopa) + +Do **not** use xAI / host-expert-ssh mutate for this. SSH as `hernani` → local HTTP **9024**. + +```bash +# unique token name (default gitea-admin may already exist) +podman exec koopa-forgejo gitea admin user generate-access-token \ + --username hernani \ + --token-name "oneshot-git-meta-$(date +%s)" \ + --scopes write:repository,write:admin \ + --raw +# → TOKEN (never log / never commit) + +curl -sS -X POST \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"name":"git","private":true,"auto_init":false,"default_branch":"main"}' \ + http://127.0.0.1:9024/api/v1/admin/users/hernani/repos +# expect HTTP 201, full_name=hernani/git +``` + +Token delete via API often **403** with those scopes — purge leftover `oneshot-*` in Forgejo UI if needed. + +## Related + +- This admin-log’s own origin: `2026-07-10--admin-log-origin-forgejo.md` (public) +- Forgejo install: `2026-07-10--forgejo-rootless.md` +- Host skill quirk: private repos need explicit `private:true` +- Meta Must: no secrets / no child worktrees in this Forgejo repo diff --git a/scripts/caddy/README.md b/scripts/caddy/README.md index 8b022fd..a9f5139 100644 --- a/scripts/caddy/README.md +++ b/scripts/caddy/README.md @@ -10,6 +10,17 @@ sudo caddy validate --config /etc/caddy/Caddyfile sudo systemctl reload caddy ``` +## dossiers.ngi* — basic_auth (htaccess-in-front) + +Caddy **ignores** Apache `.htaccess`. Use: + +```bash +sudo bash /home/hernani/koopa-admin-log/scripts/caddy/apply-dossiers-ngi-basicauth.sh +``` + +Password file (not git): `/home/hernani/koopa-secrets/dossiers-ngi-basicauth.txt` +Hosts: `dossiers.ngi` / `dossiers.2.ngi` / `dossiers.3.ngi`.hacktivism.ch + ## New HTTPS vhost Add a site block to the Caddyfile (live + mirror), then validate and reload. Include the host in the shared HTTP site list (ACME + redirect) at the bottom of the file. diff --git a/scripts/caddy/apply-dossiers-ngi-basicauth.sh b/scripts/caddy/apply-dossiers-ngi-basicauth.sh new file mode 100755 index 0000000..4587f6a --- /dev/null +++ b/scripts/caddy/apply-dossiers-ngi-basicauth.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +# Apply HTTP basic_auth (Caddy equivalent of "htaccess in front") +# to dossiers.ngi / dossiers.2.ngi / dossiers.3.ngi.hacktivism.ch +# +# Caddy file_server does NOT honor Apache .htaccess — this edits the Caddyfile. +# +# On koopa (password for sudo): +# sudo -n true 2>/dev/null || sudo -v +# sudo bash /home/hernani/koopa-admin-log/scripts/caddy/apply-dossiers-ngi-basicauth.sh +# +# Idempotent. Password file is NOT in git: +# /home/hernani/koopa-secrets/dossiers-ngi-basicauth.txt +set -euo pipefail + +if [[ "$(id -u)" -ne 0 ]]; then + echo "ERROR: run as root: sudo bash $0" >&2 + exit 1 +fi + +CADDY=/etc/caddy/Caddyfile +USER_NAME="${DOSSIERS_AUTH_USER:-hernani}" +SECRETS_DIR=/home/hernani/koopa-secrets +PASS_FILE="${SECRETS_DIR}/dossiers-ngi-basicauth.txt" +SITES=( + dossiers.ngi.hacktivism.ch + dossiers.2.ngi.hacktivism.ch + dossiers.3.ngi.hacktivism.ch +) + +if [[ ! -f "$CADDY" ]]; then + echo "ERROR: missing $CADDY" >&2 + exit 1 +fi +command -v caddy >/dev/null || { echo "ERROR: caddy not in PATH" >&2; exit 1; } + +mkdir -p "$SECRETS_DIR" +chown hernani:hernani "$SECRETS_DIR" +chmod 700 "$SECRETS_DIR" + +if [[ -f "$PASS_FILE" ]]; then + # shellcheck disable=SC1090 + # file format: USER=... PASS=... HASH=... + # PASS may contain spaces; read with grep + USER_NAME="$(awk -F= '/^USER=/{print substr($0,6); exit}' "$PASS_FILE")" + PASS="$(awk -F= '/^PASS=/{print substr($0,6); exit}' "$PASS_FILE")" + HASH="$(awk -F= '/^HASH=/{print substr($0,6); exit}' "$PASS_FILE")" + if [[ -z "$USER_NAME" || -z "$HASH" ]]; then + echo "ERROR: $PASS_FILE incomplete — move it aside and re-run" >&2 + exit 1 + fi + echo "OK: reusing credentials in $PASS_FILE" +else + PASS="$(openssl rand -base64 18 | tr -d '/+=' | head -c 20)" + HASH="$(caddy hash-password --plaintext "$PASS")" + umask 077 + cat >"$PASS_FILE" < str: + marker = f"{site} {{" + i = src.find(marker) + if i < 0: + raise SystemExit(f"ERROR: site block not found: {site}") + # already has basic_auth in this block? + j = src.find("\n}", i) + if j < 0: + raise SystemExit(f"ERROR: unclosed block: {site}") + block = src[i:j] + if "basic_auth" in block or "basicauth" in block: + print(f"OK: {site} already has basic_auth") + return src + needle = ' header Alt-Svc "clear"\n' + k = block.find(needle) + auth = ( + needle + + " basic_auth {\n" + + f" {user} {hash_caddy}\n" + + " }\n" + ) + if k >= 0: + new_block = block.replace(needle, auth, 1) + else: + # insert after opening brace + nl = block.find("\n") + new_block = block[: nl + 1] + auth + block[nl + 1 :] + print(f"OK: injected basic_auth in {site}") + return src[:i] + new_block + src[j:] + +for s in sites: + text = inject_block(text, s) + +if text == orig: + print("no Caddyfile change") +else: + path.write_text(text) + print(f"wrote {path}") +PY + +echo "== validate ==" +caddy validate --config "$CADDY" + +echo "== reload ==" +if systemctl is-active --quiet caddy; then + systemctl reload caddy +else + echo "WARN: caddy unit not active — start it yourself" >&2 +fi + +echo +echo "Done. Browser: https://dossiers.ngi.hacktivism.ch/ (and .2. / .3.)" +echo "User/pass: $PASS_FILE" +echo "Reload later: sudo caddy validate --config $CADDY && sudo systemctl reload caddy"