Hosszú idő után nem a felhőben, hanem ismét a valódi vasak világában találkoztam régi ismerősömmel, a Linuxxal. Eljött az idő a rendkívül koros Intel Atom alapú házi szerverem ráncfelvarrására, és AMD Ryzen alapokra helyezésére. A régi idők emlékére először a Fedora Linux segítségével próbálom meg feléleszteni a gépet.

Titkosítsunk! Mit és miért?

Ha az ember valódi hardverre telepít, nem a felhőben virtualizálva dolgozik, akkor olyan problémákat kell megoldjon maga, amiket a felhőben már megoldottak a háttérben dolgozó szorgos kezek, és adottságként állnak rendelkezésre. Ilyen a bizalmas adatok hardware selejtezés utáni szivárgásának megakadályozása. Akinek kellett már félig haldokló lemezek szeméttel felülírásával vacakolnia mielőtt selejtezhette volna őket, már biztos elgondolkozott azon, hogy mi lenne ennek a hatékony megoldása. Van aki úthengerre, lángszóróra, vagy kalapácsra szavaz, de mint minden hardveres problémát, természetesen ezt is akad aki szoftver segítségével akarja megoldani: a lemez titkosításával.

Jó pár éve már, hogy olvastam az Apple iPhone telefonokban alkalmazott gyors törlési megoldásában: mivel a teljes háttértárat felülírni soká tartana, ezért a teljes háttértár titkosítva van, csak a kulcs van egy biztonságos tárhelyen tárolva, és a (távoli) törlési kérelem esetén csak a kulcsot kell eltávolítani, így a sok titkosított adat máris hozzáférhetetlen. Ezt a megoldást elég kiterjedten alkalmazzák azóta.

Egy példa: a / filerendszer nem titkosított, így a /etc alatt egy olyan program bizalmas információt (pl. tanúsítványokat) tárol, ami elkerült a rendszergazda figyelmét, aki az általa telepített szolgáltatok általa ismert bizalmas adatait gondosan titkosított tárhelyre helyezte. Ha a teljes lemezt titkosítjuk, akkor minimalizáljuk annak az esélyét, hogy véletlen adatot szivárogtassunk.

Hogy oldjuk fel?

Ha titkosítva van a rendszer, hogyan oldjuk fel a titkosítást a használathoz? Alapesetben egy jelszó a kulcs, amit a telepítés során lehet megadni. A rendszer betöltés korai szakaszában szükséges ezt megadni az initrd scriptek egyike, hogy a root filerendszert fel tudja oldani. Alapesetben egy jelszó-prompt jelenik meg, ahol be kell gépelni a jelszót, hogy a betöltés folytatódni tudjon. Ez egy notebookon megfelelő felhasználói élmény, de egy szerveren nem jó, ha interaktív tevékenység szükséges a konzolon az indítás során.

Több megoldás kínálkozik, a legegyszerűbb, amit alapjáraton is támogat a rendszer, ha egy boot során rendelkezésre álló külső eszközön (pendrive) tárolt kulccsal is feloldható a rendszer.

Az ellen nem véd!

Fontos tudni, hogy mi a fenyegetési modellünk:

  • Ha a géphez fizikailag hozzáfér egy támadó, akkor a beledugott pendrivehoz is hozzáfér. Így el tudja indítani a gépet, és a lemezt fel tudja oldani. Azonban, ha fizikailag hozzáfért a géphez, akkor a gép már amúgy sem megbízható többé, más módokon is tudná kompromittálni, és megszerezni a szükséges kulcsokat.
  • Ha mindig be van dugva a pendrive, akkor egy megfelelően magas jogokat szerző távoli támadó fel tudja csatolni, és meg tudja szerezni a kulcsot. Ekkor azonban már amúgy is teljes hozzáférése van a géphez, és ekkorra már bármilyen bizalmas adatot meg tudott szerezni.

Mi ellen véd akkor? Ahogy már fent is írtam: Ha a lemezt selejtezzük, többé nem kell aggódni azon, hogy adatot szivárogtatunk róla, mert külön van tárolva a feloldáshoz szükséges titkosítási kulcs.

Lehetséges bonyolultabb, de szűkebb támadási felületet nyújtó nem-interaktív feloldási sémák megalkotása is, például hálózatról letöltött kulcs, amivel pl. betörő ellen védhető a gépen tárolt adat, mert a kulcsforrás feletti ellenőrzés továbbra is megmarad, míg a pendriveot magával tudja vinni a betörő. Ezek azonban számottevő extra erőfeszítést igényelnek.

Sok a rizsa! hogy kell megcsinálni?

Valóban bő lére eresztettem, de a megoldás egyszerűségéhez képest sok macerával járt, mivel sajnos az internetes keresések találatai alapján indultam neki a megoldás keresésének. Így sok elavult, még több gányolt, és számtalan haszontalan tanácsot láttam, sokat ki is próbáltam, de végül tiszta lapról kezdve a dokumentációból dolgozva sikerült megtalálni a következő egyszerű receptet:

Rendszer telepítése

ℹ Az alábbiakat a Fedora 31 verzión végeztem el.

