- Aprender
- Computação e TI
- Ciência da computação
- Sistemas operacionais
- Proteção, isolamento e máquinas virtuais
Proteção, isolamento e máquinas virtuais
IntermediárioAula 9 de 9 do curso Curso de Sistemas operacionais
O que você vai aprender
- Descreva os modos do processador, os pontos de entrada controlados e as proteções de memória que impedem os programas de prejudicar uns aos outros ou o núcleo, e os mecanismos que dificultam ataques a eles.
- Separe o modo usuário do modo núcleoExplique os níveis de privilégio e as instruções privilegiadas, e o que acontece quando um programa tenta fazer algo que somente o núcleo pode fazer.
- Entre no núcleo com segurança por meio de chamadas de sistemaAcompanhe uma chamada de sistema desde a armadilha até a verificação de permissões e explique por que o núcleo deve desconfiar de cada argumento recebido.
- Proteja a memória e os dispositivosUse permissões das tabelas de páginas, mapeamentos exclusivos do núcleo e a IOMMU para explicar como o núcleo mantém cada processo dentro de sua própria memória.
- Dificulte ataques a programas e ao núcleoExplique como memória não executável, aleatorização de endereços, filtros de chamadas de sistema, inicialização segura e registros de auditoria aumentam o custo de exploração e deixam um registro.
- Separe o modo usuário do modo núcleo
- Explique como um sistema operacional verifica quem é um usuário, armazena senhas com segurança, usa outros fatores de autenticação e associa a identidade resultante a cada processo.
- Associe identidades aos processosAcompanhe um login desde a solicitação da senha até um interpretador de comandos em execução e explique IDs de usuários, grupos, herança e programas que alteram privilégios, como programas setuid e sudo.
- Armazene e verifique senhas com segurançaExplique o cálculo de hash, o uso de sal e as funções lentas de hash de senhas, e calcule como eles alteram o custo de ataques por tentativa de senhas.
- Autentique com o que você possui e com o que você éCompare senhas, tokens e biometria, combine-os na autenticação multifator e autentique serviços e máquinas que não têm uma pessoa ao teclado.
- Associe identidades aos processos
- Represente direitos como uma matriz de acesso, implemente-os com listas de controle de acesso ou capacidades, interprete e configure permissões do Unix e do Windows e compare os modelos discricionário, obrigatório e baseado em papéis.
- Compare listas de controle de acesso e capacidadesArmazene os mesmos direitos por objeto ou por sujeito e avalie as duas abordagens para verificar, revisar, delegar e revogar acessos.
- Interprete e configure permissões do Unix e do WindowsInterprete bits de permissão e modos em octal, aplique as regras de verificação do Unix a arquivos e diretórios e interprete ACLs POSIX e entradas de controle de acesso do Windows.
- Compare os controles de acesso discricionário, obrigatório e baseado em papéisDiferencie modelos em que os proprietários decidem daqueles em que uma política de todo o sistema decide, e use papéis para gerenciar os direitos de muitos usuários.
- Compare listas de controle de acesso e capacidades
- Explique como um hipervisor compartilha o processador, a memória e os dispositivos de um computador entre vários sistemas operacionais completos, mantendo-os isolados.
- Descreva máquinas virtuais e hipervisoresDefina máquinas virtuais e hipervisores, diferencie projetos de tipo 1 e tipo 2 e explique para que a virtualização é usada e quais são os limites de seu isolamento.
- Virtualize o processadorExplique a interceptação e emulação, por que o x86 clássico não podia usá-la diretamente e como a tradução binária, a paravirtualização e o suporte de hardware resolveram o problema.
- Virtualize a memóriaTraduza um endereço virtual do convidado para um endereço real da máquina e compare tabelas de páginas sombra com paginação aninhada por hardware.
- Virtualize dispositivos e mantenha as máquinas virtuais isoladasCompare dispositivos emulados, paravirtuais e de atribuição direta e explique os pontos fortes e os limites do isolamento entre máquinas virtuais.
- Descreva máquinas virtuais e hipervisores
- Construa um contêiner com recursos do núcleo (espaços de nomes para o que um processo pode ver, grupos de controle para o que pode usar e limites de privilégios para o que pode fazer) e decida quando usar um contêiner ou uma máquina virtual.
- Limite o que um processo pode ver com espaços de nomesExplique os tipos de espaços de nomes do Linux, crie espaços de nomes e ingresse neles, e interprete espaços de nomes de PID, montagem, rede e usuários.
- Limite o que um processo pode usar com grupos de controleOrganize processos em grupos de controle e defina limites de CPU, memória, número de processos e entrada e saída, interpretando os valores dos limites.
- Restrinja contêineres e escolha entre contêineres e máquinas virtuaisReduza o que um processo em contêiner pode fazer, explique o risco de um núcleo compartilhado e escolha contêineres, máquinas virtuais ou ambos para uma determinada carga de trabalho.
- Limite o que um processo pode ver com espaços de nomes
Guia de estudo de Proteção, isolamento e máquinas virtuais
1Explique como o hardware e o núcleo protegem o sistema
Programas são rápidos porque instruções comuns são executadas diretamente no processador. Permissões de hardware e pontos de entrada controlados no núcleo tornam essa liberdade segura o suficiente para compartilhar uma máquina. Acompanhe a fronteira desde o privilégio da CPU, passando pelas verificações de chamadas de sistema, até o acesso à memória e a dispositivos. Depois, veja como restrições de execução, aleatorização, verificação da inicialização e registros limitam ataques a programas e ao núcleo.
1.1 Separe o modo usuário do modo núcleo
Um programa precisa de liberdade suficiente para calcular rapidamente sem assumir o controle de todo o computador. O modo usuário permite que ele execute instruções comuns diretamente. O modo núcleo, também chamado modo supervisor, dá ao sistema operacional acesso às instruções que controlam a máquina.
Deixe o hardware aplicar os privilégios
A CPU mantém um nível de privilégio atual. Adições, leituras, escritas e saltos normalmente são executados em velocidade máxima, sujeitos às permissões de memória. O núcleo não inspeciona cada instrução por software. Isso é execução direta limitada: executar diretamente até que uma operação protegida ou uma interrupção exija o núcleo.
Uma instrução privilegiada gera uma armadilha se o código de usuário tentar executá-la. No x86-64, HLT, a escrita no registrador base da tabela de páginas CR3 e a instalação de uma tabela de interrupções com LIDT exigem privilégio de núcleo. Caso contrário, uma aplicação poderia parar a CPU, substituir suas próprias fronteiras de memória ou redirecionar o tratamento de interrupções.
Suponha que uma aplicação execute HLT. A CPU gera uma falha de proteção geral em vez de parar. Ela entra no tratador registrado pelo núcleo. O Linux normalmente envia SIGSEGV ao processo, encerrando-o enquanto outros programas continuam. A aplicação não pode escolher um endereço conveniente dentro do núcleo e começar a executá-lo ali.
Atravesse a fronteira por uma entrada controlada
Armadilhas, exceções e interrupções entram por endereços registrados pelo núcleo. O hardware altera o privilégio e transfere o controle ao tratador; o código de entrada do núcleo preserva o estado necessário para o retorno. Uma instrução especial de retorno restaura a execução em modo usuário no contador de programa salvo. No x86-64, o retorno pode usar SYSRET ou IRETQ.
O temporizador torna esse controle útil mesmo quando um programa nunca solicita um serviço. Antes de executá-lo, o núcleo programa um temporizador. Quando a interrupção chega, o escalonador pode selecionar outro processo. O código de usuário não pode desativar interrupções nem reprogramar esse temporizador, então um laço infinito não pode manter um núcleo de processamento para sempre.
Leia corretamente os diagramas de privilégios
| Arquitetura | Aplicação | Núcleo | Outros níveis |
|---|---|---|---|
| x86 | Anel 3 | Anel 0 | Os anéis 1 e 2 existem, mas os núcleos comuns do Linux e do Windows não os usam |
| ARMv8-A | EL0 | EL1 | EL2 oferece suporte a um hipervisor; EL3 oferece suporte ao monitor de firmware seguro |
| RISC-V | Modo U | Modo S | O modo M tem privilégio de máquina |
As convenções de numeração diferem: um número menor de anel x86 significa mais privilégio, enquanto um nível de exceção ARM maior significa mais privilégio. A virtualização Intel também acrescenta operação VMX root e não root; elas são independentes do número do anel.
Mantenha identidade e modo da CPU separados
Root é uma identidade de usuário, UID 0, que o software do núcleo reconhece. O código comum de uma aplicação root ainda é executado em modo usuário e entra no núcleo por chamadas de sistema. Um driver de dispositivo executado em modo núcleo tem muito mais poder direto: um erro de memória nele pode danificar o estado do núcleo sem passar por uma verificação de permissão de arquivo.
A camada que impõe uma fronteira deve controlar a camada dentro dela. O núcleo impõe fronteiras entre processos com modos da CPU e tabelas de memória. De modo semelhante, um hipervisor controla sistemas operacionais convidados usando suporte de hardware à virtualização.
Principais conclusões
- Instruções de usuário são executadas diretamente até que o hardware exija uma entrada no núcleo.
- Operações privilegiadas protegem tabelas de páginas, interrupções, temporizadores e controle de dispositivos.
- O temporizador permite que o escalonador recupere um núcleo de processamento de um laço infinito.
- A identidade root não coloca uma aplicação em modo núcleo.
- A numeração dos privilégios depende da arquitetura.
1.2 Entre no núcleo com segurança por meio de chamadas de sistema
Uma chamada de sistema é uma requisição controlada de um serviço do núcleo. Abrir arquivos, criar processos e enviar dados pela rede exigem decisões que uma aplicação não pode tomar com segurança por conta própria. Entrar no núcleo dá autoridade ao tratador; isso não dá a quem fez a chamada permissão para fazer tudo que solicitou.
Acompanhe a requisição
Uma função da biblioteca C que encapsula a chamada, como open(), coloca o número da chamada e os argumentos em registradores. Ela usa SYSCALL no x86-64, SVC no ARM64 ou ECALL no RISC-V. O núcleo então:
- Entra pelo ponto de entrada registrado e salva os registradores do usuário.
- Seleciona o tratador na tabela de chamadas de sistema, rejeitando um número desconhecido.
- Lê a identidade e as credenciais de quem fez a chamada a partir do processo atual.
- Verifica argumentos, direitos de acesso e os objetos envolvidos.
- Executa a operação ou retorna um erro.
- Restaura o estado salvo e retorna ao modo usuário.
A identidade vem das credenciais do processo, não de um nome fornecido pelo usuário. Quem faz uma chamada não pode obter os direitos de outro usuário acrescentando o nome dele a uma requisição.
Trate argumentos como não confiáveis
Um ponteiro é apenas um número fornecido por quem faz a chamada. O núcleo deve verificar todo o intervalo de memória de usuário solicitado, incluindo seu tamanho e a direção do acesso. O Linux usa rotinas verificadas como copy_from_user e copy_to_user para atravessar a fronteira com segurança.
Em read(fd, buf, 4096), um buf que aponta para a memória do núcleo não deve se tornar um destino para dados de arquivo. O Linux retorna EFAULT para esse buffer de usuário inválido. Um erro diferente tem outra causa: write() por meio de um descritor aberto com O_RDONLY falha com EBADF, pois o descritor nunca recebeu acesso de escrita. Uma requisição comum negada retorna um erro; ela não encerra automaticamente o processo. Em C, a função que encapsula a chamada normalmente retorna −1 e define errno.
Verifique o objeto realmente usado
Uma condição de corrida entre verificação e uso (TOCTTOU) separa uma decisão do objeto que ela deveria proteger. Um programa auxiliar privilegiado verifica access("/tmp/report", W_OK) e depois abre o caminho. Um atacante substitui o caminho por uma ligação simbólica para /etc/passwd entre essas operações. O nome não muda, mas o objeto aberto é diferente.
A correção é acessar o objeto realmente aberto usando as credenciais pretendidas. Abandone privilégios antes de abrir e use opções como O_NOFOLLOW quando ligações simbólicas não forem desejadas. Copiar argumentos uma vez para a memória do núcleo também evita confiar repetidamente em dados de usuário que podem mudar; a estrutura copiada ainda deve ser validada.
Identifique em que se deve confiar
Um monitor de referência intermedeia o acesso. Ele deve ser acionado sempre que o acesso for obtido, protegido contra alterações e pequeno o suficiente para ser examinado com cuidado. Depois que o núcleo concede um mapeamento de memória, cada leitura e escrita passa pelas verificações de permissão da MMU; cada uma delas não faz uma chamada de sistema.
A base de computação confiável (TCB) é o hardware, o firmware e o software privilegiado de cujo funcionamento correto depende a proteção. Ela inclui a CPU, a cadeia de inicialização, o núcleo e componentes confiáveis de login. Transferir drivers ou sistemas de arquivos para servidores em modo usuário pode reduzir a parte dessa base que fica no núcleo, como fazem projetos de micronúcleo. Uma aplicação comum comprometida usa indevidamente os direitos que recebeu; um componente confiável comprometido pode prejudicar as próprias verificações.
Principais conclusões
- Entrar no núcleo e ter permissão para executar uma operação são coisas distintas.
- Valide intervalos de ponteiros e direitos de acesso antes de usar argumentos de usuário.
- Uma condição de corrida TOCTTOU pode fazer um nome verificado referir-se a outro objeto.
- Um monitor de referência deve resistir a tentativas de contorná-lo e alterá-lo.
- A TCB inclui mais do que o núcleo.
- Uma chamada de sistema recusada normalmente retorna um erro que o programa pode tratar.
1.3 Proteja a memória e os dispositivos
A memória virtual protege programas além de traduzir endereços. Um processo pode alcançar os quadros físicos indicados por sua tabela de páginas ativa, com as permissões definidas pelo núcleo. Os quadros privados de outro processo estão ausentes; mapeamentos deliberados de memória compartilhada são uma exceção explícita.
Verifique cada acesso à memória
A unidade de gerenciamento de memória (MMU) verifica as entradas da tabela de páginas nos acessos. Permissões importantes incluem presença ou validade, permissão de escrita, acesso pelo usuário e execução. No x86, U/S distingue páginas acessíveis ao usuário de páginas exclusivas do supervisor; NX ou XD desativa a execução. O ARM chama sua restrição de execução de XN.
Uma violação gera uma falta de página. A falta informa que uma verificação de hardware falhou; o núcleo decide se essa falha é esperada e reparável. Considere duas escritas em páginas somente para leitura:
- Um processo sobrescreve uma página de código que não é de cópia na escrita. O núcleo a trata como uma escrita inválida e normalmente envia
SIGSEGV. - Após
fork(), um processo escreve em dados compartilhados marcados para cópia na escrita. O núcleo aloca uma cópia privada, altera o mapeamento para permitir escrita e tenta novamente a instrução.
Ambas as faltas começam em um bit de proteção. Os registros do núcleo explicam por que os mapeamentos eram somente para leitura e determinam a resposta. Portanto, uma falta de página não é automaticamente uma falha fatal nem uma requisição para buscar dados no disco.
Proteja os mapeamentos do núcleo nos dois sentidos
Organizações tradicionais mapeiam a memória do núcleo nos espaços de endereçamento dos processos como exclusiva do supervisor, facilitando a entrada no núcleo enquanto bloqueiam leituras e escritas em modo usuário. O ataque Meltdown, de 2018, mostrou que alguns processadores podiam vazar esses dados por execução especulativa. O isolamento das tabelas de páginas do núcleo (KPTI) remove a maioria dos mapeamentos do núcleo enquanto o código de usuário é executado em sistemas afetados.
O código do núcleo também precisa de proteção contra redirecionamento para memória controlada pelo usuário. No x86, a SMEP impede a execução em modo núcleo a partir de páginas de usuário. A SMAP bloqueia acessos a dados em páginas de usuário pelo modo núcleo, exceto durante operações de cópia autorizadas deliberadamente. O ARM fornece proteções relacionadas por meio de PXN e PAN. Essas verificações reduzem as formas pelas quais um atacante pode usar um erro no núcleo para executar código ou fornecer dados falsos ao núcleo.
O acesso somente para leitura protege a integridade, não o sigilo. Se um processo pode ler uma página mapeada, ele pode conhecer seu conteúdo mesmo quando as escritas falham. Dados confidenciais devem ser inacessíveis a esse processo: deixe-os sem mapeamento ou imponha uma fronteira apropriada exclusiva do supervisor.
Dê aos dispositivos sua própria fronteira
Aplicações normalmente solicitam operações de dispositivos por meio de um driver. Os registradores de dispositivos costumam ser exclusivos do núcleo, embora um processo autorizado possa receber determinados mapeamentos, como ocorre com drivers gráficos ou entrada e saída em espaço de usuário no Linux.
Um dispositivo que realiza acesso direto à memória (DMA) lê ou escreve na RAM sem enviar esses acessos pela MMU da CPU. As permissões de página da CPU, por si só, não conseguem impedir que um dispositivo defeituoso sobrescreva os quadros de outro processo. Uma IOMMU traduz e restringe endereços de dispositivos com mapeamentos por dispositivo. Intel VT-d e AMD-Vi fornecem esse mecanismo.
Para um dispositivo atribuído a uma VM, a IOMMU restringe o DMA à memória atribuída a essa VM. O lado da CPU precisa de uma fronteira paralela: uma segunda etapa de tradução de páginas mapeia endereços físicos do convidado somente para quadros permitidos pelo hipervisor. Proteger uma carga de trabalho exige cobrir tanto os acessos da CPU quanto os acessos dos dispositivos.
Principais conclusões
- A MMU aplica os mapeamentos e bits de permissão instalados pelo núcleo.
- Uma falta de página pode provocar recuperação, cópia na escrita ou um sinal fatal.
- O acesso somente para leitura não torna os dados confidenciais.
- O KPTI remove a maioria dos mapeamentos do núcleo durante a execução de código de usuário.
- SMEP e SMAP restringem o uso de páginas de usuário pelo núcleo.
- A IOMMU limita o DMA que passa fora da MMU da CPU.
1.4 Dificulte ataques a programas e ao núcleo
Um erro de segurança de memória pode dar origem a um ataque quando dados corrompidos alteram o fluxo de controle do programa. Um estouro de buffer na pilha, por exemplo, pode sobrescrever um endereço de retorno salvo. As defesas do sistema operacional restringem o que um atacante pode fazer com esse erro; elas não corrigem a escrita incorreta.
Separe dados de código executável
O bit NX marca páginas de dados como não executáveis. O Windows chama isso de prevenção de execução de dados (DEP). Injetar instruções em um buffer na pilha é menos útil quando saltar para ele causa uma falta.
W^X, escrita ou execução, mutuamente exclusivas, é mais rígida: nenhuma página permite escrita e execução ao mesmo tempo. A DEP, por si só, não impede que um programa solicite explicitamente esse mapeamento. Sob W^X, um compilador just-in-time escreve o código gerado em memória gravável e depois altera suas permissões antes de executá-lo.
Um atacante pode, em vez disso, reutilizar instruções executáveis existentes. A programação orientada a retornos (ROP) encadeia pequenas sequências de instruções chamadas gadgets. A aleatorização do espaço de endereçamento (ASLR) altera as localizações de pilhas, áreas de alocação dinâmica, bibliotecas e programas independentes de posição, tornando os endereços dos gadgets difíceis de prever.
Com a base de uma biblioteca escolhida uniformemente entre posições, uma tentativa às cegas tem probabilidade de acerto de 1 em 268.435.456. Com apenas posições e uma organização preservada após falhas de processos trabalhadores, testar posições distintas exige no máximo 256 tentativas e, em média, 128,5. Um endereço vazado dentro de uma biblioteca conhecida revela sua base e os deslocamentos dos gadgets nessa biblioteca. Uma pilha aleatorizada separadamente ainda pode permanecer desconhecida.
Reduza os serviços que um atacante pode solicitar
Filtros seccomp do Linux restringem as chamadas de sistema que um processo pode fazer. Um renderizador de navegador, por exemplo, pode ser impedido de fazer chamadas para iniciar programas ou abrir arquivos diretamente. Os filtros são herdados pelos processos filhos e não podem ser removidos; filtros posteriores podem aumentar as restrições. Um renderizador comprometido ainda tem suas operações permitidas, então um filtro é uma fronteira em torno dos serviços, não uma prova de que o programa não tem erros. O pledge do OpenBSD e o App Sandbox do macOS fornecem restrições relacionadas.
Verifique a inicialização e preserve evidências
A inicialização segura verifica assinaturas ao longo da cadeia de inicialização. O firmware verifica um carregador de inicialização confiável; o carregador verifica o núcleo; o núcleo pode exigir módulos assinados. Um componente modificado sem uma assinatura confiável é recusado. Isso ajuda a impedir alterações persistentes no software de inicialização, mas uma assinatura válida não prova que o software não tem vulnerabilidades.
A inicialização medida registra hashes dos componentes carregados, normalmente usando um módulo de plataforma confiável (TPM). Essas medições dão suporte à atestação: outra parte pode comparar o que foi iniciado com um estado esperado. Medir e recusar a inicialização são operações diferentes.
O registro de auditoria documenta logins, falhas de autenticação, permissões negadas, alterações em contas e ações privilegiadas como sudo. Os registros ajudam na detecção e na reconstrução. Um atacante que controla um hospedeiro pode apagar registros locais, então o registro protegido ou remoto preserva evidências fora desse hospedeiro.
Atacantes podem combinar um vazamento de endereço, um erro de corrupção de memória e uma fuga do ambiente isolado. Atualizações eliminam as vulnerabilidades subjacentes que essas defesas deixam presentes.
Principais conclusões
- NX bloqueia a execução a partir de páginas de dados marcadas; W^X também proíbe permissões simultâneas de escrita e execução.
- A ASLR torna mais difícil prever endereços para reutilização de código.
- Um vazamento de endereço de biblioteca não revela necessariamente regiões aleatorizadas separadamente.
- Filtros de chamadas de sistema restringem os serviços disponíveis a um processo comprometido.
- A inicialização segura verifica a confiança nos componentes de inicialização; a inicialização medida registra o que foi carregado.
- Registros de auditoria ajudam na detecção e na reconstrução, portanto proteja-os contra exclusão.
2Autentique usuários e atribua uma identidade aos processos
Um nome de usuário só se torna útil ao núcleo quando está associado a credenciais confiáveis de processo. Acompanhe um login até um interpretador de comandos em execução, incluindo o tratamento cuidadoso de programas auxiliares com privilégios elevados. Depois, examine como hashes de senhas com sal dificultam ataques a verificadores roubados e como chaves, códigos baseados em tempo e biometria mudam a comprovação de identidade antes do início das verificações normais de permissão.
2.1 Associe identidades aos processos
Um login bem-sucedido associa uma identidade humana a credenciais de processo mantidas pelo núcleo. A autenticação verifica a identidade declarada; a autorização decide o que essa identidade pode fazer. Uma entidade de segurança pode ser uma pessoa ou uma conta de serviço, e processos agem em seu nome.
Leve a identidade aos programas em execução
Sistemas semelhantes ao Unix identificam usuários por UIDs numéricos e grupos por GIDs. /etc/passwd associa nomes a UIDs, diretórios pessoais e interpretadores de comandos. As comparações do núcleo usam os números: dois nomes de conta com um único UID são uma identidade para as verificações de acesso. O UID 0 é root e ignora a maioria das verificações comuns de permissão.
O Windows usa identificadores de segurança (SIDs) para usuários e grupos. O token de acesso de um processo registra seu SID de usuário, SIDs de grupos e privilégios. Nas duas plataformas, as credenciais do programa em execução fornecem a identidade para decisões posteriores.
Um login típico com senha no Linux segue esta sequência:
- Um serviço de login privilegiado, como
login,sshdou um gerenciador gráfico de sessão, recebe as credenciais. - O PAM, módulos de autenticação conectáveis, verifica-as por meio dos módulos de autenticação configurados.
- O serviço define os grupos suplementares e o GID do usuário e depois altera o UID para abandonar root.
- Ele inicia o interpretador de comandos. Processos filhos herdam essas credenciais por
fork()e normalmente as mantêm apósexecve().
A ordem importa. Abandonar root antes de definir os grupos pode deixar o processo sem condições de substituir sua lista herdada de grupos privilegiados. Além disso, editar a associação de uma conta a grupos não reescreve as credenciais de processos que já estão em execução; uma nova sessão de login recebe a nova lista.
Entenda uma alteração controlada de privilégio
Um processo tem um UID real, que normalmente identifica quem o iniciou; um UID efetivo, usado na maioria das verificações de acesso; e um UID salvo, que permite retornar de forma controlada após uma redução temporária. Em programas comuns, os três são iguais.
O /usr/bin/passwd, pertencente a root, ilustra o setuid. Seu modo 4755, exibido como -rwsr-xr-x, faz o UID efetivo ser root quando um usuário comum o executa. Se alice tem UID 1000, seu UID real permanece 1000 enquanto o UID efetivo passa a ser 0. O programa pode atualizar /etc/shadow e usa a identidade real de quem fez a chamada para restringir de quem a senha pode ser alterada. Um executável setgid altera de modo semelhante o grupo efetivo.
Esse pequeno programa confiável possui uma autoridade perigosa. Um erro pode expor direitos de root, então os sistemas reduzem ao mínimo os programas setuid e abandonam privilégios cedo. Para um serviço que precisa apenas de uma porta de número baixo, CAP_NET_BIND_SERVICE concede um privilégio do Linux mais restrito do que root completo.
Administre sem compartilhar uma identidade
sudo autentica o usuário que o invoca, verifica quais comandos esse usuário pode executar como qual identidade de destino e registra o uso. Sua política normalmente fica em /etc/sudoers. Identidades individuais preservam a responsabilização que se perde ao compartilhar uma senha de root. No Windows, o UAC normalmente inicia os programas de um administrador com um token filtrado e solicita consentimento para elevação.
Aplicações cotidianas devem ser executadas com direitos comuns, e serviços devem ter contas dedicadas como www-data. Assim, um visualizador de documentos comprometido herda essas credenciais limitadas em vez da autoridade completa de um administrador.
Principais conclusões
- A autenticação estabelece a identidade; a autorização verifica os direitos.
- O Unix verifica UIDs e GIDs numéricos; o Windows usa SIDs e tokens.
- Defina os grupos antes de abandonar permanentemente o privilégio de alterá-los.
- O UID efetivo é usado na maioria das verificações de acesso do Unix.
- Programas auxiliares setuid precisam de verificações cuidadosas porque têm autoridade elevada.
- Processos existentes mantêm sua lista antiga de grupos após uma edição da conta.
2.2 Armazene e verifique senhas com segurança
Um verificador de senha precisa reconhecer uma senha correta sem armazenar uma cópia recuperável. Ele armazena um hash de senha com as informações necessárias para repetir a verificação. No login, o sistema recalcula o hash a partir da senha digitada e compara os resultados; ele nunca descriptografa o hash armazenado.
Proteja o verificador armazenado
No Linux, /etc/shadow contém hashes de senhas protegidos. O arquivo /etc/passwd, legível por muitos usuários, contém informações de contas e um x no lugar da senha. Um campo de senha em shadow registra um identificador de algoritmo, parâmetros de custo, um sal e o hash resultante. $y$ identifica yescrypt, usado por padrão no Debian 11, Ubuntu 22.04, Fedora 35 e versões posteriores; $6$ identifica SHA-512-crypt.
Um arquivo de hashes roubado permite um ataque offline. O atacante calcula hashes de tentativas em hardware separado, sem os atrasos do serviço de login. Um ataque de força bruta enumera sequências; um ataque de dicionário começa com palavras prováveis, senhas vazadas e variações como “Senha1!”.
Para exatamente oito letras minúsculas, são possíveis sequências. A tentativas por segundo, esgotar o espaço leva cerca de 21 segundos. A tentativas por segundo, leva cerca de segundos, aproximadamente 242 dias. Esses são tempos de busca completa, não garantias para uma senha individual. Doze letras minúsculas fornecem cerca de sequências, aproximadamente 110 dias mesmo na taxa mais rápida.
Torne caro atacar cada conta
Um sal criptográfico é um novo valor aleatório armazenado ao lado de cada hash de senha. Ele faz senhas iguais produzirem hashes diferentes e inviabiliza tabelas pré-calculadas reutilizáveis. O sal é público; sua função é exigir trabalho separado para contas diferentes.
Considere 1.000 contas e uma lista de tentativas, verificadas a hashes por segundo. Sem sais, calcular a lista uma vez leva 100 segundos e serve para todas as contas. Sais únicos exigem cálculos, cerca de segundos ou 27,8 horas. Uma senha comum ainda pode ser encontrada perto do início da lista.
Esquemas de hash de senhas como bcrypt, scrypt, yescrypt, Argon2 e PBKDF2 têm custos de processamento ajustáveis. Scrypt, yescrypt e Argon2 também impõem custos de memória. Um login prático pode tolerar uma fração de segundo; uma campanha de tentativas em grande escala repete esse custo milhões de vezes. Um único cálculo rápido de SHA-256 não tem esse custo deliberado.
Projete a política de login em torno das tentativas
A norma NIST SP 800-63B-4 (2025) exige sais de pelo menos 32 bits e um custo de hash de senhas tão alto quanto viável. Sua orientação para senhas exige pelo menos 15 caracteres para autenticação somente por senha, ou pelo menos oito quando a senha faz parte da MFA, e recomenda aceitar pelo menos 64 caracteres.
Ela rejeita combinações obrigatórias, como um dígito e um símbolo, e alterações periódicas forçadas de senha. Exige bloquear escolhas comuns ou comprometidas, limitar tentativas online e exigir uma alteração quando houver evidência de comprometimento. Limites de taxa online protegem o serviço em funcionamento; hashes lentos com sal protegem verificadores roubados. Uma senha mais longa escolhida de forma previsível em uma lista comum ainda pode ser fraca.
Principais conclusões
- O login recalcula um hash de senha; ele não descriptografa uma senha.
- Tentativas offline contornam os limites de taxa do serviço de login em funcionamento.
- Um sal público e único impede a reutilização do trabalho de cálculo de hash entre contas.
- Um custo de processamento ajustável torna cada tentativa cara.
- O comprimento da senha e listas de bloqueio ajudam mais do que regras previsíveis de composição.
2.3 Autentique com o que você possui e com o que você é
Senhas comprovam conhecimento. Outros autenticadores comprovam a posse de um objeto ou uma característica física. O sistema operacional acaba associando a identidade autenticada aos processos, mas o caminho até essa identidade afeta a facilidade com que um atacante pode se passar pelo usuário.
Combine tipos diferentes de fatores
Os três tipos de fatores são algo que você sabe, como uma senha ou PIN; algo que você possui, como um celular, cartão inteligente ou chave de segurança; e algo que você é, como uma impressão digital. A autenticação multifator (MFA) combina tipos diferentes. Uma senha mais uma pergunta de segurança repetem o fator de conhecimento.
Senhas de uso único baseadas em tempo (TOTP) usam um segredo compartilhado e um intervalo de tempo, normalmente de 30 segundos, para produzir códigos correspondentes em um autenticador e em um servidor. A RFC 6238 define o método. Um código expira rapidamente, mas uma página falsa de login pode repassar um código recente antes que ele expire. Códigos de aplicativo evitam a troca fraudulenta de chip; códigos por SMS dependem do controle do número de telefone e podem ser redirecionados se ele for tomado.
Comprove a posse sem enviar a chave
Um autenticador de chave pública assina um novo desafio com uma chave privada. O servidor o verifica com uma chave pública armazenada, que não pode, por si só, ser reutilizada para assinar um login. Chaves de segurança FIDO2 e chaves de acesso também vinculam a autenticação à identidade do site, de modo que uma resposta para um site falso não pode autenticar no verdadeiro. Uma chave SSH comum também comprova posse, mas não se deve presumir que tenha o mesmo mecanismo de vinculação ao site.
O armazenamento muda o risco. Chaves vinculadas ao dispositivo em uma chave de segurança de hardware, TPM ou enclave seguro assinam dentro do hardware sem expor a chave privada. Chaves de acesso sincronizadas copiam material de chave criptografado entre dispositivos por meio de uma conta da plataforma, facilitando a recuperação e ao mesmo tempo incluindo essa conta na fronteira de confiança. Uma chave privada SSH comum é um arquivo protegido por permissões e, opcionalmente, por uma frase secreta.
Interprete erros biométricos
Um sistema biométrico compara características medidas com um modelo armazenado. Ele aceita quando uma pontuação de similaridade atinge um limiar; não exige uma imagem idêntica a cada vez.
| Taxa | População usada como denominador | Erro contado |
|---|---|---|
| Taxa de falsa aceitação (FAR) | Tentativas de impostores | Impostores aceitos |
| Taxa de falsa rejeição (FRR) | Tentativas legítimas | Usuários legítimos rejeitados |
Dois impostores aceitos em 10.000 tentativas resultam em FAR de 0,02%. Trinta rejeições em 1.000 tentativas legítimas resultam em FRR de 3%. Aumentar o limiar de similaridade reduz a FAR e aumenta a FRR. Uma correspondência mais exigente reduz o sucesso de impostores, mas torna mais comuns novas tentativas legítimas.
Uma característica biométrica vazada não pode ser alterada como uma senha, e sensores precisam de defesas contra fotos ou impressões digitais copiadas. Um projeto útil usa biometria localmente para desbloquear uma chave protegida, enviando somente uma assinatura ao servidor.
Autentique processos também
Para uma conexão local de domínio Unix, SO_PEERCRED no Linux obtém as credenciais da outra parte a partir do núcleo, em vez de confiar em um nome enviado pelo cliente. Entre máquinas, serviços usam chaves, certificados ou tokens armazenados com acesso restrito à conta de serviço. Após o login, as verificações comuns de acesso do sistema operacional usam o UID ou token de acesso; elas não perguntam se o usuário digitou uma senha ou tocou em uma chave.
Principais conclusões
- A MFA combina tipos diferentes de fatores, não apenas duas perguntas.
- Códigos TOTP podem ser repassados enquanto estiverem válidos.
- O login por chave pública comprova a posse sem enviar a chave privada.
- O FIDO2 vincula a autenticação ao site pretendido.
- FAR e FRR usam populações de tentativas diferentes.
- Um limiar biométrico mais exigente reduz as aceitações de impostores, mas aumenta as rejeições de usuários legítimos.
- Credenciais da outra parte em uma conexão local devem vir do núcleo.
3Controle o acesso a arquivos e outros recursos
Uma identidade autenticada ainda precisa de uma decisão sobre cada recurso solicitado. Represente direitos em uma matriz de acesso e compare listas associadas a objetos com tokens mantidos por processos. Analise permissões de arquivos e diretórios antes de acrescentar políticas obrigatórias e papéis profissionais. Uma mesma requisição pode envolver um identificador aberto, bits comuns de modo e uma fronteira de serviço aplicada centralmente.
3.1 Compare listas de controle de acesso e capacidades
Uma decisão de acesso tem três partes: um sujeito pede para executar uma operação em um objeto. O sujeito normalmente é um processo que age em nome de uma entidade de segurança; objetos incluem arquivos, dispositivos e outros processos. Uma matriz de acesso representa os direitos em células, com sujeitos nas linhas e objetos nas colunas.
Armazene os mesmos direitos de duas formas
Suponha que alice possa ler e escrever em report.txt, bob possa apenas lê-lo e o serviço de backup possa ler tanto report.txt quanto payroll.db. Bob também pode ler e escrever em payroll.db. Alice e bob podem usar a impressora; o serviço de backup não pode. A maioria das células da matriz muito maior de um sistema real está vazia.
Uma lista de controle de acesso (ACL) armazena uma coluna junto com seu objeto. A lista de report.txt nomeia alice, bob e backup com seus respectivos direitos. Uma lista de capacidades armazena uma linha junto com o sujeito. Bob possui tokens para ler o relatório, ler e escrever na folha de pagamento e usar a impressora.
| Pergunta | ACL | Lista de capacidades |
|---|---|---|
| Quem pode usar este objeto? | Examine sua lista | Encontre todos que possuem tokens |
| O que este sujeito pode usar? | Examine muitos objetos | Examine seus tokens |
| Como direitos restritos são delegados? | Acrescente ou altere entradas | Passe tokens selecionados sem acrescentar direitos |
| O que dificulta a revogação? | Identificadores já concedidos podem permanecer | Cópias de tokens podem ter se espalhado |
Uma capacidade identifica tanto um objeto quanto as operações permitidas e não pode ser falsificada nem ampliada por quem a possui. Cópias e delegações autorizadas são possíveis. O núcleo pode manter o token real enquanto o código de usuário mantém um índice; outro projeto protege um token com criptografia.
Acompanhe um descritor após a abertura
O Unix combina as duas abordagens. open() verifica quem fez a chamada em relação às permissões do arquivo e retorna um descritor de arquivo que registra o acesso concedido. Leituras e escritas posteriores verificam esse identificador aberto. Um processo filho pode herdá-lo por fork(), ou um processo pode recebê-lo por um socket de domínio Unix.
Alice abre app.log para escrita. Seu proprietário altera o modo para 444. O descritor de alice, já aberto, ainda pode escrever; uma nova tentativa de abrir o arquivo para escrita encontra o novo modo. Atualizar a ACL que rege aberturas futuras não cancela todas as capacidades já emitidas. Os identificadores do Windows seguem o mesmo padrão geral.
O Capsicum do FreeBSD torna isso útil para confinamento. Após cap_enter(), um processo não pode abrir um caminho absoluto arbitrário. Ele pode operar por meio de descritores existentes, receber descritores e usar openat() dentro de um diretório cujo descritor possui. Assim, um processo pai pode dar a um trabalhador exatamente os arquivos de que ele precisa. Núcleos baseados em capacidades, como seL4 e Fuchsia, estendem a ideia aos objetos do núcleo em geral.
Diferencie o outro significado de capacidade no Linux
As capacidades do Linux dividem os privilégios de root em categorias. CAP_NET_BIND_SERVICE permite a associação a portas de número baixo; CAP_DAC_OVERRIDE ignora verificações comuns de acesso a arquivos. Esses privilégios não identificam um objeto específico, então são diferentes de uma capacidade no sentido da matriz de acesso. Um único privilégio do Linux pode autorizar uma classe de operações em muitos objetos.
Principais conclusões
- ACLs organizam direitos por objeto; listas de capacidades os organizam por sujeito.
- Uma capacidade não pode ser falsificada nem ampliada por quem a possui.
- Descritores preservam o acesso concedido quando um objeto foi aberto.
- Alterar o modo de um arquivo normalmente não revoga descritores existentes.
- Capacidades do Linux dividem privilégios de root e não identificam objetos individuais.
3.2 Interprete e configure permissões do Unix e do Windows
As permissões do Unix associam direitos ao proprietário, ao grupo proprietário e a todos os demais. Para decidir sobre o acesso, identifique primeiro a operação e o objeto relevante. Ler o conteúdo de um arquivo, atravessar um diretório e excluir um nome exigem permissões diferentes.
Decodifique e selecione os bits
Leitura é 4, escrita é 2 e execução é 1. Some esses valores para cada classe: 754 significa rwxr-xr--; 640 significa rw-r-----. chmod 640 notes.txt define um modo, enquanto chmod g+w,o-r notes.txt edita bits selecionados. O proprietário ou root pode alterar o modo; alterar a propriedade exige autoridade de root, representada por CAP_CHOWN no Linux.
O núcleo seleciona a primeira classe correspondente: proprietário se o UID efetivo corresponder, caso contrário grupo se um grupo do processo corresponder, caso contrário demais. Ele não combina classes nem tenta novamente uma mais generosa. Alice é proprietária de um arquivo de modo 077: seus bits de proprietário estão vazios, então ela não pode lê-lo, embora grupo e demais tenham direitos completos. Ela ainda pode alterar o modo como proprietária.
Root normalmente ignora as verificações de leitura e escrita. Para executar um arquivo comum sob as verificações discricionárias comuns do Linux, pelo menos um bit de execução deve estar definido. Uma política obrigatória pode impor outras restrições.
Interprete bits de diretório e bits especiais
A leitura de diretório lista nomes; a execução permite travessia e busca; a escrita junto com a execução permite criar, excluir e renomear entradas. Remover um nome altera seu diretório, então um arquivo de modo 000 pode ser excluído por alguém com os direitos necessários no diretório.
Setuid acrescenta octal 4000 ao modo de um executável e altera a identidade efetiva de usuário na execução. Setgid acrescenta 2000 e altera o grupo de modo semelhante; em um diretório, faz com que novos arquivos herdem o grupo do diretório. O bit de restrição de exclusão acrescenta 1000. Um diretório como /tmp, de modo 1777, permite exclusão ou renomeação apenas pelo proprietário do arquivo, proprietário do diretório ou um processo privilegiado, ainda exigindo as permissões comuns do diretório.
Remova bits ao criar arquivos
Uma umask limpa bits do modo solicitado por um programa. É uma operação de bits, não uma subtração octal. Com as solicitações usuais de 666 para arquivos e 777 para diretórios:
| Umask | Novo arquivo | Novo diretório |
|---|---|---|
| 022 | 644 | 755 |
| 027 | 640 | 750 |
| 000 | 666 | 777 |
Uma umask não pode acrescentar direitos de execução ausentes da solicitação do arquivo.
Interprete listas de acesso mais detalhadas
ACLs POSIX acrescentam usuários e grupos nomeados. setfacl -m u:bob:r report.txt dá a bob uma entrada nomeada de leitura; getfacl a exibe e ls -l marca a ACL estendida com +. A máscara da ACL limita usuários nomeados, grupos nomeados e o grupo proprietário, então uma entrada nomeada pode mostrar mais direitos do que os efetivos.
O NTFS do Windows usa um descritor de segurança com um SID de proprietário e uma DACL de ACEs ordenadas que permitem ou negam acesso. A avaliação para quando um direito solicitado é negado ou todos os direitos solicitados foram concedidos; direitos não concedidos são negados. A ordem preferida coloca entradas explícitas antes das herdadas, com negações antes de permissões dentro de cada grupo. Uma permissão explícita pode, portanto, resolver uma requisição antes que uma negação herdada seja alcançada. Uma SACL separada seleciona eventos de acesso para auditoria.
Principais conclusões
- Escolha a classe de permissão Unix correspondente antes de verificar seus bits.
- Permissões de diretório controlam nomes; permissões de arquivo controlam o conteúdo dos arquivos.
- O bit de restrição de exclusão acrescenta uma verificação de propriedade para exclusão e renomeação.
- Uma umask limpa bits solicitados e nunca os acrescenta.
- A máscara da ACL POSIX limita a classe de grupo e as entradas nomeadas.
- A avaliação de uma DACL do Windows depende da ordem das ACEs.
- Uma SACL seleciona eventos para auditoria em vez de conceder acesso.
3.3 Compare os controles de acesso discricionário, obrigatório e baseado em papéis
Modelos diferentes de controle de acesso respondem a perguntas diferentes de gerenciamento. Quem pode conceder acesso? Um programa comprometido pode compartilhar dados de um usuário? Como um administrador pode alterar os direitos de muitos funcionários sem editar cada arquivo? Um sistema operacional pode aplicar vários modelos à mesma requisição.
Diferencie a escolha do proprietário da política do sistema
No controle de acesso discricionário (DAC), o proprietário de um objeto decide quem pode usá-lo. Modos Unix e ACLs são mecanismos conhecidos. O ponto fraco é que um programa malicioso agindo como o usuário pode exercer os direitos desse usuário, inclusive copiar para outro lugar dados que ele possa ler.
No controle de acesso obrigatório (MAC), uma política do administrador para todo o sistema limita o acesso independentemente da vontade do proprietário. O núcleo aplica o MAC além do DAC. As duas verificações devem permitir o acesso, então um modo de arquivo permissivo não anula uma negação obrigatória.
O modelo de Bell–LaPadula protege a confidencialidade com níveis ordenados e duas regras: não ler acima e não escrever abaixo. Um processo Secreto pode ler dados Confidenciais e escrever em um destino Ultrassecreto. Ele não pode ler dados Ultrassecretos nem escrever dados Confidenciais. Um programa não pode mover informações de Secreto para Confidencial simplesmente lendo-as e reescrevendo-as. O Biba inverte as direções de leitura e escrita para proteger a integridade.
Confine um serviço mesmo quando ele for root
O SELinux rotula arquivos com tipos e executa processos em domínios. A política determina qual domínio pode executar quais operações em cada tipo; o acesso não listado é negado. Um servidor web em httpd_t pode ler páginas rotuladas como httpd_sys_content_t e ser impedido de acessar user_home_t, mesmo que os modos Unix comuns permitam a leitura. ls -Z mostra os rótulos.
No modo impositivo, o SELinux bloqueia e registra violações. No modo permissivo, ele registra sem bloquear. Root em um domínio confinado ainda deve cumprir a política impositiva. UID 0 e acesso irrestrito são, portanto, afirmações diferentes.
O AppArmor confina programas com perfis baseados em caminhos de arquivos e capacidades permitidas. É comumente usado no Ubuntu e no SUSE. SELinux e AppArmor operam por meio de pontos de verificação dos módulos de segurança do Linux (LSM) nas decisões de segurança. O Android combina UIDs específicos por aplicativo com SELinux; sistemas da Apple também usam perfis de isolamento de aplicações.
Atribua funções em vez de direitos individuais
No controle de acesso baseado em papéis (RBAC), permissões são associadas a papéis e usuários são associados a esses papéis. Mudar uma pessoa de função altera suas associações em vez de muitas permissões independentes de objetos.
Suponha que 50 funcionários precisem de 20 permissões cada. A atribuição direta exige 1.000 vínculos entre usuários e permissões. Se cinco papéis tiverem 20 permissões cada e cada funcionário tiver um papel, o gerenciamento exigirá 50 vínculos entre usuários e papéis e 100 vínculos entre papéis e permissões: 150 no total. A economia vem de padrões de função compartilhados, não da exclusão de permissões necessárias.
Grupos do Windows usados como papéis e políticas de sudo baseadas em grupos implementam esse padrão. O DAC é adequado a arquivos gerenciados pelos proprietários, o MAC contém serviços sob regras aplicadas centralmente, e o RBAC organiza atribuições administrativas. Um serviço pode receber os direitos de sua função por meio de um papel enquanto o DAC e o MAC verificam seu acesso efetivo a arquivos.
Principais conclusões
- O DAC permite que proprietários escolham o acesso; o MAC aplica uma política de todo o sistema.
- Uma requisição deve passar pelo DAC e pelo MAC em modo impositivo.
- Bell–LaPadula bloqueia leituras para cima e escritas para baixo.
- Domínios e tipos do SELinux podem confinar processos root.
- O RBAC gerencia permissões por meio de papéis profissionais.
4Execute sistemas operacionais em máquinas virtuais
Executar vários núcleos em um computador acrescenta uma camada de proteção abaixo do sistema operacional. Um hipervisor deve preservar a visão de cada convidado enquanto mantém o controle do tempo de CPU física, da memória e dos dispositivos. Acompanhe os mecanismos desde instruções interceptadas até a tradução de endereços em duas etapas e compare as interfaces de dispositivos e os caminhos restantes pelos quais um convidado pode afetar seu hospedeiro.
4.1 Descreva máquinas virtuais e hipervisores
Uma máquina virtual (VM) oferece a um sistema operacional completo seu próprio computador aparente. Esse sistema operacional é o convidado. O computador físico é o hospedeiro, e o hipervisor, ou monitor de máquina virtual (VMM), aloca tempo real de processador, memória e dispositivos aos convidados.
Preserve o comportamento mantendo o controle
O modelo de Popek e Goldberg, de 1974, identifica três propriedades. Equivalência significa que os programas se comportam como em uma máquina real, exceto pelo tempo e pelos recursos disponíveis. Controle de recursos significa que o hipervisor continua no comando do hardware. Eficiência significa que a maioria das instruções do convidado é executada diretamente no processador.
O hipervisor escalona CPUs virtuais (vCPUs) em núcleos físicos. Uma troca de máquina salva todo o estado de execução de uma VM, incluindo registradores privilegiados e configurações de interrupção, e depois restaura o de outra. Um convidado vê seu próprio estado mesmo quando compartilha um núcleo físico com outros convidados.
| Projeto | Onde o hipervisor é executado | Exemplos |
|---|---|---|
| Tipo 1, diretamente no hardware | Controla o hardware diretamente | ESXi, Xen, Hyper-V |
| Tipo 2, hospedado | É executado como uma aplicação que usa um sistema operacional hospedeiro | VirtualBox, VMware Workstation, Parallels Desktop |
O KVM transforma o próprio núcleo Linux em um hipervisor e normalmente é classificado como tipo 1. Um hospedeiro Linux completo continua disponível, o que torna menos clara a distinção simples entre os dois tipos. Para analisar a proteção, identifique qual componente realmente controla a virtualização da CPU e da memória.
Use a abstração de máquina
A consolidação de servidores reúne sistemas pouco utilizados. Doze servidores que usam, em média, 5% de um computador de oito núcleos cada um precisam, juntos, de 60% de um desses computadores. Essa média sugere que a consolidação é possível, mas picos simultâneos, demanda de RAM e de dispositivos ainda exigem uma margem de capacidade.
Um retrato do estado salva o estado de uma VM para restauração posterior. Copiar apenas uma imagem de disco não captura o estado de uma CPU em execução e sua memória. A migração em execução transfere uma VM em funcionamento para outro hospedeiro, copiando a memória e transferindo a execução com uma breve pausa. Essas operações são possíveis porque o estado de máquina do convidado é representado como dados gerenciados pelo hipervisor.
VMs também permitem testar sistemas antigos, separar softwares incompatíveis e executar sistemas operacionais diferentes em hardware compatível. Uma VM pode executar um convidado Windows ao lado de um convidado Linux, cada um com seu próprio núcleo. Instâncias de servidores em nuvem normalmente usam essa fronteira.
Separe virtualização de emulação completa
Um emulador pode interpretar ou traduzir um conjunto de instruções para outro processador, como código ARM em x86. A virtualização por hardware normalmente executa instruções do convidado diretamente em um processador compatível e intervém em eventos sensíveis. Isso explica tanto sua velocidade quanto sua necessidade de suporte da CPU.
Núcleos convidados separados formam uma fronteira útil: assumir o controle de um núcleo convidado não dá controle direto do núcleo hospedeiro. A fronteira ainda depende do funcionamento correto do hipervisor e do código do modelo de dispositivo. Um escape de VM explora essa camada, enquanto um canal lateral pode vazar dados pelo hardware compartilhado sem conceder acesso comum à memória. Escolher uma VM reduz as interfaces expostas a um convidado não confiável; isso não torna o hardware compartilhado infalível.
Principais conclusões
- Uma VM apresenta uma máquina completa ao seu sistema operacional convidado.
- Equivalência, controle de recursos e eficiência descrevem a função de um VMM.
- Uma vCPU é escalonada em uma CPU física.
- Retratos do estado e migração dependem de salvar e transferir o estado da máquina.
- A consolidação precisa de margem para picos de demanda, além de uma média baixa.
- O isolamento de VMs depende do funcionamento correto do hipervisor, do modelo de dispositivo e do hardware.
4.2 Virtualize o processador
Um núcleo convidado espera controlar sua máquina. O hipervisor deve preservar essa aparência sem entregar o computador real. A virtualização da CPU permite que instruções comuns do convidado sejam executadas diretamente e intercepta operações que precisam alterar o estado da máquina virtual.
Intercepte e emule o estado virtual
Na interceptação e emulação clássica, os privilégios do núcleo convidado são reduzidos. Sua tentativa de carregar um registrador de tabela de páginas ou instalar uma tabela de armadilhas gera uma armadilha para o hipervisor. O hipervisor atualiza o registrador ou a tabela virtual do convidado e retoma a execução. Ele não permite que o convidado substitua as estruturas de controle reais do hipervisor.
Uma chamada de sistema do convidado pode exigir várias travessias nessa arquitetura. A aplicação convidada gera uma armadilha para o tratador real pertencente ao hipervisor. O hipervisor transfere a execução para o tratador registrado do núcleo convidado com privilégio reduzido. Quando o núcleo convidado retorna, esse retorno privilegiado gera outra armadilha; o hipervisor conclui o retorno real à aplicação convidada.
A condição de Popek e Goldberg para essa técnica é que toda instrução sensível seja privilegiada. Sensível significa que ela altera a configuração da máquina ou se comporta de modo diferente conforme o privilégio. Privilegiada significa que ela gera uma armadilha fora do modo mais privilegiado. Diferenças silenciosas não podem ser emuladas se o hipervisor nunca souber que ocorreram.
Entenda o obstáculo do x86 clássico
A análise de Robin e Irvine, de 2000, identificou 17 instruções x86 sensíveis e não privilegiadas. Por exemplo, POPF pode restaurar o indicador de habilitação de interrupções com privilégio suficiente, mas deixá-lo inalterado silenciosamente com privilégio reduzido. Um convidado com privilégios reduzidos pode acreditar que desativou interrupções, embora nenhuma armadilha tenha informado o hipervisor para atualizar seu estado virtual de interrupção.
Três abordagens resolvem esse problema:
| Abordagem | Como intercepta a operação | Alteração no convidado |
|---|---|---|
| Tradução binária | Reescreve instruções problemáticas do núcleo convidado antes da execução e armazena o código traduzido em cache | Nenhuma alteração no código-fonte |
| Paravirtualização | Substitui operações privilegiadas por hiperchamadas explícitas | Núcleo convidado modificado |
| Suporte de hardware | Fornece operação separada para o convidado e saídas controladas da VM | Um convidado não modificado pode ser executado |
A VMware usou tradução binária em 1999; o Xen usou paravirtualização em 2003. O Intel VT-x chegou em 2005 e o AMD-V em 2006. Aplicações comuns do convidado ainda podem ser executadas diretamente quando o código do núcleo precisa de tradução ou hiperchamadas.
Mantenha o número do anel separado do modo de virtualização
Com Intel VT-x, o hipervisor opera em modo VMX root e um convidado em modo não root. O núcleo convidado pode usar o anel 0 nesse modo. O anel 0 em um convidado não dá controle sobre o hospedeiro físico.
Eventos configurados causam uma saída da máquina virtual, salvando o estado da vCPU em uma estrutura de controle como a VMCS. O hipervisor trata o evento e retoma a execução por uma entrada na máquina virtual. Muitas chamadas de sistema podem permanecer inteiramente dentro do convidado. O ARM usa EL2 para o hipervisor; o RISC-V fornece uma extensão de hipervisor.
Se um convidado executa HLT e esse evento está configurado para causar uma saída, o hipervisor marca sua vCPU como em espera e escalona outro trabalho até chegar uma interrupção virtual. O núcleo físico não precisa ficar ocioso. Saídas e entradas ainda custam tempo, normalmente de centenas a milhares de ciclos, então o agrupamento de operações e as interfaces paravirtuais continuam úteis.
Principais conclusões
- A interceptação e emulação aplica operações sensíveis ao estado da máquina virtual.
- A interceptação e emulação clássica exige que instruções sensíveis gerem armadilhas.
- A tradução binária reescreve código; a paravirtualização altera a interface do convidado.
- O anel 0 do convidado sob VT-x continua separado da operação VMX root.
- Saídas da VM são eventos controlados com um custo real de desempenho.
4.3 Virtualize a memória
Uma aplicação convidada usa um endereço virtual do convidado. Seu núcleo o traduz para um endereço físico do convidado, que é a visão da RAM pelo convidado. O hipervisor então mapeia esse endereço para um endereço físico do hospedeiro, ou da máquina. Cada convidado pode acreditar que sua RAM começa em zero enquanto usa quadros reais diferentes.
Preserve o deslocamento na página
Use páginas de 4 KiB. O convidado mapeia a página virtual 2 para o quadro 7 do convidado; o hipervisor mapeia o quadro 7 do convidado para o quadro 42 da máquina. Para o endereço 0x2ABC:
- Divida-o em página 2 e deslocamento
0xABC. - Substitua a página 2 pelo quadro 7 do convidado, resultando em
0x7ABC. - Substitua o quadro 7 do convidado pelo quadro 42 da máquina, em hexadecimal
0x2A. - Mantenha o deslocamento, resultando no endereço da máquina
0x2AABC, ou 174.780 bytes a partir do endereço zero.
Somente o número da página muda. Tratar o endereço físico do convidado como um endereço real da RAM contornaria a decisão de alocação e isolamento do hipervisor.
Compare a tradução por software e por hardware
Tabelas de páginas sombra mapeiam páginas virtuais do convidado diretamente para quadros da máquina. A MMU real usa essas tabelas, construídas pelo hipervisor. O hipervisor protege contra escrita as páginas que contêm tabelas de páginas do convidado e intercepta alterações e trocas dessas tabelas para manter suas tabelas sombra consistentes. Alterações frequentes no espaço de endereçamento do convidado, portanto, causam armadilhas extras.
A paginação aninhada, Intel EPT ou AMD NPT, fornece as duas etapas à MMU. O hardware percorre as tabelas do convidado e as tabelas que traduzem endereços físicos do convidado para endereços da máquina. As atualizações das tabelas de páginas do convidado deixam de exigir todas uma interceptação por software. A TLB armazena em cache a tradução final combinada.
Uma ausência no cache ainda pode ser cara. Com quatro níveis em cada etapa, cada uma das quatro entradas da tabela do convidado precisa de quatro referências à tabela aninhada mais a própria entrada: 20 referências. Traduzir o endereço físico dos dados finais do convidado acrescenta mais quatro, totalizando 24 referências de tradução antes do acesso aos dados. Páginas grandes e caches de percurso de tabelas de páginas reduzem esse trabalho sem cache no pior caso.
Recupere memória com conhecimento limitado do convidado
O supercomprometimento de memória promete mais memória total aos convidados do que o hospedeiro possui. Quatro VMs de 16 GiB totalizam 64 GiB em um hospedeiro de 48 GiB. Isso só funciona enquanto suas necessidades ativas couberem na capacidade; se todas ficarem ocupadas, será necessário recuperar memória ou transferir páginas para a área de troca.
Um driver de balão dentro de um convidado aloca páginas a pedido do hipervisor. O sistema operacional convidado escolhe o que liberar, enquanto o hipervisor recupera os quadros da máquina correspondentes às páginas do balão. Isso reduz a lacuna de informação: o convidado sabe quais dados são importantes, enquanto o hipervisor vê alocações sem conhecer todo o seu significado.
O compartilhamento de páginas, como o KSM do Linux, reúne páginas idênticas em uma cópia somente para leitura e as separa em uma escrita. A troca de páginas pelo hipervisor é outra alternativa, mas pode fazer escolhas ruins por não ter o conhecimento do convidado. Um dispositivo atribuído à VM também precisa de uma IOMMU para traduzir e restringir seus endereços de DMA.
Compartilhar páginas idênticas entre clientes tem um custo de privacidade: o tempo da cópia na escrita pode revelar se outro convidado possui os mesmos dados. Provedores de nuvem normalmente desativam essa forma de compartilhamento entre clientes, embora ela economize memória.
Principais conclusões
- Endereços virtuais do convidado, físicos do convidado e da máquina são camadas diferentes.
- O deslocamento na página permanece inalterado nas duas traduções.
- Tabelas sombra exigem que o hipervisor acompanhe alterações nas tabelas do convidado.
- A paginação aninhada realiza as duas etapas em hardware e armazena o resultado combinado em cache.
- O supercomprometimento depende de a demanda permanecer abaixo da capacidade disponível.
- A recuperação por balão usa o conhecimento do convidado; o compartilhamento de páginas pode expor informações pelo tempo de execução.
4.4 Virtualize dispositivos e mantenha as máquinas virtuais isoladas
Uma VM precisa de armazenamento, rede e outros dispositivos, além de tempo de CPU e RAM. A interface de dispositivo afeta a compatibilidade, o desempenho e o código que um convidado não confiável pode alcançar. Uma interface rápida e uma interface confiável pequena são escolhas de projeto relacionadas, mas não são a mesma propriedade.
Escolha como o convidado acessa um dispositivo
| Abordagem | Interface do convidado | Principal compromisso |
|---|---|---|
| Emulação | Um modelo de um dispositivo físico conhecido | Drivers existentes funcionam, mas operações em registradores exigem trabalho de software |
| Dispositivo paravirtual | Um driver preparado para virtualização e filas compartilhadas | Agrupamento eficiente, mas o convidado precisa do driver |
| Atribuição direta | Um dispositivo físico ou função virtual atribuído | Acesso próximo ao nativo, com compartilhamento e migração mais difíceis |
Um auxiliar como o QEMU pode emular uma placa de rede Intel e1000. O driver comum do convidado escreve em registradores conhecidos; o auxiliar implementa o efeito. Acessos frequentes a registradores podem causar muitas saídas e operações de software.
Um driver virtio, por sua vez, troca requisições por filas em memória compartilhada. Ele pode colocar várias operações na fila e notificar o componente de atendimento uma vez. O vmxnet3 da VMware e os dispositivos VMBus do Hyper-V seguem projetos relacionados, preparados para virtualização. Um driver de dispositivo paravirtual não significa que todo o núcleo convidado precise usar operações de CPU paravirtuais.
Na atribuição direta de dispositivo, o convidado recebe um dispositivo físico ou uma função virtual SR-IOV. A IOMMU limita o DMA à memória da VM. A atribuição direta reduz a mediação por software, mas transferir o estado do dispositivo para outro hospedeiro pode dificultar a migração em execução.
Trate discos virtuais como estado gerenciado
Um disco virtual normalmente é um arquivo no hospedeiro, como qcow2, VMDK ou VHDX, ou um volume de armazenamento. Imagens com cópia na escrita permitem que muitos convidados compartilhem uma base enquanto registram alterações separadas. Retratos do estado podem preservar o estado do disco com baixo custo, e um retrato completo de uma VM em execução também precisa do estado de execução e da memória. Clonagem e migração dependem da capacidade do hipervisor de gerenciar essas representações.
Localize a fronteira que um atacante precisa atravessar
Um núcleo convidado comprometido já controla essa VM, mas alcançar o hospedeiro exige um escape de máquina virtual ou outra falha de fronteira. A falha VENOM, de 2015, afetava o controlador de disquete emulado do QEMU e podia permitir que código do convidado fosse executado no processo QEMU do hospedeiro. Manter a emulação de dispositivos em um processo separado e isolado limita a autoridade exposta por esse erro.
Caches de CPU, preditores de desvio e barramentos de memória compartilhados também criam canais laterais. Spectre e L1TF mostraram que o isolamento não pode ser avaliado apenas pelos mapeamentos de páginas. Medidas de mitigação incluem atualizações do processador e do microcódigo, limpeza do estado relevante entre convidados e evitar a execução simultânea de clientes diferentes em threads de hardware do mesmo núcleo.
A computação confidencial, incluindo AMD SEV-SNP e Intel TDX, protege a memória do convidado contra o hipervisor com chaves de criptografia mantidas pelo hardware e permite atestar o ambiente iniciado. Ela estende a fronteira de confiança contra um hospedeiro ou operador comprometido. Ela não elimina todos os canais laterais nem todas as formas pelas quais um hospedeiro pode interromper o serviço. A segurança da VM ainda depende do hipervisor, das interfaces de dispositivos, do hardware e de sua configuração.
Principais conclusões
- A emulação favorece a compatibilidade; filas paravirtuais reduzem saídas repetidas.
- A atribuição direta exige que a IOMMU limite o DMA do dispositivo.
- Discos virtuais e o estado salvo da máquina permitem retratos do estado e migração.
- Erros no modelo de dispositivo podem permitir um escape de máquina virtual.
- O hardware compartilhado pode vazar informações sem uma falha comum de permissão de memória.
- A computação confidencial protege a memória do convidado contra o hospedeiro dentro das garantias de seu hardware.
5Isole aplicações com contêineres
Contêineres criam um ambiente isolado em torno de processos comuns que usam o núcleo do hospedeiro. Suas visões privadas, limites de recursos e autoridade vêm de recursos diferentes do núcleo, então cada um precisa de atenção separada. Interprete mapeamentos de espaços de nomes e configurações de grupos de controle e depois relacione-os às restrições de privilégios. Use a fronteira do núcleo compartilhado para decidir onde contêineres, VMs ou uma combinação deles são adequados a uma carga de trabalho.
5.1 Limite o que um processo pode ver com espaços de nomes
Um contêiner Linux é um conjunto de processos que usa o núcleo do hospedeiro com visões e privilégios restritos. Ele não tem núcleo separado nem computador emulado. Espaços de nomes dão aos processos instâncias privadas de recursos que, de outra forma, seriam globais.
Relacione cada espaço de nomes à sua visão
| Espaço de nomes | O que separa |
|---|---|
| Montagem | Sistemas de arquivos montados e a árvore de arquivos visível |
| PID | Números de processos e visibilidade dos processos |
| Rede | Interfaces, endereços, rotas, portas e regras de firewall |
| UTS | Nome do hospedeiro e nome de domínio NIS |
| IPC | Objetos de IPC do System V e filas de mensagens POSIX |
| Usuários | Mapeamentos de IDs de usuários e grupos e capacidades de escopo limitado |
| Cgroup | A parte visível da hierarquia de cgroups |
| Tempo | Deslocamentos dos relógios monotônico e de inicialização |
clone() com opções de espaços de nomes cria um processo filho nos novos espaços de nomes selecionados. unshare() separa o contexto de espaços de nomes, e setns() ingressa em um espaço de nomes existente por meio de um descritor, como um aberto a partir de /proc/1234/ns/net. A reassociação de PID afeta processos filhos posteriores sem mover quem fez a chamada. Para espaços de nomes de tempo, unshare(CLONE_NEWTIME) também prepara um espaço de nomes para processos filhos posteriores; setns() pode mover quem fez a chamada para um espaço de nomes de tempo existente. Espaços de nomes de tempo são criados com unshare().
Assim, unshare --pid --fork --mount-proc bash usa --fork para criar o interpretador de comandos dentro do novo espaço de nomes de PID. Esse interpretador é o PID 1 ali, mesmo que seu PID no hospedeiro seja 48213. O PID 1 adota processos órfãos; se ele terminar, o núcleo encerra os processos restantes do espaço de nomes. Processos em um espaço de nomes ancestral podem ver os descendentes, enquanto processos dentro dele não podem ver os espaços de nomes de PID ancestrais.
Separe arquivos e rede
Um espaço de nomes de montagem fornece uma lista privada de montagens. Um ambiente de execução monta uma árvore de arquivos e a torna a raiz usando pivot_root. Um contêiner pode usar /etc e /usr de outra distribuição Linux enquanto ainda faz chamadas ao núcleo do hospedeiro. chroot sozinho apenas altera o ponto inicial da busca por caminhos; ele não é uma fronteira segura contra um processo privilegiado.
Um novo espaço de nomes de rede tem uma interface de loopback. Um ambiente de execução pode conectá-lo por um par de interfaces veth, com uma extremidade dentro dele e outra conectada a uma ponte no hospedeiro. Pilhas separadas permitem que dois contêineres escutem na porta 80 sem disputar a porta de um mesmo espaço de nomes.
Traduza identidades por meio de um espaço de nomes de usuários
Uma linha em /proc/<pid>/uid_map lista o primeiro ID interno, o primeiro ID externo e o tamanho do intervalo. A linha 0 100000 65536 mapeia os IDs internos 0–65535 para os IDs 100000–165535 do hospedeiro. O UID interno 1000, portanto, é mapeado para 101000 externamente. IDs sem um mapeamento utilizável normalmente são exibidos como o UID de transbordamento 65534.
Root dentro desse espaço de nomes tem capacidades sobre recursos controlados por ele, não autoridade sobre todo o hospedeiro. Carregar um módulo do núcleo ou alterar o relógio real do sistema ainda exige privilégio no espaço de nomes de usuários inicial. Um mapeamento de UID não protege um socket privilegiado do ambiente de execução disponibilizado ao contêiner.
Uma visão privada também não limita o consumo. Um processo com seus próprios espaços de nomes de PID e montagem ainda pode consumir CPU e RAM. Cgroups limitam quantidades, enquanto limites de capacidades e seccomp restringem operações.
Principais conclusões
- Contêineres usam processos do núcleo do hospedeiro com visões privadas de recursos.
- Os oito tipos de espaços de nomes separam tipos diferentes de estado global.
- A reassociação de PID e o uso de unshare em espaços de nomes de tempo afetam processos filhos posteriores; setns pode ingressar diretamente em um espaço de nomes de tempo.
- O PID 1 tem responsabilidades especiais no ciclo de vida dentro de seu espaço de nomes.
- Espaços de nomes de usuários traduzem IDs e limitam o escopo da autoridade.
- Visões privadas precisam de limites separados de recursos e privilégios.
5.2 Limite o que um processo pode usar com grupos de controle
Um grupo de controle, ou cgroup, reúne processos para contabilização e controle de recursos. Espaços de nomes determinam sua visão; cgroups controlam quantidades como tempo de CPU, memória e número de tarefas. Processos filhos herdam o grupo do processo pai, e a hierarquia impede que um grupo filho escape dos limites de um ancestral.
Interprete os arquivos do cgroup v2
O cgroup v2 usa uma hierarquia unificada, normalmente em /sys/fs/cgroup. Um grupo pai habilita controladores para seus filhos por meio de cgroup.subtree_control, por exemplo, +cpu +memory +pids. Arquivos individuais em cada grupo filho contêm limites e contadores.
Os controladores incluem cpu, cpuset, memory, io, pids, hugetlb e rdma. Eles controlam tempo de CPU, posicionamento em CPUs e nós de memória, memória comum, entrada e saída de blocos, número de tarefas, páginas enormes e recursos de RDMA. Eventos de desempenho compatíveis com cgroups dão suporte à medição, e cgroup.freeze pausa a execução de um grupo.
Diferencie um limite de CPU de uma parcela
cpu.max contém uma cota e um período em microssegundos. 50000 100000 permite 50 ms de execução de CPU a cada 100 ms, o equivalente à metade de uma CPU. 200000 100000 permite o equivalente ao tempo de duas CPUs, potencialmente distribuído entre núcleos. max 100000 significa ausência de limite de cota. Quando a cota é consumida, o grupo aguarda o próximo período, mesmo que uma CPU esteja ociosa.
cpu.weight define uma parcela relativa durante a competição, de 1 a 10.000, com padrão 100. Para grupos igualmente posicionados e prontos para execução em quatro CPUs, os pesos 100 e 300 dividem o tempo disponível na proporção 1:3: aproximadamente uma CPU e três CPUs. Se o grupo de maior peso ficar ocioso, o outro poderá usar as quatro, a menos que outro limite interfira. Um peso não é uma reserva nem um teto rígido.
Contenha o esgotamento de memória e tarefas
memory.high aplica pressão para recuperar memória e desacelera tarefas acima de seu limiar. memory.max impõe uma fronteira rígida. O núcleo primeiro tenta recuperar memória, incluindo cache e usando a área de troca disponível. Se não conseguir recuperar o suficiente, o tratamento de falta de memória do cgroup encerra um processo elegível dentro do grupo afetado.
Para memory.max de 512M, o limite é de 536.870.912 bytes, ou 512 MiB. Um processo com vazamento pode forçar a recuperação de memória e acabar provocando um encerramento por falta de memória, mas a vítima é selecionada pelo núcleo e não há garantia de que seja esse processo. A fronteira do grupo contém o evento em vez de escolher um processo não relacionado do hospedeiro.
pids.max conta processos e threads. Com um limite de 100, novas criações falham com EAGAIN, contendo o crescimento de tarefas de uma bomba de fork. Um limite de entrada e saída como 8:0 rbps=10485760 em io.max limita as leituras do dispositivo de blocos 8:0 a 10 MiB/s.
Esses arquivos não escondem processos nem nomes de arquivos do hospedeiro. Além disso, /proc/meminfo e ferramentas que o leem podem informar a RAM do hospedeiro em vez de memory.max; o total exibido, por si só, não prova que um cgroup não tem limite. As medições de recursos devem ser lidas na camada que impõe a fronteira.
Principais conclusões
- O cgroup v2 aplica controles de recursos por uma hierarquia unificada.
- Um grupo filho continua restrito pelos limites dos ancestrais.
- cpu.max é uma cota rígida; cpu.weight é uma parcela relativa durante a competição.
- memory.high aplica pressão; memory.max pode levar ao encerramento local por falta de memória.
- pids.max conta threads além de processos.
- Limites de cgroup não criam visões privadas dos recursos do hospedeiro.
5.3 Restrinja contêineres e escolha entre contêineres e máquinas virtuais
Uma fronteira útil de contêiner combina visões, controles de recursos e autoridade restrita. Uma árvore de arquivos privada, por si só, não impede chamadas de sistema perigosas, e uma cota de CPU não impede o acesso a um arquivo exposto do hospedeiro. O núcleo do hospedeiro aplica todos esses controles.
Reduza a autoridade do processo
Um ambiente de execução combina espaços de nomes, cgroups e uma imagem de sistema de arquivos que contém programas e bibliotecas. Ele pode fortalecer a fronteira ao:
- Executar a carga de trabalho como não root ou mapear IDs do contêiner por um espaço de nomes de usuários.
- Remover capacidades do Linux, especialmente poderes amplos como
CAP_SYS_ADMINeCAP_SYS_MODULE. - Aplicar seccomp para restringir chamadas desnecessárias.
- Aplicar uma política SELinux ou AppArmor.
- Tornar o sistema de arquivos raiz somente para leitura quando viável.
- Definir
no_new_privspara que a execução setuid não possa elevar privilégios.
Cada controle cobre um caminho diferente. Um sistema de arquivos raiz somente para leitura ainda permite operações de rede autorizadas; um filtro seccomp ainda permite as chamadas de sua lista. O projeto deve corresponder às operações de que a aplicação realmente precisa.
Identifique o risco do núcleo compartilhado
Todos os contêineres comuns compartilham o núcleo do hospedeiro. Um erro no núcleo que possa ser alcançado pode, portanto, comprometer o hospedeiro e outros contêineres. Em uma VM, explorar o núcleo convidado dá controle desse convidado; alcançar o hospedeiro exige uma falha adicional na fronteira do hipervisor ou de dispositivos.
Root dentro de um contêiner exige atenção especial. Sem um espaço de nomes de usuários, ele é UID 0 para o núcleo do hospedeiro, limitado por capacidades, filtros e política obrigatória. O modo privilegiado ou o acesso ao sistema de arquivos raiz do hospedeiro pode remover essas restrições. Um socket do ambiente de execução pertencente a root também é perigoso: seu cliente pode pedir ao ambiente que execute ações privilegiadas. Mapear root do contêiner para um ID sem privilégios no hospedeiro não torna esse socket seguro nem elimina vulnerabilidades do núcleo.
Escolha uma fronteira para a carga de trabalho
| Necessidade | Fronteira adequada | Razão |
|---|---|---|
| Serviços Linux de uma equipe implantados com frequência | Contêineres restritos | Inicialização rápida e baixa sobrecarga em um único núcleo |
| Código de clientes que não confiam uns nos outros | VMs ou micromáquinas virtuais | Núcleos convidados separados reduzem a exposição ao núcleo compartilhado |
| Uma aplicação exclusiva do Windows em hospedeiros Linux | VM | A carga de trabalho precisa de outro núcleo |
Um contêiner Linux precisa de um núcleo Linux. Por isso, plataformas no Windows e no macOS frequentemente fornecem uma VM Linux sob os contêineres Linux. VMs inicializam um sistema operacional e alocam memória para cada núcleo; contêineres iniciam processos comuns e podem acomodar cargas de trabalho com maior densidade.
Reconheça projetos intermediários
O gVisor trata muitas chamadas de sistema de contêineres em um núcleo em espaço de usuário, reduzindo o contato direto com o núcleo do hospedeiro. O Kata Containers dá a cada ambiente isolado, normalmente um pod do Kubernetes, uma VM leve; os contêineres nesse ambiente compartilham seu núcleo convidado. O Firecracker fornece micromáquinas virtuais com um modelo mínimo de dispositivos para plataformas que executam funções ou cargas de trabalho de contêineres, incluindo o AWS Lambda.
Sistemas de nuvem frequentemente colocam contêineres dentro de VMs: uma VM separa clientes enquanto contêineres organizam as aplicações de um cliente. Os núcleos convidados e o núcleo do hospedeiro permanecem distintos, então um escape de contêiner dentro de uma VM não prova, por si só, um escape do hipervisor.
Principais conclusões
- O isolamento de contêineres precisa de visões, limites de recursos e restrições de privilégios.
- Todos os contêineres comuns em um hospedeiro compartilham seu núcleo.
- Um mapeamento de UID sem privilégios de root no hospedeiro reduz a autoridade, mas não corrige erros no núcleo.
- O acesso a um socket privilegiado do ambiente de execução pode conceder controle do hospedeiro.
- VMs podem trazer outro núcleo; contêineres usam o núcleo que está abaixo deles.
- gVisor, Kata e Firecracker acrescentam fronteiras diferentes em torno das cargas de trabalho.
- Contêineres dentro de VMs combinam densidade de aplicações com núcleos convidados separados.
Exercícios resolvidos de Proteção, isolamento e máquinas virtuais
1Acompanhe uma requisição através da fronteira do núcleo
16 passos
- 1IntroduçãoComece com uma aplicação em execução
Um serviço de relatórios passa a maior parte do tempo calculando em modo usuário. Ele precisa do núcleo apenas para trabalho protegido, como abrir um arquivo ou preparar um mapeamento.
Acompanhe o que muda quando a execução atravessa essa fronteira: o privilégio da CPU muda, mas a identidade de quem fez a chamada e a validade de sua requisição ainda precisam ser verificadas. Depois, acompanhe as proteções separadas para memória, dispositivos e código executável.
- 2ExplicaçãoExecute código comum diretamente
A CPU executa diretamente as adições, leituras e saltos do serviço. O hardware verifica o privilégio e as permissões de memória durante a execução; o núcleo não aprova cada instrução por software.
Uma tentativa de substituir uma tabela de páginas ou desativar interrupções deve gerar uma armadilha. Caso contrário, o programa poderia remover as próprias restrições que deveriam contê-lo. Essa combinação é a execução direta limitada.
- 3DesafioUm serviço para de fazer requisições
O serviço fica preso em um laço infinito em modo usuário. Ele não faz mais nenhuma chamada de sistema. O escalonador ainda pode executar outro processo pronto?
---reveal---
Sim. Uma interrupção do temporizador de hardware entra no núcleo independentemente da cooperação do serviço. O escalonador pode selecionar outro processo. Programar o temporizador e desativar interrupções exigem privilégio, então o serviço em laço não consegue manter o núcleo de processamento evitando chamadas de sistema.
- 4ExplicaçãoSolicite um serviço protegido
Para ler um arquivo, a função de biblioteca que encapsula a chamada coloca um número de chamada, um descritor, um endereço de buffer e um tamanho em registradores e depois executa a instrução de entrada de chamada de sistema da arquitetura.
O núcleo salva o estado do usuário, seleciona o tratador e obtém as credenciais de quem fez a chamada a partir do processo atual. Entrar com privilégio de núcleo é apenas o começo: o tratador ainda precisa decidir se essa pessoa ou processo e esses argumentos são autorizados.
- 5ExemploExamine o destino completo
Suponha que o serviço solicite
read(fd, buf, 8192)para copiar bytes para seu buffer. O primeiro byte ser válido não é suficiente: a cópia pode atravessar uma fronteira de página e entrar em um intervalo proibido.O núcleo deve validar e acessar com segurança todo o destino necessário para a transferência. As rotinas verificadas de cópia de dados de usuário do Linux tratam endereços de usuário inválidos sem permitir que a cópia solicitada sobrescreva a memória do núcleo.
- 6DesafioUma requisição usa o tipo de acesso errado
O buffer é válido, mas o serviço tenta
write()usando um descritor que abriu comO_RDONLY. O que o núcleo deve verificar, e o processo precisa terminar?---reveal---
Ele verifica o acesso concedido ao descritor e rejeita a escrita com
EBADFno Linux. Esse é um resultado de erro que o programa pode tratar. A chamada entrou no núcleo corretamente, mas o descritor não contém o direito solicitado. - 7Ideia-chaveMantenha um caminho verificado associado ao seu objeto
Um programa auxiliar verifica a permissão em um caminho e depois o abre com maior privilégio. Entre as duas operações, outro processo pode substituir a entrada de diretório. Uma cópia da cadeia de caminho não impede essa substituição.
Essa é uma condição de corrida TOCTTOU. Abra com as credenciais pretendidas e use uma estratégia de obtenção do objeto que verifique o que é realmente aberto; use
O_NOFOLLOWquando ligações simbólicas não forem desejadas. - 8ExplicaçãoDeixe os mapeamentos controlarem acessos posteriores
Depois que um mapeamento é concedido, leituras e escritas usam a MMU sem uma chamada de sistema por byte. A MMU verifica as permissões de escrita, usuário ou supervisor e execução da tabela de páginas ativa.
Uma página de usuário somente para leitura protege seu conteúdo contra alterações, mas ainda permite que o processo o leia. Para manter os dados em sigilo desse processo, o mapeamento também deve negar a leitura, por exemplo, estando ausente ou sendo exclusivo do supervisor.
- 9ExemploInterprete duas faltas de escrita em páginas somente para leitura
O serviço escreve primeiro em sua página de código e depois em dados compartilhados após
fork(). Ambas as páginas são somente para leitura, então as duas escritas inicialmente causam faltas.Os registros do núcleo separam os resultados. Uma escrita não autorizada em código normalmente leva a
SIGSEGV. Uma falta válida de cópia na escrita em dados leva a uma cópia privada e à reinicialização da instrução. O hardware informa a violação; os registros do núcleo decidem se ela pode ser reparada. - 10DesafioUm dispositivo atravessa a fronteira da memória
O serviço é limitado pelas tabelas de páginas da CPU, mas um dispositivo defeituoso escreve diretamente em uma área de RAM não relacionada. Por que esses mapeamentos da CPU não o impediram?
---reveal---
O DMA não passa pela MMU da CPU. O dispositivo precisa de um mapeamento na IOMMU que restrinja seus próprios endereços. Proteger leituras e escritas da CPU é uma fronteira; limitar transferências originadas em dispositivos exige a fronteira correspondente para dispositivos.
- 11ExplicaçãoBloqueie a execução de bytes injetados
Um estouro de buffer pode sobrescrever um endereço de retorno salvo. Marcar a pilha com NX torna não executáveis as instruções injetadas nela, então um salto para esse local causa uma falta.
W^X acrescenta a regra de que nenhuma página pode permitir escrita e execução ao mesmo tempo. Um compilador just-in-time deve escrever o código gerado e depois alterar as permissões antes de executá-lo. Essas verificações restringem a exploração, mas a escrita original fora dos limites ainda precisa ser corrigida.
- 12ConexãoDificulte a localização de código existente
Um atacante pode reutilizar instruções que já estão em bibliotecas executáveis em vez de injetar novas instruções. A ROP liga esses pequenos gadgets em uma nova computação.
A ASLR torna seus endereços mais difíceis de prever. O vazamento de um endereço de uma biblioteca conhecida revela a base e os deslocamentos conhecidos dessa biblioteca, mas não revela uma pilha aleatorizada independentemente. A aleatorização funciona melhor quando erros não conseguem revelar os endereços escolhidos.
- 13DesafioContenha um renderizador comprometido
Um renderizador foi comprometido. Sua pilha tem NX e os endereços de suas bibliotecas agora são conhecidos pelo atacante. Uma política seccomp ainda bloqueia chamadas para iniciar programas. A reutilização de código pode simplesmente remover essa restrição?
---reveal---
Não. Reutilizar instruções executáveis não remove um filtro seccomp instalado. O processo continua limitado às chamadas permitidas, então iniciar outro programa exige outra forma de contornar o filtro ou outra falha de fronteira.
- 14ExplicaçãoSepare verificações de inicialização de registros de eventos
A inicialização segura verifica assinaturas antes de passar o controle ao próximo componente confiável de inicialização. A inicialização medida registra hashes dos componentes, frequentemente usando um TPM, para que um verificador externo possa avaliar o que foi carregado.
O registro de auditoria tem uma finalidade posterior: documenta eventos como falhas de login e comandos executados com privilégios elevados. Proteger cópias fora do hospedeiro ajuda a preservar essas evidências caso um invasor obtenha autoridade para apagar registros locais.
- 15DesafioEscolha a camada de proteção ausente
Um serviço root mapeia dados sensíveis como somente para leitura em um processo trabalhador não confiável e restringe suas chamadas de sistema. O trabalhador então lê os dados. Qual decisão os expôs?
---reveal---
O mapeamento legível pelo usuário expôs o conteúdo. Somente leitura protege contra alterações, e um filtro de chamadas de sistema não bloqueia leituras comuns de uma página permitida. O núcleo deve negar ao trabalhador esse mapeamento ou sua permissão de leitura para preservar a confidencialidade.
- 16RecapitulaçãoLocalize a verificação que controla a ação
Para uma falha desconhecida, acompanhe a operação: instrução da CPU, requisição ao núcleo, acesso à memória mapeada ou DMA de dispositivo. Cada uma chega a um ponto de aplicação diferente.
Depois, pergunte o que o atacante já controla. Identidade root, gadgets executáveis e um descritor válido conferem poderes diferentes. Um diagnóstico útil identifica a verificação exata que falta, em vez de supor que uma defesa bem-sucedida protege todos os caminhos.
2Acompanhe o login até as credenciais de processo
14 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoTransforme um login em uma identidade em execução
- 2ExplicaçãoDefina os grupos antes de abandonar root
- 3ExemploAcompanhe um programa auxiliar setuid de senhas
- 4DesafioAtualize uma conta durante uma sessão
- 5ExplicaçãoRecalcule um verificador sem recuperar uma senha
- 6ExemploMeça o trabalho de tentativas para uma conta
- 7ExemploRepita o trabalho para sais diferentes
- 8DesafioUm bloqueio não alcança o arquivo roubado
- 9ExplicaçãoDiferencie um código de uma assinatura vinculada ao site
- 10ExemploEscolha o denominador antes de calcular
- 11DesafioDois segredos ainda são um tipo de fator
- 12ConexãoDeixe o núcleo identificar a outra parte local
- 13DesafioDescubra onde a força do login deixa de importar
- 14RecapitulaçãoMantenha a prova e os direitos resultantes distintos
3Analise uma decisão de acesso
15 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoNomeie a operação e seu objeto
- 2ExplicaçãoOrganize direitos por objeto ou por sujeito
- 3ExemploPasse uma concessão restrita a um trabalhador
- 4DesafioAltere permissões após conceder um identificador
- 5ExplicaçãoSelecione uma classe antes de somar seus bits
- 6ExemploCrie um arquivo sob uma máscara
- 7ExemploTeste o acesso usando o modo resultante
- 8DesafioRemova um nome sem ler seus dados
- 9DicaLeia o limite da ACL além da entrada
- 10ExplicaçãoAcrescente uma política que o proprietário não pode dispensar
- 11ExemploAcompanhe informações confidenciais entre níveis
- 12DesafioExplique a leitura negada a um serviço root
- 13ConexãoAltere uma função por meio de papéis
- 14DesafioAcompanhe uma concessão por vários controles
- 15RecapitulaçãoAcompanhe a decisão em uma ordem útil
4Execute um convidado sem entregar o hospedeiro
17 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoDê a um núcleo seu próprio computador aparente
- 2ExplicaçãoEscalone um processador virtual
- 3DesafioAvalie uma afirmação sobre consolidação
- 4ExplicaçãoEmule apenas o estado de controle do convidado
- 5ExemploCorrija uma instrução que não gera armadilha
- 6DesafioMantenha o anel 0 do convidado sob controle
- 7ExplicaçãoSepare os três nomes de endereço
- 8ExemploAplique primeiro o mapeamento do convidado
- 9ExemploAplique em seguida o mapeamento do hipervisor
- 10DesafioTraduza outro byte na página
- 11ConexãoEscolha onde manter o mapeamento combinado
- 12Ideia-chaveRecupere memória com ajuda do convidado
- 13ExplicaçãoTroque compatibilidade de dispositivos por menos transições
- 14DesafioReduza saídas frequentes causadas por dispositivos
- 15ExplicaçãoProteja uma fronteira mais ampla que os mapeamentos de páginas
- 16DesafioPrepare uma máquina em execução para outro hospedeiro
- 17RecapitulaçãoMantenha o controle em cada interface virtual
5Construa e avalie uma fronteira de contêiner
16 passos
Salve esta aula para seguir cada Lição Interativa passo a passo.
- 1IntroduçãoSepare três funções dentro de um contêiner
- 2ExplicaçãoDê aos processos visões privadas de recursos
- 3ExemploInicie o primeiro processo filho em um espaço de nomes de PID
- 4ExemploMapeie uma identidade interna para o hospedeiro
- 5DesafioEscolha a visão que resolve um conflito
- 6ExplicaçãoInterprete um limite rígido de CPU
- 7ExemploDivida o limite de um grupo pai entre grupos filhos
- 8DesafioDeixe um grupo concorrente ficar ocioso
- 9ExplicaçãoContenha o crescimento de memória e tarefas
- 10DesafioLeia o limite na camada que o aplica
- 11ExplicaçãoReduza o que o processo pode solicitar
- 12DesafioUm UID mapeado ainda alcança um serviço privilegiado
- 13ConexãoEscolha onde colocar um núcleo separado
- 14ExplicaçãoReconheça camadas adicionais de isolamento
- 15DesafioPosicione tarefas não confiáveis com limites de recursos
- 16RecapitulaçãoAssocie cada necessidade ao seu mecanismo
Questões de Proteção, isolamento e máquinas virtuais
Conjunto 1: Acompanhe as fronteiras do hardware e do núcleo10 Questões de Prática
Questão 1 de 10
Mostrar respostaOcultar resposta
Questão 2 de 10
LIDT no x86. O que o impede de assumir o controle do tratamento de interrupções?Mostrar respostaOcultar resposta
Questão 3 de 10
Mostrar respostaOcultar resposta
Questão 4 de 10
write() por meio desse descritor. Qual erro do Linux corresponde à ausência de acesso no descritor?Mostrar respostaOcultar resposta
write() rejeita seu uso com EBADF. EACCES normalmente descreve uma negação de controle de acesso ao obter acesso, mas esta falha diz respeito ao modo de um descritor já aberto. EFAULT, por sua vez, identificaria um endereço inválido de memória de usuário.Questão 5 de 10
Mostrar respostaOcultar resposta
Questão 6 de 10
Mostrar respostaOcultar resposta
Questão 7 de 10
fork(). Os registros do núcleo a marcam para cópia na escrita. Que resposta preserva o comportamento normal do programa?Mostrar respostaOcultar resposta
Questão 8 de 10
fork(). Escritas em ambas causam faltas. Um driver também precisa de DMA para um buffer separado. Que resposta preserva as fronteiras pretendidas?Mostrar respostaOcultar resposta
Questão 9 de 10
Mostrar respostaOcultar resposta
Questão 10 de 10
Mostrar respostaOcultar resposta
Conjunto 2: Acompanhe identidades e autenticação10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 3: Decida quem pode usar um recurso10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
metrics.bin. O proprietário então remove a permissão de escrita do modo do arquivo. O que acontece com escritas comuns por esse descritor?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 4: Acompanhe um convidado pelo hardware virtual10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
0x53D0?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 5: Interprete visões e limites de contêineres10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
0 220000 8000. Qual UID do hospedeiro corresponde ao UID interno 1750?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
unshare(CLONE_NEWPID), cria seu primeiro processo filho no novo espaço de nomes e permanece em execução fora dele. Esse processo filho cria um processo de registro e depois termina. O que acontece com o processo de registro e com o supervisor?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
cpu.max de 120000 100000. Que limite de CPU isso representa?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
pids.max de 30. O grupo filho A tem quatro processos com sete threads no total em cada um e um limite local de 40; o grupo irmão B contém dois processos com uma thread cada. A pode criar outra thread enquanto todas as tarefas existentes permanecem ativas?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Conjunto 6: Diagnostique falhas nas camadas de isolamento10 Questões de Prática
Salve esta aula para ver todas as respostas e praticar cada conjunto.
Questão 1 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 2 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 3 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 4 de 10
access() e depois abre esse caminho com privilégio total. Um atacante pode substituir a entrada nomeada. Qual falha permanece?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 5 de 10
0x9B20, e o quadro resultante está dentro do mapeamento do dispositivo?Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 6 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 7 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 8 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 9 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Questão 10 de 10
Mostrar respostaOcultar resposta
Salve esta aula para ver esta resposta.
Travou em uma questão sua? Ajuda com Tarefas
Termos-Chave
A
Acesso direto à memória
Aleatorização do espaço de endereçamento
Anel de proteção
Ataque de dicionário
Ataque de força bruta
Ataque offline
Atribuição direta de dispositivo
Autenticação
Autenticação multifator
Autenticador de chave pública
Autorização
B
Base de computação confiável
Bit de proibição de execução
Bit de restrição de exclusão
C
Capacidade de objeto
Capacidade do Linux
CAP_NET_BIND_SERVICE permite a associação a portas de número baixo sem conceder todos os poderes de root.Chamada de sistema
open() faz uma chamada de sistema para que o núcleo possa verificar o acesso antes de retornar um descritor de arquivo.Chave de acesso
Compartilhamento de páginas
Computação confidencial
Condição de corrida entre verificação e uso
Contêiner
Contêiner sem privilégios de root no hospedeiro
Controlador de grupo de controle
Controle de acesso baseado em papéis
Controle de acesso discricionário
Controle de acesso obrigatório
CPU virtual
cpu.max
cpu.max de 75000 100000 permite no máximo três quartos do tempo de uma CPU por período.cpu.weight
cpu.weight maior favorece um grupo ocupado em relação a grupos pares concorrentes, mas não pode anular sua cota separada.Custo de cálculo do hash de senha
D
Descritor de arquivo
Diretório com setgid
Domínio do SELinux
E
EFAULT
read() com destino na memória do núcleo pode retornar EFAULT em vez de sobrescrever o núcleo.Emulação de dispositivos
Endereço físico do convidado
Entidade de segurança
Entrada de controle de acesso
Entrada na máquina virtual
Escape de máquina virtual
Escrita ou execução, mutuamente exclusivas
Espaço de nomes
Espaço de nomes de montagem
Espaço de nomes de PID
Espaço de nomes de rede
Espaço de nomes de usuários
Estouro de buffer
Execução direta limitada
F
Falta de página
G
Grupo de controle
gVisor
H
Hash de senha
Hiperchamada
Hipervisor
I
Identificador de usuário efetivo
Inicialização medida
Inicialização segura
Instrução privilegiada
HLT no x86 gera uma falha de proteção.Instrução sensível
Interceptação e emulação
Interrupção do temporizador
Isolamento das tabelas de páginas do núcleo
K
Kata Containers
L
Lista de controle de acesso
Lista de controle de acesso discricionário
M
Mapeamento de UIDs
Máquina virtual
Máscara de ACL POSIX
Máscara de criação de arquivos
Matriz de acesso
memory.high
memory.high enquanto a pressão de recuperação de memória aumenta, diferentemente de um limite fixo simples de alocação.memory.max
memory.max pode forçar o encerramento de uma tarefa elegível no grupo.Micromáquina virtual
Migração em execução
Modelo biométrico
Modelo de Bell–LaPadula
Modo de permissões em octal
Modo núcleo
Modo usuário
Módulos de autenticação conectáveis
Monitor de referência
N
Nível de exceção
no_new_privs
no_new_privs definido, um processo de contêiner não pode ganhar autoridade simplesmente iniciando um executável setuid.P
Paginação aninhada
Par de interfaces veth
Paravirtualização
Perfil do AppArmor
pids.max
pids.max mesmo quando seu número de processos distintos parece pequeno.Programação orientada a retornos
Proteção contra acesso a páginas de usuário no modo supervisor
Proteção contra execução em páginas de usuário no modo supervisor
R
Recuperação de memória por balão
Registro de auditoria
Retrato do estado
Revogação de capacidades
S
Saída da máquina virtual
HLT do convidado permite que o hipervisor pare de escalonar a vCPU ociosa e execute outra carga de trabalho.Sal criptográfico
Seccomp
Senha de uso único baseada em tempo
Setuid
Sistema operacional convidado
Socket do ambiente de execução de contêineres
Supercomprometimento de memória
T
Tabela de páginas sombra
Taxa de falsa aceitação
Taxa de falsa rejeição
Token de acesso
Tradução binária
Travessia de diretório
U
Unidade de gerenciamento de memória
Unidade de gerenciamento de memória de entrada e saída
V
Virtio
Sobre esta aula
Crie seus próprios Materiais de Estudo
Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.