Mini-How-To: Criptografando seus dados de forma transparente

Iniciado por AlexBR, 14 de Junho de 2007, 22:50

tópico anterior - próximo tópico

AlexBR

Mini-How-To: Criptografando seus dados de forma transparente: O sistema super-seguro

Introdução

Sempre tive receio em deixar dados pessoais (e comprometedores) no meu computador. O medo é que os dados sejam interceptados em caso de roubo. Não tenho notebook, mas acredito que os usuários desse tipo de sistema estão ainda mais vulneráveis a esse classe de problema.

Para a segurança de dados, sempre optei por criptografar os arquivos mais importantes usando o algoritimo PGP. Evidentemente, isto é muito cansativo, pois cada arquivo deve ser criptografado e "descriptografado" manualmente. (Aqui, o risco maior é você mesmo esquecer a chave de um de seus arquivos e nunca mais poder acessar os seus dados.) Após algumas pesquisas, acho que a melhor forma de proteger os seus dados é criptografando uma partição inteira. Assim, tudo que for armazenado na partição será criptografado automaticamente.

Neste Mini-How-To, eu apresento os passos necessários para criptografar uma partição inteira. Isto é feito tendo em mente dois objetivos: a) montar e desmontar a partição da forma mais transparente possível e b) proteger os dados a qualquer custo. Como será visto, a proteção dos dados não envolve apenas cuidados com a partição em si, mas também com outras partes do sistema como, por exemplo, a memória virtual e o diretório /tmp.

Instalação do Software

