Feito com Chinaski

Reforço de Segurança

Reforço de segurança

Um deployment Chinaski vai ao ar trancado por padrão: o serviço roda numa sandbox systemd, os arquivos têm permissões restritivas, o daemon se liga ao loopback atrás de um reverse proxy, e o CMS adiciona headers de segurança estritos a cada resposta. Esta página explica o que são essas proteções e algumas coisas que você pode fazer para mantê-las intactas.

Sandboxing do systemd

A unit systemd de produção executa cada instância como um usuário dedicado chinaski em uma sandbox estrita:

  • Todo o sistema de arquivos é somente leitura, exceto o diretório da própria instância; uma exploração no app não consegue alcançar mais nada no host.
  • A instância recebe um /tmp privado, não enxerga os diretórios home e não pode mexer nas configurações do kernel nem criar arquivos privilegiados.
  • A memória é limitada a 1 GB (com um teto flexível de 768 MB), a CPU a 200% e 256 tarefas concorrentes, para que um job descontrolado não esgote o host.
  • No desligamento o serviço para de forma graciosa, dando tempo para que as requisições em andamento e um build em execução terminem.
  • Os reinícios são automáticos, mas limitados, e toda a saída vai para o journal: leia com journalctl -u chinaski@<instance>.

Esses limites vêm do arquivo da unit; ajuste-os em hosts maiores, mas poucos sites precisam de mais do que os valores distribuídos.

Permissões de arquivo

O instalador define permissões restritivas na hora da instalação e você não precisa alterá-las:

  • O diretório da aplicação pertence ao usuário chinaski e só pode ser lido por esse usuário e pelos membros do grupo.
  • O arquivo do banco de dados (chinaski.db) só pode ser lido pelo usuário e grupo chinaski.
  • O diretório que guarda o arquivo env (que contém o seu secret) é somente do proprietário (0700) e o próprio arquivo env é 0600.
  • O diretório de backup é somente do proprietário (0700).

Se a propriedade se desviar (por exemplo, um deploy foi executado com o usuário errado), o script de deploy reaplica a propriedade correta ao diretório da aplicação na próxima execução.

Mantenha o daemon fora da rede pública

  • Vincule o CMS a um endereço de loopback (http://127.0.0.1:3001 é o exemplo na unit systemd) e deixe o reverse proxy encarar a internet. O daemon só confia em IPs de cliente encaminhados vindos de conexões de loopback; vinculá-lo a uma interface pública permitiria que visitantes falsificassem seu IP e derrotassem os limites de taxa e os bloqueios de login.
  • Se o seu proxy fala com o daemon a partir de um endereço que não é de loopback (por exemplo, uma rede bridge do Docker), defina CHINASKI_TRUSTED_PROXIES com essa faixa de IP (endereços separados por vírgula ou faixas IPv4) para que o IP real do cliente continue sendo reconhecido. O loopback é sempre confiável; nada mais é, a menos que você o liste.
  • No modo offline (“EOTW”), o hypnotoad serve HTTP puro diretamente, sem proxy. O CMS então lê o endereço real da conexão e ignora totalmente os headers encaminhados, então a limitação de taxa funciona como está. Mas não há TLS neste modo: não envie senhas por uma rede não confiável; restrinja o acesso com uma VPN ou regras de firewall.

Modo airgap

Defina CHINASKI_AIRGAP=1 antes de iniciar o servidor em hosts isolados. Isso desliga toda requisição de saída (webhooks de build, webhooks de formulário e a verificação anti-bot) e oculta o widget de verificação mesmo que as chaves estejam armazenadas no banco de dados. O CMS continua funcionando normalmente no restante.

Headers de resposta

A aplicação adiciona headers de segurança a toda resposta por conta própria; nenhuma configuração de proxy é necessária para o básico:

  • Ela remove o header Server e define proteção contra enquadramento (SAMEORIGIN), proteção contra content-type sniffing, uma política de referrer estrita e HSTS de um ano (espera-se que o TLS termine no seu reverse proxy).
  • Recursos do navegador que o CMS nunca usa (câmera, microfone, geolocalização, pagamento, USB e mais) são desativados via Permissions-Policy.
  • Scripts e estilos inline são protegidos por um nonce por requisição na Content Security Policy. Submissões e incorporação de formulários ficam restritas à origem do próprio site.
  • Dois relaxamentos deliberados, ambos restritos a superfícies não públicas: as pré-visualizações de conteúdo afrouxam a política para que as pré-visualizações de tema sejam renderizadas corretamente (elas exigem uma sessão de admin ou um token secreto de pré-visualização), e as páginas públicas de formulário permitem ser incorporadas por outros sites, já que esse é o uso projetado, enquanto os envios de formulário ainda só fazem POST para o seu servidor.

Os exemplos de proxy (Caddy e nginx em deploy/) espelham esses headers como cinto-e-suspensório, para que sejam definidos mesmo quando o proxy responde com um erro em cache.

Honeypots para scanners

Os exemplos de proxy encaminham sondagens comuns de scanners (.env, .git/config, wp-login.php, wp-admin, phpmyadmin, xmlrpc.php e afins) ao CMS em vez do servidor estático. Os acessos são registrados e deliberadamente retardados, em vez de receberem um 404 silencioso. Se você usa os exemplos de proxy distribuídos, isso funciona automaticamente; mantenha o bloco de honeypot ao adaptar a configuração.

Leia este site em