runv-server

server tooling for runv.club
Log | Files | Refs | README

commit 61272ab855cf56544337b81c78a78da16ad8d9f3
parent 9e010b7150f86e8eafbcdcaee5d45c686d2077e8
Author: Pablo Murad <pablo@pablomurad.com>
Date:   Sat, 21 Mar 2026 16:41:56 -0300

fix

Diffstat:
Mscripts/admin/setup_alt_protocols.py | 11++++++-----
Mscripts/docs/alt_protocols.md | 6++++--
2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/scripts/admin/setup_alt_protocols.py b/scripts/admin/setup_alt_protocols.py @@ -7,7 +7,7 @@ Infraestrutura Gopher (gophernicus) e Gemini (molly-brown) para runv.club. Idempotente, dry-run, subprocess sem shell. Executar como root no Debian. -Versão 0.11 — runv.club +Versão 0.12 — runv.club """ from __future__ import annotations @@ -32,7 +32,7 @@ from typing import Any, Final # Constantes # --------------------------------------------------------------------------- -VERSION: Final[str] = "0.11" +VERSION: Final[str] = "0.12" LETSENCRYPT_LIVE: Final[Path] = Path("/etc/letsencrypt/live") LETSENCRYPT_ARCHIVE: Final[Path] = Path("/etc/letsencrypt/archive") @@ -75,7 +75,7 @@ DEFAULT_USER_INDEX_GMI: Final[str] = """# ~{username} — runv.club (Gemini) Bem-vindo ao teu capsule em `gemini://runv.club/~{username}/` (canónico Molly: um só segmento de path **`/~{username}/`**, tilde **colado** ao nome). O formato `gemini://runv.club/~/{username}/` (slash extra) redirecciona para o canónico. **Não** uses `gemini://runv.club/{username}` — não é capsule. -Edita este ficheiro em `~/public_gemini/index.gmi`. Mantém pastas **755** e ficheiros **644** para o servidor ler o conteúdo. +Edita este ficheiro em `~/public_gemini/index.gmi`. Mantém pastas **755** e ficheiros **644** para o servidor ler o conteúdo (se usares **ACL** POSIX, garante leitura efectiva para o serviço — `getfacl`). ## Dicas @@ -709,7 +709,7 @@ def _runuser_can_read( def _www_data_can_read(path: Path, *, dry_run: bool, log: logging.Logger) -> bool | None: - """Compatível com Molly Brown (utilizador típico ``www-data`` no Debian).""" + """Heurística de leitura como ``www-data`` (ACL POSIX pode afectar o UID real do Molly).""" return _runuser_can_read(path, "www-data", dry_run=dry_run, log=log) @@ -790,7 +790,8 @@ def validate_final( if can is False: log.warning( "amostra %s: www-data não consegue ler %s (runuser … test -r falhou). " - "Confirme home 755 (ou o+x), public_gemini 755, index.gmi 644 e symlink %s.", + "Confirme home 755 (ou o+x), public_gemini 755, index.gmi 644, symlink %s; " + "se `ls -l` mostrar +, veja getfacl no path (ACL).", sample, index_gmi, sl, diff --git a/scripts/docs/alt_protocols.md b/scripts/docs/alt_protocols.md @@ -25,8 +25,10 @@ O Molly **não** espelha o HTTP `mod_userdir` no mesmo path: **`gemini://runv.cl Apache (`mod_userdir`), **gophernicus** e **molly-brown** precisam de **execução para «others»** (`o+x`, mínimo) em **cada** componente do caminho até a pasta pública (`~/public_html`, `~/public_gopher`, `~/public_gemini`). O utilizador de runtime **não é o mesmo** em todos: no Debian o pacote **molly-brown** usa **`User=molly-brown`** com **`DynamicUser=yes`** (não `www-data`); o **gophernicus** usa o **`User=`** do unit (tipicamente `gophernicus`) — veja `/lib/systemd/system/gophernicus@.service`. Uma home em **`700`** impede a travessia: **HTTP, Gopher e Gemini** deixam de servir conteúdo (p.ex. Gemini **«Not found»** com `index.gmi` presente). +- **ACL (POSIX):** se `ls -l` mostrar **`+`** nos modos, há entradas **`getfacl`** além do `chmod`. Uma **mask** restritiva ou ausência de leitura efectiva para «other» / utilizador do serviço pode bloquear o Apache, gophernicus ou Molly mesmo com **`644`/`755`** aparentes. Diagnóstico: `getfacl ~/public_gemini/index.gmi` (e directórios no caminho). + - **Novas contas:** [`create_runv_user.py`](../admin/create_runv_user.py) aplica **`755`** na home em `apply_runv_permissions`. -- **Backfill:** a partir do **v0.07**, [`setup_alt_protocols.py`](../admin/setup_alt_protocols.py) repõe a home do utilizador para **`755`** quando o modo actual é outro (com registo em log). O **v0.08** corrige a detecção de caminhos Let's Encrypt quando `live`/`archive` são **symlinks**. O **v0.09** introduziu redirects Molly baseados numa leitura incorrecta do README upstream. O **v0.11** corrige **`[TempRedirects]`** para **`/~/user…` → `/~user…`** (alinhado ao `resolvePath` em Go). Validação **`test -r`** do `gophermap` com o utilizador do serviço gophernicus mantém-se. +- **Backfill:** a partir do **v0.07**, [`setup_alt_protocols.py`](../admin/setup_alt_protocols.py) repõe a home do utilizador para **`755`** quando o modo actual é outro (com registo em log). O **v0.08** corrige a detecção de caminhos Let's Encrypt quando `live`/`archive` são **symlinks**. O **v0.09** introduziu redirects Molly baseados numa leitura incorrecta do README upstream. O **v0.11** corrige **`[TempRedirects]`** para **`/~/user…` → `/~user…`** (alinhado ao `resolvePath` em Go). O **v0.12** documenta **ACL POSIX** na travessia e alarga o **WARNING** do `test -r` do `index.gmi` com indicação a `getfacl` quando `ls` mostra `+`. Validação **`test -r`** do `gophermap` com o utilizador do serviço gophernicus mantém-se. - **Conflito:** [`patches/patch_permissions.py`](../../patches/patch_permissions.py) pode aplicar **`chmod 700`** em cada `/home/<user>` por política de privacidade — isso **quebra** a hospedagem em `public_*` até voltar a alinhar permissões (provisionamento ou `chmod` manual). ## Let's Encrypt e chave TLS (v0.07+; symlinks v0.08+) @@ -52,7 +54,7 @@ Se o grupo **`ssl-cert`** não existir no sistema, o script regista **WARNING** No fim da execução, além de verificar ficheiros e symlink **como root**: - Se **`gophernicus.socket`** estiver **`active`**, o script tenta **`runuser -u <User=do_unit> -- test -r`** no **`gophermap`** da primeira conta da lista (o `User=` lê-se de `/lib/systemd/system/gophernicus@.service`; fallback **`gophernicus`**). Falha → **WARNING** (home `755`/`o+x`, `public_gopher` `755`, `gophermap` `644`). -- Se **`molly-brown@`** estiver **`active`**, tenta **`runuser -u www-data -- test -r`** no **`index.gmi`** da amostra (heurística: o unit Debian usa **`molly-brown`** dinâmico; ficheiros **`644`** e pastas **`755`** devem permitir leitura a «others»). Falha → **WARNING** (`public_gemini` `755`, `index.gmi` `644`, symlink `/var/gemini/users/<user>`). +- Se **`molly-brown@`** estiver **`active`**, tenta **`runuser -u www-data -- test -r`** no **`index.gmi`** da amostra (heurística: o unit Debian usa **`molly-brown`** dinâmico; ficheiros **`644`** e pastas **`755`** devem permitir leitura a «others» — ou **ACL** compatível; ver nota **ACL** na secção de travessia). Falha → **WARNING** (`public_gemini` `755`, `index.gmi` `644`, symlink `/var/gemini/users/<user>`). Em **`--dry-run`**, só regista os comandos. Sem **`runuser`** (util-linux), estes passos são omitidos.