styczeń 2004
30
bezpieczeństwo
Loop-AES – szyfrowane
systemy plików
Skarbimir Kwiatkowski
K
ażdy, kto uzyska nieautoryzowany dostęp do
komputera, zwłaszcza fizyczny, jest w stanie
poznać wszystkie tajemnice powierzone jego
dyskom twardym. Jak wobec tego zabezpie-
czyć się przed ujawnieniem poufnych danych firmy lub
prywatnych sekretów, np. w przypadku kradzieży notebo-
oka albo gdy dostęp do komputera mają osoby trzecie? Jest
na to rada.
Linux oferuje wiele mechanizmów ochrony danych
opartych na silnej kryptografii. Otwartość źródeł stanowi
gwarancję, że nikt nie zostawił w nich otwartej tylnej furtki.
To ważna zaleta. Nie bez znaczenia jest też możliwość
dostosowania konfiguracji do potrzeb użytkownika w stop-
niu znacznie większym niż w przypadku – często niezbyt
elastycznych – produktów komercyjnych.
W dalszej części artykułu przedstawię kilka modelo-
wych rozwiązań opartych na jednym z najwygodniejszych
narzędzi kryptograficznych w Linuksie – module jądra Loop-
AES z wbudowaną obsługą szyfrowania. W odróżnieniu od
takich programów, jak gpg, mcrypt lub ccat, nadających
się do szyfrowania pojedynczych plików lub archiwów,
Loop-AES pozwala na wygodne szyfrowanie dużych porcji
danych, np. całych partycji (zarówno podstawowych, jak
i logicznych) lub systemów plików utworzonych w zwy-
kłych plikach o niemal dowolnej wielkości. Dostęp do nich
uzyskujemy po wymagającym autoryzacji montowaniu za
pośrednictwem urządzenia loop. Do innych użytecznych
zastosowań modułu Loop-AES należą szyfrowanie partycji
wymiany (swap) oraz korzystanie z zabezpieczonych kryp-
tograficznie płyt CD.
Niewątpliwym atutem tego modułu jest stosunkowo
duża elastyczność i przenośność. Możemy go użyć w sys-
temach z jądrem z serii 2.0, 2.2, 2.4 oraz – choć czasami
nie bez kłopotów – 2.6. Nie ma przy tym znaczenia, czy
korzystamy z jądra dystybucyjnego czy samodzielnie zbu-
dowanego. Loop-AES nie wymaga także nakładania łat na
źródła jądra. Gdy obsługa urządzenia blokowego loopback
nie została wkompilowana w jądro lub sterownik tego urzą-
dzenia został umieszczony w module, obejdzie się nawet
bez jego rekonfiguracji i rekompilacji.
Praca z szyfrowanym systemem
plików
Z punktu widzenia użytkownika, praca z zaszyfrowanym
systemem plików – jeśli pominąć czynności związane z jego
przygotowaniem i montowaniem – nie różni się niczym od
pracy na zwykłej, niezabezpieczonej partycji. Proces szyfro-
wania danych jest "przezroczysty", odbywa się na poziomie
jądra i nie wymaga wykonywania dodatkowych czynno-
ści czy stosowania specjalnych narzędzi. Możemy więc
tworzyć lub usuwać katalogi i pliki przy użyciu zwykłych
poleceń systemowych (touch, mkdir, rm itp.), zapisywać
w nich dowolne dane, przenosić je z innych, niezaszyfrowa-
nych partycji za pomocą standarowego polecenia cp albo
między panelami ulubionego menedżera plików. Dopiero
próba "podejrzenia" zawartości zabezpieczonej partycji po
odmontowaniu uświadomi nam, że wszystko to, co na niej
zapisaliśmy, prezentuje się jako zupełnie nieczytelny gąszcz
przypadkowych znaków.
O autorze:
Autor pracuje w Zakładzie Logiki i Semiotyki Uniwersytetu
Mikołaja Kopernika w Toruniu. Od kilku lat wykorzystuje
Linuksa, FreeBSD i Solaris w działalności zawodowej i poza-
zawodowej. Kontakt z autorem: autorzy@linux.com.pl.
Rysunek 1.
Strona NIST poświęcona AES
31
www.linux.com.pl
loop-aes
Co i jak szyfrować?
Zanim wybierzemy konkretny model zastosowania Loop-
AES, warto zastanowić się – biorąc pod uwagę różne
istotne okoliczności – nad szczegółami rozwiązania.
Jakie dane naprawdę potrzebują ochrony? Czy posiadamy
wolną część dysku, którą możemy przeznaczyć na party-
cję szyfrowaną, czy raczej zależy nam na zabezpieczeniu
partycji już istniejących i wykorzystywanych? Czy chcemy
mieć możliwość łatwego usuwania lub przenoszenia
całości zaszyfrowanych danych, np. na płytach CD? Czy
korzystamy z tej maszyny sami, czy wspólnie z innymi?
Ile spośród tych osób ma mieć dostęp do wrażliwych
danych? Czy wygodniej i bezpieczniej będzie podzielić
je na części dostępne z osobna dla każdego uprawnione-
go, czy może użyć wspólnej partycji chronionej hasłem
dostępu albo kluczami GnuPG ? Czy potrzebujemy szyfro-
wanej partycji wymiany?
Ochrona prywatności lub tajemnic firmy jest ważna,
ale starajmy się nie popadać w paranoję. Uczestnicy grup
dyskusyjnych czasem pytają: “czy mogę zaszyfrować całe
drzewo katalogów?”. Oczywiście można to zrobić, pyta-
nie tylko, czy rzeczywiście warto. Poufne dane zajmują na
ogół tylko pewną część dysku, reszta to m.in. powszech-
nie używane programy, których źródła są publicznie
dostępne. Szyfrując wszystko bez wyboru, najprawdopo-
dobniej zużyjemy niepotrzebnie część mocy obliczenio-
wej maszyny i przysporzymy sobie kłopotów związanych
z rekompilacją jądra, modyfikacją trybu uruchamiania
systemu itp. Z tego powodu odradzam ten pomysł. Uparci
eksperymentatorzy znajdą precyzyjną instrukcję w doku-
mentacji modułu Loop-AES.
Przygotowanie narzędzi
Przed rozpoczęciem pracy z szyfrowanymi systemami
plików, musimy zaopatrzyć się w pliki źródłowe, które
posłużą do zbudowania niezbędnych binariów:
• źródła modułu Loop-AES (loop-AES-latest.tar.bz2);
Warto również zaopatrzyć się w Ciphers (ciphers-
latest.tar.bz2), zawierające źródła dodatkowych modu-
łów kryptograficznych, współpracujących z Loop-AES
(loop_serpent.o, loop_twofish.o i loop_blowfish.o),
oraz źródła pomocniczego narzędzia Aespipe (aespi-
pe-latest.tar.bz2), służącego do szyfrowania danych
w potoku (pipe). Ten ostatni program przyda się
nam, gdy będziemy chcieli zaszyfrować już istniejącą
i wykorzystywaną partycję, na której przechowujemy
pliki wymagające ochrony. Aespipe i Ciphers stanowią
część tego samego projektu Loop-AES.
• źródła zestawu narzędzi Util-linux (util-linux-2.12pre.
tar.bz2);
Programy mount, umount, losetup, swapon, swapoff
muszą mieć zaimplementowaną obsługę kryptograficz-
ną, więc użyjemy odpowiednio połatanej wersji.
• źródła jądra lub co najmniej jego pliki nagłówkowe (w
wielu dystrybucjach dostępne w osobnych pakietach),
pliki nagłówkowe biblioteki glibc oraz kompilator
języka C (gcc).
AES
Moduł Loop-AES, autorstwa Fina Jariego Ruusu, implementuje
symetryczny szyfr blokowy Rijndael, który w 2000 r. został
wyłoniony w konkursie ogłoszonym przez National Institute of
Standards and Technology (NIST) jako nowy standard zaawan-
sowanej kryptografii. Z tego powodu Rijndael zwany jest najczę-
ściej po prostu AES (Advanced Encryption Standard).
Zwycięzca konkursu zastąpił wysłużony, zbyt powolny
i nie dość bezpieczny algorytm DES. Oprócz kryteriów tech-
nicznych, AES musiał spełnić warunki publicznej dostępności
specyfikacji, braku ograniczeń natury patentowo-licencyjnej
oraz zapewnić wysoką wydajność. W finałowej piątce, prócz
opracowanego przez Belgów Joana Daemena i Vincenta Rijme-
na algorytmu Rijndael, znalazły się również algorytmy Serpent
i Twofish, stosowane w dodatkowych modułach z projektu
Loop-AES.
Algorytm AES użyty w module loop przetwarza niezaszyfro-
wany tekst na tekst zaszyfrowany o tej samej długości. Dane
szyfrowane są 128-, 192- lub 256-bitowym kluczem w 128-
bitowych blokach, co zapewnia bardzo silne rozproszenie,
a tym samym skuteczną ochronę przed rozszyfrowaniem (Ry-
sunek 2). Szyfrowanie bloków odbywa się w trybie CBC (Cipher
Block Chaining), a jako klucz służy skrót hasła podanego przez
użytkownika, obliczany funkcją skrótu SHA-256, SHA-384 lub
SHA-512.
Jak dotąd, nie są znane przypadki złamania AES. Atak
„siłowy”, polegający na sprawdzaniu wszystkich kluczy, jest
przy obecnych mocach obliczeniowych komputerów nieefek-
tywny, a możliwość ataku algebraicznego – dającego szansę
otrzymania rezultatów w rozsądnym czasie – stanowi w tej
chwili zaledwie przedmiot kontrowersji wśród specjalistów.
Zainteresowanym szczegółami polecam stronę domową
projektu Rijndael, a także stronę NIST, poświęconą tematyce
AES.
Rysunek 2.
Schemat działania algorytmu AES
styczeń 2004
32
bezpieczeństwo
Przede wszystkim powinniśmy sprawdzić, czy używane
jądro systemu spełnia wspomniany wcześniej warunek, t.j.
nie posiada statycznie wkompilowanego urządzenia loop.
Jeśli konfigurowaliśmy je i kompilowaliśmy wcześniej,
wystarczy zajrzeć do pliku .config w katalogu ze źródłami.
Standardowe wersje jądra domyślnie nie włączają obsługi
loopback.
Jeżeli używamy jądra z dystrybucyjnego pakietu,
możemy poszukać jego konfiguracji (np. Debian umieszcza
stosowny plik z numerem jądra w katalogu /boot) albo po
prostu spróbować załadować moduł loop i/lub zamontować
obraz dowolnej płyty CD z danymi.
Gdy wykonamy polecenie
grep CONFIG_BLK_DEV_LOOP
/usr/src/linux/.config
, odpowiedź "CONFIG_BLK_DEV_
LOOP is not set " oznacza, że możemy od razu zająć się
utworzeniem nowego modułu.
Gdy w konfiguracji znajdziemy "CONFIG_BLK_DEV_
LOOP=y", to niestety będzie potrzebne nowe jądro syste-
mu. Po wydaniu polecenia
make menuconfig
, w katalogu
zawierającym źródła, w sekcji "Block devices" wyłączamy
opcję "Loopback device support ". W sekcji "Loadable module
support " zaznaczamy "Enable loadable module support ",
a dla wygody, choć nie jest to konieczne, "Kernel module
loader " ("CONFIG_KMOD=y").
W przypadku, gdy jądro zostało wyposażone w ładowal-
ny moduł loop ("CONFIG_BLK_DEV_LOOP=m"), a z jakichś
powodów nie chcemy budować nowego jądra, możemy
spróbować obejść kłopot w mało elegancki, lecz skuteczny
sposób. Usuwamy lub kopiujemy w bezpieczne miejsce
istniejący moduł /lib/modules/`uname -r`/kernel/drivers/
block/loop.o, a następnie wydajemy polecenie
depmod -a
.
Powinno to umożliwić instalację Loop-AES.
Czas zbudować moduł. O ile pliki nagłówkowe jądra
są zlokalizowane w typowym miejscu (/lib/modules/
`uname -r`/build, /usr/src/linux, /usr/src/linux-`uname
-r` lub /usr/src/kernel-source `uname -r`), to po rozpa-
kowaniu archiwum wystarczy ograniczyć się do wyko-
nania polecenia
make
i zaktualizowania listy dostępnych
modułów:
tar jxvf loop-AES-latest.tar.bz2
cd loop-AES-v1.7e
su
make && depmod -a
Jeśli lokalizacja źródeł jest inna, to komenda
make
wymaga
podania ścieżki do odpowiedniego katalogu:
make
LINUX_SOURCE=/sciezka/do/katalogu/ze/zrodlami/jadra
.
W katalogu /lib/modules/`uname -r` znajdziemy teraz nowy
podkatalog block, a w nim nowy plik loop.o.
Aby dodać moduły loop_serpent.o, loop_blowfish.o
i loop_twofish.o, w analogiczny sposób postępujemy
z archiwum ciphers-latest.tar.bz2. Zyskamy w ten sposób
dodatkowe silne algorytmy Serpent, Blowfish i Twofish.
Każdy z nich może być używany z kluczem 128-, 192-
i 256-bitowym, a ponadto ostatni występuje również
w postaci Twofish160.
Teraz przystępujemy do przygotowania narzędzi, które
pozwolą nam w pełni korzystać z nowego modułu (lub
modułów). Będziemy potrzebowali zmodyfikowanych pro-
gramów mount, umount i losetup, a także – jeśli planujemy
używać szyfrowanej partycji wymiany – swapon i swapoff.
Odpowiednia łata dołączona jest do archiwum loop-
AES-latest.tar.bz2. W naszym przypadku jest to plik util-
linux2.12pre.diff. Przed instalacją warto zadbać o kopie
zapasowe. Możemy również, jeżeli np. zamierzamy ograni-
czyć się jedynie do testów, umieścić zbudowane programy
w innym katalogu. Pamiętajmy jednak, że skrypty startowe
systemu, o ile ich nie zmodyfikujemy, będą korzystały ze
starych wersji. Typową procedurę kompilacji i instalacji
potrzebnych narzędzi przedstawia Listing 1.
Szyfrowanie partycji
Wreszcie nadeszła pora, aby wypróbować przygotowa-
ne oprogramowanie! Na początek przedstawię przykład
najbardziej oczywisty, a przy tym prosty. Wolną partycję
chcemy przeznaczyć na szyfrowane dane. Przyjmuję, że
partycja została już wcześniej założona, np. fdiskiem.
W pierwszym kroku przyłączamy partycję do urzą-
dzenia loop. Za pomocą flagi
-e
określamy szyfr (zamiast
AES256 może to być np. AES128 czy AES192, a jeśli zbu-
dowaliśmy moduły z Ciphers, także np. serpent128 czy
twofish256 ). Nie musimy własnoręcznie ładować modułu
loop, gdyż zadba o to jądro systemu, o ile podczas kon-
figuracji zaznaczyliśmy "CONFIG_KMOD=y ". Natomiast
Rysunek 3.
Strona domowa projektu Loop-AES na serwerze
SourceForge
33
www.linux.com.pl
loop-aes
moduły loop_serpent czy loop_twofish powinniśmy
w razie potrzeby załadować poleceniem
modprobe
lub
insmod
. Flaga
-T
informuje program, że ma dwukrotnie
pytać o hasło. Polecenie wygląda więc tak:
losetup -e AES256 -T /dev/loopX /dev/hdaN
Tu i w dalszej części artykułu X oznacza numer urządzenia
loop, a N – numer partycji. Osoby używające devfs powinny
odpowiednio dostosować polecenia, wpisując
/dev/loop/0
,
/dev/loop/7
itp. Dodajmy, że domyślna liczba urządzeń
loop w systemie wynosi osiem. W razie potrzeby możemy
zwiększyć ją za pomocą mknod nawet do 256.
Program losetup nie pozwoli na użycie hasła krótszego
niż dwadzieścia znaków. To dużo, ale wybierzmy je sta-
rannie, tak aby maksymalnie utrudnić ewentualny atak
słownikowy.
Zakładamy na partycji system plików ext2 (z pewnymi
ograniczeniami może to być również system plików z księ-
gowaniem, np. ext3; w sprawie szczegółów odsyłam do
dokumentacji). Zwróćmy uwagę, że w tej operacji pośred-
niczy loop, dlatego jako argument polecenia podajemy
/dev/loopX. Jeśli wszystko przebiegło poprawnie, odłącza-
my urządzenie i zakładamy katalog, który posłuży nam do
montowania partycji. Opisane polecenia wyglądają tak:
mkfs -t ext2 /dev/loopX
losetup -d /dev/loopX
mkdir /mnt/crypto
Możemy teraz zamontować partycję:
mount -t ext2 /dev/hdaN /mnt/crypto
S
-o loop=/dev/loopX,encryption=AES256
Zamiast
loop =/dev/loopX
wystarczy podać po prostu
loop
. System sam wybierze wolne urządzenie. Polecenie
mount
bez opcji powinno nam teraz pokazać m.in. coś
takiego:
/dev/hda7 on /mnt/crypto type ext2
S
(rw,loop=/dev/loop0,encryption=AES256)
Jeśli wolimy oszczędzić sobie wpisywania za każdym razem
długiej komendy, powinniśmy dopisać do /etc/fstab:
/dev/hdaN /mnt/crypto ext2 defaults,noauto,
S
loop=/dev/loopX,encryption=AES256 0 0
Listing 1.
Kompilacja i instalacja narzędzi z Util-linux
$ tar jxvf util-linux-2.12pre.tar.bz2
$ cd util-linux-2.12pre
$ patch -p1 <../loop-AES-v1.7e/util-linux-2.12pre.diff
$ CFLAGS=-O2 ./configure
$ make SUBDIRS="lib mount"
$ cd mount
$ strip -s mount umount losetup swapon
$ su
# for prog in `which mount umount losetup swapon
S
swapoff`
> do echo "Tworzę kopię zapasową $prog.sav"
> cp -p $prog $prog.sav
> done
# install -m 4755 -o root mount umount /bin
# install -m 755 losetup swapon /sbin
# rm -f /sbin/swapoff && ( cd /sbin && ln -s
S
swapon swapoff )
# for item in /usr/share/man/man8/{mount,umount,
S
losetup,swapon,swapoff}.8.gz \
> /usr/share/man/man5/fstab.5.gz
> do echo "Tworzę kopię zapasową $item"
> mv $item $item.sav
# install -m 644 mount.8 umount.8 losetup.8 swapon.8 \
> swapoff.8 /usr/share/man/man8
# install -m 644 fstab.5 /usr/share/man/man5
# mandb
Rysunek 4.
Zabezpieczenie dostępu do klucza AES szyfrem niesymetrycznym przy pomocy GnuPG
styczeń 2004
34
bezpieczeństwo
Nie potrzeba niczego więcej. To już działa! Choć tego
w ogóle nie dostrzegamy, pliki zapisane w katalogu /mnt/
crypto są szyfrowane i po odmontowaniu partycji będą nie-
dostępne dla niepowołanych oczu.
Gdyby zależało nam na wzmocnieniu ochrony party-
cji przed atakiem słownikowym, moglibyśmy dodatkowo
użyć losowo wygenerowanego zarodka hasła oraz podać
liczbę powtórzeń klucza (flagi
-S
i
-C
programu
losetup
).
Zarodek jest dodawany do wpisanego przez administra-
tora hasła, zanim zostanie ono potraktowane nieodwra-
calną funkcją haszującą (f. skrótu), natomiast na skutek
podania po fladze
-C
liczby N, utworzony skrót hasła szy-
frowany jest N tysięcy razy przy użyciu algorytmu AES-
256. Zabiegi te są dość skutecznym sposobem znacznego
spowolnienia ataku.
Losowy zarodek hasła możemy wybrać używając przy-
kładowo takiej kombinacji poleceń:
head -c 15 /dev/urandom | uuencode -m - |
S
awk 'NR == 2 {print}
Powinniśmy otrzymać coś w rodzaju:
8bqMfh75PZnMu+wwjy-
Vq
. Oczywiście za każdym razem ten ciąg będzie inny. Wyj-
ściowe polecenie
losetup
, od którego zaczęliśmy procedurę
szyfrowania partycji, wyglądałoby zatem tak:
losetup -e AES256 -T -S 8bqMfh75PZnMu+wwjyVq
S
-C 100 /dev/loopX /dev/hdaN
a do fstab wpisalibyśmy w takim przypadku:
/dev/hdaN /mnt/crypto ext2 defaults,noauto,
S
loop=/dev/loopX,encryption=AES256,itercountk=100,
S
pseed=8bqMfh75PZnMu+wwjyVq 0 0
Plik jak partycja
Zdarza się, że cały dysk jest już podzielony na sforma-
towane partycje, z których korzystamy, a wygospodaro-
wanie wolnej części wymagałoby dużo starań. W takim
przypadku nic nie stoi na przeszkodzie, abyśmy utworzy-
li zaszyfrowaną strukturę katalogów w zwykłym pliku,
który jak wiadomo, w Linuksie może „udawać” urządze-
nie blokowe, takie jak partycja na dysku twardym. Roz-
wiązanie to ma i tę dobrą stronę, że plik można w razie
potrzeby przenieść w inne miejsce na dysku albo nagrać
na płytę CD.
Tworzymy zatem plik o wielkości np. 700 MB,
a następnie poleceniem
losetup
podłączamy go do urzą-
dzenia loop - dzięki czemu będzie on traktowany jak
partycja – i wybieramy hasło. W dalszej kolejności forma-
tujemy go, tworząc strukturę systemu plików ext2. Jako
źródło, z którego czyta program
dd
, moglibyśmy wykorzy-
stać /dev/zero, ale lepiej użyć /dev/urandom –
dd
zapisze
wtedy cały plik losowo wybranymi znakami, co spowo-
duje, że podglądając plik, nie będzie można zorientować
się, w którym miejscu zaczynają się i kończą zaszyfrowane
dane. Ostatecznie wygląda to tak:
dd if=/dev/urandom of=/jakis_katalog/crypto_file bs=4k
S
count=179200
losetup -e AES256 -T /dev/loopX /jakis_katalog/crypto_file
mkfs -t ext2 /dev/loopX
Oczywiście i tu znalazłyby zastosowanie flagi
-S
i
-C
pro-
gramu
losetup
(zarodek hasła i liczba iteracji). Pominąłem
je, aby nie komplikować przykładów.
Na koniec zakładamy katalog, którego będziemy
używać podczas montowania i ewentualnie dodajemy do
/etc/fstab odpowiedni wpis:
/jakis_katalog/crypto_file /mnt/crypto ext2 defaults,
S
noauto,loop,encryption=AES256 0 0
Jeśli chcemy umożliwić zwykłym użytkownikom (znającym
hasło) montowanie szyfrowanego systemu plików, dopisu-
jemy ponadto do opcji montowania
user
. To samo dotyczy
poprzedniego przypadku szyfrowanej partycji.
Z kluczem GnuPG na dyskietce
Dostęp do szyfrowanego systemu plików możemy zabez-
pieczyć dodatkowo kluczem GnuPG. Ideę tę przedstawia
poglądowo Rysunek 4. Nie ma większego znaczenia, czy
Listing 2.
Przykładowy plik /etc/fstab z wpisami
dotyczącymi montowania szyfrowanych systemów plików
# /etc/fstab: statyczna informacja o systemach plików.
# <system plikow><punkt montowania><typ><opcje> <dump>
<pass>
/dev/hda2 / ext3 errors=remount-ro 0 1
# szyfrowany swap
/dev/hda5 none swap sw,
S
loop=/dev/loop0,encryption=AES256 0 0
proc /proc proc defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
/dev/hda6 /usr ext3 defaults 0 0
/dev/hda7 /home reiserfs defaults 0 0
/dev/hda8 /scratch reiserfs defaults 0 0
/dev/fd0 /floppy auto user,noauto 0 0
/dev/cdrom /cdrom iso9660 ro,user,exec,noauto,
S
iocharset=iso8859-2 0 0
/dev/scd1/mnt/cdrw iso9660 ro,user,noauto,
S
iocharset=iso8859-2 0 0
# szyfrowane urządzenia
/dev/hda4 /mnt/crypto1 ext2 defaults,noauto,
S
loop=/dev/loop1,encryption=AES256,
S
gpgkey=/floppy/moj_klucz.gpg,gpghome=/floppy 0 0
/dev/hda9 /mnt/crypto2 ext2 defaults,user,
S
noauto,encryption=AES256,loop=/dev/loop2,
S
gpgkey=/etc/kluczepub-crypto.gpg 0 0
/home/self/crypto_fs /mnt/crypto3 ext2 defaults,
S
noauto,user,loop,encryption=AES256 0 0
35
www.linux.com.pl
loop-aes
system plików zostanie utworzony według przedstawio-
nej przed chwilą recepty w dużym pliku, czy na fizycznej
partycji.
Powinniśmy posłużyć się dyskietką z systemem plików
pozwalającym ustalać prawa dostępu, np. ext2. Jeżeli użyje-
my dyskietki „dosowej”,
gpg
będzie zgłaszał błąd.
Zaczynamy od zamontowania dyskietki i generujemy
parę kluczy GnuPG, chyba że skorzystamy z już posiada-
nych:
mount /dev/fd0 /floppy
gpg --gen-key --homedir /floppy
Połączenie komend
head
,
uuencode
i
awk
pozwoli utworzyć
odpowiednio długi, losowy ciąg znaków, który posłuży
do szyfrowania systemu plików. Otrzymane w ten sposób
hasło zabezpieczamy szyfrem niesymetrycznym przy
pomocy
gpg
i zapisujemy na dyskietce:
head -c 45 /dev/random | uuencode -m - | awk 'NR == 2
S
{print}' | \
gpg --homedir /floppy -e -a -r "Imię Nazwisko" >
S
/floppy/moj_klucz.gpg
Do /etc/fstab dopisujemy poniższy wiersz:
/
dev/hdaN /mnt/crypto1 ext2 defaults,noauto,
S
loop=/dev/loopX,encryption=AES256,
S
gpgkey=/floppy/moj_klucz.gpg,gpghome=/floppy 0 0
W przypadku szyfrowania pliku, a nie partycji, pierwszy
człon należy zastąpić jego nazwą. Kolejne polecenia są
następujące:
losetup -F /dev/loopX
mkfs -t ext2 /dev/loopX
losetup -d /dev/loopX
Flaga
-F
powoduje, że losetup pobiera opcje z /etc/fstab.
Drugą komendą formatujemy urządzenie i po poprawnym
zakończeniu tej operacji, resetujemy je.
O ile tylko istnieje docelowy katalog, możemy już
zamontować system plików poleceniem
mount /mnt/crypto
.
Oczywiście, każda kolejna próba musi być poprzedzona
umieszczeniem dyskietki w napędzie i jej poprawnym
zamontowaniem. Należy jej strzec, gdyż zgubienie albo
zniszczenie kluczy uniemożliwi raz na zawsze dostęp do
zaszyfrowanych plików. Z tego względu rozsądniejsze jest
skopiowanie niezbędnych plików na trwalszy niż dyskietka
nośnik i odpowiednia modyfikacja ścieżek dostępu w /etc/
fstab.
Wielu użytkowników, wiele kluczy
GnuPG
Teraz zajmiemy się bardziej skomplikowanym rozwiąza-
niem. Przygotujemy szyfrowaną partycję (lub plik pełniący
funkcję urządzenia blokowego), do której użytkownicy
wskazani przez administratora otrzymają dostęp na pod-
stawie pary kluczy GnuPG. Każdy z nich będzie korzystał
z własnych kluczy i, co za tym idzie, własnego hasła.
Administrator (root) musi mieć wygenerowaną parę
kluczy GnuPG i dysponować kluczami publicznymi użyt-
kowników, którym chce przekazać prawo montowania.
Sprawdzamy to komendą
gpg –list-public-keys
. Jeśli na
liście brak jest którejś z tych osób, pomocne będzie pole-
cenie
gpg --import plik_z_kluczem
. Prawa odczytu two-
rzonych plików najlepiej ograniczyć zmieniając domyślne
ustawienia powłoki poleceniem
umask 077
. Kolejne polece-
nia wyglądają następująco:
head -c 45 /dev/random | uuencode -m - | awk 'NR == 2
S
{print}' | gpg -e -a -r "Charlie Root" >
S
/root/masterkey-crypto.gpg
losetup -e AES256 -K /root/masterkey-crypto.gpg
S
/dev/loopX /dev/hdaN
mkfs -t ext2 /dev/loopX
losetup -d /dev/loopX
Co zrobiliśmy? Czytelnik zapewne domyśla się, że pierwsza
linia ma na celu otrzymanie losowego ciągu znaków oraz
zaszyfrowanie go przy pomocy klucza GnuPG należącego
do administratora. Wynik zapisywany jest w pliku /root/
masterkey-crypto.gpg. Następnie przyłączamy partycję do
urządzenia /dev/loopX. Wybieramy przy tym algorytm szy-
frowania AES256, a flaga
-K
powoduje, że hasło pobierane
z pliku masterkey-crypto.gpg jest przekazywane do progra-
mu gpg w celu odszyfrowania przed użyciem. Formatujemy
partycję i odłączamy ją od urządzenia loopX.
Przechodzimy do /etc/fstab, dopisując:
/dev/hdaN /mnt/crypto2 ext2 defaults,user,noauto,
S
encryption=AES256,loop=/dev/loopX,
S
gpgkey=/etc/userkey-crypto.gpg 0 0
Na koniec deszyfrujemy hasło i szyfrujemy ponownie, tym
razem używając kluczy publicznych wybranych użytkow-
ników, a rezultat kierujemy do wymienionego w /etc/fstab
pliku userkey-crypto.gpg. Każde z nazwisk podajemy
w cudzysłowach następujących po fladze
-r
.
Dane te muszą zgadzać się z opisem kluczy. Wygląda
to tak:
gpg --decrypt < /root/masterkey-crypto.gpg |
S
gpg -e -a –always-trust -r "Charlie Root"
S
-r "Jas Kowalski" -r "Joanna Malinowska" >
S
/etc/userkey-crypto.gpg
Od tej chwili każdy z użytkowników wskazanych przez
administratora może montować partycję hdaN korzystając
z własnego klucza prywatnego i hasła GnuPG.
Aby zwiększyć bezpieczeństwo, należałoby jeszcze
skłonić użytkowników, aby nie przechowywali klucza pry-
styczeń 2004
36
bezpieczeństwo
watnego GnuPG na dysku tego komputera. W przeciwnym
przypadku ochrona będzie na tyle skuteczna, na ile hasła
okażą się odporne na atak. Niestety, w znacznym stopniu
zmniejsza to funkcjonalność tego rozwiązania.
Co z partycją wymiany?
Zagrożenie dla poufności danych i prywatności może
także pochodzić ze strony partycji wymiany, na której
system tymczasowo zapisuje dane. Jest bowiem prawdo-
podobne, że podczas pracy uprawnionego użytkownika,
gdy muszą być one dostępne w formie niezaszyfrowanej,
system odłoży je na partycji swap. Cały wysiłek włożony
w instalację i skrupulatne używanie zabezpieczeń krypto-
graficznych może wtedy łatwo pójść na marne, chyba że...
zaszyfrujemy także swap.
Moduł Loop-AES pozwala na to, o ile nasz system jest
wyposażony w jądro z serii 2.4 lub nowsze. Decydując się
na szyfrowanie partycji wymiany powinniśmy pamiętać, że
obarczenie systemu, zwłaszcza mocno obciążonego, opera-
cjami kryptograficznymi może zmniejszyć jego wydajność.
Najpierw wyłączamy aktywne partycje wymiany pole-
ceniem
swapoff -a
. Następnie modyfikujemy wpisy odno-
szące się do partycji wymiany w /etc/fstab:
/dev/hdaN none swap sw,loop=/dev/loopX,encryption=AES128 0 0
Ten prosty zabieg pozwala nam ponownie uaktywnić swap.
Robimy to poleceniem
swapon -a
, które przywracając jego
działanie użyje losowego klucza i wykona komendę
mkswap
na wskazanym urządzeniu loop.
Jeżeli podczas ponownego uruchomienia systemu poja-
wią się komunikaty o błędzie podobne do poniższego:
insmod: modprobe: cannot create /var/log/ksymoops/
20031012.log Read-only file system
insmod: /lib/modules/2.4.22-grsec/block/loop.o: cannot
create /var/log/ksymoops/20031012.log Read-only file system
to dzieje się tak dlatego, że system aktywujący partycję
wymiany jednocześnie ładuje moduł loop, a modprobe
próbuje zapisać informację o tym w logach, choć partycja,
na której się znajdują, nie została jeszcze zamontowana do
zapisu.
Autor dokumentacji modułu Loop-AES proponuje w celu
pozbycia się tego błędu usunąć katalog /var/log/ksymoops.
Bez tego katalogu modprobe nie podejmie próby logowania
komunikatu o ładowaniu modułu. Bardziej elegancki, choć
zapewne trudniejszy w realizacji, wydaje się pomysł mody-
fikacji skryptów startowych w taki sposób, aby partycja
wymiany była aktywowana nieco później, gdy możliwe już
będzie zapisywanie logów.
Istniejąca partycja z danymi
Niewykluczone, że w praktyce natkniemy się na dość
prozaiczny kłopot: planujemy zaszyfrować partycję,
z której już korzystamy i którą zdążyliśmy zapełnić
ważnymi danymi. Jak to zrobić nie tracąc danych? Jeżeli
reorganizacja dysku nie wchodzi w grę, a z jakichś
powodów nie chcemy jej zastępować dużym plikiem,
z pomocą przyjdzie nam program Aespipe, stanowiący
niewielki, lecz użyteczny dodatek do Loop-AES (do jego
kompilacji wystarczy triada poleceń
./configure ; make ;
make install
). Jak podpowiada nazwa, Aespipe potrafi
szyfrować dane pobierane na wejściu. Pomysł jego wyko-
rzystania w tym przypadku polega na odczytaniu zawar-
tości partycji za pomocą dd, zaszyfrowaniu "w locie" (to
właśnie rola Aespipe) i zapisaniu w tym samym miejscu
dysku.
Operacja jest nieco ryzykowna, więc lepiej zawczasu
przygotować kopię zapasową całej partycji.
Zaczynamy od jej odmontowania. W kolejnym kroku
wpisujemy poniższe polecenie:
dd if=/dev/hdaN bs=64k | aespipe -e AES256 -T |
S
dd of=/dev/hdaN bs=64k conv=notrunc
Jak widać, dd odczytuje partycję i przekazuje wyjście
do aespipe, którego zadaniem jest zaszyfrowanie tego,
co otrzyma przy użyciu wybranego algorytmu. Wynik
z kolei wędruje do ponownie uruchomionego dd w celu
zapisania na urządzeniu, tym razem już w postaci zaszy-
frowanej. Podobnie jak we wcześniejszych przykładach
dotyczących losetup, flaga
-e
pozwala nam wybrać algo-
rytm szyfrujący, a
-T
powoduje, że Aespipe rozpoczynając
działanie zapyta dwukrotnie o hasło, którego chcemy
użyć.
Rysunek 5.
Szyfrowanie istniejącej partycji, na której
przechowujemy już dane
37
www.linux.com.pl
loop-aes
Wariant dla ambitnych polega na wzmocnieniu zabez-
pieczeń przez użycie zarodka hasła i iterowanym szyfro-
waniu skrótu hasła. Wymaga on zastosowania znanych już
z programu losetup opcji
-S
(dodanie wygenerowanego
zawczasu zarodka do hasła) oraz
-C
(liczba wskazująca, ile
tysięcy razy szyfrowany jest skrót hasła). Ciąg otrzymany
z polecenia (tu:
qwSIxpGIi6pZNAvj0e7w
):
head -c 15 /dev/urandom | uuencode -m - | awk 'NR == 2
S
{print}'
zostanie użyty w kolejnym kroku jako zarodek hasła:
dd if=/dev/hdaN bs=64k | aespipe -e AES256 -T
S
-S qwSIxpGIi6pZNAvj0e7w -C 100 | dd of=/dev/hda2
S
bs=64k conv=notrunc
Po zakończeniu operacji edytujemy opcje montowa-
nia w /etc/fstab, dodając do linii dotyczącej tej partycji:
noauto,loop=/dev/loopX,encryption=AES256
i ewentualnie
itercountk=100,pseed=qwSIxpGIi6pZNAvj0e7w
, o ile użyli-
śmy drugiego wariantu.
Można również wspomnieć o innym ciekawym zastoso-
waniu Aespipe, mianowicie szyfrowaniu płyt CD, a ściślej,
obrazów przygotowanych za pomocą Mkisofs. Tworzymy je
poleceniem:
mkisofs -V TAJNE -J -r nazwa_katalogu | aespipe
S
-e AES256 -T > image.raw
Po nagraniu można zamontować krążek w taki sposób:
mount -t iso9660 /dev/cdrom /cdrom
S
-o loop=/dev/loopX,encryption=AES256
Rzecz jasna, dostęp do niego będziemy mieli tylko po
podaniu hasła i wyłącznie w systemach wyposażonych
w moduł loop-AES.
Wydajność
Na koniec załączę kilka słów na temat wydajności. Nie-
wątpliwie, dodatkowe obciążenie komputera operacjami
szyfrowania danych „w locie” w mniejszym lub większym
stopniu musi wpłynąć na działanie systemu. Trzeba
jednak przyznać, że zarówno trafnie wybrany przez
autora projektu algorytm szyfrowania, jak i wykorzysta-
nie urządzenia loop, dość skutecznie minimalizują narzut
czasowy.
Ponadto, jeśli zachowamy umiar, wpływ ten może
pozostać niemal niezauważalny. Potwierdzają to doświad-
czenia autora. Próby przeprowadzane na maszynach
z jednym procesorem Pentium 1 GHz lub Athlon 1700
MHz oraz 512 MB RAM, czyli dość typowych, przy jed-
noczesnym wykorzystaniu dwóch szyfrowanych partycji
i jednego szyfrowanego pliku o wielkości 1 GB, prowadzą
do wniosku, że komfort pracy nie zmniejsza się w istotny
sposób (oczywiście, to tylko subiektywna ocena). Jak się
wydaje, najbardziej optymalne z punktu widzenia wydaj-
ności jest szyfrowanie fizycznej partycji dysku.
W przypadku komputerów starych i powolnych albo
bardzo przeciążonych pozostaje rozważyć użycie opcji
lo_nice
i
lo_prealloc
.
Pierwsza z nich, o domyślnej wartości -20, pozwa-
la modyfikować priorytet zadań. Można ją zmniejszyć
w /etc/modules.conf (np.
options loop lo_nice =-5
).
Druga opcja odpowiada za liczbę 4-kilobajtowych
stron pamięci operacyjnej przeznaczanych dla urządzeń
/dev/loopX w chwili montowania. Domyślna wartość
wynosi 125. Możemy ją zwiększyć lub zmniejszyć glo-
balnie, dopisując do /etc/modules.conf np.
options loop
lo_prealloc=200
. Możemy również zróżnicować wielkość
RAM-u prealokowaną przez poszczególne urządzenia:
options loop lo_prealloc=100,3,200,4,250.
Pierwsza liczba oznacza zmniejszoną wartość domyśl-
ną, następne pary liczb nadpisują ją, przeznaczając dla
loop3 200 stron pamięci, a dla loop4 250 (składnia dopusz-
cza co najwyżej cztery takie pary).
Uwagi końcowe
Starałem się przedstawić zalety omawianych narzędzi
możliwie wszechstronnie. Nie zamykam przy tym oczu na
wady loop-AES. Zalicza się do nich zwłaszcza uciążliwość
dodatkowych zabiegów związanych z kompilacją i instala-
cją niezbędnych binariów, co gorsza, pociągająca za sobą
ingerencję w integralność systemu pakietowego. Sądzę
jednak, że korzyści warte są podejmowania tego wysiłku.
Jeśli Czytelnik nie czuje się w pełni przekonany o pożyt-
kach płynących ze stosowania zaawansowanej krypto-
grafii, być może samodzielne próby, do których gorąco
zachęcam, staną się czynnikiem przesądzającym.
W Sieci:
• Strona projektu loop-AES:
http://loop-aes.sourceforge.net/projects/loop-aes/
• Strona domowa projektu Rijndael:
http://www.esat.kuleuven.ac.be/~rijmen/rijndael/
• Strona NIST poświęcona AES:
http://csrc.nist.gov/CryptoToolkit/aes/rijndael/
• Strona entuzjastów algorytmu Rijndael:
http://rijndael.com/
• Źródła modułu Loop-AES:
http://loop-aes.sourceforge.net/loop-AES-latest.tar.bz2
• Źródła dodatkowych modułów:
http://loop-aes.sourceforge.net/ciphers-latest.tar.bz2
• Źródła Aespipe:
http://loop-aes.sourceforge.net/aespipe-latest.tar.bz2
• Źródła Util-linux:
ftp://ftp.kernel.org/pub/linux/utils/util-linux/util-linux-
2.12pre.tar.bz2