NextCloud : File-based Restoration
Background
Nextcloud is a well known file share platform, open source, freely available with nice syncing features. It is the OwnCloud "successor". The platform is providing a web based portal to manage files and shares but as well syncing clients are available on most OSs. The use case I'm trying to achieve here is the file-level restoration. Most of the time, the backup is doing a full VM backup with all files. But what if a user is requesting a restoration of a single file or directory ?
File-based Restoration
When user deletes a folder or a file in NextCLoud, they can - in most of the case - use their own recycle bin to recover the files/folders. This article describes the case where using the user recycle bin is not possible.
NextCloud is organised as a web/cloud application so all metadata are stored into a DB, this DB is the only one who knows where files are stored and what are the owner of these files. When looking at the folder structure, we can see in the data folder a lot of folders with random names like hashes. The folders are the home folder of the users. You need to know the name's behind that hash to be able to restore the file at the right place. Digging in each folders is an option when you have 5 users, not when you have thousands.
Here is an example of a directory structure of the root data folder on a massive NextCloud deployment (above 800 users)
# ls /data/nextcloud/ -l
total 767332
drwxr-xr-x. 4 apache apache 44 Sep 19 2019 833c9c0a-627e-1039-8a58-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Aug 28 2018 85cd2996-3ae6-1038-8fdf-35a02700ab07
drwxr-xr-x. 7 apache apache 115 Sep 9 2019 8631ff06-5dcc-1039-8a52-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Oct 21 2019 87586048-6c75-1039-8a68-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Oct 19 2018 88429ef2-2b48-1038-8fcc-35a02700ab07
drwxr-xr-x. 5 apache apache 54 Apr 15 2019 8b90f3be-e408-1038-90c8-35a02700ab07
drwxr-xr-x. 6 apache apache 96 Apr 3 2020 8272271e-9a44-1039-8a9f-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Oct 2 2018 85353ada-8890-1037-8566-09a7876daa78
drwxr-xr-x. 7 apache apache 91 Sep 5 2018 8648953e-1ac1-1038-8fab-35a02700ab07
drwxr-xr-x. 6 apache apache 89 Nov 26 2019 879faa60-2f0f-1037-8420-09a7876daa78
drwxr-xr-x. 7 apache apache 91 Mar 18 2019 883fca62-71ef-1038-903b-35a02700ab07
drwxr-xr-x. 6 apache apache 69 Apr 10 2019 8ad2ba32-f022-1036-837a-09a7876daa78
[...]
total 767332
drwxr-xr-x. 4 apache apache 44 Sep 19 2019 833c9c0a-627e-1039-8a58-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Aug 28 2018 85cd2996-3ae6-1038-8fdf-35a02700ab07
drwxr-xr-x. 7 apache apache 115 Sep 9 2019 8631ff06-5dcc-1039-8a52-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Oct 21 2019 87586048-6c75-1039-8a68-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Oct 19 2018 88429ef2-2b48-1038-8fcc-35a02700ab07
drwxr-xr-x. 5 apache apache 54 Apr 15 2019 8b90f3be-e408-1038-90c8-35a02700ab07
drwxr-xr-x. 6 apache apache 96 Apr 3 2020 8272271e-9a44-1039-8a9f-dd20dc2926d4
drwxr-xr-x. 4 apache apache 32 Oct 2 2018 85353ada-8890-1037-8566-09a7876daa78
drwxr-xr-x. 7 apache apache 91 Sep 5 2018 8648953e-1ac1-1038-8fab-35a02700ab07
drwxr-xr-x. 6 apache apache 89 Nov 26 2019 879faa60-2f0f-1037-8420-09a7876daa78
drwxr-xr-x. 7 apache apache 91 Mar 18 2019 883fca62-71ef-1038-903b-35a02700ab07
drwxr-xr-x. 6 apache apache 69 Apr 10 2019 8ad2ba32-f022-1036-837a-09a7876daa78
[...]
When reading the above profiles folder, this is impossible to match any of folder names with a real username.
Hopefully, there is a NextCloud tool that can convert the folder name into a real username. The tool is called occ, but I have created a script that encapsulate it so it is easier to use.
Here is an example with my account (the folder returned is an example and not the real one. As well as the above list of folder name is obfuscated for security reasons.
Sample call :
$ ./getUserFolder.php flhoest
Home folder for flhoest is /data/nextcloud/8c597676-e5c5-1036-9db5-09a7876daa78
Home folder for flhoest is /data/nextcloud/8c597676-e5c5-1036-9db5-09a7876daa78
#!/usr/bin/php
<?php
<?php
$rootFolder="/data/nextcloud";
if(@!$argv[1])
{
print("Error! must specify username.\n\n");
exit();
}
else
{
$usr=$argv[1];
$result=exec("sudo -u apache php /opt/nextcloud/occ ldap:search ".$usr);
$tmp=explode("(",$result);
$username=str_replace(")", "",$tmp[1]);
$homeFolder=$rootFolder."/".$username;
print("Home folder for ".$usr." is ".$homeFolder."\n");
}
?>
This will help IT Administrators to locate the folder where you need to restore file. When the file is restored, you still need to make a sync between the disk content and the DB content (yes, remember, NextCloud is an application). The tool is again occ but called with different parameters. It allows to rescan the disk and make sure the internal NextCloud DB is matching the data.
Sample call :
$ ./rescanUserFolder.php flhoest
Looking for flhoest home folder
Rescan in progress for /data/nextcloud/8c597676-e5c5-1036-9db5-09a7876daa78 ...
Rescan summary :
+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 995 | 8399 | 00:00:22 |
+---------+-------+--------------+
Looking for flhoest home folder
Rescan in progress for /data/nextcloud/8c597676-e5c5-1036-9db5-09a7876daa78 ...
Rescan summary :
+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 995 | 8399 | 00:00:22 |
+---------+-------+--------------+
The code of the above script is here :
#!/usr/bin/php
<?php
$rootFolder="/data/nextcloud";
if(!$argv[1])
{
print("Error! must specify username.\n\n");
exit();
}
else
{
// Step 1 : get home folder location
$usr=$argv[1];
print("Looking for ".$usr." home folder\n");
$result=exec("sudo -u apache php /opt/nextcloud/occ ldap:search ".$usr);
$tmp=explode("(",$result);
$username=str_replace(")", "",$tmp[1]);
$homeFolder=$rootFolder."/".$username;
print("Rescan in progress for ".$homeFolder." ...");
$output=exec("sudo -u apache php /opt/nextcloud/occ files:scan ".$username,$fullOutput);
print("\nRescan summary :\n");
for($i=1;$i<count($fullOutput);$i++)
{
print($fullOutput[$i]."\n");
}
print("\n");
}
?>
When the data are in sync, the user is now able to see the restored files/folders and continue to work efficiently !
I saved my butt a couple of times. I hope this helps ! ;)
Comments
Post a Comment
Thank you for your message, it has been sent to the moderator for review...