
Criptografia de disco completo para Kali no Raspberry usando LUKS
Este guia é dedicado a executar o Kali no Raspberry (ou outra arquitetura semelhante, por exemplo, ODROID-C2 usando criptografia de disco completo com LUKS. Baseado no documento um pouco desatualizado aqui.
Implantar o Kali no Raspberry Pi (ou outro hardware semelhante, pequeno e de baixo consumo) em um ambiente de LAN como uma "hackbox descartável" é obviamente útil. No entanto, manter os dados coletados em segredo é um requisito essencial. É aqui que entra a criptografia de disco completo como um conceito de segurança obrigatório.
Primeiro, devemos configurar uma imagem oficial atual do Kali para o Raspberry Pi (sem criptografia) em um cartão SD.
A opção recomendada (agora) é usar uma compilação personalizada para Raspberry Pi 3 com o patch nexmon (para usar os recursos de monitoramento e injeção de pacotes da WiFi integrada). Há um script de compilação automatizado no repositório oficial kali-arm-build-scripts que prepara a imagem do zero (em uma distribuição Kali). E aqui está uma versão corrigida que também funciona em outras distribuições além do Kali (testada no Gentoo). Atualmente (2017-08), o script de compilação funcional para ODROID-C2 também está neste repositório fork.
Obtenha as ferramentas de compilação e compile a imagem do zero como root (pode levar algumas horas):
$ git clone https://github.com/tothi/kali-arm-build-scripts
$ cd kali-arm-build-scripts
$ sudo ./rpi3-nexmon.sh 2.0
A imagem resultante é rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz.
Copie-a para o cartão SD (usando pv para exibir o progresso):
# pixz -d rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz - | pv -treb | dd of=/dev/mmcblk0 bs=512k
(A imagem deve funcionar; agora ela pode ser testada.)
Montamos a imagem do cartão SD e preparamos um initramfs
capaz de usar recursos do LUKS em um ambiente chroot. Para que
isso funcione, um binário qemu-arm-static para x86 (host) é necessário
no sistema de arquivos do cartão SD. O script de compilação rpi3-nexmon.sh
corrigido acima instala e o deixa na imagem, então tudo
deve funcionar bem. (Caso contrário, copiar o binário
qemu estático apropriado para a imagem é necessário.)
Inicializando o ambiente chroot (no sistema host como root):
# mkdir -p /mnt/chroot/boot
# mount /dev/mmcblk0p2 /mnt/chroot/
# mount /dev/mmcblk0p1 /mnt/chroot/boot/
# mount -t proc none /mnt/chroot/proc
# mount -t sysfs none /mnt/chroot/sys
# mount -o bind /dev /mnt/chroot/dev
# mount -o bind /dev/pts /mnt/chroot/dev/pts
# LANG=C chroot /mnt/chroot/
Primeiro, alteramos a senha padrão do root:
passwd
Instale os pacotes necessários (no ambiente chroot):
# apt-get update
# apt-get install busybox cryptsetup dropbear
Observe que precisamos inserir a chave de descriptografia a
cada boot. Preferimos fazer isso remotamente via SSH,
por isso o dropbear é necessário (no initramfs).
Agora edite /boot/cmdline.txt, altere o dispositivo raiz para
o dispositivo criptografado mapeado (/dev/mapper/crypt_sdcard)
e adicione o parâmetro cryptdevice apropriado.
Portanto, aqui está o /boot/cmdline.txt original:
dwc_otg.fiq_fix_enable=2 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rootflags=noload net.ifnames=0
E aqui está o atualizado (diferenças nos parâmetros root e cryptdevice):
dwc_otg.fiq_fix_enable=2 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mapper/crypt_sdcard cryptdevice=/dev/mmcblk0p2:crypt_sdcard rootfstype=ext4 rootwait rootflags=noload net.ifnames=0
Agora crie /boot/config.txt com o seguinte conteúdo:
initramfs initramfs.gz followkernel
Observe que em outro hardware etapas semelhantes são necessárias
(o arquivo que contém os parâmetros de boot no ODROID-C2 é
/boot/boot.ini).
Vamos configurar a autenticação por chave SSH do Dropbear. Crie um par de chaves (sem senha) na máquina host (fora do chroot!) e leia a chave pública:
$ ssh-keygen -N "" -f kali-dropbear
$ cat ./kali-dropbear.pub
Adicione a chave pública em /etc/dropbear-initramfs/authorized_keys.
Restrinja o acesso SSH do Dropbear apenas para configuração do cryptroot
prefixando a chave com isto:
command="/scripts/local-top/cryptroot && kill -9 `ps | grep -m 1 'cryptroot' | cut -d ' ' -f 3`"
Corrija as permissões:
chmod 600 /etc/dropbear-initramfs/authorized_keys
Edite o /etc/fstab. Original:
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
Dispositivo / atualizado, alterado para /dev/mapper/crypt_sdcard:
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mapper/crypt_sdcard / ext4 defaults,noatime 0 1
Adicione esta linha ao /etc/crypttab:
crypt_sdcard /dev/mmcblk0p2 none luks
Modifique o /etc/cryptsetup-initramfs/conf-hook definindo
CRYPTSETUP=y
para incluir os arquivos do cryptsetup na imagem initramfs.
Por fim, crie o initramfs para a versão atual do kernel e saia do chroot (não se preocupe com erros/avisos durante o mkinitramfs):
# ls -l /lib/modules/ |awk -F" " '{print $9}'
4.4.50-v7+
# mkinitramfs -o /boot/initramfs.gz 4.4.50-v7+
Observe que devemos ter cuidado ao gerar a imagem
(especialmente em outro hardware), pois
uname -r retorna a versão do kernel do host, não a do chroot.
Então, por exemplo, no ODROID-C2 o /boot/mkuinitrd não funciona
prontamente; devemos executar os comandos do script manualmente
(ajustando a versão do kernel PARA OUTRO HARDWARE!):
# rm /boot/initrd.img-3.14.79
# update-initramfs -c -k 3.14.79
# mkimage -A arm64 -O linux -T ramdisk -C none -a 0 -e 0 -n "uInitrd" -d /boot/initrd.img-3.14.79 /boot/uInitrd
#
Saia do ambiente chroot
exit
Desmonte os sistemas de arquivos e faça backup do rootfs antes de criar o volume criptografado (e apagar tudo) no cartão SD:
# umount /mnt/chroot/boot
# umount /mnt/chroot/sys
# umount /mnt/chroot/proc
# mkdir -p /mnt/backup
# rsync -avh /mnt/chroot/* /mnt/backup/
Desmonte o chroot completo:
# umount /mnt/chroot/dev/pts
# umount /mnt/chroot/dev
# umount /mnt/chroot
Exclua a partição raiz não criptografada (nº 2) e crie uma vazia (preenchendo o cartão SD):
# echo -e "d\n2\nw" | fdisk /dev/mmcblk0
# echo -e "n\np\n2\n\n\nw" | fdisk /dev/mmcblk0
Agora (provavelmente) é necessário remover e inserir o cartão SD para que as novas partições sejam registradas.
Crie um volume criptografado com uma senha forte (este passo destrói o rootfs original!):
# cryptsetup -v -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/mmcblk0p2
# cryptsetup -v luksOpen /dev/mmcblk0p2 crypt_sdcard
# mkfs.ext4 /dev/mapper/crypt_sdcard
Restaure o rootfs para o volume criptografado e feche o disco:
# mkdir -p /mnt/encrypted
# mount /dev/mapper/crypt_sdcard /mnt/encrypted/
# rsync -avh /mnt/backup/* /mnt/encrypted/
# umount /mnt/encrypted/
# cryptsetup luksClose /dev/mapper/crypt_sdcard
# sync
Ejete o cartão SD e teste-o no Raspberry.
O primeiro processo de boot falhará e cairá no busybox. Digite os seguintes comandos:
# cryptsetup luksOpen /dev/mmcblk0p2 crypt_sdcard
## provide password
# exit
Seu dispositivo deve inicializar agora. Faça login com a senha que você escolheu anteriormente e execute:
mkinitramfs -o /boot/initramfs.gz
reboot
Agora você será solicitado a informar a senha com um prompt mais amigável; além disso, você deve conseguir acessar o busybox via ssh e inserir a senha
(você pode usar um arquivo known_hosts personalizado, se quiser):
$ ssh -o "UserKnownHostsFile=~/.ssh/known_hosts.initramfs" -i ~/.ssh/kali-dropbear [email protected]
Quando estiver funcionando, não se esqueça de limpar os arquivos de backup no host:
# rm -fr /mnt/backup
# rm -fr /mnt/chroot
Para obter saída de depuração completa durante o boot, você pode adicionar debug=1 no cmdline.txt