Como não armazenar a chave de criptografia do hdd na máquina, mas ainda montar na inicialização?

4

Configuração: estou usando um fragberry pi com um USB HDD, executando o arch linux e syncthing para minha própria sincronização "em nuvem".

Problema: No caso de uma invasão física em que o HDD pi e o HDD são roubados, eu gostaria de garantir que os arquivos no HDD permaneçam confidenciais.

Idéia atual de alto nível: criptografar o HDD, armazenar a chave no servidor da web. Na inicialização, baixe a chave, descriptografe e monte. Não armazene a chave no cartão HDD / SD. Em caso de roubo, pare de atender a chave do servidor da Web.

Pergunta: Como implementar isso?

(O crypttab pode resolver isso? As minhas próprias unidades de sistema estão a escrever o caminho a seguir? Quaisquer outras ideias, ou mesmo soluções, são bem-vindas)

    
por kidmose 27.09.2015 / 00:34

2 respostas

8

A maneira mais fácil de configurar isso seria ter uma partição do sistema de texto não criptografado (no cartão SD, eu presumo) e uma partição de dados criptografados. Use dmcrypt para criptografar a partição de dados, com uma chave armazenada em um arquivo de chave que é baixado do servidor.

Primeiro, configure a infraestrutura do servidor, faça o download do arquivo de chaves e crie o volume criptografado com cryptsetup luksFormat /dev/sdb1 /run/data.keyfile ou adicione a chave ao volume existente com cryptsetup luksAddKey /dev/mapper/encrypted /run/data.keyfile . Observe que você pode organizar o volume a ser desbloqueado com uma frase secreta ou um arquivo de chave, o que pode ser conveniente para a administração (você pode digitar a frase secreta mesmo se o servidor não estiver disponível).

O arquivo de chave não precisa estar em nenhum formato específico. Apenas gere alguns bytes aleatórios no servidor; 16 bytes é bastante (qualquer coisa a mais não lhe dará melhor segurança, mas qualquer coisa a menos não lhe dará um melhor desempenho): </dev/urandom head -c 16 >pi.keyfile .

Sirva a chave com HTTPS para evitar que seja snooped. Se você não tiver um certificado validado por uma CA, crie o seu próprio e adicione-o a /etc/ssl/certs ou passe-o para o comando de download ( wget --ca-certificate /etc/local/my.cert ou curl --cacert /etc/local/my.cert ).

Você precisa baixar a chave antes de ativar o volume de criptografia. Você pode fazer isso em um passo com um dos

wget -nv -O - https://myserver.example.com/pi.keyfile | cryptsetup luksOpen /dev/sdb1 --key-file /dev/stdin
curl https://myserver.example.com/pi.keyfile | cryptsetup luksOpen /dev/sdb1 --key-file /dev/stdin

ou você pode baixar a chave para um arquivo temporário, ativar o volume e, finalmente (não é necessário, mas pode melhorar um pouco a segurança) remover o arquivo temporário. O local natural desse arquivo temporário está em /run , que está na RAM e pode ser gravado somente pelo root (não baixe a chave para armazenamento persistente). Você deve tornar o arquivo legível apenas pelo root (você pode definir umask 700 antes de fazer o download para organizar isso), embora isso só tenha importância se você não controlar todo o código executado no momento da inicialização.

Se você baixar a chave para um arquivo temporário, poderá colocar o arquivo-chave em /etc/crypttab e adicionar uma unidade systemd para fazer o download do arquivo-chave que é executado antes do que ativa o volume criptografado (mas após a disponibilidade da rede) outra unidade para remover o arquivo de chaves depois. Colocar wget … | cryptsetup … em /etc/rc.local parece mais fácil de configurar.

Você provavelmente desejará autenticar o cliente quando fizer o download da chave. O token de autenticação terá que ser armazenado em texto claro no Pi. Você pode usar um certificado de cliente SSL:

curl --cert /etc/keyfile.cert https://myserver.example.com/pi.keyfile
wget --certificate /etc/keyfile.cert https://myserver.example.com/pi.keyfile

ou uma senha com autenticação básica HTTP, armazenada em /root/.netrc :

curl -n --user=pi https://myserver.example.com/pi.keyfile
wget --user=pi /etc/keyfile.cert https://myserver.example.com/pi.keyfile

A configuração da autenticação básica talvez seja mais fácil de configurar no lado do servidor. Use uma senha gerada aleatoriamente sem caracteres especiais (por exemplo, </dev/urandom | head -c 16 | base64 ).

Note que o que você fizer, alguém que roubar o Pi receberá a senha e poderá baixar a chave se você não a bloquear primeiro no lado do remetente. Além disso, alguém que tenha acesso físico ao Pi pode retirar rapidamente o cartão SD, fazer uma cópia e inseri-lo de volta; Se você não monitorar nada além do tempo de atividade, isso parecerá uma falha de energia. Não há como proteger completamente contra isso. Você pode colocar a chave em um cartão inteligente, o que impediria o invasor de duplicá-lo, mas não de roubar o cartão inteligente ou usá-lo no local para fazer o download do arquivo-chave.

Mais uma vez, você não pode proteger contra alguém com acesso físico baixando rapidamente o arquivo de chave, depois roubando o disco e descriptografando-o quando quiser. Se você quiser proteger-se contra isso, é necessário investigar o hardware resistente a violações, que está em uma faixa de preço diferente.

    
por 27.09.2015 / 01:37
0

Eu resolvi o mesmo problema usando uma solução um pouco diferente: porque eu estava usando o ZoL, preferi usar o EcryptFS. Além disso, como eu queria que a chave fosse acessível, eu a armazenei criptografada ... em um serviço de troca de arquivos (por exemplo, Dropobox). Então, o processo é:

a) A systemd unit connects to the file exchange service, downloads the key and 
   decrypts it.
b) The dependent systemd units wait until the previous has finished and then use 
   the decrypted key to mount the file systems.
c) I have a service that monitors a box switch, so if the server box is opened I 
   receive an alert via pushbullet and the key is deleted from dropbox.

A ideia é que quando a integridade física do servidor é comprometida, o servidor é roubado, etc., a chave é excluída da caixa de depósito e os dados ficam ilegíveis.

    
por 04.06.2016 / 21:04