Szyfrowanie partycji wymiany

Z funus.net

Jak zaszyfrować partycję wymiany (swap) pod Linuksem? Oczywiście metod jest wiele, w tym najbardziej oczywista: szyfrowanie całego dysku. Załóżmy jednak, że chcemy ograniczyć się tylko do szyfrowania swapa.

Dlaczego? System przerzuca do swapa dane nie mieszczące się w pamięci operacyjnej. Mogą się więc tam znaleźć wpisywane przez nas hasła czy inne wrażliwe informacje, wprowadzane do różnych programów, jak choćby przeglądarki WWW. Dane raz przeniesione z pamięci na dysk pozostają tam zwykle do czasu, aż zostaną nadpisane czymś innym, a nigdy nie wiadomo, kiedy to nastąpi. Domyślnie partycje (czy pliki) używane jako swap nie są w żaden sposób zamazywane, gdy nie są już potrzebne. Jeśli się więc zdarzy, że dysk wpadnie w niepowołane ręce, ktoś przeszukawszy swap mógłby odnaleźć np. nasze hasła do serwisów bankowych bądź inne informacje, których znaleźć nie powinien. (Inna sprawa to zwykłe pliki trzymane na takim dysku – tu przydaje się szyfrowanie katalogu domowego bądź całego dysku).

Częściowym rozwiązaniem tego problemu może być nadpisanie partycji swap podczas procesu zamykania systemu. Można w tym celu zmodyfikować odpowiednie skrypty systemowe (w przypadku Debiana będzie to /etc/init.d/umountfs) i po dezaktywacji swapa zamazać go np. programem shred. Takie podejście nie sprawdzi się jednak, gdy system nie zostanie poprawnie zamknięty (np. z powodu awarii zasilania). Lepszym, choć trudniejszym wyjściem, będzie więc zastosowanie szyfrowania.

Czym zaszyfrować? EncFS i CFS do szyfrowania partycji się nie nadają, więc trzeba poszukać czegoś innego, np. TrueCrypta bądź loop-aes. Na Wikipedii znajduje się zestawienie programów do szyfrowania dysków (wikipedia:Comparison of disk encryption software), można spróbować wybrać coś stamtąd. Ja postanowiłem zapoznać się z cryptsetupem i LUKS-em, które działają w oparciu o dm-crypt, wchodzący w skład infrastruktury device mappera. Zaletą jest brak konieczności wprowadzania do jądra jakichś niestandardowych modułów.

Spis treści

[edytuj] Składniki

  • W miarę współczesny Linux z jądrem 2.6 (np. Debian 4)
  • działający device mapper
  • oprogramowanie: cryptsetup, hashalot

W moim przypadku sprowadziło się to do wydania polecenia:

aptitude install cryptsetup hashalot

[edytuj] Cele

  • Oczywiście partycje swap mają być zaszyfrowane
  • Szyfrowanie powinno odbywać się przy pomocy klucza jednorazowego, którego nie trzeba będzie przechowywać nigdzie na dysku
  • Proces powinien dać się zautomatyzować tak, by nie wymagał interakcji z użytkownikiem podczas startu systemu

[edytuj] Koszty

  • Spadek wydajności przy korzystaniu ze swapa – szyfrowanie kosztuje
  • Przy banalnym podejściu tu zastosowanym można się pożegnać z hibernacją (suspend-to-disk), ale mi to akurat specjalnie nie przeszkadza

[edytuj] Jak

Uwaga: jeśli nie wiesz, o co tu chodzi, nie rób tego; w przeciwnym wypadku możesz uszkodzić system lub skasować swoje bezcenne dane.

1. Sprawdź, która partycja (bądź partycje) są używane jako swap. Można to zrobić na kilka sposobów, np.:

swapon -s

W moim przypadku są to dwie partycje: /dev/sda2 i /dev/hda5 i do nich będę się odnosić w dalszym tekście.

2. Zdezaktywuj swap (oczywiście lepiej tego nie robić, gdy jest on intensywnie używany – system będzie próbował upchać dane ze swapa do pamięci, co niekoniecznie musi się zakończyć powodzeniem).

swapoff -av

Powinieneś też usunąć z odpowiednich plików konfiguracyjnych wpisy, powodujące używanie tych partycji jako swap. Najprawdopodobniej będą one wymienione w /etc/fstab.

3. Opcjonalnie zobacz sobie, co się kryje w twoim swapie, np.:

strings /dev/sda2 | less

i spróbuj odszukać swoje hasła :-) pamiętając o późniejszym usunięciu pliku historii polecenia less (shred ~/.lesshst).

4. Oczyść partycje swap z danych, które się na nich znajdują:

shred -n1 /dev/sda2
shred -n1 /dev/hda5

5. Opcjonalnie: ponownie oznacz je jako partycje swap:

mkswap /dev/sda2
mkswap /dev/hda5

Nie jest to konieczne, bo nie będziemy ich używać bezpośrednio jako swapa. Zauważyłem jednak, że sygnatura taka nie koliduje ze strukturami cryptsetupa/luksa, a może się przydać do weryfikacji, czy operujemy na właściwej partycji, gdy całość będziemy chcieli zautomatyzować.

6. Przygotuj plik-klucz, który będzie używany do szyfrowania swapa. Ja mam dwie partycje swap, więc zrobię sobie dwa klucze.

umask 077
dd if=/dev/urandom of=/dev/shm/swapkey-1 bs=1 count=64
dd if=/dev/urandom of=/dev/shm/swapkey-2 bs=1 count=64

Umieszczam te pliki w katalogu /dev/shm/, który powinien być ramdyskiem (tmpfs), żeby nie zostawić trwałych śladów na dysku.

Nie wiem jeszcze, jak stosowanie klucza zamiast hasła i długość tego klucza wpływa na siłę szyfrowania przez cryptsetup/luks/dm-setup. Na razie optymistycznie zakładam, że 64-bajtowy plik z /dev/urandom będzie nie gorszy niż solidne, 20-znakowe hasło.

7. Sformatuj partycje do użycia z cryptsetupem/luksem:

cryptsetup luksFormat /dev/sda2 /dev/shm/swapkey-1
cryptsetup luksFormat /dev/hda5 /dev/shm/swapkey-2

8. Otwórz zaszyfrowane partycje:

cryptsetup --key-file=/dev/shm/swapkey-1 luksOpen /dev/sda2 swap-1
cryptsetup --key-file=/dev/shm/swapkey-2 luksOpen /dev/hda5 swap-2

Jeśli wszystko poszło poprawnie, powinny pojawić się dwa nowe urządzenia zarządzane przez devmappera: /dev/mapper/swap-1 i /dev/mapper/swap-2.

9. Pliki-klucze nie będą już potrzebne, więc się ich pozbądź:

shred /dev/shm/swapkey-[12]

10. Oznacz partycje jako swap:

mkswap /dev/mapper/swap-1
mkswap /dev/mapper/swap-2

11. Aktywuj swapowanie:

swapon -v /dev/mapper/swap-[12]

I gotowe. Pozostaje jeszcze zautomatyzowanie tych czynności poprzez zrobienie jakiegoś skryptu startowego. Warto zachować ostrożność (odpowiednie sprawdzenia w takim skrypcie), żeby sobie przypadkowo nie zepsuć czegoś np. po zmianie układu bądź przeznaczenia partycji na dysku.

[edytuj] Odmontowanie

Żeby odmontować zaszyfrowane partycje należy:

  • dezaktywować swap
    swapoff -va
  • odmapować partycje:
    cryptsetup luksClose swap-1
    cryptsetup luksClose swap-2

[edytuj] Prościej

To była metoda "ręczna". Ale można to zrobić prościej, pod warunkiem, że twórcy naszej dystrybucji o tym pomyśleli. Tak jest np. w Debianiie: po instalacji pakietu cryptsetup pojawia się plik /etc/crypttab, w którym można zdefiniować szyfrowane partycje. Będą one zamapowane przez skrypt startowy /etc/init.d/cryptdisks.

Tym razem użyję cryptsetup bez rozszerzenia LUKS, co pozwoli w wygodny sposób podać bezpośrednio /dev/urandom (bądź /dev/random) jako plik-klucz. Moje partycje swap to /dev/sda2 i /dev/hda5, więc w pliku /etc/crypttab wpisuję:

swap-1      /dev/sda2               /dev/urandom     swap
swap-2      /dev/hda5               /dev/urandom     swap

To oznacza, że podczas startowania systemu zostaną utworzone dwa urządzenia devmappera: swap-1 (oparty na partycji /dev/sda2) i swap-2 (na /dev/hda5). Plik-klucz dla każdego z nich to /dev/random, czyli klucz będzie pseudolosowy. Opcja swap spowoduje, że oba urządzenia zostaną oznaczone jako swap (przez mkswap).

Teraz w /etc/fstab należy umieścić wpisy dla urządzeń swap-1 i swap-2:

/dev/mapper/swap-1  none  swap  sw,pri=2
/dev/mapper/swap-2  none  swap  sw,pri=2

Niestety, może tu wystąpić problem z kwestią (pseudo)losowości kluczy. /dev/random dostarcza liczby pseudolosowe generowane na podstawie "szumu środowiska" - klawiatura, mysz, dyski, karta sieciowa itp. Podczas pracy interaktywnej ma to sens, jednak gdy system startuje, nie ma raczej interakcji z użytkownikiem i ta "losowość" może być całkiem przewidywalna. Można zastosować /dev/urandom, którego pula entropii jest w rozmaitych dystrybucjach Linuksa zachowywana podczas zamykania systemu i odtwarzana przy następnym restarcie. Ale np. w Debianie 4 zrobili to tak, że inicjalizacja szyfrowanych partycji zapisanych w /etc/crypttab odbywa się dużo wcześniej, niż zainicjalizowanie generatora liczb pseudolosowych. Dlatego prawdopodobnie w tym przypadku klucze będą raczej kiepskiej jakości. Trzeba będzie coś z tym zrobić...

[edytuj] Zobacz też