Compare commits
3 commits
master
...
magikoopa-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56460c6bd7 | ||
|
|
f6691c6de0 | ||
|
|
bb62ebea36 |
5 changed files with 229 additions and 1 deletions
24
2026/2026-09-05--taler-apt-src-ubuntu.md
Normal file
24
2026/2026-09-05--taler-apt-src-ubuntu.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# taler apt-src ubuntu (noble) on koopa
|
||||
|
||||
**2026-09-05** — Freigabe: create Ubuntu track next to existing trixie apt-src pods.
|
||||
|
||||
## container
|
||||
|
||||
| name | base | suite | image |
|
||||
|------|------|-------|-------|
|
||||
| `koopa-taler-deploy-test-apt-src-ubuntu` | `ubuntu:24.04` | `noble` @ `deb.taler.net/apt/ubuntu` | `localhost/…:setup` after commit |
|
||||
|
||||
ensure: `~/src/taler-monitoring/host-agent/ensure-apt-deploy-test-containers.sh ubuntu`
|
||||
(branch `llm-lightweight-monitoring` / tip after `v1.27.0`)
|
||||
|
||||
## verify
|
||||
|
||||
```bash
|
||||
podman ps -a --filter name=koopa-taler-deploy-test-apt-src-ubuntu
|
||||
ANSIBLE_SMOKE_PODMAN=1 ANSIBLE_SMOKE_REQUIRE_UBUNTU=1 \
|
||||
./taler-monitoring.sh ansible-smoke
|
||||
```
|
||||
|
||||
## notes
|
||||
|
||||
Debian trixie×4 unchanged. Spam mailbox secrets / durable monitord still separate Freigabe items.
|
||||
55
2026/2026-09-07--git-meta-origin-forgejo.md
Normal file
55
2026/2026-09-07--git-meta-origin-forgejo.md
Normal file
|
|
@ -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
|
||||
|
|
@ -53,7 +53,8 @@ regional_currency:
|
|||
regional_currency_common_amounts: "GOA:10 GOA:20 GOA:50 GOA:100 GOA:200 GOA:1000"
|
||||
regional_currency_static_coins_file: goa-exchange-coins.conf
|
||||
regional_currency_coin_withdraw_duration: 7 days
|
||||
regional_currency_default_debt_limit: "GOA:4503599627370496"
|
||||
# Must stay < 2^52 (libeufin amount overflow on withdraw confirm).
|
||||
regional_currency_default_debt_limit: "GOA:1000000000000"
|
||||
|
||||
regional_currency_exchange_master_public_key_expected: "TW6K5FXF81VYCAH0YWYX0SX98KBBSJ42VX27WAX01FTFH400QG10"
|
||||
regional_currency_exchange_master_priv_src: "{{ lookup('ansible.builtin.env', 'HOME') }}/git/admin-logs/koopa-admin-secrets/backups/goa/current/exchange-offline/master.priv"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
137
scripts/caddy/apply-dossiers-ngi-basicauth.sh
Executable file
137
scripts/caddy/apply-dossiers-ngi-basicauth.sh
Executable file
|
|
@ -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" <<EOF
|
||||
USER=${USER_NAME}
|
||||
PASS=${PASS}
|
||||
HASH=${HASH}
|
||||
EOF
|
||||
chown hernani:hernani "$PASS_FILE"
|
||||
chmod 600 "$PASS_FILE"
|
||||
echo "OK: wrote new password to $PASS_FILE (not git)"
|
||||
fi
|
||||
|
||||
# Caddyfile treats $ as env — double it for a literal bcrypt hash
|
||||
HASH_CADDY="${HASH//\$/\$\$}"
|
||||
|
||||
ts=$(date +%Y%m%d-%H%M%S)
|
||||
cp -a "$CADDY" "${CADDY}.bak-dossiers-auth-${ts}"
|
||||
echo "backup ${CADDY}.bak-dossiers-auth-${ts}"
|
||||
|
||||
python3 - "$CADDY" "$USER_NAME" "$HASH_CADDY" "${SITES[@]}" <<'PY'
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(sys.argv[1])
|
||||
user = sys.argv[2]
|
||||
hash_caddy = sys.argv[3]
|
||||
sites = sys.argv[4:]
|
||||
text = path.read_text()
|
||||
orig = text
|
||||
|
||||
def inject_block(src: str, site: str) -> 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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue