citadel/docs/duck/realmfs.duck

140 lines
6.7 KiB
Plaintext

= RealmFS Images
[topic]
@link[guide >index#user]
@desc Realm root filesystem images
A RealmFS image contains a root filesystem for one or more realm instances.
Similar to resource images, RealmFS images are signed and mounted with dm-verity
to prevent tampering with the data on the root filesystem such as the
installation of malware or backdoors. The keys used to sign RealmFS images are
controlled by the user which makes it possible to upgrade software and install
new packages on the image.
RealmFS images are always mounted as read-only and this property is enforced
with dm-verity. Since RealmFS images are immutable a single image can be shared
between multiple running realm instances. By default, when a realm is launched a
temporary overlay is added to the root filesystem so that changes can be
performed that will last only until the realm is stopped or restarted. This
allows experimenting with the system configuration or installing new software
temporarily. The root filesystem can then be reverted to the original state by
simply restarting the realm.
== Updates
Since the root filesystem of realms are stored on read-only disk images,
packages cannot be permanently installed or upgraded in the usual way. Changes
to the root filesystem will succeed inside a realm, but these changes will be
lost as soon as the realm is stopped or restarted.
To make persistent changes to a RealmFS image, the image is first copied, then
changes are applied to the copy. After applying changes a new dm-verity hash
tree is generated for the image and the RealmFS image header is updated and
signed.
[note .advanced]
The process of generating a signature and a dm-verity hash tree for a RealmFS image
after applying some changes such as updating packages is called $em[.strong](Sealing)
the image.
=== Apt-Cacher NG Realm
Upon booting a system utility realm is started which runs an Apt-Cacher NG
instance. Each realm is configured to use this realm as a proxy for package
installation.
[code]
/etc/apt/apt.conf.d/000apt-cacher-ng-proxy
Acquire::http::Proxy "http://172.17.0.213:3142/";
The apt source lines use the special Apt-Cacher NG syntax.
[code]
/etc/apt/sources.list
deb http://HTTPS///deb.debian.org/debian buster main contrib non-free
Using a package cache avoids downloading and storing packages multiple times
when updating multiple RealmFS images. It also makes it possible to download and
cache packages while connected to a network before booting the system into a
safe mode without enabling the network to perform upgrades of realm packages.
=== Updates (Container method)
First the RealmFS image is copied to a temporary file. On a filesystem such as
btrfs, the image file will be cloned as a reflink rather than copying the file.
The copy of the RealmFS will then be mounted as writable so that changes can be
made. A systemd-nspawn container is launched and a root shell opened so that the
user can update packages, install new software, or perform any other
modifications to the root filesystem.
Once the shell is exited a prompt asks the user if they would like to save the
current changes or discard them. If the user chooses to save the changes, the
copied image is then sealed by generating a dm-verity hash tree and the header
of the image is signed with the user RealmFS sealing key.
=== Updates with pH Hypervisor
When a realm is launched with pH, the overlay is managed by the emulated disk
device of the hypervisor which tracks changes to blocks of the disk and stores
the changed blocks in memory. Since the hypervisor is tracking all of the
changes to the disk, it can also transparently apply the changes and generate a
new sealed RealmFS image and then discard the changed blocks and start directly
using the new image.
This process is initiated by the user when they decide they would like to commit
any changes they have made to the root filesystem in the running realm
permanently to the underlying RealmFS image.
[steps]
* The user makes changes to the root filesystem of the realm and pH tracks the blocks that have changed.
* A user request is made to pH to apply the changes to the RealmFS image.
* pH opens a prompt on the desktop to ask the user to confirm that they really did make this request.
* A copy (or reflink) of the current RealmFS is made, and pH applies the changed blocks to this copy.
* The copy is then sealed with the RealmFS key of the user.
* Now pH can quietly swap in the new version of the RealmFS image and discard all of the tracked block changes.
== Signing RealmFS Images
A secret key for signing RealmFS images is generated during installation and
stored on disk in an encrypted file called the User Keyring. During boot
when the user enters a passphrase to decrypt the disk, this passphrase is also
used to decrypt the keyring file and the public and secret key pair is
loaded into the kernel key storage.
The risk exists that an attacker who is able to compromise the kernel may
recover this secret key. This would allow the attacker to modify sealed RealmFS
images and install backdoors or other malware into realm root filesystems. Even
without obtaining the signing key an attacker who has compromised Citadel could
wait for the user to perform an update and make malicious changes at the same
time which the user will then sign.
For these reasons, it is also possible to configure the system so that only
the public key is retained in the kernel upon boot and the user must boot
into a special mode so that the private key is available to perform updates.
=== Safe Mode
If upgrades are performed in normal operating mode, an attacker who has
compromised citadel can persistently backdoor the upgraded realmfs images.
Safe mode is a way to boot citadel without starting any realms or enabling the
network device. Since the integrity of the Citadel root filesystem is enforced
by dm-verity and no realms are running, even if the system had become compromised
at some point in the past it is assumed to now be in a safe state for performing
updates and signing them with the user sealing keys.
Since the network is not available in safe mode, the packages to be installed or
upgraded must be stored somewhere. By either performing the packge updates with
the $code(--download-only) flag or installing them to the temporary overlay of a realm
the user will cause them to be stored on the Apt-Cache NG service realm so that
they are available for install in safe mode.
== Base RealmFS image
Citadel ships with a RealmFS image called $code(base-realmfs.img). There is nothing
special about this image other than that it is initially signed by Subgraph until
the user modifies or updates it. During installation, a copy of this RealmFS is
created with the name $code(main-realmfs.img) and sealed with the newly generated
user keys.