runv-server

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

commit 3046d7d0dd1380eedd7846e3b0de784e2dfc4977
parent 8f21b46d62364b6f11a92b0d06efa97dd079ac74
Author: Pablo Murad <pablo@pablomurad.com>
Date:   Fri, 27 Mar 2026 01:31:41 -0300

docs

Diffstat:
DDOCS_REBUILD_CHANGELOG.md | 111-------------------------------------------------------------------------------
Adocs/admin.md | 536+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 536 insertions(+), 111 deletions(-)

diff --git a/DOCS_REBUILD_CHANGELOG.md b/DOCS_REBUILD_CHANGELOG.md @@ -1,111 +0,0 @@ -# Changelog da reconstrução da documentação (runv-server) - -Documento em **pt-BR**. Data da passagem: conforme o commit em que este ficheiro foi adicionado. - -## Ficheiros criados (canónico `docs/`) - -| Ficheiro | Função | -|----------|--------| -| [docs/README.md](docs/README.md) | Porta de entrada, ordem de leitura, mapa rápido | -| [docs/00-overview.md](docs/00-overview.md) | Visão geral, limites público/privado, fontes de verdade | -| [docs/01-server-baseline-debian.md](docs/01-server-baseline-debian.md) | Debian, tempo, locale, pré-requisitos | -| [docs/02-admin-access-and-ssh.md](docs/02-admin-access-and-ssh.md) | Modelo root/admin, SSH | -| [docs/03-paths-files-and-state.md](docs/03-paths-files-and-state.md) | Caminhos `/var/lib/runv`, logs, email, web | -| [docs/04-bootstrap-and-base-system.md](docs/04-bootstrap-and-base-system.md) | `starthere.py`, quotas ext4, Apache, UFW | -| [docs/05-tools-and-system-experience.md](docs/05-tools-and-system-experience.md) | `tools.py`, MOTD, skel, jail SSH | -| [docs/06-site-and-apache.md](docs/06-site-and-apache.md) | `genlanding.py`, DocumentRoot, TLS | -| [docs/07-public-members-directory.md](docs/07-public-members-directory.md) | `build_directory.py`, `members.json`, privacidade | -| [docs/08-email.md](docs/08-email.md) | Mailgun, legado msmtp, ficheiros de estado | -| [docs/09-terminal-entre.md](docs/09-terminal-entre.md) | Conta `entre`, fila, limites (não provisiona Unix) | -| [docs/10-user-provisioning-and-admin-ops.md](docs/10-user-provisioning-and-admin-ops.md) | `create_runv_user.py`, fluxo de aprovação | -| [docs/11-daily-operations.md](docs/11-daily-operations.md) | Operação corrente | -| [docs/12-security-and-privacy.md](docs/12-security-and-privacy.md) | Confiança, dados sensíveis | -| [docs/13-troubleshooting.md](docs/13-troubleshooting.md) | Erros frequentes | -| [docs/14-smoke-tests-and-validation.md](docs/14-smoke-tests-and-validation.md) | Verificações seguras | -| [docs/15-glossary-and-reference.md](docs/15-glossary-and-reference.md) | Glossário, índice de scripts | -| [docs/diagrams/architecture.mmd](docs/diagrams/architecture.mmd) | Sequência SSH entre → fila (Mermaid) | -| [docs/diagrams/member-flow.mmd](docs/diagrams/member-flow.mmd) | Fluxo pedido → admin → dados públicos (Mermaid) | - -## Actualizações posteriores (código + docs) - -- **`genlanding.py --sync-public-only`:** cópia de `site/public/` para o DocumentRoot + `members.json`, sem reconfigurar Apache (`site/genlanding.py` v0.05). -- **`create_runv_user.py`:** após criar membro, invoca esse modo em vez de só `build_directory.py`; `--no-refresh-landing-members` omite cópia e JSON. -- **MOTD** [`tools/motd/60-runv`](tools/motd/60-runv): título “Últimos usuários online” sem o sufixo explicativo entre parêntesis. -- Documentação actualizada: `docs/06`, `docs/07`, `docs/10`, `docs/11`, `docs/13`, `docs/15`. - ---- - -Alteração mínima **fora** de `docs/` para não quebrar referências em código ou templates (reconstrução inicial): - -- [README.md](README.md) (raiz): ponteiro para `docs/README.md`. -- `tools/tools.py`, `site/build_directory.py`, `email/configure_mailgun.py`, `email/configure_msmtp_legacy.py`: docstrings / mensagens apontam para `docs/…` em vez de `.md` removidos nos módulos. -- `terminal/templates/admin_mail.txt`: linha de ajuda ao admin aponta para `docs/10-user-provisioning-and-admin-ops.md` (antes referia `terminal/docs/ADMIN.md`, removido). - -**Nota:** existiu cópia errónea em `dev-notes/DOCS_REBUILD_CHANGELOG.md`; foi removida — a versão canónica é **sempre** este ficheiro na raiz. - -## Fontes de evidência usadas - -- Código Python em `scripts/admin/`, `terminal/`, `site/`, `tools/`, `email/`, `patches/`. -- `terminal/config.example.toml`, exemplos em `site/example-users.json`. -- Documentação modular **antes da remoção**: `INSTALL.md` (raiz), `site/*.md`, `terminal/docs/*.md`, `tools/docs/*.md`, `email/docs/*.md`, `scripts/**/*.md`, `dev-notes/RUNV_CURRENT_STATE_AUDIT.md`. -- `terminal/docs/ARCHITECTURE.md` (fluxo e componentes). -- Diff e defaults nos scripts (caminhos predefinidos, flags). - -## Contradições identificadas e como foram tratadas - -1. **Cron vs refresh “sem cron”** - - `INSTALL.md` sugeria exemplo de cron para `build_directory.py`. - - `site/README.md` enfatizava refresh via `create_runv_user.py` / `genlanding.py` sem cron. - - **Resolução:** em `docs/07-public-members-directory.md` (e operações diárias) ficam explícitos **dois modos válidos**: regeneração automática nos fluxos de provisionamento/landing **ou** cron/manual — não são mutuamente exclusivos. - -2. **`USO.md` inexistente** - - `terminal/docs/ARCHITECTURE.md` referia `USO.md`, que não existia no repositório. - - **Resolução:** descrito em `docs/09-terminal-entre.md` e neste changelog; o fluxo cobre-se nos docs canónicos. - -3. **Múltiplos `INSTALL.md` por módulo** - - Conteúdo sobreposto entre raiz e `tools/`, `email/`, `terminal/`. - - **Resolução:** um único percurso numerado em `docs/01`–`docs/11`, com secções por componente. - -## O que ficou explicitamente **NÃO VERIFICADO** neste ambiente - -- Execução de `--help` e comportamento em runtime de `scripts/admin/create_runv_user.py`, `terminal/setup_entre.py` e `site/genlanding.py` em **Windows**: falham no import (`fcntl` / `grp` inexistentes). **Verificação plena:** correr em **Debian/Linux** alvo. -- Estado real de um servidor de produção (Apache vhosts, TLS, quotas aplicadas, conteúdo de `/var/lib/runv/users.json`): apenas inferência a partir de defaults no código — qualquer deploy concreto deve ser confirmado no servidor. - -## Verificações executadas (2026-03-22, Windows / PowerShell) - -| Comando | Resultado | -|---------|-----------| -| `python -m compileall -q scripts terminal site tools email patches` | Exit 0 | -| `cd email && python -m pytest tests/ -q` | 11 passed | -| `python site/build_directory.py --users-json site/example-users.json --dry-run` | JSON válido no stdout (`username`, `since`, `path`) | -| `python site/build_directory.py --help` | Exit 0 | -| `python email/configure_mailgun.py --help` | Exit 0 | -| `python scripts/admin/create_runv_user.py --help` | **Falha:** `ModuleNotFoundError: fcntl` | -| `python terminal/setup_entre.py --help` | **Falha:** `ModuleNotFoundError: grp` | -| `python site/genlanding.py --help` | **Falha:** `ModuleNotFoundError: grp` | -| `git status -sb` | Registado no momento da passagem (working tree com `docs/` e alterações pendentes) | - -## Pressupostos dependentes do ambiente (operador) - -- **Um único host Debian** com paths tipo `/var/www/runv.club/html`, `/var/lib/runv/`, `/opt/runv/terminal/` — são defaults no código; outros caminhos exigem flags explícitas. -- **Root/sudo** para bootstrap, `tools.py`, email, `entre`, provisionamento de utilizadores. -- **Decisões de segurança** (firewall, TLS, política de passwords SSH) combinam o que o repo automatiza com o que o operador mantém — ver `docs/02` e `docs/12`. - -## Documentação `.md` removida nesta reconstrução - -Removidos de propósito para evitar duplicação e contradições com `docs/` (lista não exaustiva de paths relativos à raiz do repo): - -- `INSTALL.md` -- `dev-notes/RUNV_MEMBER_BUBBLE_CHANGELOG.md` (changelog local; conteúdo operacional relevante está em `docs/07` e `docs/10`) -- `dev-notes/RUNV_CURRENT_STATE_AUDIT.md` -- `site/README.md`, `site/build_directory.md`, `site/genlanding.md`, `site/news/README.md` -- `terminal/README.md`, `terminal/docs/INSTALL.md`, `terminal/docs/ARCHITECTURE.md`, `terminal/docs/ADMIN.md` -- `tools/README.md`, `tools/skel/README.md`, `tools/docs/INSTALL.md`, `tools/docs/ADMIN.md`, `tools/docs/USER_EXPERIENCE.md` -- `email/README.md`, `email/docs/INSTALL.md`, `email/docs/ADMIN.md`, `email/docs/INTEGRATION.md`, `email/docs/TROUBLESHOOTING.md` -- `scripts/starthere.md`, `scripts/skel.md`, `scripts/create_runv_user.md`, `scripts/del-user.md`, `scripts/admin/perm1.md`, `scripts/doom/doom.md`, `scripts/docs/*.md` - -**Não removido:** `email/.pytest_cache/README.md` (artefacto gerado por pytest; não é documentação do produto). - -## Adequação para um operador novo - -A documentação é **utilizável** para alguém que não escreveu o código, desde que leia `docs/README.md` na ordem sugerida e execute verificações em **Debian** onde os scripts Unix são relevantes. Lacunas conhecidas estão marcadas como NÃO VERIFICADO ou recomendação, sem afirmar CI/deploy que não exista no repositório. diff --git a/docs/admin.md b/docs/admin.md @@ -0,0 +1,536 @@ +# Guia do Administrador + +Manual prático para operações administrativas do `runv-server` no servidor Debian do `runv.club`. + +Use este documento como folha de referência rápida. Quando houver dúvida sobre comportamento detalhado, a fonte de verdade continua sendo o código dos scripts em `scripts/`, `tools/`, `site/`, `terminal/`, `patches/` e a árvore `docs/`. + +## Convenções + +Assuma: + +```bash +cd /caminho/para/runv-server +``` + +Nos exemplos abaixo, substitua: + +- `REPO` pelo caminho real do clone +- `USER` pelo username Unix do membro +- `EMAIL` pelo email do membro +- `PUBKEY.pub` pelo arquivo `.pub` aprovado + +## Pré-requisitos + +- Executar como `root` ou com `sudo` +- Servidor Debian com Python 3 +- Quotas ext4 prontas se for usar quota automática +- Apache / DocumentRoot configurados se quiser refresh público automático + +## Bootstrap inicial do servidor + +Bootstrap conservador do host: + +```bash +sudo python3 REPO/scripts/admin/starthere.py --verbose +``` + +Simular sem alterar: + +```bash +sudo python3 REPO/scripts/admin/starthere.py --dry-run --verbose +``` + +## Ferramentas globais, MOTD, skel e IRC + +Aplicar ferramentas globais, `MOTD`, `skel`, drop-in SSH jailed e patch IRC: + +```bash +sudo python3 REPO/tools/tools.py +``` + +Simular: + +```bash +sudo python3 REPO/tools/tools.py --dry-run --verbose +``` + +Reaplicar só arquivos e patch IRC, sem APT: + +```bash +sudo python3 REPO/tools/tools.py --skip-apt +``` + +## Setup do onboarding via SSH (`entre`) + +Instalar/configurar o usuário `entre` e o fluxo de pedido: + +```bash +sudo python3 REPO/terminal/setup_entre.py --help +``` + +Exemplo de execução: + +```bash +sudo python3 REPO/terminal/setup_entre.py +``` + +## Fila de pedidos + +Fila padrão: + +- `/var/lib/runv/entre-queue/` + +Listar pedidos: + +```bash +sudo ls -lah /var/lib/runv/entre-queue +``` + +Inspecionar um pedido JSON: + +```bash +sudo cat /var/lib/runv/entre-queue/ID_DO_PEDIDO.json +``` + +Ou com formatação: + +```bash +sudo jq . /var/lib/runv/entre-queue/ID_DO_PEDIDO.json +``` + +Log do onboarding: + +```bash +sudo tail -n 200 /var/log/runv/entre.log +``` + +## Criar usuário novo + +Fluxo canônico de provisionamento: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub +``` + +Simular: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub \ + --dry-run --verbose +``` + +Exigir quota pronta antes de criar: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub \ + --require-quota +``` + +Criar sem quota: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub \ + --no-quota +``` + +Criar sem jail: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub \ + --no-jail +``` + +Criar com valores de quota explícitos: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub \ + --quota-soft-mb 450 \ + --quota-hard-mb 500 \ + --quota-inode-soft 10000 \ + --quota-inode-hard 12000 +``` + +Modo interativo: + +```bash +sudo python3 REPO/scripts/admin/create_runv_user.py --interactive +``` + +## Atualizar usuário existente + +Abrir menu interativo: + +```bash +sudo python3 REPO/scripts/admin/update_user.py --interactive --username USER +``` + +Atualizar email: + +```bash +sudo python3 REPO/scripts/admin/update_user.py --username USER --email EMAIL +``` + +Substituir chave pública: + +```bash +sudo python3 REPO/scripts/admin/update_user.py \ + --username USER \ + --ssh-replace-file PUBKEY.pub +``` + +Acrescentar chave pública: + +```bash +sudo python3 REPO/scripts/admin/update_user.py \ + --username USER \ + --ssh-append-file PUBKEY.pub +``` + +Definir nova senha de login: + +```bash +sudo python3 REPO/scripts/admin/update_user.py --username USER --set-password +``` + +Alterar quota: + +```bash +sudo python3 REPO/scripts/admin/update_user.py \ + --username USER \ + --quota-soft-mb 450 \ + --quota-hard-mb 500 \ + --quota-inode-soft 10000 \ + --quota-inode-hard 12000 +``` + +Simular: + +```bash +sudo python3 REPO/scripts/admin/update_user.py \ + --username USER \ + --email EMAIL \ + --dry-run +``` + +## Remover usuário / banimento técnico + +Remover conta e home: + +```bash +sudo python3 REPO/scripts/admin/del-user.py --username USER +``` + +Execução não interativa: + +```bash +sudo python3 REPO/scripts/admin/del-user.py --username USER -y +``` + +Simular: + +```bash +sudo python3 REPO/scripts/admin/del-user.py --username USER --dry-run +``` + +Observações: + +- o script desmonta jail/binds antes de remover +- atualiza `users.json` +- pode sincronizar a landing pública após a remoção + +## Remoção em massa + +Ferramenta perigosa, só com backup: + +```bash +sudo python3 REPO/scripts/doom/doom.py --help +``` + +Simular: + +```bash +sudo python3 REPO/scripts/doom/doom.py --dry-run +``` + +## Reparar Gopher e Gemini + +Reconfigurar infraestrutura de Gopher e Gemini: + +```bash +sudo python3 REPO/scripts/admin/setup_alt_protocols.py +``` + +Simular: + +```bash +sudo python3 REPO/scripts/admin/setup_alt_protocols.py --dry-run --verbose +``` + +Sem instalar pacotes: + +```bash +sudo python3 REPO/scripts/admin/setup_alt_protocols.py --skip-install +``` + +Sem backfill de usuários: + +```bash +sudo python3 REPO/scripts/admin/setup_alt_protocols.py --skip-backfill +``` + +## Site público e landing + +Primeira montagem completa da landing / Apache: + +```bash +sudo python3 REPO/site/genlanding.py +``` + +Somente sincronizar `site/public` + `members.json` para o DocumentRoot: + +```bash +sudo python3 REPO/site/genlanding.py --sync-public-only \ + --document-root /var/www/runv.club/html \ + --members-users-json /var/lib/runv/users.json +``` + +Atualizar só `members.json`: + +```bash +sudo python3 REPO/site/build_directory.py \ + --users-json /var/lib/runv/users.json \ + -o /var/www/runv.club/html/data/members.json +``` + +## Notícias + +Publicar notícias novas: + +```bash +sudo python3 REPO/site/news/publish_news.py +``` + +Simular: + +```bash +sudo python3 REPO/site/news/publish_news.py --dry-run +``` + +Publicar sem sincronizar Apache: + +```bash +sudo python3 REPO/site/news/publish_news.py --skip-genlanding +``` + +## Wiki + +Gerar a wiki estática localmente a partir de `site/wiki/*.txt`: + +```bash +python3 REPO/site/wiki/build_wiki.py +``` + +Depois, sincronizar a landing: + +```bash +sudo python3 REPO/site/genlanding.py --sync-public-only \ + --document-root /var/www/runv.club/html \ + --members-users-json /var/lib/runv/users.json +``` + +## Email + +Configurar Mailgun: + +```bash +sudo python3 REPO/email/configure_mailgun.py --help +``` + +Configurar msmtp: + +```bash +sudo python3 REPO/email/configure_msmtp.py --help +``` + +Modo legado SMTP/msmtp: + +```bash +sudo python3 REPO/email/configure_msmtp_legacy.py --help +``` + +Diagnóstico: + +```bash +sudo sh REPO/email/scripts/diagnose_msmtp.sh +``` + +Teste de envio: + +```bash +sudo sh REPO/email/scripts/send_test_mail.sh +``` + +## IRC da casa + +Aplicar/reaplicar a configuração IRC em todos os usuários: + +```bash +sudo python3 REPO/patches/patch_irc.py --all-users +``` + +Aplicar a um único usuário: + +```bash +sudo python3 REPO/patches/patch_irc.py --user USER +``` + +Simular: + +```bash +sudo python3 REPO/patches/patch_irc.py --all-users --dry-run --verbose +``` + +Padrão atual: + +- servidor `irc.tilde.chat` +- porta `6697` +- TLS ligado +- canal `#runv` +- comando de uso do membro: `chat` + +## Moderação da comunidade e square + +### Política + +A política editorial e disciplinar está em: + +- [site/wiki/05_punicoes-e-moderacao.txt](/Z:/Códigos/runv-server/site/wiki/05_punicoes-e-moderacao.txt) +- [site/wiki/04_regras-da-comunidade.txt](/Z:/Códigos/runv-server/site/wiki/04_regras-da-comunidade.txt) + +### O que este repositório faz + +Este repositório fornece os comandos para: + +- criar conta +- atualizar conta +- remover conta +- regenerar presença pública +- aplicar infraestrutura e serviços + +### O que este repositório não fornece + +Este snapshot **não inclui** um CLI canônico próprio para moderar a `square` em nível de posts, salas, threads, silenciamento, suspensão comunitária ou revisão de conteúdo dentro da aplicação social. + +Então, para `square`, a orientação operacional é: + +- aplicar a moderação pelos controles nativos da própria plataforma `square` que vocês já operam +- registrar internamente a medida tomada +- se a medida envolver perda de acesso ao servidor, complementar com `del-user.py` ou `update_user.py`, conforme o caso + +Exemplos de fluxo: + +1. Advertência ou limitação comunitária na `square`: usar a ferramenta da própria `square`; não há comando neste repo. +2. Suspensão temporária na `square` sem remover conta Unix: executar na `square`; se necessário, ajustar quota, senha ou chaves com `update_user.py`. +3. Banimento permanente com encerramento de conta no servidor: moderar na `square` e depois executar `del-user.py`. + +## Comandos de inspeção úteis + +Ver quotas: + +```bash +quota -vs USER +sudo repquota -s /home +``` + +Ver mounts: + +```bash +mount | grep usrquota +findmnt /home +``` + +Ver Apache: + +```bash +sudo apache2ctl configtest +sudo systemctl status apache2 +``` + +Ver SSH: + +```bash +sudo sshd -t +sudo systemctl status ssh +``` + +Ver usuários com sessão: + +```bash +who +last +``` + +Ver logs do onboarding: + +```bash +sudo tail -n 200 /var/log/runv/entre.log +``` + +## Fluxos rápidos + +### Aprovar pedido e criar conta + +```bash +sudo jq . /var/lib/runv/entre-queue/ID_DO_PEDIDO.json +sudo python3 REPO/scripts/admin/create_runv_user.py \ + --username USER \ + --email EMAIL \ + --public-key-file PUBKEY.pub +``` + +### Corrigir perfil público + +```bash +sudo python3 REPO/site/genlanding.py --sync-public-only \ + --document-root /var/www/runv.club/html \ + --members-users-json /var/lib/runv/users.json +``` + +### Corrigir IRC de todos os usuários + +```bash +sudo python3 REPO/patches/patch_irc.py --all-users +``` + +### Banir tecnicamente uma conta + +```bash +sudo python3 REPO/scripts/admin/del-user.py --username USER -y +``` + +## Referências rápidas + +- [docs/10-user-provisioning-and-admin-ops.md](/Z:/Códigos/runv-server/docs/10-user-provisioning-and-admin-ops.md) +- [docs/11-daily-operations.md](/Z:/Códigos/runv-server/docs/11-daily-operations.md) +- [docs/05-tools-and-system-experience.md](/Z:/Códigos/runv-server/docs/05-tools-and-system-experience.md) +- [docs/06-site-and-apache.md](/Z:/Códigos/runv-server/docs/06-site-and-apache.md) +- [docs/08-email.md](/Z:/Códigos/runv-server/docs/08-email.md) +- [docs/09-terminal-entre.md](/Z:/Códigos/runv-server/docs/09-terminal-entre.md)