Ir para o conteúdo

Verificar a instalação

Os binários

peart version
peart-portal version

Assinaturas de release

Todo release assina seu manifesto de checksums e seu SBOM sem chave (keyless) com o cosign, publicado no log de transparência público do Sigstore. Não há chave pública a buscar; a identidade é o fluxo de release. Verifique o manifesto:

cosign verify-blob \
  --certificate-identity-regexp 'https://github.com/mentesan/peart/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --signature checksums.txt.sig --certificate checksums.txt.pem \
  checksums.txt

Depois confira os binários contra o manifesto verificado:

sha256sum --check --ignore-missing checksums.txt

O SBOM é assinado da mesma forma; verifique o sbom.json com seu sbom.json.sig e sbom.json.pem.

A imagem de container

A imagem é assinada pelo digest do conteúdo, não por uma tag que se move:

cosign verify \
  --certificate-identity-regexp 'https://github.com/mentesan/peart/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/mentesan/peart@<digest>

O bill of materials do software

O SBOM do release é um documento CycloneDX listando cada módulo Go e cada pacote de front-end vendorizado. Leia-o para ver exatamente de que um dado release é construído; a Segurança do ciclo de desenvolvimento explica como ele é produzido.

O sidecar de renderização recebeu o socket (bare metal)

O sidecar roda sem rede própria, e é alcançável porque o peart-render.socket abre a porta fora desse isolamento e entrega o descritor já ouvindo. Três passos dizem se a entrega aconteceu, e cada um prova uma coisa diferente.

systemctl status peart-render.socket

O socket está ativo e ouvindo em 127.0.0.1:8090. Essa é a metade que abre a porta. Ver o peart-render.service como inativo aqui é o esperado, e não defeito: ele sobe na primeira conexão.

journalctl -u peart-render

Depois da primeira geração de relatório (ou da checagem de saúde que a superfície interna faz ao subir, que é ela mesma a primeira conexão), o log traz:

peart-render listening on the socket systemd passed (127.0.0.1:8090)

Essa frase, e nenhuma outra, é o que prova que o descritor foi herdado. Se em vez dela aparecer peart-render listening on 127.0.0.1:8090, sem menção ao socket, o serviço abriu a porta por conta própria dentro do namespace de rede dele, e nada de fora vai alcançá-lo. O conserto é habilitar o socket e parar de habilitar o serviço: Rodar como serviço tem os comandos, e Atualização tem o disable de que uma instalação existente também precisa.

Se o serviço sobe, a linha certa aparece, e ainda assim a conexão não completa, o que sobrou é o filtro de endereços alcançando o socket herdado. Não remova IPAddressDeny=any nem PrivateNetwork=yes: é o isolamento atrás do qual o renderizador existe. Relate o caso: é decisão de desenho a tomar, não instalação a remendar.

Um aviso de sidecar logo depois do boot

Com ativação por socket o serviço sobe na primeira conexão, e o Python com o WeasyPrint leva alguns segundos para subir. A checagem que a superfície interna faz no arranque é melhor esforço e não é fatal (um sidecar ainda inalcançável não pode recusar toda outra rota que o processo serve), e é refeita, preguiçosamente, na primeira vez que um relatório é de fato gerado. Então um aviso de sidecar não verificado nos primeiros momentos depois do boot se resolve sozinho, e não pede ação.

A primeira geração de relatório (bare metal)

Gerar um relatório é a única checagem que exercita o caminho de renderização inteiro, e é a que pega um diretório de trabalho com grupo ou modos errados. O diretório de job é onde dois usuários se encontram: o peart escreve o HTML e as cópias das evidências, o peart-render lê esses arquivos e escreve o out.pdf de volta. Se qualquer um dos lados não conseguir, a geração falha e a interface diz apenas que falhou.

journalctl -u peart-render -n 20

O sidecar nomeia a falha e onde ela aconteceu, por exemplo:

render failed for job 01J8Z...: PermissionError: [Errno 13] Permission denied: '/var/lib/peart/work/01J8Z.../index.html'

Um PermissionError ali quer dizer que o contrato de grupo não está de pé. Confira o diretório de trabalho e as duas participações:

