- O systemd oferece recursos poderosos de gerenciamento de serviços, mas a configuração padrão é otimizada mais para usabilidade do que para segurança, por isso é necessário aplicar opções adicionais de hardening
- Com o comando
systemd-analyze security, é possível analisar os indicadores de exposição de segurança de todos os serviços ou de um serviço específico e definir prioridades
- Existem várias opções de segurança que podem ser aplicadas no nível da unidade de serviço, e elas podem ser ajustadas individualmente por meio de
/etc/systemd/system/ServiceName.service.d/override.conf e afins
- Entre as principais opções estão
ProtectSystem, PrivateTmp, NoNewPrivileges, SystemCallFilter, MemoryDenyWriteExecute e outras que restringem privilégios de processos e acesso a recursos
- Em vez de buscar segurança perfeita, é mais eficaz priorizar o hardening de serviços expostos externamente para reduzir riscos, e isso também pode trazer grande efeito em ambientes self-hosting
Visão geral do systemd
- O systemd oferece uma abordagem muito madura e robusta para gerenciamento de serviços
- No entanto, como prioriza a usabilidade imediata mais do que a segurança, a configuração padrão é relativamente permissiva
- Este documento apresenta várias opções de reforço de segurança que podem ser aplicadas a unidades de serviço do systemd e ao podman quadlet, para reduzir a possibilidade de comprometimento e minimizar o impacto caso ele ocorra
- Não se trata de um guia para aplicar tudo de forma uniforme a todos os serviços; é necessário experimentar, verificar logs e ajustar individualmente conforme as características e os requisitos de cada serviço
- A responsabilidade pela segurança da infraestrutura é totalmente do operador, e este documento serve como ferramenta de referência
Análise de segurança do systemd
- Com o comando
systemd-analyze security, é possível verificar o estado geral de segurança dos serviços ou analisar em detalhe as configurações de um serviço específico (por exemplo, sshd.service)
- A saída inclui status de verificação, nome do recurso, descrição e pontuação de Exposure; quanto maior o Exposure, maior o risco
- As opções de segurança podem ser adicionadas na seção
[Service] (systemd) ou na seção [Container] (podman quadlet)
- Recomenda-se usar
systemctl edit ServiceName.service para criar um arquivo override; se houver falha, é preciso verificar as permissões necessárias e ajustá-las
Opções de segurança para serviços
- O systemd fornece várias palavras-chave de opções de segurança, que podem ser consultadas em
man systemd.exec 5, man capabilities 7 e afins
- Algumas opções representativas relacionadas à segurança
ProtectSystem → opção para restringir o sistema de arquivos a somente leitura
ProtectHome → opção para bloquear acesso a /home, /root, /run/user
PrivateDevices → opção para bloquear acesso a dispositivos físicos e permitir apenas dispositivos virtuais como /dev/null
ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs → opções para bloquear acesso a recursos do kernel
NoNewPrivileges → opção para impedir obtenção de novos privilégios via setuid/setgid etc.
MemoryDenyWriteExecute → bloqueia o uso simultâneo de memória gravável e executável; pode causar problemas em algumas linguagens com JIT
SystemCallFilter → opção para restringir as system calls permitidas; em caso de violação, o processo pode ser encerrado ou receber retorno EPERM
Explicação de cada opção
- ProtectSystem: com
strict, monta todo o sistema de arquivos como somente leitura; /dev, /proc, /sys exigem opções de proteção separadas
- ReadWritePaths: permite reabilitar escrita apenas em alguns caminhos
- ProtectHome: bloqueia acesso a
/home, /root, /run/user
- PrivateDevices: desativa acesso a dispositivos físicos, permitindo apenas pseudo-dispositivos como
/dev/null
- ProtectKernelTunables: trata
/proc, /sys como somente leitura
- ProtectControlGroups: permite apenas acesso de leitura a cgroups
- ProtectKernelModules: proíbe carregamento explícito de módulos do kernel
- ProtectKernelLogs: restringe acesso ao buffer de logs do kernel
- ProtectProc: com
invisible, oculta em /proc/ processos pertencentes a outros usuários
- ProcSubset: bloqueia em
/proc conteúdos fora de itens relacionados a PID específicos
- NoNewPrivileges: bloqueia nova elevação de privilégios via setuid, setgid e capabilities do sistema de arquivos
- ProtectClock: bloqueia escrita no relógio do sistema/hardware
- SystemCallArchitectures: com
native, permite apenas syscalls nativas, como x86-64
- RestrictNamespaces: restringe namespaces voltados a contêineres
- RestrictSUIDSGID: bloqueia a configuração de bits setuid e setgid em arquivos
- LockPersonality: impede mudança do domínio de execução (necessário apenas em aplicações antigas)
- RestrictRealtime: restringe escalonamento em tempo real (necessário apenas para alguns serviços muito específicos)
- RestrictAddressFamilies: restringe as famílias de endereços de socket permitidas (por exemplo, AF_INET, AF_INET6, AF_UNIX etc.)
- MemoryDenyWriteExecute: bloqueia a criação adicional de regiões de memória graváveis e executáveis ao mesmo tempo (serviços com JIT exigem cuidado)
- ProtectHostname: proíbe uso das syscalls sethostname e setdomainname
- SystemCallFilter: define permissão/bloqueio de syscalls por serviço, com filtragem detalhada
- É possível ajustar grupos, syscalls individuais e modos de permissão/bloqueio
- Também há suporte para retornar códigos de erro como EPERM em vez de encerrar em caso de violação
- A lista completa pode ser consultada em
systemd-analyze syscall-filter ou man systemd.exec(5)
- É possível negar toda a lista com o prefixo
~ (ex.: CapabilityBoundingSet=~CAP_SETUID etc.)
Processo de ajuste das restrições de SystemCallFilter
- Com
auditd, é possível verificar nos logs quais syscalls foram bloqueadas quando um serviço falha
- Execute
sudo ausearch -i -m SECCOMP -ts recent e verifique o valor da syscall
- Em seguida, adicione essa syscall ou um grupo relacionado em
SystemCallFilter para resolver o problema gradualmente
Prioridade de aplicação do hardening e dicas operacionais
- Não é necessário aplicar tudo a todos os serviços
- O ponto central é o modelo de ameaça e a gestão de risco; em especial, serviços expostos externamente (httpd, nginx, ssh etc.) devem ser considerados prioritários
- Também é eficaz aplicar de forma preventiva a comandos customizados e unidades timer (substitutas do cron antigo)
- Quanto menos complexo o serviço, maior a chance de fazer ajustes finos
Checklist: combinação recomendada de opções de segurança (prioridade inicial de aplicação)
ProtectSystem=strict
PrivateTmp=yes
ProtectHome=yes ou ProtectHome=tmpfs
ProtectClock=yes, ProtectKernelLogs=yes, ProtectKernelModules=yes
RestrictSUIDGUID=yes
UMask=0077
LockPersonality=yes
RestrictRealtime=yes
MemoryDenyWriteExecute=yes
DynamicUser=yes ou definir User como um usuário específico diferente de root
- Os itens acima geralmente podem ser usados em serviços com pouco ou nenhum impacto
- Para aplicar adicionalmente filtragem de syscalls (
SystemCallFilter), é necessário testar em detalhe
Exemplo de configuração do Traefik
- Um caso de uso em que um serviço Traefik baseado em contêiner é executado com systemd quadlet, com várias opções de segurança aplicadas
- Uso de
ProtectSystem=full, ProtectHome=yes, SystemCallFilter=@system-service @mount @privileged etc.
- Remoção de privilégios específicos com
CapabilityBoundingSet=~CAP_SETUID CAP_SETPCAP
- Aplicação de restrição de acesso de rede com
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK etc.
Conclusão
- As opções de hardening de segurança do systemd são um recurso prático que vale a pena manter no kit de ferramentas de qualquer administrador de sistemas Unix-like
- Não devem ser tratadas como solução de segurança perfeita, mas como ferramentas para reduzir riscos, e não há necessidade de aplicar configurações de segurança indiscriminadamente a todos os serviços
- Especialmente para administradores de ambientes self-hosting, elas podem ajudar muito a elevar o nível de segurança
- Priorizando a "praticidade acima da perfeição", recomenda-se aplicar essas opções ao menos parcialmente, dentro do que fizer sentido para o trabalho e o ambiente
Ainda não há comentários.