Proteger contêineres do Windows

Aplica-se a: Windows Server 2022, Windows Server 2019 e Windows Server 2016

Os contêineres prestam seu tamanho de imagem reduzido ao fato de que eles podem confiar no host para fornecer acesso limitado a vários recursos. Se o contêiner souber que o host será capaz de fornecer a funcionalidade necessária para executar um conjunto específico de ações, o contêiner não precisará incluir o software relevante em sua imagem base. No entanto, a extensão do compartilhamento de recursos que ocorre pode ter um impacto significativo no desempenho e na segurança do contêiner. Se muitos recursos forem compartilhados, o aplicativo também poderá ser executado apenas como um processo no host. Se os recursos forem compartilhados muito pouco, o contêiner se tornará indistinguível de uma VM. Ambas as configurações são aplicáveis a muitos cenários, mas a maioria das pessoas que usam contêineres geralmente optam por algo intermediário.

A segurança de um contêiner do Windows é derivada do grau de compartilhamento que ocorre com o host do contêiner. O limite de segurança de um contêiner é constituído pelos mecanismos de isolamento que separam o contêiner do host. O mais importante é que esses mecanismos de isolamento definem quais processos no contêiner podem interagir com o host. Se o design de um contêiner permite que um processo elevado (administrador) interaja com o host, a Microsoft não considera como robusto o limite de segurança desse contêiner.

Contêineres do Windows Server versus contêineres do Linux

Contêineres de processo isolado do Windows Server e contêineres do Linux compartilham graus semelhantes de isolamento. Para ambos os tipos de contêiner, o desenvolvedor deve assumir que qualquer ataque que possa ser executado por meio de um processo elevado no host também pode ser executado por meio de um processo elevado no contêiner. Ambos operam por meio dos recursos primitivos oferecidos por seus respectivos kernels de host. As imagens de contêiner são criadas contendo binários do modo de usuário que utilizam as APIs fornecidas pelo kernel do host. O kernel do host fornece as mesmas funcionalidades de isolamento e gerenciamento de recursos para cada contêiner em execução no espaço do usuário. Se o kernel estiver comprometido, todos os contêineres que compartilham esse kernel também estarão comprometidos.

O design fundamental dos contêineres do Linux e do Windows Server troca a segurança pela flexibilidade. Os contêineres do Windows Server e do Linux são criados com base nos componentes primitivos fornecidos pelo SO. Isso fornece flexibilidade para compartilhar recursos e namespaces entre os contêineres, mas agrega uma complexidade adicional que abre as portas para explorações. De modo geral, não consideramos o kernel como um limite de segurança suficiente para cargas de trabalho multilocatário hostis.

Isolamento do kernel com contêineres isolados por hipervisor

Contêineres isolados por hipervisor fornecem um grau mais alto de isolamento do que os contêineres isolados por processo do Windows Server ou do Linux e são considerados limites de segurança robustos. Os contêineres isolados por hipervisor consistem em um contêiner do Windows Server encapsulado em uma VM ultraleve e depois executado junto com o SO host por meio do hipervisor da Microsoft. O hipervisor fornece isolamento no nível de hardware, que inclui um limite de segurança altamente robusto entre o host e outros contêineres. Mesmo que uma exploração fosse capaz de escapar do contêiner do Windows Server, ela seria contida na VM isolada por hipervisor.

Nem os contêineres do Windows Server, nem os contêineres do Linux fornecem o que a Microsoft considera um limite de segurança robusto; portanto, não devem ser usados em cenários multilocatário hostis. O contêiner deve ser restrito a uma VM dedicada para impedir que um processo de contêiner vampiro interaja com o host ou com outros locatários. O isolamento por hipervisor permite esse grau de separação, oferecendo também vários ganhos de desempenho em relação às VMs tradicionais. Portanto, é altamente recomendável que, em cenários multilocatário hostis, você escolha os contêineres isolados por hipervisor.

Critérios dos serviços de segurança do contêiner

A Microsoft se compromete a aplicar patches em todas as explorações e escapes que violem o limite de isolamento estabelecido de qualquer tipo de contêiner do Windows. No entanto, somente as explorações que violam um limite de segurança são atendidas por meio do processo MSRC (Microsoft Security Response Center). Somente os contêineres isolados por hipervisor fornecem um limite de segurança, os contêineres isolados por processo não. A única maneira de gerar um bug para o escape de um host de contêiner isolado por processo é se um processo que não seja de administrador conseguir obter acesso ao host. Se uma exploração usar um processo de administrador para escapar do contêiner, a Microsoft vai considerar que ele é um bug não relacionado à segurança e aplicará patch nele no âmbito do processo normal de manutenção. Se uma exploração usar um processo que não seja de administrador para executar uma ação que viole um limite de segurança, a Microsoft investigará isso de acordo com os critérios de manutenção de segurança estabelecidos.

