Инструкция по отрицаемому хранению данных на носителе с Tails
Цель
Иметь на одном и том же носителе как загрузочный Tails, так и хранилище для дополнительных данных, которое не будет вычищаться перезагрузкой, причём это хранилище должно быть отрицаемым.
Общая идея
На носитель устанавливается Tails, а на оставшемся свободном месте диска (в хвосте) делается бессигнатурный шифрованный раздел для хранения данных.
Легенда
Затёрли флэшку/диск/SD-карточку рандомом, потом записали стандартный Tails по инструкции с сайта, и всё на том. Больше ничего не делали, никаких скрытых данных нет.
Подводные камни
- В ядре Linux решили не заморачиваться консистентностью разных компонент ядра, просто запретив их взаимодействие. Итог: всё dm-based (dmsetup, cryptsetup, LVM) совместимо между собой, но несовместимо с монтированием файловой системы. В частности, если на диске /dev/sda есть файловая система на /dev/sda<N>, и она подмонтирована, нельзя адресовать свободное (неразбитое) дисковое пространство на /dev/sda с помощью dmsetup или cryptsetup (ядро ставит bd_claim на блочное устройство /dev/sda, запрещая его использование dm'у; задаваемые оффсеты и размеры при этом совершенно неважны). Однако, если файловая система находится на ином блочном устройстве (важен логический, а не физический уровень) — к примеру, на /dev/mapper/name, который зацеплен на /dev/sda<N>, монтирование этой ФС не будет препятствовать использованию dm/cryptsetup на /dev/sda.1
- По умолчанию Tails не грузит все файлы в память, а каждый раз запрашивает их с диска/флешки, т.е. файловая система с диска будет всегда подмонтирована. Из-за предыдущего пункта это блокирует возможность использовать неразбитое дисковое пространство для хранения данных. Можно, конечно, загрузить Tails, потом на лету менять MBR, добавляя и убирая нужные разделы, но это геморройно, грязно и может испортить легенду.
Недокументированные возможности
С помощью реверс-инжиниринга можно выяснить, что в Tails есть тайная недокументированная опция загрузки, которая держится в строжайшем секрете — toram («to RAM»). Она позволяет вэйпонизировать Tails в нужном направлении: в самом начале загрузки, когда выводится меню isolinux с двумя вариантами (обычный и fail-safe), выбираем нам нужный, нажимаем tab, дописываем toram к опциям загрузки и грузим. После этого Tails будет загружен в память, а файловые системы на носителе, с которого он был загружен, не будут подмонтированы — носитель можно будет даже отключить, и Tails продолжит работать из RAM.
Семь шагов на пути к успеху
- Следуя инструкциям на сайте Tails, с помощью isohybrid преобразовываем iso в образ, нужный для записи на флешку/диск.2 (Примечание: возможно, в этом уже нет необходимости).
- Записываем получившийся образ с помощью команды(предполагаем, что запись идёт на /dev/sdb). Это создаёт на устройстве MBR и таблицу разделов, в первом разделе (/dev/sdb1) будет находиться Tails.
# dd if=/path/to/file.iso of=/dev/sdb
- Создаём бессигнатурный шифрованный раздел на неразбитом пространстве диска:3Оффсет (задается в секторах) можно не запоминать, потому что его легко посмотреть fdisk-ом — это последний сектор первого раздела + 1. В данном случае мы используем вариант «выделяем всё пространство до конца диска». Однако, лучше сделать иначе: если размер носителя позволяет, взять какой-то фиксированный offset побольше, чтобы при последующем обновлении Tails и его записи на этот же носитель через dd (размер может увеличиться) наш бессигнатурный раздел не был затёрт.
# cryptsetup -c aes-xts-plain64 -s 512 -h sha512 -o оффсет create NAME /dev/sdb
Вышеприведённая команда cryptsetup создаёт устройство /dev/mapper/NAME с несменяемым паролем на шифрование. Внутри него лучше создать LVM с LUKS-шифрованными логическими томами или просто один LUKS-раздел на всё устройство, чтобы не терять возможность менять пароль, убивать слоты и т.д. Как это сделать технически — уже обсуждалось [3], [4].
- Если работаем c SD-карточки, имеющей физический переключатель для блокировки записи, включаем его: на этапе загрузки запись на носитель нам не понадобится.
- Грузимся, включая опцию загрузчика toram (см. выше).
- При поставленном локе на адаптере (см. п.5, этот комментарий только на случай, если он используется) и dmsetup и cryptsetup позволяют создавать только read only mappings, причем cryptsetup умный и сам догадывается включить режимр r/o, а вот dmsetup'у надо указывать опцию -r явно. В предположении, что нужный раздел с данными уже заранее создан на свободном дисковом пространстве, монтируется он так же:(остальные опции подключения LUKS/LVM добавляем по вкусу, если нужны). Если же нужно сделать r/w-доступ к скрытому разделу на SD-карте, надо:
# cryptsetup -c aes-xts-plain64 -s 512 -h sha512 -o оффсет create NAME DEVICE
- Достать SD-карту (предполагаем, что она не подмонтирована).
- Объяснить ядру, что мы её достали (бывают «умные» адаптеры, которые usb disconnect не ловят, пока к SD-карте не обратишься).
- Cнять лок и перевставить SD-карточку.
- Подключить скрытый раздел и смонтировать его в режиме r/w.
1Уже давно пора разделы диска делать принудительно через dm, тогда бы такой проблемы не возникло вообще. Некоторые пояснения:
2) Дело не в том, что раздел открыт на запись; дело в том, что при монтировании ФС ядро делает bd_claim. Таким образом, никакая другая компонента ядра не может сделать bd_claim на подраздел и блочное устройство (диск) в целом (т.е. дело не в том, где физически находится монтируемый подраздел, а в том, логической частью какого блочного устройства он является — bd_claim делается именно на блочное устройство; из-за этого можно без проблем подмонтировать mapping и это ни на что не повлияет — каждый mapping сам по себе блочное устройство).
3) Это проблемы Linux, а точнее — интерференция системы подразделов и системы dm. Во имя консистентности был забит костыль, дабы эти подсистемы не мешали друг другу. В общем, как всегда, проблема legacy и эволюционного проектирования.
Монтирование ФС — это частный случай bd_claim. Важно то, что
b) Одна и та же компонента ядра может это делать без ограничений. Например, всё, что делается через dm (это и dmsetup linear, и dm-crypt, и LVM) совместимо друг с другом.
Т.е. dm внутри себя поддерживает консистентность маппингов, а костыль с bd_claim сделан, чтобы не заморачиваться консистентностью разных подсистем ядра для доступа к одним и тем же блочным устройствам.
2Обычные iso'шки не поддерживают загрузки с флэшек хотя бы потому, что там нет MBR нет и т.п. Гибридные iso когда делаются, а когда нет — это от авторов зависит. Не исключаю, что в Debian iso гибридные по умолчанию.
3Поскольку по умолчанию TRIM отключен, микроконтроллер не знает, какие сектора диска ОС считает свободными. Для нашего случая это хорошо, т.к. неиспользуемое место не будет обнуляться в случае флэшек и SD-карточек.
Вы идёте неправильным путём. Tails не предназначен для модификаций. Это решение искоробочное. Хотите сделать для себя и по уму — ставьте бессигнатурку, хотите в ней амнезию — ставьте Xen с соответствующими настройками. Это будет лучше Tails хотя бы из-за того, что от зловредов можно скрыть, какое железо и серийники на ПК используются.
Вы совершенно правы в общем случае. Однако, мой юзеркейс, к счастью для меня, позволяет воспользоваться более простыми методами, чем бессигнатурка и xen. Даже дистр модифицировать не понадобится, достаточно уметь воспользоваться его возможностями, о которых раньше не подозревал.
Да и куда мне сейчас заниматься бессигнатуркой и виртулизацией? Мне бы хоть с простыми действиями справиться. :-)
Кое-где я грубо ошибался. В действительности, процессор в основном загружают следующие процессы:
dpkg
ldconf
gnome-terminal
gnome-panel
Более всего загружают первые два. Установку удалось закончить удачно и сравнительно быстро, ограничив использование процессора для каждого из двух процессов на 20% командами (в отдельных терминалах)
Но это совсем уж сложносочлененный костыль. Попробовал перейти в консоль и остановить gdm3, но тогда административный пароль, заданный при старте дистра, является недействительным, поскольку существует только в рамках графической среды. :-)
Как войти в консоль без Гнома, пока не разобрался. Может быть кто-то подскажет?
Пожалуйста, пинайте, если видите ошибки или глупость.
Зачем эти извращения, когда достаточно написать nice -n 20 перед любой командой?
Ctrl+Alt+F1, Ctrl+Alt+F2 и т.д. На одной из них запущены иксы (по умолчанию вроде на F7). В Tails, когда я на него смотрел, был то ли пустой пароль, то ли сразу открытая рутовая консоль (в текстовых терминалах).
Но стратегически вы должны понимать, что чем дальше, тем больше вы будете заниматься не столько решением проблем, сколько войной с автоматикой Tails'а.
К сожалению, не помогает. Пробовал много раз сейчас и раньше. Причина в том, что nice перераспределяет все доступные ресурсы процессора. Это не помогает избежать пиковых загрузок.
Поэтому пользуюсь в таких случаях утилитой cpulimit. Она ограничивает количество ресурсов, занятых конкретным процессом. В предложенном выше варианте, два процесса получили к диспозиции по 20% от ресурсов процессора. Т.е., они занимают вместе только 40% и не могут никак занять больше. А остальные 60% свободны для других процессов. Это позволяет удерживать общую загрузку процессора на уровне 60-70% (кроме кратких пиков) и утановить пакет с большим количеством зависимостей.
Мы не поняли друг друга. Имелось ввиду другое. При запуске Tails появляется предложение задать административный пароль. Если этого не сделать, то будут невозможны никакие административные действия.
Я подумал, что перейдя в консоль и остановив Гном, можно снизить пиковые загрузки процессора при установке "сложных" пакетов. Вполнил
Либо через канувший в лета TrueCrypt, ограниченная поддержка которого теперь есть в LUKS, либо через доморощенные костыли. Помимо оговорок про все минусы отрицаемости в TrueCrypt, я, кстати, должен сказать, что не знаю, работали ли обманные ОС в Linux хоть когда-нибудь, и, если работали, то как с этим обстоят дела сейчас.
В норме там шифруют всё с помощью LUKS, см. man cryptsetup. Он является частью ядра и не зависит от того, какая ФС (файловая система) будет нарезана поверх него (и будет ли она там вообще, а не какой-нибудь LVM или ещё что).
Понятно. Это безусловно баг, потому что установка пакета превращается в форк-бомбу, которая завешивает компьютер. При nice -n 20 даже при загрузке процессора под завязку завешиваться ничего не должно, т.к. новые процессы получают безусловный приоритет перед жрущими проц.
А если не задавать, а сразу после запуска Tails перейти в консоль и залогиниться под рутом? Он не даст войти с пустым паролем? Если вы зашли под рутом в какой-то момент, sudo можно более нигде не писать, а менять пароль можно с помощью команды passwd, если вам это действительно нужно.
Вы оказались правы. Причем баг был, скорее всего где-то у меня самого. Команда nice -n 20 решает проблему, как Вы и указывали. Установка нужных пакетов еще и ускорилась.
Таким образом, к настоящему моменту с помощью сравнительно простых действий можно скрытно пользоваться пакетами, не входящими в стандартный Tails дистрибутив.
Спасибо всем за помощь.
1. Открываем plain-контейнер (который заполнен нулями).
2. Файловой системы на нем нет. Создаем LUKS-контейнер внутри plain-контейнера
3. Открываем LUKS-контейнер и создаем на нем ФС
Все ли правильно и безопасно?
Что за бред? Откуда там нули? Вы про затирание данных нулями, которые пишутся при заполнении диска рандомом? Так потом случайный ключ удаляется, и можно считать, что там просто рандом. Вы же открываете plain-контейнер новой пассфразой. Можно, конечно, и той, которая использовалась при затирании, но я не вижу в этом никакого смысла.
--use-random, пожалуй, нет смысла писать. Хуже от этого не станет, но просто нет смысла.
Да, именно так. Я, просто, неточно выразился.
А если я игнорирую параметр -o (оффсет) и сразу продолжаю как:
# сryptsetup -c aes-xts-plain64 -s 512 -h sha512 create NAME /dev/sdb2
Получаю предложение ввести пароль. Ввожу. Все ОК.
Ну а как к нему получить доступ?
# cryptsetup luksOpen /dev/sdb2 db – не помогает.
Его же нужно расшифровать, монтировать и форматировать в какую то файловую систему. Мне например LVМ не нужен.
выходит инфа.
Но как только пытаешься выполнить luksOpen, вылезает:
"Device /dev/sdb2 is not a valid LUKS device."
Help смотрю – иных <action> не вижу.
# cryptsetup -c aes-xts-plain64 -s 512 -h sha512 -o оффсет create NAME /dev/sdb
Enter passphrase:
Device NAME already exists.
# cryptsetup -q --use-random -c aes-xts-plain64 -s 512 -h sha512 luksFormat /dev/mapper/NAME
Enter LUKS passphrase:
# cryptsetup luksOpen /dev/mapper/NAME NAME
Device 555 already exists.
# mkfs.ext4 /dev/mapper/NAME
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
....
....
Allocating group tables: done
Writing inode tables: done
Creating journal (XXXXX blocks): done
Writing superblocks and filesystem accounting information: done
# mkdir /NAME
# mount /dev/mapper/NAME /NAME
В файловой системе появляется папка NAME.
Все правильно сделано?
Этой командой легко можно нечайно выстрелить себе в ногу, так что лучше отдавать себе отчёт в том, что делаете, а то запорете инфу на дисках. В начале диска записан Tails. Если не указать offset, файлы Tails'а будут перезаписаны. Если вы так без оффсета шифруете просто посторонний другой чистый диск, то проблем нет. И обратите внимание, там /dev/sdb написано, а не /dev/sdb2. Шифруется неразмеченное дисковое пространство, а не второй дисковый раздел (так тоже можно делать, но это будет минус для отрицаемости).
Желательно внутри отформатировать устройство хотя бы под LUKS:
Отключение в обратном порядке:
При повторном монтировании всё будет так же, только команды luksFormat и mkfs.ext4 выполнять не надо, иначе затрёте там записанную информацию. Если при повторном открытии контейнера при вводе пароля в первой команде ошиблись, нужно выполнить