Příspěvek obsahuje pár poznámek ohledně možností zálohování dát v jiných lokalitách – tj. snaha o zabezpečení vůči ztrátě dat následkem požáru, vloupání atd. S tím související prvek je přenos a šifrování vzdáleně uložených dat pro případ možného zneužití.
Nejjednodušší, ale též nejméně pohodlné, je uchovávat médium se zálohovanými daty někde jinde (v bankovní schránce, v zaměstnání), ale kdo se s tím má zabývat :-), takže zbývají on-line služby pro ukládání (a sdílení) dat a zálohování přes internet na jiný (vlastní) počítač.
On-line úložiště
Díky rychlému internetu se čím dál více prosazuje ukládání dat v on-line cloudech, přičemž provozovatelé služeb se snaží o co nejsnadnější propojení se zařízeními uživatele. Evidentně nejdále je zatím Apple se svým iCloud, ale i pro další služby jako např. Dropbox existuje podpora pro různé operační systémy a zařízení. Primárním účelem těchto služeb nebývá zálohování dat, jako spíše jejich dostupnost kdykoliv a odkudkoliv.
Byť přenosy dat a mnohdy i jejich uložení v cloudu je šifrováno, za bezpečné uložení dat (z pohledu možného zneužití či úniku) se to považovat nedá – klíče k dešifrování má k dispozici i provozovatel. Takže prakticky platí ono známé: „Cokoliv dáte na internet, jsou již prakticky veřejná data.“ A je celkem jedno, zda je to FaceBook nebo iCloud.
Řešením je v cloudu ukládat data, která jsou šifrována již lokálně na zařízení uživatele:
- Nejtransparentnější řešení nabízí encfs – nešifruje se celý diskový oddíl či souborový kontejner pro totéž, ale jednotlivé soubory samostatně. Existuje i verze pro MS Windows (encfs4win), ale zatím jsem to netestoval. Bohužel není klient pro android.
- Další řešení s omezenějším použitím je šifrování dat v souborovém kontejneru (Truecrypt, LUKS), ale to se hodí spíše pro malý objem dat – kontejner se při jakékoliv změně musí zálohovat celý – nebo pro specifické účely (KeePass).
- Nakonec je samozřejmě možné šifrovat soubory v samotných aplikacích (Libre Office, GnuCash), pomocí syncany, GPG, ZIP, atd.
Pokud bude využívána možnost automatické synchronizace lokálních dat ze vzdálenými, tak pozor na to, že při smazání na jakémkoliv lokálním zařízení data nejspíše zmizí i ze všech ostatních.
Potíž s on-line službami je jejich cena: např. Dropbox nabízí 100 GB za cca 20 USD měsíčně.
Zálohování ve vlastní režii
Pokud je nutné zálohovat řádově větší množství dat jako například vlastní foto archiv, zdá se být nejlepší cestou nalezení spřízněné duše, která má rychlé připojení na internet, a požádat ji přidělení přístupu na počítač a diskový prostor.
Pokud je ona spřízněná duše potenciálně nedůvěryhodná, pak nezbude, než použít encfs (tj. na šifrovat na lokálním disku a zálohovat již šifrované soubory). Šifrovat disk s fotkami v prostředí domácí sítě je poněkud paranoidní, ale hlavně to komplikuje používání – nicméně to lze vyřešit automatickým připojováním šifrovaných souborů během startu počítače (použitím lokálně či vzdáleně uloženého hesla).
V mém případě je ona duše dostatečně důvěryhodná (její počítač spravuji já), takže volba padla na druhou metodu – lokální data nejsou šifrována vůbec a po přenosu (šifrovaném) na vzdálený počítač jsou ukládána na šifrovaný diskový oddíl na externím hard disku – použit je LUKS (dm-crypt).
V krátkosti postup pro vytvoření šifrovaného oddílu:
/dev/drive: disk, na kterém budou vytvořeny šifrované diskové oddíly. /dev/mapper/data: virtuální blokové zařízení, které obsahuje nešifrovaná data.
Volitelný krok: přemazat nový disk náhodnými daty (možné alternativy, kvalita „náhodnosti“ klesá a rychlost použití stoupá směrem dolu):
$ sudo dd if=/dev/random of=/dev/drive bs=1M $ sudo dd if=/dev/random of=/dev/drive bs=1M $ sudo badblocks -c 10240 -wsvt random /dev/drive
Toto je svým způsobem zbytečné, neb LUKS nebyl navržen k tomu, aby se nedalo poznat, zda se jedná či nejedná o šifrovaná data. (Poznat se to dá podle LUKS hlavičky na začátku oddílu disku.) Nicméně mělo by to pomoci k tomu, aby nebylo vidět, kde končí šifrovaná data.
Vytvoření oddílu: běžným způsobem vytvořit linuxový diskový oddíl /dev/drive1 (tj. pomocí fdisk, cfdisk, atd.), na typu zřejmě nezáleží.
LUKS – vytvoření šifrovaného oddílu chráněného ručně zadávaným heslem:
$ sudo cryptsetup -c aes-xts-benbi -y -s 512 luksFormat /dev/drive1
LUKS – otevření šifrovaného oddílu a namapování na /dev/mapper/data:
$ sudo cryptsetup luksOpen /dev/drive1 data
S /dev/mapper/data se již pracuje jako s běžným diskovým oddílem. LUKS (dm-crypt) jakoukoli operaci provedenou s /dev/mapper/data automaticky šifruje a ukládá do /dev/drive1.
Vytvoření souborového systému: běžným způsobem, např.
$ sudo mkfs.ext4 -m 0 -L data /dev/mapper/data
Připojení souborového systému do adresáře ./data:
$ mkdir ./data && sudo mount /dev/mapper/data ./data
LUKS – zavření šifrovaného oddílu (nejprve je nutné odpojit připojený oddíl):
$ cryptsetup luksClose /dev/drive1
LUKS – přidání dalšího klíče (hesla) – celkem lze 10:
$ cryptsetup luksAddKey /dev/drive1
LUKS – odebrání existujícího klíče (hesla):
$ cryptsetup luksRemoveKey /dev/drive1
Zálohování pomocí rsync a ssh
Skript, který je spuštěn na lokálním počítači (odkud se bude zálohovat). Je dost „hard-coded“, takže použití na vlastní nebezpečí a pouze po úpravách na konkrétní situaci.
#!/bin/bash ## This script ## a) copies part of itself to the remote computer ## b) creates temporary id_rsa keys for passwordless access ## to the local computer from the remote computer ## c) runs the remote script, which ## - identifies a hdd on the basis of its size ## (you have been warned: avoid using two drives of the same size!) ## - mounts the LUKS device (w/ password) ## - backups defined directory from local computer to the LUKS device ## The current setup requires to enter root@remote.computer password ## in step a) and b) and the LUKS password in step c). set -o errexit # check privileges test `whoami` = "root" || ( echo "This script should be run with root privileges." ; exit 1 ) ###### # Create a stand-alone script, which shall be transferred to remote computer cat > tmp-script.sh << 'EOF' #!/bin/bash # Include a trailing slash in src directory if do not you want the last directory to be # created also in the dest directory. # The incremental backup using hardlinks based on # http://www.gentoo-wiki.info/Simple_snapshot_style_backup set -o errexit # Check privileges test `whoami` = "root" || ( echo "This script should be run with root privileges." ; exit 1 ) Initial() { # In the initial run, we perform a full copy. cd ${DEST_DIR} echo "rsync ${SRC_DIR}" mkdir -p ${DATE} rsync --ignore-errors -aAvP --rsh="${OTHER_OPTS0}" ${OTHER_OPTS} ${SRC_DIR} ${DATE} } BackUp() { # In the normal run, we hardlink everything, and only copy changed files. cd ${DEST_DIR} PREV=`/bin/ls -dl current | rev | awk '{print $1}' | rev` echo "rsync ${SRC_DIR} hardlinked to ${PREV}" rsync --ignore-errors -aAvP --delete --link-dest=../${PREV} \ --rsh="${OTHER_OPTS0}" ${OTHER_OPTS} ${SRC_DIR} ${DATE} } DoSync() { DATE=`date +%Y%m%d%H%M%S` # Check ${DEST_DIR} test -d ${DEST_DIR} || ( echo "${DEST_DIR} does not exist." ; exit 1 ) # Run backup if test -L ${DEST_DIR}/current then echo "Incremental backup using hard links..." BackUp else echo "Initial run. This may take a while..." Initial fi # Update symlink cd ${DEST_DIR} rm -f current ln -s ${DATE} current } ### Main ### HDD_LABEL=data HDD_SIZE="320173056" # size of the block device (external drive) HDD_ENC="undefined_yet" SRC="root@local.computer" # which shall be backed-up SRC_DIR="${SRC}:/usr/local" DEST_DIR="/mnt/${HDD_LABEL}" OTHER_OPTS0="ssh -p 22 -l root -i /root/tmp-key-file" OTHER_OPTS="--exclude=/lost+found" echo "NB: This script requires a (pseudo) terminal." # Identify block device, open LUKS and mount the filesystem test -f `which cryptsetup` || ( echo "Cannot find cryptsetup binary." ; exit 1 ) test -f `which rsync` || ( echo "Cannot find rsync binary." ; exit 1 ) # Identify the block device based on known size. Expecting only a single partition. for i in /sys/block/*; do test `cat ${i}/size` -eq ${HDD_SIZE} && ( HDD_ENC="/dev/`basename ${i}`1"; break ) done test -b ${HDD_ENC} || ( echo "Cannot find disk ${HDD_ENC}." ; exit 1 ) # Open the 1st partition with LUKS and mount it cryptsetup luksOpen ${HDD_ENC} ${HDD_LABEL} || ( echo "Opening LUKS failed..." ; exit 1 ) mkdir -p /mnt/${HDD_LABEL} mount -o defaults,acl /dev/mapper/${HDD_LABEL} /mnt/${HDD_LABEL} || ( echo "Mounting failed..." ; exit 1 ) mount | grep -q /mnt/${HDD_LABEL} || ( echo "Filesystem not mounted..." ; exit 1 ) touch /mnt/${HDD_LABEL}/touch || ( echo "Cannot touch file in /mnt/${HDD_LABEL}" ; exit 1 ) # Back-up the remote data DoSync # Unmount the filesystem, close LUKS cd umount /mnt/${HDD_LABEL} || ( echo "Cannot unmount /mnt/${HDD_LABEL}" ; exit 1 ) rmdir /mnt/${HDD_LABEL} || ( echo "Cannot remove /mnt/${HDD_LABEL}. Not empty?" ; exit 1 ) cryptsetup luksClose ${HDD_LABEL} || ( echo "Closing LUKS failed..." ; exit 1 ) echo "HDD enclosure can be detached now." # Delete itself and the key rm /root/tmp-script.sh /root/tmp-key-file exit 0 EOF ##### ### LOCAL part of the script ### KEY_AUTH="/root/.ssh/authorized_keys" REMOTE="root@remote.computer" # name of remote computer PORT=22 # port to remote computer # Generate temporary key pair ssh-keygen -N "" -C "Temporary key pair XY" -f tmp-key-file # Add the public key to authorized_keys cat tmp-key-file.pub >> ${KEY_AUTH} # Upload the files to the remote computer scp -P ${PORT} tmp-script.sh tmp-key-file ${REMOTE}:/root # Run the backup script on the remote computer ssh -p ${PORT} -t ${REMOTE} sh tmp-script.sh # Remove the key from authorized_keys and delete temporary files test -f ${KEY_AUTH} && ( mv ${KEY_AUTH} ${KEY_AUTH}xx ; \ cat ${KEY_AUTH}xx | grep --invert-match 'Temporary key pair' > ${KEY_AUTH}; \ rm ${KEY_AUTH}xx ) rm tmp-key-file tmp-key-file.pub tmp-script.sh