Szyfrowanie partycji wymiany
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ć...