Dropbox i kontener LUKS
Spis treści
Ogarnęliśmy już szyfrowanie plików na Dropbox przy pomocy encfs oraz kontenerów TrueCrypt. Każda z w/w operacji drastycznie poprawiła prywatność naszych plików, które przechowujemy w chmurze. Poniższy wpis będzie w podobnym klimacie, tj. spróbujemy umieścić na Dropbox kontener LUKS, co niesie ze sobą sporo udogodnień i czyni korzystanie z zaszyfrowanego Dropbox'a praktycznie transparentnym.
Tworzenie kontenera pod dane na Dropbox
Przede wszystkim, musimy utworzyć plik składający się z samych zer. Tak stworzony plik umieszczamy na Dropbox. Sam plik może być dowolnego rozmiaru i nie ma tutaj znaczenia czy będzie to 100 MiB czy 10GiB. Liczy się tylko to ile miejsca chcemy przeznaczyć na Dropbox na szyfrowane pliki. Najciekawsze w tym wszystkim jest to, że plik składający się z samych zer zostanie przed wysłaniem do chmury skompresowany, a kompresja samych zer daje wynik porównywalny z zerem. I tak, np. 10 GiB plik będzie zajmować parę KiB, co oczywiście cieszy, bo nie będzie trzeba wysyłać do chmury całych 10GiB danych.
Na sam początek zatrzymujemy synchronizację plików w Dropbox i przechodzimy do katalogu gdzie mamy swoją lokalną kopię plików. W nim tworzymy plik kontenera LUKS:
$ cd /media/Server/Dropbox/
$ dropbox status
Syncing paused
$ dd if=/dev/zero of=./luks_dropbox bs=2M count=500
Puszczamy synchronizację i po chwili kontener powinien zostać przesłany do chmury. Stan synchronizacji możemy sprawdzić w poniższy sposób:
$ dropbox filestatus
luks_dropbox: up to date
Ponownie wstrzymujemy synchronizację plików, po czym logujemy się na konto root w celu przygotowania
urządzenia loop
, które zamontuje nam w systemie plik kontenera:
# losetup /dev/loop0 /media/Server/Dropbox/luks_dropbox
# losetup -a
/dev/loop0: [0807]:2883594 (/media/Server/Dropbox/luks_dropbox)
Teraz trzeba zaszyfrować plik kontenera przy pomocy cryptsetup
. Pamiętajmy by wskazać urządzenie
/dev/loop0
, a nie faktyczny plik na dysku:
# cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random --verify-passphrase --verbose luksFormat /dev/loop0
Otwieramy kontener i tworzymy w nim system plików:
# cryptsetup luksOpen /dev/loop0 crypt_dropbox
# mkfs.ext4 -m 0 -L dropbox /dev/mapper/crypt_dropbox
W tej chwili mamy przygotowany kontener na dane. Zamykamy go i synchronizujemy Dropbox'a:
# cryptsetup luksClose crypt_dropbox
$ dropbox status
Updating (1 file, 9 mins left)
Uploading "luks_dropbox" (70.0 kB/sec, 9 mins left)
Konfiguracja kontenera LUKS
Powyższy setup powinien działać prawidłowo. Musimy jednak jeszcze nauczyć system jak automatycznie montować ten kontener. Ja już mam w swoim systemie kilka zaszyfrowanych dysków, dlatego też u mnie nie będzie potrzebne dodatkowe hasło, które trzeba by podawać przy starcie systemu. Hasła co prawda są inne, i w przypadku systemu, i w przypadku kontenera dropbox ale przy pomocy ciekawej sztuczki można uzależnić kontener Dropbox'a od klucza jakiejś zaszyfrowanej już partycji. Można też wykasować hasło do kontenera ale wtedy uzależnimy kontener zupełnie od nagłówków tej partycji. Jeśli te nagłówki ulegną uszkodzeniu albo przez przypadek stworzymy nowy kontener pod nowy system, stracimy dostęp do danych na Dropbox.
Przede wszystkim narzędzie losetup
musi widzieć nasz kontener:
# losetup -a
/dev/loop0: [0807]:2883594 (/media/Server/Dropbox/luks_dropbox)
Plik /etc/crypttab
Edytujemy teraz plik /etc/crypttab
, z tym, że konfiguracja w nim zawarta będzie się różnić w
zależności od tego czy mamy już w systemie jakieś zaszyfrowane dyski, czy tez i nie. Jeśli nie
mamy, to trzeba będzie niestety podawać na starcie systemu hasło. Można też sprecyzować keyfile,
choć na niezaszyfrowanym systemie nie polecam tego rozwiązania. Keyfile jest dopuszczalną formą
uzyskania dostępu do kontenera, tylko gdy rezyduje na zaszyfrowanej przestrzeni, w chronionej przez
roota lokalizacji (prawa 400). Także jeśli nie mamy zaszyfrowanego systemu, w pliku /etc/crypttab
dodalibyśmy coś na wzór tej linijki poniżej:
crypt_dropbox /media/Server/Dropbox/luks_dropbox none luks,noauto
Ja nie będę się zajmował powyższym rozwiązaniem, bo jest ono wielce niepraktyczne. Dlatego ja wykorzystuje pełne szyfrowanie dysku i jak zobaczymy poniżej, to powoli zaczyna ułatwiać życie.
Tak powinien mniej więcej wyglądać plik /etc/crypttab
przy posiadaniu zaszyfrowanego dysku
systemowego:
sda2_crypt UUID=727fa348-8804-4773-ae3d-f3e176d12dac none luks
crypt_dropbox /media/Server/Dropbox/luks_dropbox sda2_crypt luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived,noauto
Teraz jeszcze trzeba wyciągnąć 128 znakowy ciąg z tabeli dmsetup
:
# dmsetup table --showkeys
Odczytujemy ten długi ciąg znaków przy pozycji sda2_crypt
i dodajemy go do nagłówka kontenera LUKS
jako hasło:
# cryptsetup luksAddKey /media/Server/Dropbox/luks_dropbox
Sprawdzamy czy są zajęte dwa sloty:
# cryptsetup luksDump /media/Server/Dropbox/luks_dropbox
...
Key Slot 0: ENABLED
...
Key Slot 1: ENABLED
...
Zamykany kontener:
# cryptsetup luksClose crypt_dropbox
# losetup -D
Plik /etc/fstab
Otwórzmy raz jeszcze kontener z plikami Dropbox'a, bo jakby nie patrzeć, to nie jest koniec naszej
pracy. Musimy min. dodać odpowiedni wpis w /etc/fstab
. By to zrobić trzeba uzyskać UUID systemu
plików w kontenerze:
# tune2fs -l /dev/mapper/crypt_dropbox | grep UUID
Filesystem UUID: 0d959e74-ec19-43bf-b779-60134c676aef
Edytujemy plik /etc/fstab
i dodajemy tam poniższy wpis:
# dropbox
UUID=0d959e74-ec19-43bf-b779-60134c676aef /media/Dropbox ext4 defaults,noauto,user,nofail,noatime,commit=20 0 2
Tworzymy także punkt montowania w katalogu /media/
:
# mkdir /media/Dropbox
Generowanie nowego initramfs
Po dostosowaniu plików /etc/crypttab
i /etc/fstab
musimy wygenerować nowy initramfs przy pomocy
poniższego polecenia:
# update-initramfs -u -k all
W tej chwili system będzie w stanie wykorzystać hexalną wartość klucza partycji systemowej do odblokowania kontenera przeznaczonego pod pliki Dropbox'a. Możemy sprawdzić czy tak faktycznie się stanie. By otworzyć kontener wydajemy poniższe polecenie:
# cryptdisks_start crypt_dropbox
By zamknąć:
# cryptdisks_stop crypt_dropbox
Skrypty cryptdisks_start
oraz cryptdisks_stop
działają w oparciu o plik /etc/crypttab
i by z
nich skorzystać, trzeba mieć w tym pliku zdefiniowane kontenery.
Problemy z odblokowaniem kontenera LUKS
Przy otwieraniu kontenera możemy napotkać na pewien problem. Mianowicie, ten kontener znajduje się
na partycji, a jej system plików z kolei trzeba pierw zamontować by uzyskać dostęp do znajdującego
się na nim kontenera. To powoduje, że nie można ustawić automatycznego otwarcia kontenera przy
starcie systemu w /etc/crypttab
. Jeśli się przyjrzymy bliżej temu plikowi, to dostrzeżemy tam
opcję noauto
. Jeśli nie można otworzyć kontenera na starcie, nie można też zamontować
automatycznie jego systemu plików. A to z kolei obeszliśmy przez opcję noauto
w pliku
/etc/fstab
.
Problem jest jeszcze taki, że mimo iż kontener nie jest otwierany, a jego system plików nie jest
montowany to i tak podczas startu systemu jest wyrzucany błąd o braku urządzenia z UUID naszego
kontenera. Opcja nofail
w /etc/fstab
rozwiązuje ten problem i tłumi ten komunikat.
Automatyczne montowanie systemu plików kontenera
Obecnie, za sprawą opcji, które ustawiliśmy, ani kontener nie jest otwierany na starcie, ani system
plików nie jest montowany. To chyba nie tak miało wyglądać, prawda? Oczywiście, że nie. Musimy
stworzyć dwa pliki w katalogu /etc/systemd/system/
, które będą wchodzić w skład potrzebnej nam
usługi.
Plik systemd-cryptsetup@dropbox.service
:
[Unit]
Description=Cryptography Setup for %I
Documentation=man:cryptdisks_start man:cryptdisks_stop man:systemd-cryptsetup@.service(8)
IgnoreOnIsolate=true
DefaultDependencies=no
Requires=media-Kabi.mount
After=cryptsetup-pre.target
After=systemd-fsck-root.service
After=media-Kabi.mount
Before=systemd-fsck@dev-mapper-crypt_dropbox.service
Before=cryptsetup.target
Before=media-Dropbox.mount
Before=umount.target shutdown.target
Conflicts=umount.target shutdown.target
ConditionPathExists=/media/Kabi/luks_dropbox
[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutSec=30
ExecStart=/lib/systemd/systemd-cryptsetup attach 'crypt_dropbox' '/media/Kabi/luks_dropbox' 'none' 'luks'
ExecStop=/lib/systemd/systemd-cryptsetup detach 'crypt_dropbox'
[Install]
WantedBy=cryptsetup.target
Plik media-Dropbox.mount
:
[Unit]
Documentation=man:fstab(5)
Requires=systemd-fsck@dev-mapper-crypt_dropbox.service
Requires=systemd-cryptsetup@crypt_dropbox.service
Requires=media-Kabi.mount
After=systemd-fsck@dev-mapper-crypt_dropbox.service
After=systemd-cryptsetup@crypt_dropbox.service
After=media-Kabi.mount
Before=local-fs.target
[Mount]
What=/dev/mapper/crypt_dropbox
Where=/media/Dropbox
Type=ext4
Options=defaults,errors=remount-ro,commit=20,loop=/dev/loop5
Dodajemy jeszcze systemd-cryptsetup@dropbox.service
do autostartu systemu:
# systemctl enable systemd-cryptsetup@dropbox.service
I to by było w zasadzie wszystko. Po starcie systemu, kontener zostanie otworzony a jego system plików zamontowany. Przy czym, taki otwarty kontener jest przez dropboxa traktowany jako plik w fazie edycji.
Ochrona kontenera z plikami Dropbox'a
Jeszcze kilka słów na temat tego w jaki sposób dostęp do kontenera dropbox powinien być chroniony. Słabe hasło najlepiej jest zastąpić przez keyfile. Oczywiście sposób uzyskiwania dostępu do kontenera zostaje taki sam ale na wypadek problemów z zależną partycją musimy mieć jakieś zabezpieczenie, by dane z Dropbox'a nie przepadły. Najlepiej stworzyć keyfile w oparciu o plik binarny, który jest trzymany "w głębokim ukryciu". Głębokie ukrycie będzie polegało na wybraniu jakiegoś pliku, który rezyduje na naszym dysku ale jest już używany w jakiś sposób, np. plik mp3 czy avi.
Teraz przy pomocy --new-keyfile-size=
oraz --new-keyfile-offset=
możemy wskazać, od której
części pliku ma się zaczynać nasz keyfile oraz jak długi ma on być. Przykład wykorzystania takiego
mechanizmu:
cryptsetup luksAddKey --new-keyfile-size=2048 --new-keyfile-offset=4096 '/media/Server/Dropbox/luks_dropbox' '/media/mp3/mp3.mp3'
Jeśli spróbowalibyśmy otworzyć ten kontener przy pomocy powyższego pliku, nie uda nam się ta operacja:
# cryptsetup luksOpen '/media/Server/Dropbox/luks_dropbox' crypt_dropbox --key-file='/media/mp3/mp3.mp3'
No key available with this passphrase.
Podobnie sprawa ma się w przypadku podania niewłaściwych parametrów, tj. rozmiaru i offsetu pliku klucza:
# cryptsetup luksOpen '/media/Server/Dropbox/luks_dropbox' crypt_dropbox --key-file='/media/mp3/mp3.mp3' --keyfile-offset=4095 --keyfile-size=2048
No key available with this passphrase.
# cryptsetup luksOpen '/media/Server/Dropbox/luks_dropbox' crypt_dropbox --key-file='/media/mp3/mp3.mp3' --keyfile-offset=4096 --keyfile-size=2047
No key available with this passphrase.
Powyżej został pokazany prosty przykład, jednak wartościami offset
i size
można dowolnie
manipulować i ustawić można sobie dowolne wartości i nawet jeśli już ktoś wejdzie w posiadanie
naszego pliku, to będzie musiał znać 2 parametry by odblokować kontener. Możliwe jest, co prawda,
zdefiniowanie tego keyfile w /etc/crypttab
i użycie go do odblokowania kontenera ale ja bym tego
nie robił. Można tym zdradzić położenie keyfile no i oczywiście wartości offset
i size
. Lepiej
zostawić ten keyfile jako backup.
W przypadku zrobienia backupu w postaci keyfile, trzeba pamiętać też o wyczyszczeniu odpowiednich
slotów w nagłówku kontenera LUKS. Służy do tego cryptsetup luksKillSlot
:
# cryptsetup luksKillSlot '/media/Server/Dropbox/luks_dropbox' 0
Enter any remaining passphrase: