Enhance UVM installation and configuration for Ubuntu 22.04 root filesystem
- Update README and USAGE documentation to reflect changes in rootfs handling, including the default local build from Ubuntu 22.04 packages. - Modify the installer to support building the rootfs locally with authenticated packages and to require SHA-256 checksums for prebuilt images. - Implement checks for setuid permissions on sudo and update the provisioning logic for guest users to ensure proper sudo access. - Adjust tests to validate the new rootfs building process and ensure that existing functionality is preserved. - Refactor code to improve clarity and maintainability, including the introduction of constants for Ubuntu release and guest packages.
This commit is contained in:
+41
-7
@@ -545,6 +545,13 @@ The new `/home/USERNAME` directory is mode `0700`, owned by the new UID/GID;
|
||||
Directory ownership/modes and account-file writes are read back before the
|
||||
disk can be marked ready. The default `root` account must already exist.
|
||||
|
||||
Custom login users are VM administrators. Provisioning requires a root-owned,
|
||||
setuid `/usr/bin/sudo` and `/etc/sudoers`, and appends a user-scoped `PASSWD: ALL`
|
||||
rule with root/target/runas-password defaults disabled. Sudo authenticates with
|
||||
the login user's password; root's separate shadow entry is not changed. Global
|
||||
sshd directives precede managed and existing `Match` blocks so standard Ubuntu
|
||||
`UsePAM`/`Subsystem` settings remain valid.
|
||||
|
||||
UVM replaces conventional RSA, ECDSA, and Ed25519 host keys in each private
|
||||
disk and removes the known public login key from Firecracker's bionic image.
|
||||
A VM must never rely on reusable SSH private keys from a shared template.
|
||||
@@ -557,14 +564,19 @@ A VM must never rely on reusable SSH private keys from a shared template.
|
||||
- A local `integrity.json` manifest recording artifact hashes and whether the
|
||||
installation was verified.
|
||||
|
||||
Strict installation requires all of these values:
|
||||
Strict installation requires these values for downloaded artifacts:
|
||||
|
||||
```text
|
||||
UVM_FIRECRACKER_SHA256
|
||||
UVM_KERNEL_SHA256
|
||||
UVM_ROOTFS_SHA256
|
||||
```
|
||||
|
||||
The default rootfs is built from signature-verified Ubuntu packages and its
|
||||
resulting digest is recorded in the same manifest. `UVM_ROOTFS_URL` explicitly
|
||||
selects a prebuilt ext4 download and additionally requires `UVM_ROOTFS_SHA256`.
|
||||
A rootfs checksum without a URL is rejected during installation to avoid using
|
||||
a stale Bionic-image checksum for a local build.
|
||||
|
||||
`UVM_ALLOW_UNVERIFIED_DOWNLOADS=1` is a local-development escape hatch. It
|
||||
writes a manifest marked `verified: false`; a later strict run will not treat
|
||||
that manifest as publisher trust. Use `install --force` with trusted digests to
|
||||
@@ -694,12 +706,30 @@ handling, downloads, and integrity-manifest publication.
|
||||
`Settings` detects and normalizes the host architecture at construction time
|
||||
(`amd64` to `x86_64`, `arm64` to `aarch64`) and rejects unsupported architectures.
|
||||
The same architecture selects the Firecracker release archive, guest kernel,
|
||||
rootfs, and architecture-specific boot arguments. Default guest URLs use
|
||||
Firecracker's `img/quickstart_guide/<architecture>/` assets: `kernels/vmlinux.bin`
|
||||
and `rootfs/bionic.rootfs.ext4`. Kernel and rootfs URL overrides are independent;
|
||||
custom assets and trusted digests must match the host architecture. ARM64
|
||||
native rootfs packages, and architecture-specific boot arguments. The default
|
||||
kernel URL uses Firecracker's `img/quickstart_guide/<architecture>/kernels/vmlinux.bin`.
|
||||
An empty `Settings.rootfs_url` selects the built Ubuntu 22.04 (Jammy) template.
|
||||
Explicit kernel/rootfs URLs and trusted digests must match the host architecture. ARM64
|
||||
uses an uncompressed Linux `Image` (PE format) and an ARM64 ext4 rootfs.
|
||||
|
||||
The default rootfs builder installs `debootstrap` and `ubuntu-keyring`, uses
|
||||
`--force-check-gpg`, and includes main/universe plus updates/security suites.
|
||||
amd64 uses `archive.ubuntu.com/ubuntu`; arm64 uses `ports.ubuntu.com/ubuntu-ports`.
|
||||
Package scripts execute in private mount/PID namespaces with a temporary
|
||||
`policy-rc.d` suppressing service startup. No mounts survive the build process.
|
||||
The staged tree retains `/var/lib/dpkg` and apt metadata, validates installed
|
||||
apt/sudo/sshd/systemd packages, enables SSH/networkd, preserves kernel-provided
|
||||
static networking, and supplies guest DNS. Template host keys and machine IDs
|
||||
are cleared for per-VM initialization. `mkfs.ext4 -d` creates a sparse 2 GiB
|
||||
template with a guest-kernel-compatible feature set; `e2fsck` and fsync precede
|
||||
atomic publication. Create still grows each private disk to at least 30 GiB.
|
||||
|
||||
Only a checksum-verified manifest and matching `/etc/uvm-image` recipe marker
|
||||
permit reuse of a built template. Old demo images and unverified caches are
|
||||
rebuilt, and `install --force` always rebuilds. A failed staging build retains
|
||||
the old template. Installation holds the existing operation lock throughout;
|
||||
existing VM disks are never upgraded or reprovisioned by installation.
|
||||
|
||||
The host package list includes `nftables` and `conntrack` as well as the
|
||||
existing iproute2/iptables, ext4, OpenSSL, OpenSSH, download, and util-linux
|
||||
tools. UVM adds no reconciliation daemon or tested external firewall-manager
|
||||
@@ -892,6 +922,9 @@ sparse ext4 images when the tools are installed: default 30 GiB creation,
|
||||
growth, shrinking, geometry, and retained data/password-hash/host-key fixtures.
|
||||
`test_images.py` uses temporary ext4 images to verify custom-user creation,
|
||||
UID/GID allocation, account/home metadata, existing accounts, and password hashes.
|
||||
`test_install.py` simulates package bootstrap and exercises real ext4 formatting
|
||||
and readback for retained dpkg metadata, sudo modes, template configuration,
|
||||
staging failures, and checksum provenance. It does not run debootstrap or boot a VM.
|
||||
Lifecycle resize tests use fake processes/networking to verify ordering,
|
||||
single-lock ownership, identity preservation, pending intent, and failure recovery.
|
||||
|
||||
@@ -926,7 +959,8 @@ on an isolated Linux host:
|
||||
1. Strict checked installation.
|
||||
2. `create` and successful guest boot.
|
||||
3. Guest IP reachability and egress.
|
||||
4. SSH with unique guest host keys.
|
||||
4. SSH with unique guest host keys, `sudo -i` for a custom login, and
|
||||
`sudo apt update && sudo apt install htop` in a newly built Ubuntu guest.
|
||||
5. Stop/start/restart with retained guest data, SSH keys, and credentials.
|
||||
6. Live private-port close in both directions, empty policy, and explicit sync
|
||||
after deliberately lost rules inside the isolated setup.
|
||||
|
||||
Reference in New Issue
Block a user