| 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. |