Альтернатива EncFS или прозрачное шифрование в фоновом режиме для userspace
Когда-то давно я пользовался утилитой под названием EncFS. Её прелесть была в том, что она позволяла монтировать одну директорию (для шифрованного контента) в другую (для дешифрованного), при этом для пользователя всё оставалось прозрачным, он работал со своими данными как обычно, а шифрование происходило в фоновом режиме. Конечно, операции чтения/записи при этом занимали бОльшее время, да и нагрузка на CPU повышалась, но всё это было более, чем приемлемым, так как эта утилита и не была рассчитана на то, чтобы с её помощью шифровали образы дисков или многогигабайтные архивы (для подобных целей очевидно, следует использовать LUKS или что-то подобное). Юзкейсы вполне просты и понятны - например, зашифровать директорию с документами перед тем, как отправить в облако.
Боль и разочарование
И волосы тех, кто пользовался EncFS были гладкими и шелковистыми ровно до того момента, пока коду EncFS в 2014-м году не провели серьёзный аудит и не выявили пачку критических уязвимостей, после чего EncFS исключили из состава пакетов stable репозитория debian, что само по себе является некоей лакмусовой бумажкой, говорящей о том, что лучше этим не пользоваться в принципе. Затем какое-то время что-то чинили, а в 2017-м снова нашли уязвимость. Я ещё после 2014-го года искал альтернативу, удовлетворяющую следующему списку требований:
- Отсутствие необходимости использовать отдельный раздел
- Прозрачное шифрование в фоне
- Простота использования
- Наличие в стандартном репозитории debian
Собственно, тогда я подобной альтернативы к своему сожалению, не нашёл и через какое-то время забыл об этом, испытывая некоторые неудобства при использовании LUKS для своих задач.
И вот, недавно я решил проверить и обнаружил в репозитории debian stable (10-й релиз на текущий момент) пакет encfs, но при установке меня постигло разочарование:
Encfs security information
According to a security audit by Taylor Hornby (Defuse Security), the current
implementation of Encfs is vulnerable or potentially vulnerable to multiple types of
attacks. For example, an attacker with read/write access to encrypted data might lower
the decryption complexity for subsequently encrypted data without this being noticed by
a legitimate user, or might use timing analysis to deduce information.
Until these issues are resolved, encfs should not be considered a safe home for
sensitive data in scenarios where such attacks are possible.
То есть, в стабильный репозиторий мы пакет добавили, но при установке предупреждаем, что он содержит уязвимости и лучше им не пользоваться. Гениально! Конечно, от любопытных глаз простых и даже не очень простых пользователей нас EncFS вполне может уберечь, но от мейнтейнеров дебиана с их фанатизмом я такого не ожидал.
Альтернатива
В связи со сложившейся ситуацией я решил проверить, а не появилось ли новых альтернатив вышеупомянутой EncFS и через полчаса обнаружил в точности то, что мне нужно, удовлетворяющее всем моим требованиям. Знакомьтесь, это CryFS, созданная в 2015-м году. Разработана была изначально с расчётом на хранение шифрованных директорий во внешнем облаке. Если вам интересно, чем она отличается от EncFS, то вам сюда, но забегая вперёд, могу сказать, что с пользовательской точки зрения ответ будет - "ничем". В статье по вышеупомянутой ссылке так же есть сравнение с eCryptfs, gocryptfs и прочими.
Кроме всего прочего, CryFS работает и под MacOS и даже можно собрать тестовый вариант под Windows, что даёт возможность надеяться на то, что в плане мультиплатформенности он скоро догонит EncFS. Да и вообще, проект довольно живой и последний коммит в официальном репозитории на гитхабе был пару месяцев назад, что не может не радовать.
Установка и использование
Установка на debian-based системах (по крайней мере на свежих версиях) до безумия проста:
sudo apt-get install cryfs
Использование так же не относится к rocket science, но есть один нюанс, который не обозначен явно в документации.
root@pve [01:51:25]:~# mkdir encrypted decrypted
root@pve [01:51:43]:~# cryfs encrypted decrypted
CryFS Version 0.9.10
Use default settings?
Your choice [y/n]: y
Generating secure encryption key. This might take some time..done
Password:
Confirm Password:
Creating config file (this can take some time)...done
Mounting filesystem. To unmount, call:
$ fusermount -u "/root/decrypted"
root@pve [01:52:03]:~# mount | tail -n 1
cryfs@/root/encrypted on /root/decrypted type fuse.cryfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
root@pve [01:52:33]:~# echo test > decrypted/test.txt
root@pve [01:52:54]:~# ls encrypted/
2FF AAE cryfs.config
В данном примере мы создали две директории - encrypted, в которой будут храниться зашифрованные данные и decrypted, которая будет являться точкой монтирования, после чего с помощью cryfs смонтировали первую во вторую, в процессе чего был запрошен пароль для шифрования и создана вся необходимая структура включая конфигурационный файл. Затем мы записали тестовый файл в директорию decrypted, после чего в директории encrypted появилось некоторое количество зашифрованных данных. С файлом test.txt мы затем можем работать как обычно - отредактировать его, переименовать, удалить, изменить права, но даже если мы создадим в директории decrypted папку, на которую выдадим права другому пользователю, то попытка этого пользователя получить доступ к этой директории закончится неудачей.
root@pve [01:58:00]:~# mkdir decrypted/guest
root@pve [01:58:25]:~# chown guest decrypted/guest/
root@pve [01:58:34]:~# sudo -u guest bash
guest@pve:/root$ cd decrypted/guest
bash: cd: decrypted/guest: Permission denied
С одной стороны это хорошо, но в моём случае есть необходимость смонтировать зашифрованную директорию, в которой будут расположены директории, владельцами которых будут различные пользователи. Можно конечно монтировать каждую директорию от имени каждого пользователя, но это не очень удобно для моей задачи. На гитхабе проекта было написано, что должен помочь следующий способ:
root@pve [01:59:30]:~# fusermount -u /root/decrypted
root@pve [02:03:12]:~# ls -la decrypted/
total 8
drwxr-xr-x 2 root root 4096 Jan 4 01:51 .
drwx------ 10 root root 4096 Jan 4 01:51 ..
root@pve [02:03:18]:~# cryfs encrypted decrypted -- -o allow_other
CryFS Version 0.9.10
Password:
Loading config file (this can take some time)...done
Mounting filesystem. To unmount, call:
$ fusermount -u "/root/decrypted"
root@pve [02:03:57]:~# cat decrypted/test.txt
test
Но и он не помог:
root@pve [02:07:48]:~# sudo -u guest bash
guest@pve:/root$ cd decrypted/guest/
bash: cd: decrypted/guest/: Permission denied
guest@pve:/root$ exit
root@pve [02:14:30]:~# ls -la | grep decry
drwxr-xr-x 2 root root 4096 Jan 4 02:03 decrypted
Решение
В итоге я нашёл, каким образом можно решить проблему. Во-первых, нужно действительно монтировать с ключом -o allow_other. И во-вторых, внутри зашифрованной директории требуется сделать поддиректорию с правами на чтение для любого пользователя, в которой уже будут храниться директории самих пользователей, после чего уже её через mount -o bind монтировать в нужное место файловой системы. Собственно, остановился на втором варианте, получилось как-то так:
#!/bin/sh
cryfs /mnt/hd1000/private /mnt/intermediate-private -- -o allow_other
mount -o bind /mnt/intermediate-private/private /mnt/private
Для чего мне это было нужно?
У меня есть несколько разношёрстных девайсов - планшет и пара телефонов на андроиде, тв-приставка, куча разных *Pi, откуда нужно синхронизировать бекапы. Самый удобный для меня способ это делать - через SFTP с использованием MySecureShell на стороне сервера. Так как устройства периодически появляются и исчезают, есть скрипты для создания пользователей со всеми необходимыми настройками. Раньше я использовал отдельный зашифрованный с помощью LUKS раздел на диске, но меня это перестало устраивать, так как периодически то хочется сэкономить место, оторванное от основного раздела, то необходимо выделить больше, чем позволяет зашифрованный раздел. Связка MySecureShell и CryFS пока меня полностью устраивает.
Теги: админское