Uma dependência do systemd pode ser aplicada somente à ação “ExecStart” de uma unidade?

4

Eu tenho um cenário em que vários volumes de armazenamento são criptografados usando chaves contidas em uma unidade flash "chaveiro" criptografada e removível. Estou executando o Arch Linux e esta pergunta é sobre a configuração de dependência do systemd.

O sistema é configurado para que, desde que o chaveiro esteja presente, o sistema inicialize e os volumes sejam montados. A frase secreta do chaveiro é inserida manualmente durante a inicialização.

Eu quero poder remover o chaveiro USB depois que o sistema estiver ativo. No entanto, estou tendo problemas com isso porque o systemd desmonta tudo.

Aqui está um exemplo do que fiz. Primeiro, /etc/crypttab

# <name>  <device>           <password>             <options>
keyring   PARTLABEL=keyring  none                   noauto
abc       /dev/lvm/abc       /root/keyring/abc.key  header=/root/keyring/abc.hdr
xyz       /dev/lvm/xyz       /root/keyring/xyz.key  header=/root/keyring/xyz.hdr
  • Estou usando um checkout recente do Git de systemd que suporta a opção header ; foi adicionado ao código-base em 8 de janeiro.

  • Estou usando o rótulo de partição do chaveiro porque há vários chaveiros físicos por motivos de backup / conveniência. Eles podem ter diferentes UUIDs, mas são configurados com o mesmo PARTUID.

  • Estou usando noauto para que o chaveiro seja apenas uma dependência de qualquer dispositivo que precise ser descriptografado.

A seguir está o /etc/fstab :

# <file system>     <dir>         <type>    <options>
/dev/mapper/keyring /root/keyring ext4      ro,noauto
/dev/mapper/abc     /srv/abc      ext4
/dev/mapper/xyz     /srv/xyz      ext4

Mais uma vez, o chaveiro é noauto , então a montagem só ocorre devido a ser uma dependência. Além disso, ele é montado somente para leitura, para que seja seguro apenas retirá-lo.

Agora, para criar a dependência entre o volume e o chaveiro, usei uma substituição drop-in , por exemplo:

# /etc/systemd/system/systemd-cryptsetup\@abc.service.d/override.conf
[Unit]
Requires=root-keyring.mount

Tudo funciona bem para a inicialização. O problema é que remover o chaveiro interrompe as unidades dependentes dele. Eu não quero que isso aconteça - a dependência só é necessária para tornar as chaves e os cabeçalhos acessíveis enquanto os volumes criptografados são desbloqueados. Depois de desbloqueadas, as chaves e os cabeçalhos não são mais necessários.

Então, minha pergunta é perguntar como posso organizar uma dependência no chaveiro que existe apenas durante o comando "ExecStart" na unidade systemd-cryptsetup @ .service ?

Alternativamente, se esta é a abordagem errada, qualquer solução melhorada seria bem-vinda.

    
por starfry 30.01.2015 / 17:27

2 respostas

1

No systemd atual (218 no momento da escrita), uma entrada em /etc/crypttab resulta em uma instância da unidade [email protected] sendo gerada pelo systemd-cryptsetup-generator que o systemd executa quando o sistema está inicializando. / p>

A unidade gerada inclui uma dependência no caminho para o arquivo de chaves:

RequiresMountsFor=/path/to/key_file

Esse tipo de dependência é documentada em man systemd.unit , onde explica que isso resulta em Requires= e After= dependencies para todas as montagens necessárias para acessar o caminho especificado.

A dependência Requires= faz com que o systemd pare a unidade cryptsetup se a unidade de montagem estiver desativada.

Isso significa que a desmontagem do dispositivo que contém a chave indica a desativação da unidade cryptsetup e bloqueia o volume quando isso ocorre.

A única alternativa possível no momento é não usar /etc/crypttab para quaisquer volumes em que isso possa ser um problema, mas fornecer uma unidade personalizada que não inclua uma RequiresMountsFor= de dependência. . Aqui está uma unidade personalizada adequada que é baseada na unidade produzida pelo gerador:

# /etc/systemd/system/systemd-cryptsetup\@.service 
[Unit]
Description=Cryptography Setup for %I
Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:[email protected](8)
DefaultDependencies=no
Conflicts=umount.target
BindsTo=dev-mapper-%i.device
IgnoreOnIsolate=true
After=cryptsetup-pre.target
Before=cryptsetup.target
BindsTo=dev-lvmvg-%i.device
After=dev-lvmvg-%i.device
Before=umount.target

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutSec=0
ExecStart=/usr/lib/systemd/systemd-cryptsetup attach '%i' '/dev/lvmvg/%i' '/root/keyring/%i.key' 'header=/root/keyring/%i.hdr'
ExecStop=/usr/lib/systemd/systemd-cryptsetup detach '%i'

[Install]
WantedBy=dev-mapper-%i.device

Este exemplo seria usado em vez deste /etc/crypttab entry:

 # <name>  <device>       <password>              <options>
mail      /dev/lvmvg/mail /root/keyring/mail.key  header=/root/keyring/mail.hdr   

Este problema foi levantado com os desenvolvedores do systemd e foi adicionado ao Lista TODO .

    
por 05.02.2015 / 13:05
1

Em vez de uma dependência explícita, talvez você possa usar um automount .

Eu lembro que o Systemd anunciou isso durante a postagem no blog inicial do Poettering , como uma espécie de dependência implícita. É como (com o systemd) você pode escrever pedidos para um socket e o serviço apropriado será iniciado para você, também conhecido como "ativação do soquete". Neste caso, acessar o sistema de arquivos fará com que seja montado.

Com essa abordagem, você pode esperar bloquear até que o serviço ou o sistema de arquivos esteja pronto. Nota : isso implica que o seu sistema terá um diretório que o bloqueará se você tentar vê-lo (depois de remover a unidade "chaveiro") ... Talvez se você usar / root para qualquer outra coisa, seria melhor montá-lo em outro lugar, por exemplo /automount/keyring , para evitar tropeçar nele. Pessoalmente, acho que esse tipo de problema torna os automounts um pouco confusos - mas parece fazer uma solução muito rápida para sua pergunta.

Se o sistema de arquivos estiver listado em /etc/fstab , basta adicionar x-systemd.automount à lista de opções.

Se ele for descrito por um arquivo nativo .mount , parece que você precisa criar um arquivo .automount com o mesmo nome. Por exemplo. root-keyring.automount , contendo:

[Automount]
Where=/root/keyring
    
por 30.01.2015 / 20:55