Arch package guidelines (Português)/Security (Português)

From ArchWiki
Status de tradução: Esse artigo é uma tradução de Arch package guidelines/Security. Data da última tradução: 2023-10-26. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.

Esta página descreve as diretrizes de empacotamento de segurança para pacotes do Arch Linux. Para projetos C/C++, o compilador e o vinculador podem aplicar opções de proteção de segurança. O Arch Linux aplica PIE, fonte Fortify, protetor de pilha, nx e relro por padrão.

Uso

As proteções hardening podem ser revisadas executando checksec.

$ checksec --file=/usr/bin/cat

RELRO

O RELRO é uma técnica genérica de mitigação para proteger as seções de dados de um processo/binário ELF. Quando um programa é carregado, várias seções da memória ELF precisam ser gravadas pelo vinculador, mas pode ser ativado como somente leitura antes de passar o controle para o programa. Isso evita que os invasores substituam algumas seções da ELF. Existem dois modos RELRO diferentes:

  • Partial RELRO (-Wl,-z,relro): algumas seções são marcadas como somente leitura após o carregamento do programa, exceto que o GOT (.got.plt) ainda pode ser gravado.
  • Full RELRO (-Wl,-z,now) durante o carregamento do programa, todos os símbolos dinâmicos são resolvidos, permitindo que o GOT completo seja marcado como somente leitura.

Se um aplicativo relatar relro parcial, investigue se a cadeia de ferramentas de compilação passa nossos LDFLAGS ou permite substituir LDFLAGS. Para os pacotes Go, investigue se o método de compilação usa build.go como uma substituição pura do Makefile golang, que não permite a passagem de LDFLAGS.

Haskell

Para Haskell, não está claro como alcançar o Full RELRO no momento.

Go

Veja Diretrizes de pacotes Go#Sinalizadores e opções de compilação.

Stack Canary

Um stack canary é adicionado pelo compilador entre o buffer e os dados de controle na pilha. Se esse valor conhecido estiver corrompido, ocorreu um estouro de buffer e o programa em execução é segmentado para impedir uma possível execução arbitrária do código.

O pacote gcc ativou a proteção de pilha por padrão com o --enable-default-ssp opção de compilação.

NX

C/C++

A proteção do espaço executável marca as regiões da memória como não executáveis, de modo que uma tentativa de executar o código da máquina nessas regiões causará uma exceção. Ele utiliza recursos de hardware como o bit NX (bit sem execução) ou, em alguns casos, emulação de software desses recursos.

PIE

C/C++

O pacote gcc o tem habilitado por padrão para C/C++ com --enable-default-pie.

Golang

Passe os seguintes sinalizadores para go build

export GOFLAGS='-buildmode=pie'
export CGO_CPPFLAGS="-D_FORTIFY_SOURCE=3"
export CGO_LDFLAGS="-Wl,-z,relro,-z,now"

Haskell

Passe o seguinte sinalizador para runhaskell Setup.hs configure:

--ghc-option='-pie'

RPATH/RUNPATH

RUNPATH/RPATH fornece outros caminhos de pesquisa para o objeto em que está listado (pode ser usado para objetos executáveis e compartilhados).

$ objdump -x /usr/bin/perl | grep -E 'RPATH|RUNPATH'

Se o valor RPATH contiver um caminho dentro do controle de um invasor, ele poderá executar o código instalando uma biblioteca maliciosa nesse diretório. Por exemplo, CVE-2006-1566 e CVE-2005-4280. Veja Debian:RpathIssue.

A entrada RPATH é configurada pelo vinculador, passando, por exemplo, a seguinte string para LDFLAGS -Wl, -rpath -Wl,/usr/local/lib. Para fazer uma entrada de RUNPATH, anexe --enable-new-dtags aos sinalizadores do vinculador.

FORTIFY

A fonte Fortify é uma macro que adiciona proteção contra estouro de buffer (buffer overflow) em várias funções que executam operações na memória e nas strings. Ele verifica se um invasor tenta copiar mais bytes para estourar um buffer e interrompe a execução do programa. Essa proteção é ativada com o CPPFLAGS padrão:

makepkg.conf
CPPFLAGS="-D_FORTIFY_SOURCE=3"

Veja makepkg (Português)#Configuração

Serviços systemd

