Title: Qubes OS backup transfer from old to new computer | |
Author: Solène | |
Date: 24 December 2023 | |
Tags: security qubesos networking | |
Description: In this article you will learn how to efficiently move all | |
the qubes from an old Qubes OS system to a new one | |
# Introduction | |
With the recent release of Qubes OS 4.2, I took the opportunity to | |
migrate to a newer laptop (from a Thinkpad T470 to a NovaCustom NV41) | |
so I had to backup all the qubes from the T470 and restore them on the | |
NV41. | |
The fastest way to proceed is to create the backups on the new laptop | |
directly from the old one, which is quite complicated to achieve due to | |
Qubes OS compartmentalization. | |
In this guide, I'll share how I created a qube with a network file | |
server to allow one laptop to send the backups to the new laptop. | |
Qubes OS official project website | |
Of course, this whole process could be avoided by using a NAS or | |
external storage, but they are in my opinion slower than directly | |
transferring the files on the new machine, and you may not want to | |
leave any trace of your backups. | |
# Explanation about the setup | |
As the new laptop has a very fast NVME disk, I thought it would be nice | |
to use it for saving the backups as it will offload a bit of disk | |
activity for the one doing backups, and it shouldn't be slowed down | |
during the restore process even if it has to write and read the backups | |
at the same time. | |
The setup consists in creating a dedicated qube on the new laptop | |
offering an NFS v4 share, make the routing at the different levels, and | |
mount this disk in a qube on the old laptop, so the backup could be | |
saved there. | |
I used a direct Ethernet connection between the two computers as it | |
allows to not think much about NFS security | |
# Preparing the backup receiver | |
## Storage qube configuration | |
On the new laptop, create a standalone qube with the name of your | |
choice (I'll refer to it as `nfs`), the following commands have been | |
tested with the fedora-38-xfce template. Make sure to give it enough | |
storage space for the backup. | |
First we need to configure the NFS server, we need to install the | |
related package first: | |
``` | |
$ sudo dnf install nfs-utils | |
``` | |
After this, edit the file `/etc/exports` to export the path | |
`/home/user/backup` to other computers, using the following content: | |
``` | |
/home/user/backup *(rw,sync) | |
``` | |
Create the directory we want to export, and make `user` the owner of | |
it: | |
``` | |
install -d -o user /home/user/backup | |
``` | |
Now, run the NFS server now and at boot time: | |
``` | |
systemctl enable --now nfs-server | |
``` | |
You can verify the service started successfully by using the command | |
`systemctl status nfs-server` | |
You can check the different components of the NFS server are running | |
correctly, if the two following commands have an output this mean it's | |
working: | |
* `ss -lapteun | grep 2049` | |
* `ss -lapteun | grep 111` | |
Allow the NFS server at the firewall level, run the following commands | |
AND add them at the end of `/rw/config/rc.local`: | |
``` | |
nft add rule qubes custom-input tcp dport 2049 accept | |
nft add rule qubes custom-input udp dport 111 accept | |
``` | |
## Route the service from the physical LAN | |
Now the service is running within the qube, we need to allow the remote | |
computer to reach it, by default the network should look like this: | |
We will make sys-net to nat the UDP port 111 and TCP port 2049 to | |
sys-firewall, which will nat them to the nfs qube, which will already | |
accept connections on those ports. | |
``` | |
+------------------------------------------------+ | |
+--------+ | DESTINATION SYSTEM | | |
| SOURCE | ethernet | +---------+ +--------------+ +-----+ | | |
| SYSTEM | <--------> | | sys-net | --> | sys-firewall | --> | nfs | | | |
+--------+ | +---------+ +--------------+ +-----+ | | |
+------------------------------------------------+ | |
``` | |
### sys-net routing | |
Write the following script inside the `sys-net` qube of the destination | |
system, make sure to update the value of the variable `DESTINATION` | |
with `sys-firewall`'s IP address, it can be found by looking at the | |
qube settings. | |
``` | |
#!/bin/sh | |
PORT=111 | |
DESTINATION=10.138.31.246 | |
if ! nft -nn list table ip qubes | grep "chain nat {" ; then | |
nft add chain qubes nat { type nat hook prerouting priority dstnat\; } | |
fi | |
nft add rule qubes custom-input udp dport "${PORT}" accept | |
nft add rule qubes custom-forward udp dport "${PORT}" accept | |
nft add rule qubes nat iifname != "vif*" udp dport "${PORT}" dnat "${DESTINATIO… | |
PORT=2049 | |
nft add rule qubes custom-input tcp dport "${PORT}" accept | |
nft add rule qubes custom-forward tcp dport "${PORT}" accept | |
nft add rule qubes nat iifname != "vif*" tcp dport "${PORT}" dnat "${DESTINATIO… | |
``` | |
Make the script executable by running the command `chmod +x` on the | |
script file. You will execute them later once the network is safe. | |
### sys-firewall routing | |
Write the following script inside the `sys-firewall` qube of the | |
destination system, make sure to update the value of the variable | |
`DESTINATION` with `nfs`'s IP address, it can be found by looking at | |
the qube settings. | |
``` | |
#!/bin/sh | |
PORT=111 | |
DESTINATION=10.137.0.10 | |
if ! nft -nn list table ip qubes | grep "chain nat {" ; then | |
nft add chain qubes nat { type nat hook prerouting priority dstnat\; } | |
fi | |
nft add rule qubes custom-input udp dport "${PORT}" accept | |
nft add rule qubes custom-forward udp dport "${PORT}" accept | |
nft add rule qubes nat iifname != "vif*" udp dport "${PORT}" dnat "${DESTINATIO… | |
PORT=2049 | |
nft add rule qubes custom-input tcp dport "${PORT}" accept | |
nft add rule qubes custom-forward tcp dport "${PORT}" accept | |
nft add rule qubes nat iifname != "vif*" tcp dport "${PORT}" dnat "${DESTINATIO… | |
``` | |
Make the script executable by running the command `chmod +x` on the | |
script file. You will execute them later once the network is safe. | |
# Backup process | |
On the source system, we need to have a running qube that will mount | |
the remote NFS server, this can be a disposable qube, an AppVM qube | |
with temporary changes, a standalone etc... | |
## Mounting qube | |
On the mounting qube, run the following command to install the NFS | |
tools we need: | |
``` | |
dnf install nfs-utils | |
``` | |
## Configure both systems network | |
In this step, you need to configure the network with the direct | |
Ethernet cable, so the two systems can speak to each other, please | |
disconnect from any Wi-Fi connections as you didn't set any security | |
for the file transfer (it's encrypted but still). | |
You can choose any address as long as the two hosts are in the same | |
subnet, an easy pick could be `192.168.0.2` for the source system, and | |
`192.168.0.3` for the new system. | |
Now, both systems should be able to ping each other, it's time to | |
execute the scripts in `sys-firewall` and `sys-net` to enable the | |
routing. | |
On the "mounting" qube, run the following command as root to mount the | |
remote file system: | |
``` | |
mount.nvfs4 192.168.0.3:/home/user/backup /mnt | |
``` | |
You can verify it worked if the output of `df` shows a line starting by | |
`192.168.0.3:/home/user/backup`, and you can ensure your user can | |
actually write in this remote directory by running `touch /mnt/test` | |
with the regular user `user`. | |
Now, we can start the backup tool to send the backup to the remote | |
storage. | |
## Run the backup | |
In the source system dom0, run the Qubes OS backup tool, choose the | |
qubes you want to transfer, uncheck "Compress backups" (except if you | |
are tight on storage for the new system) and click on "Next". | |
In the field "Target qube", select the "mounting qube" and set the path | |
to `/mnt/`, choose an encryption passphrase and run the backup. | |
If everything goes well, you should see a new file named | |
`qubes-backup-YYYY-MM-DDThhmmss` in the directory `/home/user/backups/` | |
of the `nfs` qube. | |
## Restore the backups | |
In the destination system dom0, you can run the Restore backup tool to | |
restore all the qubes, if the old `sys-net` and `sys-firewall` have any | |
value, you may want to delete yours first otherwise the restored one | |
will be renamed. | |
## how to restore dom0 $home | |
When you backup and restore dom0, only the directory `/home/` is part | |
of the backup, so it's only about the desktop settings themselves and | |
not the Qubes OS system configuration. I actually use versioned files | |
in the salt directories to have reproducible Qubes OS machines because | |
the backups aren't enough. | |
Blog post: Using git bundle to synchronize a repository between Qubes OS dom0 a… | |
Blog post: Qubes OS dom0 files workflow using fossil | |
When you restore dom0, it creates a directory | |
`/home/solene/home-restore-YYYY-MM-DDThhmmss` on the new dom0 that | |
contains the previous `/home/` directory. | |
Restoring this directory verbatim requires some clever trick as you | |
should not be logged in for the operation! | |
* reboot qubes OS | |
* don't log in, instead press ctrl+alt+F2 to run commands as the root | |
user in a console (tty) | |
* move the backup outside `/home/solene` with `mv | |
/home/solene/home-restore* /home/` | |
* delete your home directory `/home/solene` with `rm -fr /home/solene` | |
* put the old backup at the right place with `mv | |
/home/home-restore*/dom0-home/solene /home/` | |
* press ctrl+alt+F1 | |
* log-in as user | |
Your desktop environment should be like you left if during the backup. | |
If you used some specific packages or desktop environment, make sure | |
you also installed the according packages in the new dom0 | |
# Cleaning up | |
After you restored your backups, you can remove the scripts in | |
`sys-firewall` and `sys-net` and even delete the nfs qube. | |
# Conclusion | |
Moving my backup from the old system to the new one was pretty | |
straightforward once the NFS server was established, I was able to | |
quickly have a new working computer that looked identical to the | |
previous one, ready to be used. |