Pi Zero als smart USB-stick 4

Door synoniem op vrijdag 27 december 2019 17:29
Categorie: Raspberry Pi, Views: 1.982

Mijn doel voor de smart USB-stick is om hem als een deels niet ge-encrypte opslag en deels wel ge-encrypte opslag te gebruiken. En dat leverde redelijk wat gepuzzel op. Bijvoorbeeld hoe ga je de passphrase ingeven om de container te decrypten. Wanneer stel je het niet ge-encrypte deel beschikbaar? Direct bij het inpluggen of wacht je tot het ge-encrypte deel beschikbaar is?

Daarnaast kwam ik tot de ontdekking dat ik de module g_multi gelijk bij het opstarten moet laden om het goed te laten werken. Alleen werkt mijn vertragingstactiek voor de virtuele seriële port dan niet meer. Met als resultaat de terugkeer van de foutmelding "[24732.318969] cdc_acm 1-4:2.0: failed to set dtr/rts". In combinatie met g_multi dus geen mogelijkheid om in te loggen via de virtuele seriële poort.

Gelukkig werkt het met de virtuele ethernetpoort wel. Plus een virtuele netwerkverbinding biedt meer mogelijkheden zoals telnet, ssh maar ook http om een paar voorbeelden te noemen. Alleen wil je wel altijd hetzelfde ip-adres en bij voorkeur ook hostnaam hebben. Veel tutorials op het internet laten dat afhangen van de aanwezigheid van Bonjour of mDNS. Persoonlijk geef ik er de voorkeur aan om het zelf te regelen met dnsmasq als DHCPserver. Dnsmasq kan "statische" ip-adressen" afgeven op basis van het MAC-adres van de client. Alleen wordt dat MAC-adres standaard bij het laden willekeurig gegenereerd tenzij je ze hard mee geeft bij laden van g_multi.

Om te beginnen verwijderen we eerst de sporen van de module g_serial. Door de volgende regels te verwijderen uit /etc/rc.local:
code:
1
2
sleep 2
modprobe g_serial

en door het verwijderen van de inlogservice op de virtuele seriële poort:
code:
1
$ sudo systemctl disable getty@ttyGS0.service


Dan wordt het tijd om cmdline.txt aan te passen zodat dwc2 en g_multi geladen worden bij het booten:
code:
1
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=e934c5ce-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_multi


g_multi parameters
De parameters voor g_multi kun je meegeven in een configuratiebestand in /etc/modprobe.d. In mijn geval heb ik het usbgadget.conf genoemd maar het kan een willekeurige bestandsnaam hebben zolang het maar een conf extensie heeft:
code:
1
options g_multi host_addr=00:df:de:dd:dc:db dev_addr=00:df:de:dd:dc:da file=/usbshare.img removable=1,1 luns=2

Host_addr is het MAC-adres wat aan de 'host' en dev_addr het MAC-adres wat aan de Pi wordt toegewezen. De regel file=/usbshare.img removable=1,1 luns=2 is voor de volgende configuratie: het niet ge-encrypte deel wordt gelijk bij het starten geladen en is verwijderbaar. Daarnaast is er ruimte voor een tweede ge-encrypt deel wat later wordt toegewezen en daarom ook removable is. Totaal komen er maximaal twee virtuele HDD's vandaar luns=2. Let op, stel dat je drie virtuele HDD's beschikbaar wil stellen dan wordt het removable=1,1,1 en luns=3. Geef je niet removable op dan moet je een bestandsnaam of een blockdevice meegeven anders zal g_multi met een foutmelding afbreken. Geef je meer bestanden of blockdevices op dan het maximum van luns= dan worden de meerdere bestandsnamen genegeerd.

dnsmasq configuratie
We beginnen met het installeren van dnsmasq en de standaard configuratie veilig te stellen:
code:
1
2
$ sudo apt install dnsmasq
$ sudo cp /etc/dnsmasq.conf /etc/dnsmasq.old

En maken een nieuw configuratiebestand /etc/dnsmasq.conf aan met de volgende inhoud:
code:
1
2
3
4
5
listen-address=127.0.0.1,192.168.42.1
dhcp-range=192.168.42.2,192.168.42.10,255.255.255.0,12h
interface=usb0
no-hosts
dhcp-host=00:df:de:dd:dc:db,192.168.42.2