O software necessário é bastante simples. Precisamos do DM-Crypt (http://en.wikipedia.org/wiki/DM-Crypt), que criptografa os dados antes de escrevê-lo no disco rígido, e do pam_mount, um módulo do PAM (http://en.wikipedia.org/wiki/Pluggable_Authentication_Modules) que permite montar partições diferentes para cada usuário e (mais importante) associa-las ao sistema dm-crypt.

apt-get install libpam-mount cryptsetup

Habilitando a Montagem Automática

Você terá que modificar a configuração do PAM para poder usar o pam_mount. Neste mini-how-to, considerarei apenas a configuração para o console (modo texto) e o GDM (acredito que a configuração seja a mesma para o KDM).

Para o console e o GDM, acrescente as seguintes linhas ao final dos arquivos /etc/pam.d/login e /etc/pam.d/gdm.

auth       optional     /lib/security/pam_mount.so use_first_pass
session    optional     /lib/security/pam_mount.so


Pronto! Essas modificações irão permitir a você logar no seu sistema digitando apenas uma senha. Isto ocorre devido a opção use_first_pass que diz ao pam_mount para utilizar a mesma senha utilizada no login do sistema.

Preparação da Partição

Bom... este mini-how-to trata de proteção paranóica e não de esconder dados da sua irmão mais nova. Então, antes de criptografar a partição é importante preencher a partição com dados aleatórios. Isto dificultará ao máximo a descoberta da chave de proteção utilizada na criptografia.

Existem várias formas de preencher o disco com dados aleatórios. Eu selecionei apenas três.

>> O programa shred

O shred é um programa dos sistemas unix que elimina dados do disco rígido sobrescrevendo-os quatro vezes. É um método rápido, mas os algoritmo utilizado não usa dados aleatórios o suficiente.

>> O /dev/urandom

O /dev/urandom parece ter a melhor relação custo/benefício. Os dados são (quase) 100% aleatórios (muito mais do que os fornecidos pelo shred) e a operação não é tão demorada.

>> O /dev/random

Este é o campeão de segurança. Com o /dev/random, os dados aleatórios são retirados diretamente da "piscina de entropia" (do inglês: entropy pool) do kernel. Essa piscina é a fonte de números aleatórios do kernel. Não são números pseudo-aleatórios como nos casos anteriores. Contudo, o /dev/random tem um grande problema! A única forma de obter dados (realmente) aleatórios é de eventos externos ao kernel. Assim, a piscina de entropia é preenchida apenas com dados oriundos de dispositivos de I/O (rede, HD, mouse, etc). Dessa forma, tal piscina fica "seca" rapidamente e deve-se esperar algum tempo até que ela esteja cheia novamente. Para entender o que estou dizendo, execute o seguinte comando.

cat /dev/random

Você verá que, em poucos segundos, a operação parece parar. Contudo, basta você mexer um pouco o mouse para que mais dados aleatórios caíam dentro da piscina de entropia e o processo possa continuar (faça ctrl+c para interrompe-lo). Dessa forma, você deverá levar uns 300 anos para encher toda uma partição com dados aleatórios vindos do /dev/random.

Então, para preencher a partição com dados aleatórios, utilize o comando a seguir.

dd if=/dev/urandom of=/dev/hdd1 bs=1M

Vá tomar um café enquanto fica olhando o LED do HD brilhar, pois este processo leva vários minutos.

Criando o Mapeamento para o dm-crypt

Agora que o HD possui dados aleatórios, podemos habilitar o processo de criptografia da partição. Contudo, antes de iniciar, você deve criar uma chave a ser utilizada no processo. A escolha da chave é importante! Uma chave fraca tornará mais fácil a sua descoberta na "força-bruta". Não confie em você mesmo para criar tal chave. Ao invés disso, utilize dados aleatórios como segue.

export KEY=`tr -cd [:graph:] < /dev/urandom | head -c 79`

Isto cria uma chave de 79 caracteres (comando head -c 79) através do /dev/urandom e a armazena na variável KEY. Tomei cuidado para utilizar na senha apenas caracteres imprimíveis (comando tr -cd [:graph:]). Isto corresponde a utilizar uma chave de criptografia de 512 bits. (Nada mal, heim?)

Com a chave definida, podemos criar um mapeamento para a partição a ser criptografada.

echo $KEY | cryptsetup create secret /dev/hdd1

No comando anterior, foi criado um mapeamento /dev/mapper/secret para a partição /dev/hdd1. Agora, o novo dispositivo deve ser formatado.

mkfs.ext3 /dev/mapper/secret

Formatei com o sistema ext3. Utilize o seu sistema favorito. Em seguida, remova o mapeamento temporariamente.

cryptsetup remove secret[/b]

Facilitando a login

Seja sincero... Você quer digitar uma chave aleatória de 79 caracteres a cada login? Se não quer, vamos guarda-la em um arquivo texto criptografado (claro que é criptografado).

echo $KEY | openssl aes-256-ecb > $HOME/.secret.key

Obs.: Quando o sistema pedir a senha, é importante digitar a mesma senha utilizada no seu login.

Sua chave será guardada em um arquivo texto (invisível) .secret.key, no seu diretório home. (Você pode guardar tal arquivo onde quiser, mas deve ser um local que você tenha permissões de leitura e escrita.) O arquivo .secret.key foi cifrado com o algoritmo aes-256-ecb que utiliza uma chave de 256 bits. Você pode utilizar um outro algoritmo qualquer.

Para você conseguir alterar sua senha mais facilmente, devemos mudar as permissões do arquivo .secret.key e fazer uma cópia .secret.key.old.

touch $HOME/.secret.key.old
chown alexbr $HOME/.secret.key $HOME/.secret.key.old
chmod 600 $HOME/.secret.key $HOME/.secret.key.old


Nos comando anteriores, definimos as permissões para o usuário alexbr. Evidentemente, no seu caso, deves utilizar o seu nome de usuário.

No futuro, para alterar sua senha de login, utilize o seguinte comando.

passwd && passwdehd

Isto altera a sua senha de login e a senha utilizada para criptografar o arquivo .secret.key.old. É importante que as duas senhas sejam a mesma.

Para finalizar, altere o arquivo /etc/security/pam_mount.conf. Inclua a linha a seguir.

volume alexbr crypt - /dev/hdd1 /home/secret cipher=aes aes-256-ecb /home/alexbr/.secret.key

Aqui, os parâmetros a serem customizados por você são o nome de usuário (alexbr), a partição a ser criptografada (/dev/hdd1) e o seu ponto de montagem (/home/secret).

Não podemos esquecer também de criar o ponto de montagem da partição e dar permissões ao usuário proprietário.

mkdir /home/secret && chown alexbr:alexbr /home/secret

Aqui, /home/secret é o ponto de montagem e deve ser substituído de acordo com suas necessidades. Também, alexbr é um usuário válido no seu sistema.

Pronto! Sua partição criptografada está pronta para ser utilizada. Encerre sua sessão e faça login novamente. Se tudo correr bem, você a partição deve aparecer montada após o login. Agora, basta transferir seus dados mais importantes para esta partição. Não esqueça de transferir para lá os diretórios de armazenamento de suas mensagens instantâneas (.amsn ou .gaim), seus emails (.mozilla-thunderbird ou .evolution). Para isto, faça algo como o exemplo a seguir.

mv $HOME/.mozilla-thunderbird /home/secret
ln -s /home/secret/.mozilla-thunderbird $HOME/.mozilla-thunderbird


Aumentando a Segurança

O sistema só será super-seguro se os passos da próxima mensagem também forem seguidos.

AlexBR

Cifrando a Partição SWAP

Durante a utilização do sistema, seus dados são levados para a memória RAM e, eventualmente, irão também para a memória virtual. Então, do que adianta criptografar uma partição se o sistema faz o favor de levar seus dados a uma partição swap sem criptografia?

Para entender o que estou dizendo, execute o comando a seguir e veja quantas vezes a sua senha aparece na memória virtual. (Tecle crtl+c para interromper o processo.)

sudo strings < /dev/hda1 | grep suasenha

Evidentemente, substitua /dev/hda1 pela sua partição de memória virtual e suasenha pela sua senha. :-)