ls -ld /var/lib/peart/work
id peart
id peart-render

O diretório precisa ser peart:peart-work com 2750 -- drwxr-s---, sendo o s o bit setgid que põe cada arquivo novo no grupo compartilhado -- e os dois usuários precisam listar peart-work. O grupo lê e atravessa, e não escreve: o renderizador só lê o que foi preparado para ele e devolve o PDF pela conexão, então a escrita de grupo saiu e o setgid que entrega o grupo ficou. A página Primeira execução e configuração tem os comandos.

Procure no journal, e não no diretório de trabalho: o diretório de job é destruído ao fim de cada tentativa, com ou sem sucesso, então quando você for olhar não sobrou nada para inspecionar. A linha de log é a evidência que fica.

As duas superfícies sobem em qualquer ordem de abertura do banco (bare metal)

As duas superfícies abrem o mesmo peart.db em modo WAL, e o SQLite cria o peart.db-wal e o peart.db-shm quando o primeiro processo o abre, removendo os dois quando o último fecha de forma limpa. Os companheiros são, portanto, criados de novo a cada boot, por quem tiver subido primeiro, e nada ordena as duas units. A ordem é sorteada, e é por isso que uma instalação passa em todas as conferências no dia em que foi feita e falha no primeiro reboot.

Reinicie o host e confirme que as duas superfícies respondem. Depois force a ordem que não é a de sorte:

sudo systemctl stop peart peart-portal
sudo systemctl start peart-portal
sudo systemctl start peart
systemctl is-active peart peart-portal

As duas têm de responder active. Quando a filiação falta, a superfície interna não sobe, e o journalctl -u peart -n 20 mostra ela recusando o banco de que é dona:

unable to open database file (14)

com a unit reiniciando em laço atrás disso. O conserto é a filiação de grupo, não os modos dos arquivos: o peart.service declara SupplementaryGroups=peart-portal, e a Primeira execução e configuração diz por quê. Confira com id peart, que tem de listar peart-portal ao lado de peart-work.

O que cada conferência de ponta a ponta prova (bare metal)

As conferências acima testam um mecanismo cada. Estas quatro exercitam o conjunto, e a razão de fazer as quatro é que cada uma falha por um motivo diferente, então passar numa não diz nada sobre as outras.

Gere um relatório. Ele prova três coisas de uma vez, e são exatamente as que quebram numa unit endurecida: o sidecar recebeu o socket dele e respondeu sem rede própria, o passo de metadados do PDF rodou sem diretório pessoal gravável, e o diretório de job carregou o grupo compartilhado para o renderizador ler o que foi preparado. Falha aqui é a de mais causas possíveis, e é por isso que Quando a causa é uma diretiva de endurecimento é indexada pela linha de log.

Abra uma evidência. Numa instalação migrada é a conferência que mais importa, porque é a única que prova que a chave mestra que está no lugar é aquela para a qual a evidência foi cifrada. Uma chave que não bate falha aqui e em lugar nenhum mais, e num volume cifrado ela também prova que o volume decifrou, o que nenhum "o serviço subiu" informa.

Entre no portal. Isso prova que o banco e os arquivos -wal e -shm ao lado dele são graváveis pelo portal, porque uma sessão é uma escrita. É pergunta diferente de saber se a superfície interna consegue abrir o banco, que tem conferência própria: os dois processos chegam àquele arquivo por caminhos diferentes, e cada caminho quebra sozinho.

Num volume cifrado, reinicie. Isso prova que o volume desbloqueia sem ninguém no console e que os serviços esperaram a montagem em vez de escrever num ponto de montagem vazio. Endurecimento do host traz o lado negativo desse teste, tirar o servidor de chave do ar, que é a metade que prova que a cifra está mesmo valendo.

A instalação está funcionando quando

A superfície interna responde na porta dela atrás do proxy, o primeiro acesso pede para criar o administrador e inscrever o TOTP, e um relatório gerado renderiza pelo sidecar. Se a geração de relatório falhar numa instalação bare metal, a primeira coisa a conferir é se o sidecar recebeu o socket; depois disso, o que o journal diz sobre a primeira geração, e que o sidecar está de pé e que o token dele bate dos dois lados.