This article or section is a candidate for moving to systemd/Sandboxing.

Notes: Cobre o mesmo tópico que systemd#Sandboxing application environments. Ambos poderiam ser mesclados e movidos para uma página dedicada. Veja User:NetSysFire/systemd sandboxing para um rascunho proposto. (Discuss in Talk:Security#systemd unit hardening and system.conf tweaks)

Se um arquivo de serviço do systemd for enviado com o pacote devido à falta de fornecimento do upstream, aplique os seguintes recursos de proteção de serviço do systemd. O systemd fornece uma maneira de analisar os recursos de segurança habilitados para um serviço.

$ systemd-analyze security reflector.service

Acesso de arquivos

Um serviço pode ser protegido restringindo o acesso ao sistema de arquivos.

Configure um novo espaço de nomes do sistema fiel para o processo executado e que monta os diretórios /tmp e /var/tmp privados dentro dele que não são compartilhados pelos processos

PrivateTmp=true

O ProtectSystem possui três variedades diferentes de diretórios de montagem como somente leitura para o processo executado. A opção full monta /usr, /boot e /etc como somente leitura. O ProtectHome torna /home, /root e /run/user\ inacessíveis ao processo executado.

ProtectSystem=strict
ProtectHome=true

Configure um novo espaço de nomes /dev para o processo executado e adiciona apenas pseudodispositivos API como /dev/null, /dev/zero ou /dev/random, mas não para dispositivos físicos ou memória do sistema, portas do sistema e outros. Isso é útil para impedir que o processo de execução seja gravado diretamente em dispositivos físicos, o systemd também adiciona um filtro de chamadas do sistema para chamadas dentro do conjunto @raw-io.

PrivateDevices=true

Essas opções impendem o processo executado de alterar as variáveis do kernel acessíveis por meio de /proc/sys, /sys etc. ProtectControlGroups torna a hierarquia de /sys/fs/cgroup somente leitura.

ProtectKernelTunables=true
ProtectControlGroups=true

Tornar inacessíveis os caminhos de arquivos pode ser feito da seguinte forma:

InaccessiblePaths=/etc

Informações mais detalhadas podem ser encontradas em systemd.exec(5).

Usuário

Certifique-se que o processo executado e seus filhos nunca possam obter novos privilégios por meio do execve(2).

NoNewPrivileges=true

Memória

Proíba tentativas de criar mapeamentos de memória que sejam graváveis e executáveis, alterar os mapeamentos para executáveis ou criar memória compartilhada executável. Isso protege um processo contra a permissão de um invasor na memória, que também é executada. Observe que ativar isso não é compatível com todos os aplicativos que dependem de JIT.

MemoryDenyWriteExecute=true

Chamadas de sistema

Bloqueia a chamada de sistema personality(2) para que o domínio de execução do kernel não possa ser alterado.

LockPersonality=true

As chamadas de sistema também podem ser restritas em um serviço, o systemd pode exibir chamadas de sistema para filtrar:

$ systemd-analyze syscall-filter

Grupos predefinidos estão disponíveis, por exemplo, para usar o ponto de partida recomendado para chamadas de sistema na lista de permissões para serviços do sistema:

SystemCallFilter=@system-service

Chamadas de sistema podem ser restrita por sua arquitetura tal como evitar que binários 32 bits executem em máquinas 64 bit (binários não nativos):

SystemCallArchitectures=native

Rede

Se o processo em execução não exigir acesso à rede, este acesso pode ser totalmente desativado, configurando um novo espaço de nomes de rede para o processo e configurando apenas uma interface de loopback.

PrivateNetwork=true

Se a rede for necessária, o tipo de família de endereços usado pode ser restrito para a chamada de sistema socket(2), permitindo, por exemplo, apenas soquetes UNIX.

RestrictAddressFamilies=AF_UNIX

Quando é necessária apenas a rede para o localhost ou intervalos de IP específicos, um processo pode ser restringido, permitindo apenas o acesso da rede ao localhost.

IPAddressAllow=localhost
IPAddressDeny=any

Mais informações sobre filtragem de rede pode ser encontrada em systemd.resource-control(5).

Várias

Configura um novo espaço de nomes UTS para o processo de execução e não permite alterar o nome de host ou o nome de domínio.

ProtectHostname=true