LUKS (Linux Unified Key Setup) — спецификация шифрования диска (или блочного устройства), изначально предложенная для Linux, но сейчас поддерживаемая и в ряде других операционных систем.

Особенности

  • В качестве «контейнера» используется файл. Его размер фиксирован. Возможно изменение размера.
  • «Внутри» контейнера создается файловая система, любого удобного вам формата.
  • При использовании - монтируется, как обычный раздел.

—- Данные сохраняются по блокам, как в обычном файле/файловой системе. То есть :

  • модификация файла внутри контейнера приводит к перезаписи блоков, занимаемых этим файлом, но не всего контейнера;
  • «потеря/порча» одного блока приводит к потере информации «того-что-было-в-этом-блоке», и не более того.
  • при синхронизации контейнера «в облако» - как правило, перезаписывается не весь файл, а «модифицированная часть», что требует малого объема трафика.

—- В отличие от EncFS

  • «снаружи» не видны общее количество файлов, их размеры и время модификации;
  • изменение размера контейнера требует отдельных действий.

—- В отличие от Truecript

  • как правило, выше скорость обработки данных (зависит от алгоритма/размера ключа);
  • проще работа с ключами;
  • нет механизма «двойного дна»;
  • возможны проблемы при попытке использования контейнера «из другой ОС»

Создание контейнера

  • Создаем необходимые каталоги:
mkdir /home/user/keys            # каталог файла-ключа и скриптов. Должен быть недоступен другим пользователям 
mkdir /home/user/.private        # каталог контейнера. В нем хранится криптованный файл-контейнер
mkdir /home/user/private         # точка монтирования. В нем будет содержимое контейнера "в открытом виде"
  • При необходимости, доустанавливаем пакеты:
sudo apt-get install cryptsetup

и проверяем (должен быть вывод «kernel/drivers/md/dm-crypt.ko»)

modprobe -l |grep dm-crypt  
  • Создаем ключ
dd if=/dev/urandom of=/home/user/keys/container.key bs=512 count=1
  • Создаем контейнер, файл container.crt, размером 50M
dd if=/dev/urandom of=/home/user/.private/container.crt bs=1M count=50

Размечаем контейнер, как luks-систему с ключом

sudo cryptsetup luksFormat /home/user/.private/container.crt -d /home/user/keys/container.key -c aes-xts-plain64 -s 512

или - без ключа, с набором пароля при каждом открытии контейнера

sudo cryptsetup luksFormat /home/user/.private/container.crt -c aes-xts-plain64 -s 512

Будет предупреждение WARNING! Данные на /home/user/.private/container.crt будут перезаписаны без возможности восстановления. Are you sure? (Type uppercase yes), надо набрать YES.

  • Параметры полученного контейнера, смотрим
sudo cryptsetup luksDump /home/user/.private/container.crt
  • «Открываем» контейнер
sudo cryptsetup luksOpen /home/user/.private/container.crt -d /home/user/keys/container.key container

смотрим, появился ли в устройствах, и информация о нем

ls /dev/mapper/
sudo dmsetup info container

Форматируем содержимое контейнера, в данном примере в ext4, с установкой метки и отключением «резерва рута»

sudo mke2fs -t ext4 -O has_journal -L container -m 0 /dev/mapper/container

монтируем и выдаем права пользователю (себе)

sudo mount /dev/mapper/container /home/user/private
sudo chown -hR user:user /home/user/private
  • Напомним - если мы потеряли файл ключа, надо иметь пароль. Задаем пароль, при этом будут два запроса на его ввод - Введите новый пароль для ключевого слота и Verify passphrase
sudo cryptsetup luksAddKey /home/user/.private/container.crt -d /home/user/keys/container.key

и проверяем «занятые» ключами слоты (их должно быть два, если мы задали ключ и пароль, Key Slot 0: ENABLED и Key Slot 1: ENABLED)

sudo cryptsetup luksDump /home/user/.private/container.crt
  • Контейнер к работе готов. Отмонтируем и отключаем.
sudo umount /dev/mapper/container 
sudo cryptsetup luksClose /dev/mapper/container

Использование контейнера

Описание изложено для ubuntu 12.04, Unity, сервис dropbox. В приведенных скриптах работа с декриптованым содержимым контейнера выполняется при остановке службы синхронизации. После «закрытия» контейнера - запускается служба синхронизации.

Если уж мы этим занялись, сделаем «кнопку» и «раскрасим» ее подобающим образом. Мы же не будем работать с контейнером из командной строки? Выбираем любую приглянувшуюся нам картинку в /usr/share/app-install/icons/ - там их больше 2000, например, cryptkeeper.png и копируем к себе в профиль

cp /usr/share/app-install/icons/cryptkeeper.png /home/user/.icons/private.png

Создаем файл-desktop

gedit /home/user/.local/share/applications/private.desktop

такого содержания:

[Desktop Entry]
Comment=Private
X-Ubuntu-Gettext-Domain=Private
X-GNOME-Bugzilla-Bugzilla=GNOME
Name=Контейнер
Exec=/home/user/keys/privatestatus.sh
StartupNotify=true
X-Ayatana-Desktop-Shortcuts=GoGo;GoPass;Off;Starts
Terminal=false
Type=Application
Categories=GNOME;GTK
Icon=/home/user/.icons/private.png
 
[GoGo Shortcut Group]
TargetEnvironment=Unity
Name=Открываем контейнер
Exec=/home/user/keys/privateopen.sh
 
[GoPass Shortcut Group]
TargetEnvironment=Unity
Name=Открываем с паролем
Exec=/home/user/keys/privateopen2.sh
 
