2016-10-10 08:01:09 -04:00
|
|
|
---
|
2021-03-13 13:06:18 -05:00
|
|
|
lang: en
|
2016-10-10 08:01:09 -04:00
|
|
|
layout: doc
|
2021-06-16 22:56:25 -04:00
|
|
|
permalink: /doc/backup-emergency-restore-v4/
|
2016-10-10 08:01:09 -04:00
|
|
|
redirect_from:
|
|
|
|
- /en/doc/backup-emergency-restore-v4/
|
|
|
|
- /doc/BackupEmergencyRestoreV4/
|
2021-03-13 13:06:18 -05:00
|
|
|
ref: 192
|
2021-06-16 02:19:45 -04:00
|
|
|
title: Emergency Backup Recovery (v4)
|
2016-10-10 08:01:09 -04:00
|
|
|
---
|
|
|
|
|
|
|
|
|
2018-06-30 22:01:18 -04:00
|
|
|
This page describes how to perform an emergency restore of a backup created on
|
2018-07-01 19:53:47 -04:00
|
|
|
Qubes R4.X (which uses backup format version 4).
|
2018-06-30 22:01:18 -04:00
|
|
|
|
|
|
|
The Qubes backup system has been designed with emergency disaster recovery in
|
|
|
|
mind. No special Qubes-specific tools are required to access data backed up by
|
|
|
|
Qubes. In the event a Qubes system is unavailable, you can access your data on
|
|
|
|
any GNU/Linux system with the following procedure.
|
|
|
|
|
2018-07-01 19:53:47 -04:00
|
|
|
Required `scrypt` Utility
|
|
|
|
-------------------------
|
|
|
|
|
2021-06-18 09:25:06 -04:00
|
|
|
In Qubes 4.X, backups are encrypted and integrity-protected with
|
|
|
|
[scrypt](https://www.tarsnap.com/scrypt.html). You will need a copy of this
|
|
|
|
utility in order to access your data. Since `scrypt` is not pre-installed on
|
|
|
|
every GNU/Linux system, it is strongly recommended that you store a copy of it
|
|
|
|
with your backups. If your distribution has `scrypt` packaged (e.g., Debian),
|
|
|
|
you can install the package in the standard way using your distribution's
|
|
|
|
package manager. Otherwise, you'll need to obtain a compiled binary
|
|
|
|
(instructions below) or compile the program from source yourself. (Don't forget
|
|
|
|
to [verify signatures](/security/verifying-signatures) first!) Note that
|
|
|
|
versions of `scrypt` up to 1.2.0 (inclusive) do not support the `-P` option for
|
|
|
|
easier scripting, which means you'll need to enter the passphrase for each file
|
2018-07-01 19:53:47 -04:00
|
|
|
separately, instead of using `echo ... | scrypt`.
|
|
|
|
|
|
|
|
Here are instructions for obtaining a compiled `scrypt` binary. This example
|
2021-06-18 09:25:06 -04:00
|
|
|
uses an RPM-based system (Fedora), but the same general procedure should work
|
|
|
|
on any GNU/Linux system.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
2021-04-10 18:09:05 -04:00
|
|
|
1. If you're not on Qubes 4.X, [get and verify the Release 4 Signing Key](/security/verifying-signatures/#2-get-the-release-signing-key).
|
2019-03-02 02:37:08 -05:00
|
|
|
2. If you're not on Qubes 4.X, import the Release 4 Signing Key.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ sudo rpm --import qubes-release-4-signing-key.asc
|
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
3. Download the `scrypt` RPM.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ dnf download scrypt
|
|
|
|
|
|
|
|
or, if that doesn't work:
|
|
|
|
|
|
|
|
[user@restore ~]$ curl -O https://yum.qubes-os.org/r4.0/current/vm/fc28/rpm/scrypt-1.2.1-1.fc28.x86_64.rpm
|
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
4. Verify the signature on the `scrypt` RPM.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
2021-03-13 12:03:23 -05:00
|
|
|
[user@restore ~]$ rpm -K scrypt-*.rpm
|
2018-07-01 19:53:47 -04:00
|
|
|
scrypt-*.rpm: digests signatures OK
|
|
|
|
|
|
|
|
The message `digests signatures OK` means that both the digest (i.e., the
|
|
|
|
output of a hash function) and PGP signature verification were successful.
|
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
5. Install `rpmdevtools`.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ sudo dnf install rpmdevtools
|
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
6. Extract the `scrypt` binary from the RPM.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ rpmdev-extract scrypt-*.rpm
|
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
7. (Optional) Create an alias for the new binary.
|
2018-07-01 19:53:47 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ alias scrypt="scrypt-*/usr/bin/scrypt"
|
|
|
|
|
|
|
|
Emergency Recovery Instructions
|
|
|
|
-------------------------------
|
2018-06-30 22:01:18 -04:00
|
|
|
|
|
|
|
**Note:** In the following example, the backup file is both *encrypted* and
|
|
|
|
*compressed*.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2018-07-01 19:53:47 -04:00
|
|
|
1. Untar the main backup file.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ tar -i -xvf qubes-backup-2015-06-05T123456
|
|
|
|
backup-header
|
|
|
|
backup-header.hmac
|
|
|
|
qubes.xml.000.enc
|
|
|
|
vm1/private.img.000.enc
|
|
|
|
vm1/private.img.001.enc
|
|
|
|
vm1/private.img.002.enc
|
|
|
|
vm1/icon.png.000.enc
|
|
|
|
vm1/firewall.xml.000.enc
|
|
|
|
vm1/whitelisted-appmenus.list.000.enc
|
|
|
|
dom0-home/dom0user.000.enc
|
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
**To extract only specific VMs:** Each VM in the backup file has its path
|
|
|
|
listed in `qubes.xml.000.enc`. Decrypt it. (In this example, the password is
|
|
|
|
`password`.)
|
2018-05-06 08:00:31 -04:00
|
|
|
|
2019-03-02 02:37:08 -05:00
|
|
|
[user@restore ~]$ cat backup-header | grep backup-id
|
|
|
|
backup-id=20190128T123456-1234
|
|
|
|
[user@restore ~]$ scrypt dec -P qubes.xml.000.enc qubes.xml.000
|
|
|
|
Please enter passphrase: 20190128T123456-1234!qubes.xml.000!password
|
|
|
|
[user@restore ~]$ tar -i -xvf qubes.xml.000
|
|
|
|
|
|
|
|
Now that you have the decrypted `qubes.xml.000` file, search for the
|
|
|
|
`backup-path` property inside of it. With the `backup-path`, extract only
|
|
|
|
the files necessary for your VM (`vmX`).
|
|
|
|
|
|
|
|
[user@restore ~]$ tar -i -xvf qubes-backup-2015-06-05T123456 \
|
|
|
|
backup-header backup-header.hmac vmX/
|
|
|
|
|
|
|
|
2. Set the backup passphrase environment variable. While this isn't strictly
|
2018-06-30 22:01:18 -04:00
|
|
|
required, it will be handy later and will avoid saving the passphrase in
|
|
|
|
the shell's history.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2018-07-01 19:53:47 -04:00
|
|
|
[user@restore ~]$ read backup_pass
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2018-07-01 19:53:47 -04:00
|
|
|
3. Verify the integrity of `backup-header`. For compatibility reasons,
|
2018-06-30 22:01:18 -04:00
|
|
|
`backup-header.hmac` is an encrypted *and integrity protected*
|
|
|
|
version of `backup-header`.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2018-05-06 07:20:14 -04:00
|
|
|
[user@restore ~]$ set +H
|
2016-10-10 08:01:09 -04:00
|
|
|
[user@restore ~]$ echo "backup-header!$backup_pass" |\
|
2018-05-06 07:20:14 -04:00
|
|
|
scrypt dec -P backup-header.hmac backup-header.verified && \
|
2016-10-10 08:01:09 -04:00
|
|
|
diff -qs backup-header backup-header.verified
|
|
|
|
Files backup-header and backup-header.verified are identical
|
|
|
|
|
2018-06-30 22:01:18 -04:00
|
|
|
**Note:** If this command fails, it may be that the backup was tampered
|
|
|
|
with or is in a different format. In the latter case, look inside
|
|
|
|
`backup-header` at the `version` field. If it contains a value other than
|
|
|
|
`version=4`, go to the instructions for that format version:
|
2021-04-10 18:09:05 -04:00
|
|
|
- [Emergency Backup Recovery without Qubes (v2)](/doc/backup-emergency-restore-v2/)
|
|
|
|
- [Emergency Backup Recovery without Qubes (v3)](/doc/backup-emergency-restore-v3/)
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2018-07-01 19:53:47 -04:00
|
|
|
4. Read `backup-header`:
|
2016-10-10 08:01:09 -04:00
|
|
|
|
|
|
|
[user@restore ~]$ cat backup-header
|
|
|
|
version=4
|
|
|
|
encrypted=True
|
|
|
|
compressed=True
|
|
|
|
compression-filter=gzip
|
2016-10-25 15:49:17 -04:00
|
|
|
backup_id=20161020T123455-1234
|
2018-07-01 19:53:47 -04:00
|
|
|
|
|
|
|
5. Set `backup_id` to the value in the last line of `backup-header`:
|
|
|
|
|
|
|
|
[user@restore ~]$ backup_id=20161020T123455-1234
|
|
|
|
|
2021-06-18 09:25:06 -04:00
|
|
|
6. Verify the integrity of your data, decrypt, decompress, and extract
|
|
|
|
`private.img`:
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2020-10-08 11:22:54 -04:00
|
|
|
[user@restore ~]$ find vm1 -name 'private.img.*.enc' | sort -V | while read f_enc; do \
|
2016-10-10 08:01:09 -04:00
|
|
|
f_dec=${f_enc%.enc}; \
|
2020-10-09 07:07:48 -04:00
|
|
|
echo "$backup_id!$f_dec!$backup_pass" | scrypt dec -P $f_enc || break; \
|
|
|
|
done | gzip -d | tar -xv
|
2016-10-10 08:01:09 -04:00
|
|
|
vm1/private.img
|
|
|
|
|
2020-10-09 07:07:48 -04:00
|
|
|
If this pipeline fails, it is likely that the backup is corrupted or has
|
|
|
|
been tampered with.
|
|
|
|
|
2018-06-30 22:01:18 -04:00
|
|
|
**Note:** If your backup was compressed with a program other than `gzip`,
|
2020-10-09 07:29:27 -04:00
|
|
|
you must substitute the correct compression program in the command above.
|
|
|
|
This information is contained in `backup-header` (see step 4). For example,
|
|
|
|
if your backup is compressed with `bzip2`, use `bzip2 -d` instead in the
|
|
|
|
command above.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2020-10-09 07:07:48 -04:00
|
|
|
7. Mount `private.img` and access your data.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
|
|
|
[user@restore vm1]$ sudo mkdir /mnt/img
|
|
|
|
[user@restore vm1]$ sudo mount -o loop vm1/private.img /mnt/img/
|
|
|
|
[user@restore vm1]$ cat /mnt/img/home/user/your_data.txt
|
|
|
|
This data has been successfully recovered!
|
|
|
|
|
2020-10-09 07:07:48 -04:00
|
|
|
8. Success! If you wish to recover data from more than one VM in your backup,
|
|
|
|
simply repeat steps 6 and 7 for each additional VM.
|
2016-10-10 08:01:09 -04:00
|
|
|
|
2018-06-30 22:01:18 -04:00
|
|
|
**Note:** You may wish to store a copy of these instructions with your
|
|
|
|
Qubes backups in the event that you fail to recall the above procedure
|
|
|
|
while this web page is inaccessible. All Qubes documentation, including
|
|
|
|
this page, is available in plain text format in the following Git
|
|
|
|
repository:
|
2016-10-10 08:01:09 -04:00
|
|
|
|
|
|
|
https://github.com/QubesOS/qubes-doc.git
|
|
|
|
|