Role Ansible para decriptação remota de disco [ArchLinux]

Se você tem um servidor em casa ou está criando um, vai descobrir como é chato ter que, para cada reboot, inserir senhas no dispositivo para decriptação ou desbloqueio do dispositivo durante a inicialização.

Eu tenho um notebook antigo que estou usando de servidor, e uma das primeiras configurações que fiz nele foi configurar uma maneira de inserir senhas para desbloqueio remotamente, ainda na initramfs (sistema de arquivos inicial, antes do carregamento do sistema inteiro). A distro que estou utilizando é o ArchLinux, por ser bem minimalista e pela natureza pedagógica que estou tentando dar ao projeto.

Posteriormente eu pretendo incorporar mais dispositivos ao meu homelab, então uma maneira automatizada de realizar esta configuração seria o ideal, e aí que entra o Ansible. Apresento a pequena role ansible que criei, seguindo o tutorial existente na ArchWiki para decriptação/desbloqueio remoto de dispositivos na initramfs (um filesystem inicial que é carregado antes do carregamento efetivo do sistema). Segui a configuração para initramfs baseados em busybox.

Não vou entrar em muito detalhe sobre a configuração, está tudo na ArchWiki, que é uma ótima fonte de aprendizado para quem se interessa por Linux, por sinal – e mantida pela comunidade. Se você quiser saber mais sobre o que é feito pela role, recomendo a leitura da sessão da ArchWiki que mencionei acima.

Link (Github): https://github.com/afonsolpjr/homelab/tree/main/ansible/roles/remote_decrypt

A configuração se limita a conectividade Ethernet na rede local. Conectividade via VPN ou sem fio, por exemplo, não funcionaria. A habilitação destas funcionalidades nesta etapa da inicialização do sistema requer mais algumas configurações.

Abaixo, temos uma organização mínima de diretórios recomendada para a execução da role em um playbook.

├── host_vars
│   └── server.yaml
├── inventory.yml
├── remote_decrypt.yaml
└── roles
    └── remote_decrypt
        ├── files
        │   └── tiny_ssh_keys
        ├── handlers
        │   └── main.yaml
        └── tasks
            └── main.yaml
        
  • server.yaml – arquivo de variáveis necessárias da role, para um host :
YAML
ETHERNET_ADDR: # 192.168.0.22 # LAN static ip of the device 
ETHERNET_GATEWAY_ADDR: # 192.168.0.254 # your gateway address
ETH_MASK: # 255.255.255.0 
ETH_DEVICE: # this is often named as 'eth0' on early userspace (before udev)
ETH_NIC_MODULE:  # get this info with lspci -k | grep -i eth -A 5 -B 
ETHERNET_ADDR_WITH_MASK: # 192.168.0.22/24 # example
  • inventory.yaml – declaração de hosts por grupos/definição de variáveis de grupo
  • remote_decrypt.yaml – playbook simples contendo a role e os hosts alvos
  • tiny_ssh_keys – arquivo contendo as chaves publicas autorizadas a se autenticar no servidor ssh que é aberto.
  • tasks/main.yaml – arquivo principal com as tasks para instalar os pacotes necessários, configurar hooks e módulos necessários.
YAML
- name: Installing necessary packages for remote unlocking
  community.general.pacman:
    update_cache: true
    name:
      - mkinitcpio-netconf
      - mkinitcpio-tinyssh
      - mkinitcpio-utils

- name: Copy authorized tinyssh keys
  ansible.builtin.copy:
    src: tiny_ssh_keys
    dest: /etc/tinyssh/root_key
    owner: root
    group: root
    mode: "0644"
  notify: Regenerate initramfs

- name: Setting NIC mkinitcpio parameters
  ansible.builtin.lineinfile:
    path: /etc/mkinitcpio.conf
    backrefs: true
    regexp: (^MODULES=)\(({{ ETH_NIC_MODULE }} )?(.*$)
    line: \1({{ ETH_NIC_MODULE }} \3
  notify: Regenerate initramfs

- name: Setting mkinitcpio HOOK parameters
  ansible.builtin.lineinfile:
    path: /etc/mkinitcpio.conf
    backrefs: true
    regexp: (^HOOKS.*?)(netconf tinyssh )?encrypt(ssh)?(.*$)
    line: \1netconf tinyssh encryptssh\4
  notify: Regenerate initramfs


- name: Setting default GRUB parameters
  ansible.builtin.lineinfile:
    path: /etc/default/grub
    backrefs: true
    regexp: (^GRUB_CMDLINE_LINUX_DEFAULT=)"(ip={{ ETHERNET_ADDR }}::{{ ETHERNET_GATEWAY_ADDR }}:{{ ETH_MASK }}::{{ ETH_DEVICE }}:off )?(.*$)
    line: \1"ip={{ ETHERNET_ADDR }}::{{ ETHERNET_GATEWAY_ADDR }}:{{ ETH_MASK }}::{{ ETH_DEVICE }}:off \3
  notify: Regenerate grub config
  • handlers/main.yaml – handlers para execução caso haja mudança nas configurações pela execução da role.
YAML
- name: Regenerate initramfs
  ansible.builtin.command: sudo mkinitcpio -P
  ignore_errors: true

- name: Regenerate grub config
  ansible.builtin.command: sudo grub-mkconfig -o /boot/grub/grub.cfg

Em um futuro próximo, pretendo configurar o Wireguard ou o Tailscale, para poder desbloquear o dispositivo fora da LAN 🙂


Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

To respond on your own website, enter the URL of your response which should contain a link to this post’s permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post’s URL again. (Find out more about Webmentions.)