172 lines
7.7 KiB
Markdown
172 lines
7.7 KiB
Markdown
# paivana — `paivana.hacktivism.ch`
|
||
|
||
GNU Taler **paivana-httpd** reverse-proxy paywall (DD 95 / DD 76 style), GOA payments.
|
||
|
||
One process = one `BASE_URL` + one `DESTINATION_BASE_URL` + one `MERCHANT_BACKEND_URL`.
|
||
Shared **image / secrets / entrypoint / conf template**; per-service env sets
|
||
`PAIVANA_BASE_URL` + `PAIVANA_DESTINATION_BASE_URL`. Portal on **9025**; app
|
||
paywalls on **9028–9031** (Caddy unchanged). App backends listen loopback only
|
||
(`19128` SilverBullet, `19129` Galene HTTP, `19130` CryptPad edge, `19131` Meet).
|
||
|
||
| Item | Value |
|
||
|------|--------|
|
||
| Live | `/home/hernani/koopa-paivana/` |
|
||
| Containers | `koopa-paivana`, `koopa-paivana-{silverbullet,galene,cryptpad,meet}`, `koopa-paivana-upstream` |
|
||
| Image | `localhost/koopa-paivana:latest` (built from `Containerfile`); process **uid 1000** `paivana-httpd` |
|
||
| Upstream | portal: `nginxinc/nginx-unprivileged` on **:8080**; apps via host `172.17.0.1:19128–19131` |
|
||
| Host ports | **9025** portal; **9028/9029/9030/9031** app paywalls → Caddy |
|
||
| Currency | **GOA** (goa-shop); other units need other merchant backends / later instances |
|
||
| Merchant | `https://taler.hacktivism.ch/instances/goa-shop/` |
|
||
| Template | `paivana` (`template_type: paivana`, amount **`GOA:42`**, `website_regex: .*`) |
|
||
| Access | **`-g`** site-wide: pay once → that hostname free to browse |
|
||
|
||
## Layout
|
||
|
||
| Path | Role |
|
||
|------|------|
|
||
| `Containerfile` | Multi-stage: build paivana-httpd from `git.taler.net/paivana` + Taler libs |
|
||
| `compose.yml` | portal + 4 app paywalls + nginx upstream (YAML anchor `x-paivana-common`) |
|
||
| `conf/paivana.conf.template` | Shared conf; `@BASE_URL@` / `@DESTINATION_BASE_URL@` / secrets at start |
|
||
| `entrypoint.sh` | Env + secrets → run `paivana-httpd -g -f` |
|
||
| `secrets/` | **not in git** — live only |
|
||
| `upstream/` | Protected demo content |
|
||
| `container-koopa-paivana.service` | systemd --user oneshot compose up |
|
||
| `taler-systems.gpg` | Deb signing key (build context) |
|
||
|
||
## Secrets (live)
|
||
|
||
| File | Role |
|
||
|------|------|
|
||
| `~/koopa-paivana/secrets/merchant-access-token` | `secret-token:…` for goa-shop |
|
||
| `~/koopa-paivana/secrets/paivana-secret` | cookie MAC secret (stable across restarts) |
|
||
|
||
Mirror notes: `koopa-admin-secrets` → `koopa/home-hernani/koopa-paivana/secrets/` (paths only / examples).
|
||
|
||
## Was kaputt war (klar · 2026-07)
|
||
|
||
Drei **unabhängige** Defekte; Symptom oft gleich (Paywall 502 / tot / kein Template).
|
||
Stand: behoben auf koopa; nicht wiederholen.
|
||
|
||
### 1) Boot-Race: extra systemd-Unit nur für Upstream
|
||
|
||
| | |
|
||
|--|--|
|
||
| **Symptom** | Nach Reboot: `container-koopa-paivana-upstream.service` **failed** / start-limit-hit; Upstream fehlt oder Compose und Unit kämpfen. |
|
||
| **Ursache** | Separate User-Unit tat nur `podman start koopa-paivana-upstream` **ohne** dass Compose die Container schon angelegt hatte → **exit 125**. Compose-Unit startet **beide** Services (`paivana` + `upstream`) ohnehin. |
|
||
| **Fix** | **Nur** `container-koopa-paivana.service` (compose up). Separate Upstream-Unit: `disable --now`. Nicht neu anlegen. |
|
||
| **Nicht verwechseln mit** | Problem 2 (Merchant noch down → 502 trotz laufender Container). |
|
||
|
||
### 2) Start-Reihenfolge: Paivana vor Merchant-Apps → **502**
|
||
|
||
| | |
|
||
|--|--|
|
||
| **Symptom** | `paivana.hacktivism.ch` / `:9025` **502** nach Boot; Container laufen, Paywall/Template-Flow tot. |
|
||
| **Ursache** | Merchant-Container ist hoch, aber **In-App** (`taler-merchant-httpd` etc.) startet erst über `taler-merchant-apps.service` / `ensure-taler-apps`. Paivana braucht die **private Merchant-API** (Template `paivana` / goa-shop). Zu früh → 502. |
|
||
| **Fix** | Drop-in `configs/systemd/user/container-koopa-paivana.service.d/order.conf`: `After=` / `Wants=` `taler-merchant-apps.service` (+ ggf. merchant-Container). Siehe `2026/2026-07-16--reboot-recovery.md`. |
|
||
| **Check** | Merchant `https://taler.hacktivism.ch/config` **200**, dann Paivana smoke (unten). |
|
||
|
||
### 3) Pasta / DNS: Container erreicht Merchant nicht (Timeout / AAAA)
|
||
|
||
| | |
|
||
|--|--|
|
||
| **Symptom** | Paivana läuft, aber Template-Laden / Merchant-Calls **hängen oder scheitern**; Logs: Timeouts Richtung `taler.hacktivism.ch`. |
|
||
| **Ursache** | Rootless **pasta** hairpint öffentliche DNS nicht sauber. `extra_hosts: …:host-gateway` allein reichte nicht: oft gewinnt noch die **öffentliche AAAA**, Connection timeout. Merchant sitzt am Host (**~:9010**), erreichbar über Pasta-IPv4 **`172.17.0.1`**. |
|
||
| **Fix** | In `compose.yml` feste IPv4-Hosts (nicht nur host-gateway): |
|
||
|
||
```yaml
|
||
extra_hosts:
|
||
- "taler.hacktivism.ch:172.17.0.1"
|
||
- "bank.hacktivism.ch:172.17.0.1"
|
||
- "exchange.hacktivism.ch:172.17.0.1"
|
||
```
|
||
|
||
| | |
|
||
|--|--|
|
||
| **Commit** | `f26bf6a` (pin Taler hosts to pasta IPv4) |
|
||
|
||
### Kurz: was *nicht* das Problem war
|
||
|
||
- Caddy-Vhost an sich (leitet auf **9025**).
|
||
- Fehlen des Templates im Merchant (Template `paivana` / GOA:4200 war angelegt; ohne Merchant-Apps oder ohne Routing wirkt es so, als fehlte es).
|
||
- „Nur nginx-Upstream“ — Upstream ist unprivileged nginx **:8080**; ohne Problem 1/2/3 ist das stabil.
|
||
|
||
### Erwartet gesund
|
||
|
||
| Check | Expect |
|
||
|-------|--------|
|
||
| `curl -si http://127.0.0.1:9025/` | **302** → `/.well-known/paivana/templates/paivana#…` |
|
||
| `curl -si http://127.0.0.1:902{8,9,0}/` | **302** same template path (per-host BASE_URL) |
|
||
| `https://{paivana,silverbullet,galene,cryptpad,meet}.hacktivism.ch/` | unpaid → **302** `…/templates/paivana#…` (or paywall HTML) |
|
||
| monitoring `urls` | `www.paivana` OK |
|
||
| e2e (GOA, lokal) | `e2e.paivana` Template-Pay **GOA:42** (wenn `E2E_PAIVANA=1`) |
|
||
|
||
---
|
||
|
||
## Ops
|
||
|
||
```bash
|
||
# as hernani on koopa
|
||
cd ~/koopa-paivana
|
||
podman compose build
|
||
podman compose up -d
|
||
podman logs -f koopa-paivana
|
||
curl -si http://127.0.0.1:9025/ | head # 302 → /.well-known/paivana/templates/paivana#…
|
||
```
|
||
|
||
Autostart (**only** the compose unit — starts **both** `koopa-paivana` and
|
||
`koopa-paivana-upstream`):
|
||
|
||
```bash
|
||
mkdir -p ~/.config/systemd/user
|
||
cp ~/koopa-paivana/container-koopa-paivana.service ~/.config/systemd/user/
|
||
# required on koopa: After= merchant apps
|
||
# configs/systemd/user/container-koopa-paivana.service.d/order.conf
|
||
systemctl --user daemon-reload
|
||
systemctl --user enable --now container-koopa-paivana.service
|
||
```
|
||
|
||
**Do not** enable a separate `container-koopa-paivana-upstream.service` that only
|
||
runs `podman start koopa-paivana-upstream` — see failure **#1** above.
|
||
If such a unit exists:
|
||
`systemctl --user disable --now container-koopa-paivana-upstream.service`.
|
||
|
||
## Network notes
|
||
|
||
See failure **#3**. Live compose pins Taler hostnames to pasta IPv4
|
||
`172.17.0.1` so `paivana-httpd` reaches the host merchant private API without
|
||
public AAAA timeouts.
|
||
|
||
## Caddy
|
||
|
||
Vhost → `127.0.0.1:9025` (see `configs/caddy/Caddyfile`).
|
||
Flags `-g` (site-wide payment) and `-f` (X-Forwarded-For).
|
||
|
||
## Merchant template
|
||
|
||
Create (or replace via PATCH / DELETE+POST — see live merchant API):
|
||
|
||
```bash
|
||
curl -X POST 'https://taler.hacktivism.ch/instances/goa-shop/private/templates' \
|
||
-H "Authorization: Bearer secret-token:…" \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{
|
||
"template_id": "paivana",
|
||
"template_description": "Paivana paywall portal (GOA)",
|
||
"template_contract": {
|
||
"template_type": "paivana",
|
||
"summary": "Access to paivana.hacktivism.ch portal",
|
||
"website_regex": ".*",
|
||
"choices": [{ "amount": "GOA:42", "description": "Unlock portal (cryptpad / galene / silverbullet links)" }]
|
||
}
|
||
}'
|
||
```
|
||
|
||
goa-shop is GOA-only. TESTPAYSAN / FLOODS / talersticker CHF / stage-CHF need
|
||
other `MERCHANT_BACKEND_URL` values (separate Paivana process or later phase).
|
||
|
||
## Docs
|
||
|
||
- https://docs.taler.net/taler-paivana-manual.html
|
||
- https://docs.taler.net/design-documents/095-captcha-100.html
|
||
- https://docs.taler.net/design-documents/076-paywall-proxy.html
|
||
- https://docs.taler.net/manpages/paivana.conf.5.html
|