O que torna hostil uma carga de trabalho multilocatário?

Ambientes multilocatários existem quando várias cargas de trabalho estão operando em recursos e infraestrutura compartilhados. Se uma ou mais cargas de trabalho em execução em uma infraestrutura não puderem ser confiáveis, o ambiente multilocatário será considerado hostil. Os contêineres do Windows Server e do Linux compartilham o kernel do host, de modo que qualquer exploração executada em apenas um contêiner pode afetar todas as outras cargas de trabalho em execução na infraestrutura compartilhada.

Você pode tomar medidas para reduzir a chance de que uma exploração ocorra, por exemplo, usando políticas de segurança de Pod, AppArmor e RBAC (controle de acesso baseado em função), mas elas não fornecem proteção garantida contra um invasor. Recomendamos que você siga nossas melhores práticas para isolamento de cluster para qualquer cenário multilocatário.

Quando usar as contas de usuário ContainerAdmin e ContainerUser

Os contêineres do Windows Server oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator, cada uma com sua própria finalidade específica. A conta ContainerAdministrator permite que você use o contêiner para fins administrativos: instalação de serviços e software (como habilitar o IIS em um contêiner), fazer alterações de configuração e criar contas. Essas tarefas são importantes para vários cenários de IT que podem estar em execução em ambientes de implantação locais personalizados.

A conta ContainerUser existe para todos os outros cenários em que não são necessários privilégios de administrador no Windows. Por exemplo, no Kubernetes, se o usuário for o ContainerAdministrator e os hostvolumes puderem ser montados no pod, o usuário poderá montar a pasta .ssh e adicionar uma chave pública. Como ContainerUser, este exemplo não seria possível. É uma conta de usuário restrita projetada exclusivamente para aplicativos que não precisam interagir com o host. Ela é altamente recomendada ao implantar um contêiner do Windows Server em qualquer ambiente multilocatário no qual seu aplicativo seja executado por meio da conta ContainerUser. Em um ambiente multilocatário, é sempre melhor seguir o princípio de privilégios mínimos, pois se um invasor comprometer sua carga de trabalho, o recurso compartilhado e as cargas de trabalho vizinhas também terão uma menor chance de serem afetados. A execução de contêineres com a conta ContainerUser reduz consideravelmente a chance do ambiente ser comprometido como um todo. No entanto, isso ainda não fornece um limite de segurança robusto, portanto, quando a segurança for uma preocupação, você deverá usar contêineres isolados por hipervisor.

Para alterar a conta de usuário, você pode usar a instrução USER no dockerfile:

USER ContainerUser

Como alternativa, é possível criar um usuário:

RUN net user username ‘<password>’ /ADD
USER username

Serviços do Windows

Os serviços do Microsoft Windows, anteriormente conhecidos como serviços do NT, permitem que você crie aplicativos executáveis de longa execução que são executados em suas próprias sessões do Windows. Esses serviços podem ser iniciados automaticamente quando o sistema operacional é iniciado, podem ser pausados e reiniciados e não mostram nenhuma interface do usuário. Você também pode executar serviços no contexto de segurança de uma conta de usuário específica diferente do usuário conectado ou da conta padrão do computador.

Ao colocar em contêiner e proteger uma carga de trabalho que é executada como um serviço Windows, há algumas considerações adicionais a serem consideradas. Primeiro, o ENTRYPOINT do contêiner não será a carga de trabalho, pois o serviço é executado como um processo em segundo plano, normalmente o ENTRYPOINT será uma ferramenta como monitor de serviço) ou monitor de log). Em segundo lugar, a conta de segurança em que a carga de trabalho opera será configurada pelo serviço e não pela diretiva USER no dockerfile. Você pode verificar em qual conta o serviço será executado executando Get-WmiObject win32_service -filter "name='<servicename>'" | Format-List StartName.

Por exemplo, ao hospedar um aplicativo Web do IIS usando a imagem ASP.NET (Registro de Artefato da Microsoft) o ENTRYPOINT do contêiner é "C:\\ServiceMonitor.exe", "w3svc". Essa ferramenta pode ser usada para configurar o serviço do IIS e, em seguida, monitora o serviço para garantir que ele permaneça em execução e saia, interrompendo assim o contêiner, se o serviço parar por algum motivo. Por padrão, o serviço IIS e, portanto, o aplicativo Web são executados em uma conta de baixo privilégio dentro do contêiner, mas a ferramenta de monitor de serviço requer privilégios administrativos para configurar e monitorar o serviço.