Se efetuar esse teste, lembre-se de alterar a sua senha. Caso contrário, ela ficará gravada também no .bash_history do usuário root.

Bom... Criptografar a partição swap é bastante simples. Para isto, existe um script retirado do fórum Gentoo (http://forums.gentoo.org/viewtopic.php?p=1959581#1959581) que faz quase todo o trabalho. (Eu apenas adeqüei o script para poder ser utilizado no Ubuntu.)

Novamente, usaremos o algoritmo aes na cifragem da partição. Então, carregue o módulo correspondente. (Apenas se ainda não o tiver carregado.)

modprobe aes && echo "aes" >> /etc/modules

Primeiro, guarde o arquivo de configuração do script em /etc/cryptoswap.conf

# /etc/cryptoswap.conf
# cryptoswap configuration file

# The configuration is simplistic: one line per swap device.
# The cipher and keysize (in bytes for coherence with /proc/crypto)
# can be set globally.
CIPHER=aes
KEYSIZE=16
# But it's also possible to override this default value on a per device
# basis. Here are some commented sample configuration lines:
#swap=/dev/hda1   pri=3   cipher=blowfish   keysize=32
#swap=/dev/hdb2   pri=3   cipher=twofish
#swap=/dev/hda6   pri=1
swap=/dev/hda1   pri=1

# NOTES
# The used cipher must be available through the kernel Crypto API. To
# get a list of available algorithms: cat /proc/crypto
# Since this parameter is directly passed to dmsetup, it can also contain
# IV generation modes for CBC. Examples:
# aes, blowfish-cbc, twofish-cbc-essiv:sha256
# Please refer to http://www.saout.de/misc/dm-crypt/ for more information.
#
# Set the same priority for multiple devices to enable RAID0-like
# striping. (Should be faster.) See man 2 swapon for more details.


No arquivo anterior, troque /dev/hda1 pela partição utilizada como memória virtual no seu sistema.

Uma vez configurado, coloque o script a seguir em /etc/init.d/cryptoswap.

# cryptoswap 0.04
#
# This initscript uses the Device-Mapper and Crypto API of Linux >=2.6.4
# to create encrypted swap devices. Configuration is done in
# /etc/cryptoswap.conf

# USING CRYPTOSWAP
# 1. Make sure your kernel is compiled with device-mapper and
#    some cryptographic algorithms. Easiest is to compile them into
#    the kernel. You also need sys-libs/device-mapper.
# 2. Turn off swapping for all your swap partitions
#    e.g. swapoff /dev/hdb2
# 3. Remove all swap partitions from your /etc/fstab
# 4. Overwrite all swap partitions with random data from /dev/urandom
#    dd if=/dev/urandom of=/dev/hdb2 bs=1M
# 5. Configure cryptoswap (/etc/conf.d/cryptoswap)
# 6. update-rc.d cryptoswap defaults
# 7. /etc/init.d/cryptoswap start


CIPHER=${CIPHER:-aes}
KEYSIZE=${KEYSIZE:-32}
DMSETUP=/sbin/dmsetup
CONF=/etc/cryptoswap.conf

depend() {
   after urandom modules
}

# $1 = block device (e.g. /dev/hda2)
isswap () {
   PART=`fdisk -l | grep "^$1 "`
   [[ $PART == *Linux\ swap* ]]
}

cipheravailable() {
   modprobe $1 &> /dev/null
   # remove "mode" (e.g. plain, cbc, cbc-essiv-sha256)
   grep "name *: *${1%%-*}" /proc/crypto >& /dev/null
}

start() {
   if ! [ -r "$CONF" ] ; then
      echo "ERROR: Configuration file $CONF does not exist"
      echo "       or cannot be read."
      exit 1
   fi
   if ! [ -x $DMSETUP ] ; then
      echo "ERROR: The $DMSETUP executable cannot be found."
      #echo "       Please emerge sys-libs/device-mapper."
      exit 2
   fi
        echo "Setting up encrypted swap"
   NBR=0
   grep '^swap=' $CONF | while read SWAPLINE
   do
      swap="" pri="" cipher="" keysize=""
      eval $SWAPLINE
      echo "  Setting up $swap as /dev/mapper/cryptoswap$NBR"
      cipher=${cipher:-$CIPHER}
      keysize=${keysize:-$KEYSIZE}
      if ! cipheravailable "$cipher"; then
         echo "ERROR: The specified cipher $cipher is not available."
         echo "Done."
         continue
      fi
      if ! isswap "$swap"; then
         echo "WARNING: $swap is not a swap partition. Skipping."
         echo "Done."
         continue
      fi
      if [[ ! -z "$pri" && $pri -ge 0 ]]
         then OPTS="-p $pri";
         else OPTS="";
      fi
      # make sure swap is turned off for $swap
      swapoff $swap &> /dev/null
      BLOCKS=`blockdev --getsize $swap`
      HEXDIGITS=$(($keysize * 2))
      KEY=`tr -cd 0-9a-f < /dev/urandom | head -c $HEXDIGITS`
      echo 0 $BLOCKS crypt $cipher $KEY 0 $swap 0 \
         | $DMSETUP create cryptoswap$NBR
      mkswap /dev/mapper/cryptoswap$NBR > /dev/null
      swapon $OPTS /dev/mapper/cryptoswap$NBR
      echo "Done."
      let ++NBR
   done
   if ! swapon -s | grep "/dev/mapper/cryptoswap" > /dev/null
   then
      echo "ERROR: No encrypted swap devices were created!"
      echo "       Please edit $CONF."
      exit 3
   fi
}

stop() {
        echo "Turning off encrypted swap"
   # It's possible that the configuration file has changed.
   # Therefore the configuration file is ignored and we simply
   # remove all cryptoswap* mappings.
   MAPPINGS=`ls /dev/mapper/cryptoswap* 2> /dev/null`
   if [ -z "$MAPPINGS" ]; then
      echo "WARNING: No cryptoswap mapping found."
      exit 0
   fi
   for m in /dev/mapper/cryptoswap*; do
      MAPDEV=${m#/dev/mapper/}
      echo "  removing $m"
      swapoff $m
      $DMSETUP remove $MAPDEV
      echo "Done."
   done
}

status () {
   swapon -s
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status
        ;;
  restart|reload|force-reload)
        stop
        start
        ;;
  *)
        echo "Usage: cryptoswap {start|stop|status|restart|reload|force-reload}"
        exit 1
        ;;
esac


Agora, siga os seguintes passos.

1. Desligue a memória virtual na partição a ser criptografada.

swapoff /dev/hda1

(Troque /dev/hda1 pela partição utilizada como memória virtual no seu sistema.)

2. Remova todas as partições de memória virtual do seu /etc/fstab.
3. Preencha toda a partição com dados aleatórios.

dd if=/dev/urandom of=/dev/hda1 bs=1M

(Novamente, troque /dev/hda1 pela partição utilizada como memória virtual no seu sistema.)

4. Defina o script cryptoswap para ser iniciado na inicialização do seu sistema.

update-rc.d cryptoswap defaults

5. Inicialize a memória virtual do seus sistema.

/etc/init.d/cryptoswap start

Pronto! Agora, após cada boot, sua partição swap será cifrada com uma chave diferente.

Eliminando todos os rastros

O diretório /tmp é uma área de troca. Durante a operação normal do sistema, os aplicativos escrevem dados temporários nesse diretório. Por isso, nele podem haver resquísios de informações sigilosas. Sendo assim, acredito que a opção mais segura é eliminar quais quer trações de dados gravados no diretório /tmp.

Evidentemente, os problemas seriam resolvidos criando uma nova partição criptografada com ponto de montagem em /tmp. Esta opção tem dois grandes problemas: (a) se seu sistema já está em operação, a criação de uma nova partição não seria uma tarefa fácil, e; (b) uma vez que a partição tenha sido criada, é difícil alterar o seu tamanho.

Uma outra opção é criar um arquivo com dados aleatórios e transforma-lo em uma partição virtual criptografada. Neste caso, a criação da partição é fácil e o seu tamanho pode ser alterado bastando criar um novo arquivo com um tamanho diferente. Esta abordagem é tratada aqui (http://forums.gentoo.org/viewtopic-t-274651.html).

A solução escolhida por mim não foi nenhuma das anteriores. Na verdade, a solução que utilizo é mais simples ainda. Esta é baseada em partições tmpfs (http://en.wikipedia.org/wiki/TMPFS). Tal sistema de arquivo é próprio para dados temporários e não é armazenado no disco rígido. Ao invés disso, ocupa memória RAM e memória virtual. Dessa forma, desde que são armazenados em memória volátil, os dados armazenados no /tmp são perdidos a cada boot. (Existe sistema melhor para proteção de dados?)

A configuração do diretório /tmp como tmpfs é feito incluindo uma única linha no arquivo /etc/fstab, ou seja,

tmpfs   /tmp    tmpfs    defaults,nosuid,size=512M,mode=1777   0 0

Um parâmetro importante é size=512M. Este é o tamanho máximo do diretório /tmp. Contudo, a alocação da memória RAM é feita dinamicamente. Quer dizer... se seu sistema precisar de apenas 1M de espaço, é exatamente essa quantidade de memória RAM que será ocupada. Por exemplo, atualmente, meu diretório /tmp ocupa apenas 16k. Então, 16k bytes é o preço que estou pagando neste momento para segurança total dos meus dados. Além disso, é bom lembrar que esses 512M também incluem a memória virtual, ou seja, os 512M não serão retirados completamente da sua memória RAM.

O tamanho máximo a ser reservado para o seu diretório /tmp dependerá das suas necessidades e do tanto de memória RAM disponível. No meu caso, eu escolhi metade da minha memória RAM total. Faça alguns testes e descubra o valor ideal para o seu caso.

Desde que o sistema tmpfs pode utilizar também memória virtual, seus dados só estarão seguros se a sua partição de memória virtual tiver sido criptografada como indicado na seção anterior.

Por último, observe que em partições tmpfs o sistema de arquivo não precisa ser criado. Quer dizer... A partição não precisa ser formatada nem uma única vez.

Comentários Finais

1) Faça backup sempre! Já imaginou a dor de cabeça que deve ser tentar recuperar dados em uma partição criptografada após algum problema no disco rígido?
2) A proteção dos seus dados agora depende apenas da sua senha. Utilize uma senha fraca e a chave com a qual o arquivo .secret.key foi cifrado poderá ser descoberta. Isso liberará a chave utilizada na cifragem da partição.
3) Quando mover dados de uma partição não-cifrada para a partição cifrada, os dados na partição não-cifrada ainda poderão ser recuperados. Utilize o programa shred para apaga-los com segurança.

