Quem assistiu ao filme "
Snowden", de
Oliver Stone, certamente lembra-se durante o período de recrutamento de Snowden quando ele e o resto da turma receberam um desafio onde ele terminou primeiro do que todos os demais, muito provavelmente por que ele colocou o gpg para gerar entropia em primeiro lugar adiantando o resto dos passos, visto que o instrutor da NSA não estabeleceu a ordem dos passos para ele construir a rede de comunicação segura e volátil.
Ele deve ter acelerado e muito o processo com um "
md5sum /dev/urandom" em um outro shell, mas não entraremos nesse particular. No futuro pretendo escrever algo mais detalhado sobre o assunto envolvendo o GPG e OpenVPN.
Vamos explorar uma característica dos containers que é a sua efemeridade e dado ao tamanho relativamente pequeno das imagens vamos fazer o mesmo com as imagens empregando uma elegante gambiarra. Há quem não goste de gambiarras, mas que elas resolvem problemas sem aparente solução, e resolvem muito bem.
O Docker Build
Há várias formas de se criar uma imagem Docker customizada, você pode por exemplo iniciar uma imagem oficial, instalar e configurar pacotes para atender suas necessidades. Você também pode criar uma imagem a partir de uma VM. Entretanto esses métodos são interessantes para ecossistemas pequenos.
Se você tiver uma infraestrutura de médio ou grande porte pode ter milhares de VMs e dezenas ou centenas de milhares de containers e imagens. Agora imaginem como seria para escalar uma infra desse tamanho diretamente a partir das imagens. Por esse motivo o pessoal da Docker implementou o recurso "build".
O
docker build é uma espécie de "teletransporte quântico". Você não envia a imagem e sim as informações para elas sejam criadas in loco em seu destino. Isso acelera tremendamente o processos de deploy e poupa preciosos créditos em tráfego junto aos provedores de computação em nuvem.
Compreendendo o Dockerfile
Em meu
Github está disponível o
Dockerfile. Para utilizá-lo crie um diretório em sua máquina
Linux e baixe-o renomeando-o de "Dockerfile.alpine_secretchattor" para "Dockerfile" (com maiúscula e sem qualquer extensão). O mesmo vale para o docker-entrypoint.sh:
Notem que usei apenas uma única seção RUN e em uma única passada rodei todos os procedimentos. A motivo disso é para reduzir a quantidade de camadas da imagem, sendo inclusive uma boa prática recomendada pelos desenvolvedores do Docker.
Compreendendo o docker-entrypoint.sh
Arquivo
docker-entrypoint.sh:
#!/bin/bash
/usr/sbin/sshd
/usr/bin/tor &
/usr/sbin/ngircd -p -n &
while true; do timeout 0.1 cat /dev/zero; sleep 90; done >/dev/null
Um container Docker NÃO é uma VM embora possa funcionar como tal que é o caso específico deste artigo. Um container é na realidade uma aplicação que roda uma determinada aplicação dentro dela completamente isolada da máquina onde estiver rodando embora use recursos de hardware e software dela, processador, memória, kernel, cgroups etc.
O funcionamento do ENTRYPOINT é parecido com um loop FOR então para isso precisamos recorrer a uma elegante gambiarinha que é a de adicionar um loop WHILE infinito ao seu final, que faz o seguinte: Ele faz um cat em /dev/zero durante 100 ms que é definido pelo timout do shell, então aguarda 90 segundos para repetir o processo indefinidamente. Por que usar tempos tão pequenos de leitura e tão grandes de espera? A resposta é para poupar processamento do container. Notem que empreguei o & para tirar uma aplicação de foreground e liberar o shell para a seguinte.
Tornando a IMAGEM volátil
O objetivo dessa implementação é ser de rápida implementação e rápida destruição sem deixar rastros, impossibilitando a recuperação de qualquer mensagem. Para fazermos isso iremos recorrer a outra gambiarra elegante que será a de criar a imagem em um RAMDISK no Linux usando o tmpfs. Vamos ao passo a passo.
1° Pare o daemon dockerd em sua máquina via systemd caso ele esteja rodando:
# systemctl stop docker.service
2° Desabilite o SWAP de sua máquia caso o tenha.
Esse passo é imprescindível para garantir a segurança impedindo qualquer possibilidade de recuperação, embora não seja impeditivo para o funcionamento.
# swapoff -a
3° Montar os diretórios que contém as imagens em RAMDRIVE.
Todo o conteúdo das imagens Docker está situado nos diretórios:
/var/lib/docker/image
/var/lib/docker/overlay2
Montá-los em RAM com o tmpfs não causará qualquer prejuízo das imagens que você tenha em sua máquina, desde que o daemon dockerd não esteja rodando. Apenas atente para o PATH correto pois pode variar conforme a distro ou a versão do Docker. No meu caso a distro é um CentOS 7 e o Docker é a versão 19.03.5, build 633a0ea, portanto atente a esse detalhe.
# mount -t tmpfs tmpfs /var/lib/docker/image
# mount -t tmpfs tmpfs /var/lib/docker/overlay2
4° Levantar o serviço dockerd via systemd:
# systemctl status docker.service
Pronto! Agora qualquer imagem que você criar deixará de existir se a máquina for desligada pois estará rodando em memória RAM. Nem é preciso falar que você terá que ter uma quantidade razoável de RAM. Em meus ensaios rodei em uma máquina com 16GB com bons resultados.
CUIDADO!
Muito cuidado ao usar a solução em laptops que estejam com o modo de hibernação habilitado. Desabilitem esses recursos (hibernação, suspend to RAM etc).