После очередного обновления Nextcloud до 27 версии возникла проблема с шифрованием. При открытии файлов с помощью Collabora Office возникало сообщение:
Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you
Disclaimer!
Сразу скажу, в данной статье не будет пошаговой инструкции что делать, но будет дано направление и описаны все плюсы и минусы и будет немного исследований. Статья немного сумбурная, поскольку писалась через какое‑то время после всех событий.
Всё что вы делаете — вы делаете на свой страх и риск!
Перед тем, как что‑то делать — остановите все клиенты Nextcloud, сделайте по возможности бекап данных у клиентов, закройте доступы к серверу Nextcloud, сделайте всё, чтоб клиенты не ходили в Nextcloud. Maintenance — не выход. Так же сделайте бекап данных с которыми собираетесь работать, бекап app и базы данных и бекапы всех бекапов, которые у вас остались, поскольку они могут ротироваться.
Исследования
После вышеприведённого сообщения, файл больше не открывался, даже если скачать из web‑версии поскольку перезаписывались ключи шифрования для данного файла
Если забекапить их заранее и после этого не пытаться открыть с помощью collabora, а просто скачать, файл можно было прочитать, иначе доступ к файлу терялся наглухо.
Сами ключи лежат в files_encryption у каждого пользователя.
Усиленное гугление, ничего не дало, проблема на момент написания статьи не решаема.
Откатить Nextcloud можно только если есть бекап app и базы данных, файлы при обновлении как правило не трогаются, но если уже было обновление и сломало пару файлов, которые попытались открыть — то всё, с этими файлами ничего не сделать, если нет бекапов ключей. Ну если это пару файлов — то можно и вручную восстановить из локальной копии, если они не успели синхронизироваться. В общем очень много ЕСЛИ.
При этом, новые файлы в новой версии создаются нормально.
Казалось бы, какая‑то проблемы со старыми ключами шифрования, о которой есть информация в интернете, но это касалось совсем старой версии.
Команды типа:
php occ encryption:scan:legacy-format
php occ encryption:fix-encrypted-version
php occ encryption:drop-legacy-filekey
Не помогали.
Отчасти проблема еще в том, что при изменении файлов, меняется некая глубина, из-за чего в таблице в колонке encrypted в таблице oc_filecache в постгресе, значение может быть не только 0 или 1, но выше 1, вроде как согласно версии файла, но до конца не ясно как это работает.
Отключаем шифрование
Единственным решением становится полный отказ от шифрования Nextcloud и расшифровка файлов или загрузка файлов из локальных nextcloud на клиентских pc или из стороннего бекапа.
Варианты такие:
php occ encryption:decrypt-all
загрузка файлов из локальных nextcloud на клиентских pc
загрузка из стороннего бекапа всего nextcloud сервера
загрузка файлов из бекапа клиента
Использование decrypt-all-files.php ( https://github.com/syseleven/nextcloud-tools/blob/master/rescue/decrypt-all-files.php )
Преимущества и недостатки:
Очень коряво работает, часть файлов почему-то не дешифруются можно в этом убедиться с помощью команды:
find . -type f -path "*/files/*" -not -path "*/keys/*" -exec sh -c 'head -c27 "$1" |grep HBEGIN:oc_encryption_ 1>/dev/null && echo "$1"' sh {} \;
Так же есть проблемы с файлами в корзине и с версиями файлов.
Долго, клиентов может быть много, не всегда синхронизированы все папки, есть вопросы с shared папками.
Бекап может быть недостаточно свежий или не полный (крайне желателен бекап базы и app).
Почти то же самое, что и с пунктом 2, плюс встречалась проблема, что в бекапе не бекапилось время создания файлов - а это очень важно. Да клиентов может быть много.
В итоге это почти идеальный вариант.
Почти идеальный вариант
По 5 варианту поподробней:
Из минусов - не создаются пустые папки, но это не проблема - можно пройтись по папке с исходными данными и создать такие же папки. Можно даже попробовать не забыть сохранить дату создания папок.
Так же теряются связи shared папок.
Нужно делать truncate таблицы oc_filecache и некоторых других, связанных с кешированием (проще всего сделать запрос на размер таблиц в postgres и отсортировать по размеру. самые тяжелые и будут те, что нужны - на всякий случай обязательно свериться с содержимым и сделать бекап).
Очищать желательно остановив nextcloud.
Так же нужно будет на всякий случай сделать сверку с списком папок и файлов, находящихся у клиента и даже можно сравнить md5, но это не обязательно.
Например это можно сделать так:
find . -type f -exec md5sum {} ; > md5_nextcloud_test.txt comm --check-order -23 md5_nextcloud_user_sorted.txt md5_nextcloud_test_sorted.txt > md5diff_user_in_test.txt
Под виндой собрать md5 можно установив linux в wsl, на маке и в линуксе эти инструменты должны быть из коробки.
После воссоздания структуры папок у каждого пользователя, необходимо убедиться в её корректности.
Обязательно должна быть папка files, иначе nextcloud будет ругаться.
Опциональны папки
files_trashbin
files_versions
В целом из nextcloud.log можно понять, что не так.
После запуска nextcloud нужно сделатьphp occ files:scan --all
Далее могут быть проблемы с расшаренными папками, если их много — можно попробовать разобраться в этом на основе имеющегося бекапа сломанной версии nextcloud. В целом то она работает, просто collabora ломает файлы.
После сканирования и восстановления расшаренных папок — можно аккуратно выпускать Nextcloud в мир. Есть минус, о котором я не упомянул — все клиенты будут синхронизировать данные заново. Это может занять значительное время.
Так же после отключения шифрования, хочется удалить мастер‑ключи, которые лежат в корне папки с данными. Если это сделать, то начинает возникать надоедливое сообщение:
Invalid private key for encryption app. Please update your private key password in your personal settings to recover access to your encrypted files
Или что-то типа того
Чтоб вычистить нечисть окончательно, нужно удалить из таблицы oc_appconfig строки с appid=encryption
Возможно можно просто отключить модуль encryption, но я решил убрать следы шифрования совсем.
После чего, nextcloud забудет об этом как о страшном сне.
Финал
А как же шифрование? Да очень просто — создаём шифрованный раздел luks (cryptsetup) и радуемся гораздо более гибкому, более быстрому и проверенному временем решению. Инструкций полно. Но забывать про бекапы нельзя.
Никому не нужное мнение
На последок хочу сказать, что архитектура этого шифрования на мой взгляд очень кривая, создаёт тонну дополнительных файлов и легко ломается.
При количестве реальных файлов 120 тысяч, реально файлов было свыше 600 тысяч.
Бонус про версии файлов
В качестве бонуса — небольшой лайфхак, чтоб отключить для определённой папки версии файлов. У меня например в Nextcloud хранятся логи всех сессий SecureCRT. Версии логов мне не нужны.
Сразу скажу, отключить версии файлов совсем не выйдет — они всё равно будут создаваться, но можно создать специального пользователя у которого будет единственная папка SecureCRT/Logs и расшарить эту папку основному пользователю.
Далее в кроне просто создаём задание:
php occ versions:cleanup user-nv
Которая просто чистит все версии файлов, у специального пользователя (не путать с основным юзером).
Про корзину
За очистку корзины отвечает параметр trashbin_retention_obligation в конфиге.
Он легко гуглится, но основной смысл в том, что корзина чистится, только когда лимит заканчивается. Мне это не нужно - достаточно, чтоб она чистилась раз в 7 дней, поэтому:
'trashbin_retention_obligation' => '7,7'
Поверхностный бекап
Так же я дополнительно настроил поверхностный бекап, в который входит md5, дата модификации и создания файла, размер, файловая структура,база данных и папка конфигурации. Запускаю раз в сутки. Эти данные мне бы сильно пригодились при восстановлении, а места занимают не много.
dt="$(date +%Y-%m-%d_%H-%M-%S)"
find /var/www/html/data -type d -printf '%Ts %Cs %s 00000000000000000000000000000000 %p\n' > /dev/shm/nextcloud_index
find /var/www/html/data -type f -printf '%Ts %Cs %s ' -exec md5sum {} \; >> /dev/shm/nextcloud_index
cat /dev/shm/nextcloud_index | sed -re "s/^([0-9]+) ([0-9]+) ([0-9]+) ([a-z0-9]{32}) +(.*)/\"\5\";\1;\2;\3;\4/g" | sort -u | gzip -9 > backups/${dt}_index.gz
pg_dump -U nextcloud nextcloud | gzip -9 > backups/${dt}_db.gz
tar -zcf backups/${dt}_app_config.tgz web/config/
Правда если у вас всё зашифрованные данные, этот бекап поможет лишь отчасти. Делать индекс лучше всё таки для расшифрованных данных.