A rendszer telepítése során lehetőség van a titkosítás konfigurálására, ahol a kezdeti jelszót meg kell adni. Így minden partíció, és a swap egyaránt egy LVM PV-be kerül, ami egy titkosított blokkeszközön kerül tárolásra. A titkosítást LUKS segítségével végzi a rendszer.

A telepítés után a rendszer első indításánál a jelszóval kell feloldani a lemezt, hogy a gép betöltsön, és be lehessen jelentkezni.

Jelentkezzünk be rendszergazdaként, majd készítsük el a pendriveot a kulccsal. A lemezt a címkéje alapján fogjuk azonosítani. Lehetséges lenne UUID alapú azonosítás is, ám akkor a drive meghibásodása esetén új filerendszer után több konfiguráció frissítés is szükséges lenne.

mkfs.ext4 -L key-disk /dev/sda1
mount -t ext4 /dev/disk/by-label/key-disk /mnt/
dd if=/dev/urandom of=/mnt/the.key bs=1024 count=4
chown root:root /mnt/the.key
chmod 600 /mnt/the.key

Azonosítsuk a LUKS által használt blokkeszközt:

blkid

Látható a kimenetben, hogy egyetlen crypto_LUKS eszköz szerepel, és a /dev/mapper alatt egy virtuális blokkeszköz van ennek titkosítatlan képével, mely neve luks-<UUID> formát követi. Ebből megállapítható, hogy a titkosított rendszer-partíció a /dev/nvme0n1p2.

/dev/nvme0n1p1: UUID="ad346a3f-115e-4859-912a-ab12d2ec9b7a" TYPE="xfs" PARTUUID="fc06552d-01"
/dev/nvme0n1p2: UUID="e5a1edd8-1e92-4daa-bcf8-3ab26e677e32" TYPE="crypto_LUKS" PARTUUID="fc06552d-02"
/dev/sda1: LABEL="key-disk" UUID="15c0603d-a582-4303-bc10-331a639c2b4b" TYPE="ext4" PARTUUID="dd814dd5-01"
/dev/mapper/luks-e5a1edd8-1e92-4daa-bcf8-3ab26e677e32: UUID="d0prxL-fYml-QPiL-9zBr-624P-w9Kf-3KLTfM" TYPE="LVM2_member"
/dev/mapper/fedora-root: UUID="f58639e1-7369-4244-8751-9f5b0d1ecfc3" TYPE="xfs"
/dev/mapper/fedora-swap: UUID="d6ce8801-e3bd-4dbd-9cf9-3c741dd7c9e4" TYPE="swap"

A partíció LUKS kulcstartójához adjuk hozzá a korábban elkészített kulcsfilet.

cryptsetup -v luksAddKey /dev/nvme0n1p2 /mnt/the.key luks

Ekkor már a kulcsfile képes lenne feloldani a kötetet, de az initrd scriptek futása során kellene ezt automatikusan megtenni. Itt kezdett az internetes források sokasága használhatatlanná válni. Egyes források boot parancssori opciókat javasolnak, de ezek (rd.luks.key, rd.luks.uuid) sajnos nem működtek. Mások kézműves scriptek initrd-be plántálásával dolgoznak, amik szintén nem az igaziak.

A megoldás azonban nagyon egyszerű: a LUKS konfigurációja az /etc/crypttab fileban található. Ezt a filet megfelelően kitöltve, és az initrd-ben frissítve a lefutó scriptek képesek a szükséges filerendszer mountolást, és lemez feloldást elvégezni.

A telepítő által generált file 3. oszlopa, mely a titkosítási jelszót tartalmazza, none értékű, ami az interaktív belépésre kényszeríti az ez alapján dolgozó initrd scripteket. Az alábbi módosításokkal azonban megadhatjuk, hogy a keyfile mely lemezen található, milyen néven, és amennyiben ez nem áll rendelkezésre 30 másodpercen belül, úgy az interaktív belépésre váltson vissza a rendszer.

# /etc/crypttab

#
# this was the original contents:
#
#luks-e5a1edd8-1e92-4daa-bcf8-3ab26e677e32 UUID=e5a1edd8-1e92-4daa-bcf8-3ab26e677e32 none discard

# 
# use file key from the root of the block device identified by its label key-disk, 
# if not found in 30 seconds fall back to interactive password authentication,
# propagate SATA TRIM discard commands
#
luks-e5a1edd8-1e92-4daa-bcf8-3ab26e677e32 UUID=e5a1edd8-1e92-4daa-bcf8-3ab26e677e32 the.key:LABEL=key-disk discard,keyfile-timeout=30

A változtatás érvényre juttatásához frissíteni kell az initrd filet, mert a crypttab abba be van csomagolva. Mivel már létezik a célfile, ezért szükséges a --force kapcsoló.

drakut --force

Frissítések során a telepített újabb kernelekhez automatikusan elkészülnek majd a megfelelő initrd imagek.

Ezen egyszerű megoldás megtalálását kissé megnehezítette, hogy a crypttab manpage a file:blockdevice formátum létezését nem igazán hangsúlyozta, csak egy példában lehetett kiszúrni. Nekem ez csak a sokadik kört futva tűnt fel.

Kész is vagyunk!

Ezzel el is készültünk, nincs más tennivaló, mint újraindítani a rendszert, és a élvezni a munka gyümölcsét!