Zoals je ziet zal de 'host' op basis van options g_multi altijd het ip-adres 192.168.42.2 krijgen. Om te zorgen dat de Pi altijd 192.168.42.1 krijgt, maken we een nieuw configuratiebestand onder /etc/network/interfaces.d aan met de naam usb0 (Let op! Juist geen extensie gebruiken!) met de volgende inhoud:
code:
1
2
3
auto usb0
iface usb0 inet static
        address 192.168.42.1

Je kan hier uiteraard nog veel meer aan toevoegen om ook een internetverbinding op te bouwen via de 'host'. Mijn voorkeur is om voor een internetverbining wlan0 te blijven gebruiken en voor usb0 puur een één op één verbinding te maken.
Om interferentie te voorkomen van de dhcp instellingen tussen wlan0 en usb0 voegen we de volgende regels toe aan /etc/dhcpcd.conf:
code:
1
2
ipv4only
denyinterfaces usb0


dm-crypt met LUKS
Voor het maken van een ge-encrypte container gebruiken we dm-crypt met LUKS. Waarvan overigens het package in de repo van Raspbian "cryptsetup" heet. Hiervoor maken we eerst weer een bestandsimage aan, maar nu 4GiB, met:
code:
1
$ sudo dd if=/dev/zero of=/crypt.img bs=4M count=1024 status=progress

Waarna we vervolgens het image mounten als loopdevice, dm-crypt installeren, het loopdevice met cryptsetup initialiseren, openen en formatteren met FAT32 .
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ sudo losetup -f
 /dev/loop0

$ sudo losetup /dev/loop0 /crypt.img

$ sudo apt install cryptsetup

$ sudo cryptsetup -y -v luksFormat /dev/loop0
WARNING!
========
This will overwrite data on /dev/loop0 irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
Command successful

$ sudo cryptsetup luksOpen /dev/loop0 crypt  #je kan een willekeurige naam opgeven gemakshalve gebruik ik crypt

$ sudo cryptsetup -v status crypt
/dev/mapper/crypt is active and is in use.
  type:    LUKS1
  cipher:  aes-xts-plain64
  keysize: 256 bits
  device:  /dev/loop0
  loop:    /crypt.img
  offset:  4096 sectors
  size:    8384512 sectors
  mode:    read/write
Command successful.

$ sudo mkfs -t vfat /dev/mapper/crypt

Hiermee hebben we een geopende bestandscontainer die we aan de host beschikbaar kunnen stellen. Moeten we alleen weten waar we dat kunnen ingeven. Daarvoor zoeken we naar een lun1 in /sys de bestandsinterface van de kernel.
code:
1
2
$sudo find /sys -name lun1
/sys/devices/platform/soc/20980000.usb/gadget/lun1

We weten welke bestandsnaam we opgegeven hebben voor lun0 zodat we kunnen controleren of we hier de goede entry te pakken hebben.
code:
1
2
$ cat /sys/devices/platform/soc/20980000.usb/gadget/lun0/file
/usbshare.img

Ja, dit is de goede entry. Om de geopende container aan de host te koppelen kunnen we niet /crypt.img of /dev/loop0 meegeven want daar staat alleen maar random data. Wat we mee geven is de geopende container onder /dev/mapper/crypt. Dat doen we met het volgende commando:
code:
1
$ sudo bash -c "echo "/dev/mapper/crypt" > /sys/devices/platform/soc/20980000.usb/gadget/lun1/file"

En als alles goed gegaan is, zal er een nieuwe usbdrive van 4GiB verschijnen op de host.

Wat nu nog moet gebeuren is zo min mogelijk handmatige ingaves en liefst een webinterface om de USB-stick en encryptie in- en uit te schakelen. Wordt vervolgd...

Volgende: Pi Zero radio 12-04 Pi Zero radio
Volgende: Netwerk booten van een Raspberry 4 12-'19 Netwerk booten van een Raspberry 4

Reacties

Reageren is niet meer mogelijk