[Off Shortcut Group]
TargetEnvironment=Unity
Name=Закрываем контейнер
Exec=/home/user/keys/privateclose.sh
 
[Starts Shortcut Group]
TargetEnvironment=Unity
Name=Старт Dropbox
Exec=dropbox start

В даше появляется кнопка по имени «Контейнер», выносим ее на панель ланчера. По нажатию на нее -выводится сообщение о статусе (состоянии) контейнера. По ПКМ - выбираем пункт меню:

1. Открываем контейнер 
2. Открываем с паролем
3. Закрываем контейнер 
4. Старт Dropbox

По вызову «Открываем с паролем» - не используется файл-ключ, в окне терминала будет выдан запрос на ввод пароля.

—-Создадим скрипты для выполнения действий с контейнером. Для проверки статуса - проверяем монтирование. Создаем файл privatestatus.sh

gedit /home/user/keys/privatestatus.sh

Его содержание:

#!/bin/sh
if  grep -q "private" /proc/mounts; then
  notify-send -u normal "Контейнер открыт! Занято: "`df -h | grep private | awk '{print $5}'`
else
  notify-send -u normal "Контейнер закрыт"
fi

Для открытия - останавливаем службу dropbox и проверяем, не был ли уже открыт контейнер, и открываем. При открытии или проверке статуса, если контейнер открыт, сообщение дополняется информацией о размере (в процентах) использованного места, например: «Занято: 64%»

gedit /home/user/keys/privateopen.sh

Его содержание:

#!/bin/sh
dropbox stop
if  grep -q "private" /proc/mounts; then
  notify-send -u normal "Контейнер уже был открыт!"
else
  sudo cryptsetup luksOpen /home/user/.private/container.crt -d /home/user/keys/container.key container
  sudo mount /dev/mapper/container /home/user/private
  notify-send -u normal "Открытие контейнера выполнено. Занято: "`df -h | grep private | awk '{print $5}'`
fi

Для открытия с запросом ввода пароля потребуется вызов окна терминала.

gedit /home/user/keys/privateopen2.sh

Содержание:

#!/bin/sh
dropbox stop
if  grep -q "private" /proc/mounts; then
  notify-send -u normal "Контейнер уже был открыт!"
else
  gnome-terminal --command="/home/user/keys/privatepass.sh"
fi

И файл

gedit /home/user/keys/privatepass.sh

Содержание:

#!/bin/sh
sudo cryptsetup luksOpen /home/user/.private/container.crt container
sudo mount /dev/mapper/container /home/user/private
notify-send -u normal "Открытие контейнера выполнено. Занято: "`df -h | grep private | awk '{print $5}'`

Для закрытия - проверяем, не был ли уже закрыт контейнер, закрываем и стартуем службу dropbox.

gedit /home/user/keys/privateclose.sh

Его содержание:

#!/bin/sh
if  grep -q "private" /proc/mounts; then
  sudo umount /dev/mapper/container  
  sudo cryptsetup luksClose /dev/mapper/container 
   notify-send -u normal "Выполнено закрытие контейнера"
  dropbox start
else
  notify-send -u normal "Контейнер был неактивен"
fi

Даем права на выполнение

sudo chmod +x /home/user/keys/*.sh
Не обязательно именно так располагать каталоги и давать имена. Никто не мешает дать файлу ключа имя /home/user/.icons/warum.png, а контейнеру имя debian_install_QIP.tar.gz, и поместить среди иных пакетов.

В завершение, создадим ссылку для помещения в dropbox каталога .private под именем dropboxcript

sudo ln -ds /home/user/.private /home/user/Dropbox/dropboxcript

Все.

Увеличение размера (контейнера)

Посмотреть, сколько места использовано (занято файлами) в нашем контейнере, можно так:

df -h | grep container 
Файл.система           Размер Использовано  Дост Использовано% Cмонтировано в
/dev/mapper/container     43M          32M   10M           75% /home/user/private

Если заканчивается свободное место, увеличим размер контейнера. Например, на 50M. Перед этим - убедимся, что «контейнер закрыт».

  • Увеличим размер файла-контейнера (на 50M)
dd if=/dev/urandom bs=1M count=50 >> /home/user/.private/container.crt
  • Открываем
sudo cryptsetup luksOpen /home/user/.private/container.crt -d /home/user/keys/container.key container
  • Увеличим размер контейнера (на все добавленное к файлу место)
sudo cryptsetup resize container
  • Проверка файловой системы
sudo e2fsck -f /dev/mapper/container
  • Увеличение размера файловой системы (на все добавленное к контейнеру место)
sudo resize2fs -p /dev/mapper/container

Вывод выглядит так:

~$ sudo e2fsck -f /dev/mapper/container
e2fsck 1.42 (29-Nov-2011)
Проход 1: Проверка inodes, блокs, а также размеров
Pass 2: Checking каталог structure
Pass 3: Checking каталог connectivity
Pass 4: Checking reference counts
Pass 5: Checking группа summary information
container: 14/12288 files (7.1% non-contiguous), 6455/49152 blocks
 
~$ sudo resize2fs -p /dev/mapper/container
resize2fs 1.42 (29-Nov-2011)
Resizing the filesystem on /dev/mapper/container to 100352 (1k) blocks.
Begin pass 1 (max = 7)
Увеличение таблицы inod'овXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/mapper/container is now 100352 blocks long.

Монтируем и смотрим.

sudo mount /dev/mapper/container /home/user/private
df -h | grep container 
Файл.система           Размер Использовано  Дост Использовано% Cмонтировано в
/dev/mapper/container     91M          32M   58M           36% /home/user/private

Ссылки