Referências

Automatically mount dm-crypt encrypted home with pam_mount (http://forums.gentoo.org/viewtopic-t-274651.html)
Quick and painless: dm-crypt encrypted swap (http://forums.gentoo.org/viewtopic.php?p=1959581#1959581)

Changelog

14.06.2007: Publicação do mini-how-to

DiegoV

Olá,

Buscando a implementação do how-to no Ubuntu 8.10, verifiquei que é necessário adicionar uma linha no início do cryptoswap, para fazer com que o mesmo utilize o bash na sua execução, e não o dash que, pelo que pesquisei, passou a ser o padrão.

Assim, é necessário que o arquivo cryptoswap inicie com o famoso:  "#! /bin/bash" .

Para referência, o erro apresentado antes da adição da linha é: Syntax error: Bad fd number .

[], DiegoV

danpos

@DiegoV

Pois é, isso é uma grande besteira que o pessoal do Ubuntu fez e que nós, usuários mais atentos, mudamos logo de cara:

$ sudo rm /bin/sh
$ sudo ln -sf /bin/bash /bin/sh


Explicação: o "/bin/sh" é um link simbólico apontando para "/bin/dash"; então a primeira linha remove esse link; na segunda linha é criada o link simbólico "/bin/sh" apontando para "/bin/bash". Dessa forma você não precisará doravante especificar o sh ("Bash" no caso) a ser utilizado nos teus scripts.

Danpos.

DiegoV

Olá Danpos,

Pensei nessa opção, porém fiquei receoso que isto pudesse causar problemas em outros scripts do sistema.

[], Diegov

danpos

Citação de: DiegoV online 11 de Novembro de 2008, 12:08
Olá Danpos,

Pensei nessa opção, porém fiquei receoso que isto pudesse causar problemas em outros scripts do sistema.

[], Diegov

Não há problema pois o bash é um shell mais completo que o dash ... ;)

Danpos.

pigdin

Muito interessante.

Só descobri este How-to agora.

O shred eu já conhecia, achei bastante útil a criptografia da swap.

Vai ser bastante útil para minha proteção e para as aulas de segurança da informação.

Parabéns pelo tópico.
Desk: Phenom X3 2GB DDR II - Win 7 / Ubuntu 10.04 64 Bits
Note MUB: Core2Duo 4GB - Win7 / Ubuntu 10.04 / Bodhi Linux.
@alexpigdin