Ticket ID#352: Data Recovery & Password Reset for Ocusers 01 & 03 - GriffinKat/group-a GitHub Wiki
Overview:
Two owncloud users, ocuser01 and ocuser03, have reported data loss and password issues
The task is to reset their passwords and recover their data using the automated backup system
Data to be recovered was uploaded between 30th May and 3rd July
Step 1. Find the users original passwords
Using this documentation I was able to find the server and directory the passwords were stored in
Link to documentation: https://github.com/GriffinKat/group-a/wiki/Ticket-ID-%23329-Puppet%E2%80%90Managed-OwnCloud-User-Creation-for-Client-Onboarding
Screenshot of file:
Step 2. Reset passwords
Using this command I was able to reset the passwords of the affected users
sudo -u www-data php /var/www/owncloud/occ user:resetpassword ocuser01
Step 3. Ensure users can log in and access their home directories post-reset
Verified users can login here
http://group-a.op-bit.nz/owncloud
Recover Data for Affected Users
ocuser01's files prior to recovery
ocuser03's files prior to recovery
On the apps server
Step 1. Create directories for User 1 & 3's data
We make it separately so we don't overwrite any existing data
sudo mkdir -p /var/www/owncloud/ocuser01_data
sudo mkdir -p /var/www/owncloud/ocuser03_data
sudo chown -R www-data:www-data /var/www/owncloud/ocuser01_data
sudo chown -R www-data:www-data /var/www/owncloud/ocuser03_data
sudo chmod -R 750 /var/www/owncloud/ocuser01_data
sudo chmod -R 750 /var/www/owncloud/ocuser03_data
sudo chown -R group-a:group-a /var/www/owncloud/ocuser01_data
sudo chown -R group-a:group-a /var/www/owncloud/ocuser03_data
Step 2. Isolate files by date
We want to recover files from the 30th of June to the 4th of May
ssh -i /etc/backup/.ssh/id_rsa [email protected] \
'find /home/group-a/storage/app/owncloud/data/ocuser01/ -newermt "2025-05-30" ! -newermt "2025-07-04"'
That lists only files modified after May 30 and before July 4 (inclusive)
ssh -i /etc/backup/.ssh/id_rsa [email protected] \
"find /home/group-a/storage/app/owncloud/data/ocuser01/ -newermt \"2025-05-30\" ! -newermt \"2025-07-04\" | sed '\''s|/home/group-a/storage/app/owncloud/data/ocuser01/||'\''" \
| rsync -avz --relative --no-implied-dirs --files-from=- -e "ssh -i /etc/backup/.ssh/id_rsa" \
[email protected]:/home/group-a/storage/app/owncloud/data/ocuser01/ /var/www/owncloud/ocuser01_data/
'
ssh -i /etc/backup/.ssh/id_rsa [email protected] \
"find /home/group-a/storage/app/owncloud/data/ocuser03/ -newermt \"2025-05-30\" ! -newermt \"2025-07-04\" | sed '\''s|/home/group-a/storage/app/owncloud/data/ocuser03/||'\''" \
| rsync -avz --relative --no-implied-dirs --files-from=- -e "ssh -i /etc/backup/.ssh/id_rsa" \
[email protected]:/home/group-a/storage/app/owncloud/data/ocuser03/ /var/www/owncloud/ocuser03_data/
'
Step 3. Restore data to users' owncloud directories or /ocuser1_data and /ocuser3_data for validation
sudo rsync -av /ocuser1_data/ /var/www/owncloud/data/ocuser01/
ssh -i /etc/backup/.ssh/id_rsa [email protected] \
"find /home/group-a/storage/app/owncloud/data/ocuser01/ -newermt '\''2025-05-30'\'' ! -newermt '\''2025-07-04'\''" \
| sed "s|/home/group-a/storage/app/owncloud/data/ocuser01/||" > /tmp/files_relative.txt && \
rsync -avz --relative --files-from=/tmp/files_relative.txt \
-e "ssh -i /etc/backup/.ssh/id_rsa" \
[email protected]:/home/group-a/storage/app/owncloud/data/ocuser01/ \
/ocuser1_data/'
Line | Command | Explanation |
---|---|---|
1 | sudo bash -c ' |
Run everything inside the quotes as root using bash . |
2 | ssh -i /etc/backup/.ssh/id_rsa [email protected] \ |
Use SSH with the given private key to connect to the backup server. |
3 | "find /home/group-a/storage/app/owncloud/data/ocuser01/ -newermt '2025-05-30' ! -newermt '2025-07-04'" \ |
On the remote server, find all files under ocuser01 modified after May 30, 2025, but before July 4, 2025. |
4 | ` | sed "s |
5 | rsync -avz --relative --files-from=/tmp/files_relative.txt \ |
Use rsync to copy only those listed files, keeping their original folder structure (thanks to --relative ). |
6 | -e "ssh -i /etc/backup/.ssh/id_rsa" \ |
Define the SSH method for rsync (using the same private key for authentication). |
7 | [email protected]:/home/group-a/storage/app/owncloud/data/ocuser01/ \ |
Set the base source directory on the remote server from where to pull the files. |
8 | /ocuser1_data/' |
Define the destination folder on the local system where the restored data for ocuser01 will be placed. |
Change the ownership of /var/www/owncloud/data/ocuser01/files/
sudo chown -R www-data:www-data /var/www/owncloud/data/ocuser01/files/
In order to get the web interface to upload the files, run this command
sudo -u www-data php /var/www/owncloud/occ files:scan ocuser01
User 1's files are now restored
ssh -i /etc/backup/.ssh/id_rsa [email protected] \
"find /home/group-a/storage/app/owncloud/data/ocuser03/ -newermt '\''2025-05-30'\'' ! -newermt '\''2025-07-04'\''" \
| sed "s|/home/group-a/storage/app/owncloud/data/ocuser03/||" > /tmp/files_relative.txt && \
rsync -avz --relative --files-from=/tmp/files_relative.txt \
-e "ssh -i /etc/backup/.ssh/id_rsa" \
[email protected]:/home/group-a/storage/app/owncloud/data/ocuser03/ \
/ocuser3_data/'
This command grabs all the files for ocuser03
from the backup server that were changed between May 30 and July 4. It first logs into the backup server using SSH and runs a find
command to look through ocuser03
's data folder, picking out anything modified during that time. It strips out the full path so weโre just left with the file names relative to the userโs folder, and saves that list to a temporary file. Then it uses rsync
to copy only those specific files back to the local server into /ocuser3_data/
, keeping the same folder structure as they had under ocuser03
. Basically, itโs a targeted restore of just the stuff that changed during that time window.
Line | Command | Explanation |
---|---|---|
1 | sudo bash -c ' |
Run everything inside the single quotes as a root-level shell command. |
2 | ssh -i /etc/backup/.ssh/id_rsa [email protected] \ |
Connect to the backup server via SSH using the specified private key. |
3 | "find /home/group-a/storage/app/owncloud/data/ocuser03/ -newermt '2025-05-30' ! -newermt '2025-07-04'" \ |
On the remote server, find all files for ocuser03 modified after May 30, 2025, but before July 4, 2025. |
4 | ` | sed "s |
5 | rsync -avz --relative --files-from=/tmp/files_relative.txt \ |
Use rsync to copy only the files listed, preserving their folder structure relative to ocuser03/ . |
6 | -e "ssh -i /etc/backup/.ssh/id_rsa" \ |
Specify SSH again for the rsync connection, using the private key. |
7 | [email protected]:/home/group-a/storage/app/owncloud/data/ocuser03/ \ |
Define the base directory on the remote (source) system. |
8 | /ocuser3_data/' |
Define the local destination directory where files will be restored. |
Step 4. Set Proper Permissions and Ownership
ownCloud requires files to be owned by www-data (or the web server user), or else it may not access them
sudo chown -R www-data:www-data /var/www/owncloud/data/ocuser03/files/
sudo chmod -R 755 /var/www/owncloud/data/ocuser03/files/
This command moves files from our backup directory into the ownCloud directory
sudo rsync -av /ocuser3_data/files/ /var/www/owncloud/data/ocuser03/files/
In order to get the web interface to upload the files, run this command
sudo -u www-data php /var/www/owncloud/occ files:scan ocuser03
Step 5. Ensure permissions are preserved and data is intact
Create a script to check file permissions for User 01
Run the script to check file permissions
Create a script to check file permissions for User 03
OWNCLOUD_USER="ocuser03"
OWNCLOUD_DATA_DIR="/var/www/owncloud/data/$OWNCLOUD_USER/files"
EXPECTED_SOURCE="/ocuser3_data/files"
echo "๐ Comparing file structure..."
diff <(cd "$OWNCLOUD_DATA_DIR" && find . | sort) <(cd "$EXPECTED_SOURCE" && find . | sort) > /tmp/file_diff.txt
if [ -s /tmp/file_diff.txt ](/GriffinKat/group-a/wiki/--s-/tmp/file_diff.txt-); then
echo "โ ๏ธ Differences detected between source and ownCloud data:"
cat /tmp/file_diff.txt
else
echo "โ
File structure matches expected source."
fi
echo ""
echo "๐ Checking file ownership and permissions in $OWNCLOUD_DATA_DIR..."
bad_perms=$(find "$OWNCLOUD_DATA_DIR" ! -user www-data -o ! -group www-data)
if [ -n "$bad_perms" ](/GriffinKat/group-a/wiki/--n-"$bad_perms"-); then
echo "โ ๏ธ These files have incorrect ownership:"
echo "$bad_perms"
else
echo "โ
All files are owned by www-data."
fi
echo ""
echo "โ
Verification complete."
These files have incorrect permissions
Remedy this by running this command
sudo chown -R www-data:www-data /var/www/owncloud/data/ocuser03/files
Step 6. Verify Backup System
Confirm backup system has been capturing user data as scheduled
SSH into the offsite backup server and run these commands
ls -lh /home/group-a/storage/db/db-daily/
ls -lh /home/group-a/storage/db/db-weekly/
Backup System Verification (as of 2025-06-04)
/home/group-a/storage/db/db-daily/
Daily Backups โ Date | File | Size |
---|---|---|
2025-06-04 | mysql-2025-06-04.sql | 2.4M |
2025-06-04 | owncloud-2025-06-04.sql | 149K |
2025-06-03 | mysql-2025-06-03.sql | 2.4M |
2025-06-03 | owncloud-2025-06-03.sql | 148K |
2025-06-02 | mysql-2025-06-02.sql | 2.4M |
2025-06-02 | owncloud-2025-06-02.sql | 148K |
2025-06-01 | mysql-2025-06-01.sql | 2.4M |
2025-06-01 | owncloud-2025-06-01.sql | 148K |
... | ... | ... |
Files present for past 7 days and today, confirming cron-based backup is running properly.
/home/group-a/storage/db/db-weekly/
Weekly Archives โ Date | Archive Name | Size |
---|---|---|
2025-06-01 | db-weekly-2025-06-01.tar.gz | 536K |
2025-05-25 | db-weekly-2025-05-25.tar.gz | 526K |
2025-05-18 | db-weekly-2025-05-18.tar.gz | 45B |
Weekly .tar.gz
archives created every Sunday.
Schedule Check
- All backup files have timestamps around
02:00 AM
- Weekly backups align with
Sunday
schedule
Conclusion: Backup system is functioning as expected with no missed days.
List backup archives covering the period from 30 May to 3 July
Daily Backups (/home/group-a/storage/db/db-daily/)
Date | MySQL Backup File | OwnCloud Backup File |
---|---|---|
2025-05-30 | mysql-2025-05-30.sql | owncloud-2025-05-30.sql |
2025-05-31 | mysql-2025-05-31.sql | owncloud-2025-05-31.sql |
2025-06-01 | mysql-2025-06-01.sql | owncloud-2025-06-01.sql |
2025-06-02 | mysql-2025-06-02.sql | owncloud-2025-06-02.sql |
2025-06-03 | mysql-2025-06-03.sql | owncloud-2025-06-03.sql |
2025-06-04 | mysql-2025-06-04.sql | owncloud-2025-06-04.sql |
Weekly Archives (/home/group-a/storage/db/db-weekly/)
Archive File | Week Ending | Notes |
---|---|---|
db-weekly-2025-05-25.tar.gz | 2025-05-25 | Before target range |
db-weekly-2025-06-01.tar.gz | 2025-06-01 | Covers 26 May โ 1 June |
(expected) | 2025-06-08 | Should cover 2 โ 8 June |
(future expected) | to 2025-07-03 | 15, 22, 29 June, 6 July scheduled |
What improvements could be made
Security Improvements
Area | Suggestion | Why It Matters |
---|---|---|
Password Exposure | Remove hardcoded MySQL password from script | Prevent secrets leakage; use .my.cnf with restricted perms |
Key Handling | Store SSH private key securely and rotate periodically | Reduces risk of long-term key compromise |
User Permissions | Run backup as non-root Unix user | Follows the principle of least privilege |
Encrypt Backups | Add GPG or OpenSSL encryption before transfer | Protects backups at rest and in transit |
Backup Scope Improvements
Area | Suggestion | Why It Matters |
---|---|---|
Full Data Backup | Back up OwnCloud file storage (/owncloud/data ) with DB |
DB-only backups wonโt allow complete recovery |
Checksum Verification | Add SHA256 checksums and verify on restore | Detects silent corruption in .sql or .tar.gz files |
Point-in-Time Recovery | Enable MySQL binary logs and archive them | Allows fine-grained recovery to a specific moment in time |
Operational & Monitoring Improvements
Area | Suggestion | Why It Matters |
---|---|---|
Logging | Use structured logs with BEGIN/END and STATUS | Simplifies troubleshooting and automation |
Dry Run Mode | Implement --dry-run in your script |
Safely test backups without changing data |
Recovery Drills | Run regular restore tests to staging or test containers | Validates real-world recoverability |
https://rt.dataraster.com/Ticket/Display.html?id=352
Ticket Reference:Tools and Systems Used
Area | Tools/Systems Used |
---|---|
Identity Management | ownCloud , OCC CLI |
Remote Access | SSH (with key-based authentication) |
File Recovery | rsync , find , custom Bash scripting |
Automation & Scheduling | Likely cron -based backup jobs (inferred, not explicitly shown) |
Permissions & Validation | chown , chmod , diff , validation via custom Bash scripts |
Documentation & Workflow | GitHub Wiki, Screenshots, RT Ticketing System |
Located at 20.40.64.18 under /home/group-a/storage/app/owncloud/data/
Challenges faced
Accidentally copied the entire ownCloud directory into ocuser1's directory and had to delete it
Lessons learned:
Proof read my documentation, there were a lot of mistakes and omissions upon each read through. Things that seem obvious at the time but when you go back hours later you've forgotten like what server I was working on