Commit Graph

97 Commits (80077a7934c33ee12eae7c92adb355d634e6d0a4)

Author SHA1 Message Date
Dustin 80077a7934 make: Add build phony target
Now you can run `make build` to (re-)build binary packages.
2023-03-30 09:31:12 -05:00
Dustin 99971b5f50 SELinux: Allow Podman to mount /dev/log
These SELinux policy rules allow containers to log directly to
syslog/the systemd journal via the `/dev/log` socket.  To enable this,
simply mount the socket into a container's mount namespace, e.g. `-v
/dev/log:/dev/log`.
2023-03-30 09:31:12 -05:00
Dustin 77f7e6d8cc init-storage: Create intermediate dirs in /etc
When creating writable paths in the `/etc` subvolume, the `setup_etc`
function needs to create intermediate directories before copying
existing files from the root filesystem.  Without this step, `cp` will
fail with a "no such file or directory" error, referring to the
destination path.
2023-03-30 09:31:12 -05:00
Dustin 670c1f7561 yellow: Install/configure nginx
We're going to use *nginx* as the reverse proxy in front of Home
Assistant, as well as the web consoles for Zigbee2MQTT and ZWaveJS2MQTT.
It will provide TLS termination for all of these applications.

Since *nginx* will not start without a certificate and private key file
for HTTPS, the *gen-nginx-cert.service* systemd unit generates a
self-signed certificate if one does not already exist.  This ensures
that *nginx* can start by default, but still allows the administrator to
replace the certificate with a trusted one later.

The *nginx* container image has symlinks at `/var/log/nginx/error.log`
and `/var/log/nginx/access.log`, pointing to `/dev/stderr` and
`/dev/stdout`, respectively.  The intent here is to send all log
messages to the container runtime.  Unfortunately, when the the
container is managed by Podman from a systemd unit, the standard output
and standard error streams are connected to the systemd journal via a
UNIX socket.  As a result, the `/dev/stdout` and `/dev/stderr`
pseudo-files cannot be "opened" like normal files or pipes.  Thus, to
forward nginx's logs to the systemd journal correctly, we have to do a
bit of trickery.  For the error log at least, setting `error_log stderr`
works well; nginx simply writes messages to the existing file
descriptor.  Unfortunately, the access log has no such mechanism.  For
that, we use nginx's syslog capabilities.  The `/dev/log` socket is
bind-mounted into the container, and nginx is configured to connect to
it.
2023-03-30 09:23:47 -05:00
Dustin 02c3a12c08 Support semanage.mods
Aimee OS variants can now supply a `semange.mods` file in their
configuration directories.  This file contains SELinux customizations,
in the format produced by `semanage export`.  Variants can use this
mechanism to set SELinux booleans, change user/login mappings, and other
SELinux policy customization.  At build time, the base `selinux.mods`
file in the source directory is combined with the variant's file, if it
exists, and the resultant customizations are applied in a single
transaction.
2023-03-30 09:23:44 -05:00
Dustin a1999939eb SELinux: Allow init-storage to set permissions
Files and directories that have restrictive permissions and/or are now
owned by *root:root* require `cp` to have additional process
capabilities in order to copy them to the writable filesystem.
2023-03-30 09:03:45 -05:00
Dustin d1db08966d Define Podman zigbee2mqtt/zwavejs2mqtt containers 2023-03-30 09:03:45 -05:00
Dustin 38b0081012 make: Rebuild sdcard.img when rootfs built 2023-03-30 09:03:45 -05:00
Dustin 111c5967fd build-squashfs: Allow defining pseudo files
The `mksquashfs` command accepts a `-pf` argument, which specifies a
file that defines "pseudo files."  Each line in the file defines some
file path and an operation to perform on that path *in the generated
filesystem image*.  This allows, e.g. creating files, changing their
permissions, etc. that cannot be done in the source directory for
whatever reason.

Aimee OS now allows a variant to provide a pseudo file definition file
for `mksquashfs` by creating a `squashfs.pseudo` file in its
configuration directory.
2023-03-30 09:03:45 -05:00
Dustin 4a2d63c8db yellow: Install BURP
We'll use BURP for backups, just like the old Home Assistant server.

Note that Portage cannot correctly set the ownership of files when
installing to an alternate $ROOT.  To work around this, we replace the
`fowners` function for the *app-backup/burp* ebuild with a no-op, and
then set the permissions of the relevant files using SquashFS
pseudo-file definitions.  Relatedly, we're omitting the files and
directories used by the server-side of BURP.
2023-03-30 09:03:45 -05:00
Dustin a9fdee2049 More SELinux policy patches for Podman 2023-03-30 09:03:45 -05:00
Dustin 5fef6f1665 Allow systemd-tmpfiles to manage all files
The `systemd_tmpfiles_manage_all` SELinux boolean allows
systemd-tmpfiles to manage any file, not just the (very small) subset
allowed by the default SELinux policy.  Since we're using
systemd-tmpfiles to create directories and subvolumes for our
applications, we need this setting enabled.
2023-03-30 09:03:45 -05:00
Dustin b7f2d22586 Configure Mosquitto Podman container 2023-03-30 09:03:45 -05:00
Dustin b1afb4adf1 Configure Home Assistant Podman container
The default Home Assistant configuration does not allow running a
reverse proxy in front of the application.  To enable this, the
`use_x_forwarded_for` and `trusted_proxies` options have to be set.

Since we want `/var/lib/homeassistant` to be a Btrfs subvolume, we can't
simply include the necessary files in the correct location in the rootfs
image.  Instead, we must define "copy tree" (`C`) actions for
`systemd-tmpfiles` to copy them from `/usr/share/factory`.
Unfortunately, `systemd-tmpfiles` considers `v` and `C` actions
conflicting, and thus will not copy the directory contents recursively.
Each file has to be listed explicitly.
2023-03-30 08:56:14 -05:00
Dustin d6580cfdf4 SELinux: Allow Podman to relabel any file
The default SELinux policy for Podman only allows it to relabel certain
files, such as `user_home_t`, to `container_file_t`.  This effectively
precludes mounting arbitrary directories from `/var` into containers.
2023-03-30 08:55:58 -05:00
Dustin 5328e5482b yellow: Install Podman
Podman will provide the container runtime for Home Assistant et al.
Some additional kernel features are required to run containers.
2023-03-30 08:55:45 -05:00
Dustin 8d3c39373f Configure Portage to cross-compile Go
Portage does not set the `GOOS` and `GOARCH` environment variables by
default, which are required to cross-compile Go code.
2023-03-29 18:44:45 -05:00
Dustin e0c9689841 init-storage: Write output to system console
When troubleshooting issues with the *init-storage* service, it is
helpful to be able to see the output from it directly on the system
(serial) console.  If the initialization fails in certain situations, it
may be impossible to see the output otherwise.  For this to work,
though, the unit has to be activated after the systemd journal has
started.
2023-03-29 18:44:45 -05:00
Dustin a87a7d6f3e init-storage: Resize data partition
If the data volume is a partition (rather than a whole disk device), the
`init-storage` script will now attempt to resize it to use all
unallocated space on the disk.  This only works if it is the last
partition on the disk.  This situation is common when writing the
`sdcard.img` file directly to a disk that is larger than 4 GiB.
2023-03-29 18:44:45 -05:00
Dustin 306e3e52bf build: Fix building binpkgs for BDEPENDs
Apparently `FEATURES` and/or `EMERGE_DEFAULT_OPTS` set in `make.conf` do
not seem to apply to packages pulled in as `BDEPEND` dependencies and
installed in `/` instead of `/usr/${target}`.  This causes binary
packages to not be built/used for those packages.  Passing `--buildpkg`
(`-b`) and `--usepkg` (`-k`) on the command line ensures that binary
packages are built for everything.
2023-03-29 18:44:45 -05:00
Dustin 089b19e412 Copy all files from /usr/${target} to /usr
It turns out there are actually several packages that install files to
$SYSROOT instead of $ROOT, not just udev rules.
2023-03-29 18:44:45 -05:00
Dustin 0bc861ced1 Split out base squashfs.exclude
Variants no longer need to specify the full contents of the
`squashfs.exclude` file.  The "base" file in the source directory gets
combined with the one from the config directory (if it exists).
2023-03-29 18:44:45 -05:00
Dustin 2854380e2d patches/ebuilds: podman: Fix cross compiling
Gentoo bugs [902569][0] and [902571][1]

[0]: https://bugs.gentoo.org/show_bug.cgi?id=902569
[1]: https://bugs.gentoo.org/show_bug.cgi?id=902571
2023-03-26 12:12:41 -05:00
Dustin 1779f5564c patches/ebuilds: Fixes to cross-compile conmon
Gentoo bugs [901481][0] and [902085][1].

[0]: https://bugs.gentoo.org/show_bug.cgi?id=901481
[1]: https://bugs.gentoo.org/show_bug.cgi?id=902085
2023-03-26 12:12:41 -05:00
Dustin aae933e105 SELinux policy patches for Podman
* Allow crun to fchown stdio sockets inherited from init
* Allow podman-system-generator to read /etc/containers/systemd
2023-03-26 12:12:41 -05:00
Dustin 2046a2d2dd Do not build binpkg for raspberrypi-firmware
There's really no sense in having binary packages for
*sys-boot/raspberrypi-firmware*, since there is no "source" to build.
Having binary packages just wastes space.
2023-03-26 12:12:41 -05:00
Dustin 289827ee00 Enable systemd-tmpfiles to create subvols
By default, `systemd-tmpfiles` will create normal directories instead of
Btrfs subvolumes unless `/` is already a subvolume.  According to
[Lennart][0], this has to do with subvolumes being too "heavy-weight,"
whatever that means.

Fortunately, we can override this nonsense with an environment variable.

[0]: https://github.com/systemd/systemd/pull/1915
2023-03-21 19:46:04 -05:00
Dustin e42f10051c Remove setools from package.provided
Somewhat expectedly, attempting to avoid installing *app-admin/setools*
by listing it in `/etc/portage/profile/package.provided` proved more
trouble than it's worth.
2023-03-21 19:46:04 -05:00
Dustin 7293415b40 init-storage: Support custom writable paths in /etc
Custom builds of Aimee OS can now specify additional paths under `/etc`
that should be writable.  This is accomplished by populating a file
named `/etc/aimee-os/writable-etc` with a list of paths.  Each line must
indicate the type of file (regular file: `f`, directory: `d`) and the
*relative* path under `/etc`.
2023-03-21 19:44:43 -05:00
Dustin 82e835e450 Handle absent udev rules dir
It seems the bug that caused udev rules to be installed in the wrong
location has been fixed.  As such, we need to make this corrective
action step conditional, only moving rules files if any are found in the
wrong place.
2023-03-21 19:43:47 -05:00
Dustin 6abf1de348 setup-local-repo: Fix multiple patches per ebuild
If multiple patches are provided for the same package, we need to ensure
that they all applied.  Previously, only the last patch was applied,
because the ebuilds were copied from the main repository each time,
undoing all previous patches.
2023-03-21 19:42:35 -05:00
Dustin ee408805e2 Move post-build script to configdir
The base Aimee OS build does not need any post-installation tasks.
Custom builds can provide a `post-build.sh` script to implement the
tasks they need.  For example, builds targeting Raspberry Pi devices
can use this script to install the firmware files.
2023-03-21 19:40:51 -05:00
Dustin 6b262ca0fb Separate base packages from customizations
The `build.packages` and `install.packages` files in the CONFIGDIR now
only need to include *additional* packages to install.  The packages
*required* for Aimee OS are always installed, listed in the
corresponding files in the source directory.
2023-03-21 19:39:33 -05:00
Dustin 469cbb28c2 yellow: Update USE flags for linux-firmware
Recent versions of *sys-kernel/linux-firmware* dropped the `compress`
USE flag and added `compress-xz` and `compress-zstd`.
2023-03-16 18:47:47 -05:00
Dustin 1280f406f8 yellow: Only install stable packages on the host
Since the container images we're using as a base for the build system
only contain stable packages, setting ACCEPT_KEYWORDS to allow unstable
packages globally can cause a lot of rebuilds and potentially break
things.  Instead, we only set ~arch for the packages we actually need
recent versions on the host.

This does not affect packages installed in the target root, of course.
2023-03-16 18:43:30 -05:00
Dustin 2eb225f0fc build: Update/reinstall packages on the host system
The `build-host-tools.sh` script will now update packages as needed on
the host system and/or reinstall binary package that have been rebuilt.
2023-03-16 18:41:52 -05:00
Dustin 2b40255a61 selinux: Simplify policy for init-storage
As the scope of Aimee OS grows, and other applications are added to it,
the `init-storage` command will have an ever-growing list of file and
directory types to copy from the rootfs image.  Originally, I wanted to
explicitly allow it to only copy files that are found in `/var`, but
this will become untenable very quickly.  As such, to avoid having to
constantly update the SELinux policy for every new application that
stores anything in `/var` at install time, the `aimee_storinit_t` domain
can now manage all "non-security" files, directories, and symbolic
links.  This covers pretty much everything in `/var` except
`/var/log/audit`, while still excluding the most sensitive files (e.g.
`/etc/shadow`),
2023-03-16 18:36:26 -05:00
Dustin 5e8b69d659 factory-reset: Remove errant debug command
I added this `seq` command to make it easier to see output from
`factory-reset` on the serial console.  It's no longer necessary.
2023-03-15 21:48:44 -05:00
Dustin a4baa58563 Read /etc/fstab to determine data partition
Rather than hard-code the GPT partition label into the `init-storage`
and `factory-reset` scripts, these now determine the block device by
reading `/etc/fstab` and using the device specified for `/var`.
2023-03-15 21:48:44 -05:00
Dustin 749d5b818a Omit /var/log/journal from rootfs image
The persistent journal is stored in a subdirectory of `/var/log/journal`
named for the current machine ID.  Since `/etc/machine-id` is not
writable, the machine ID changes with every boot.  This effectively
makes the journal for previous boots inaccessible, so there's really not
much point in keeping them around.
2023-03-15 21:48:44 -05:00
Dustin b38f48b72f Create subvolumes in init-storage
It turns out that we cannot use `systemd-tmpfiles` to create our Btrfs
subvolumes.  Since the directories we are interested in, specifically
`/var/log` and `/var/tmp` already exist in the rootfs image and are
therefore copied into the mutable filesystem, `systemd-tmpfiles` ignores
them.

To avoid having to explicitly specify the SELinux context for each
subvolume created on the persistent filesystem, `init-storage` now
executes `setfiles` to set the appropriate labels.
2023-03-15 21:45:30 -05:00
Dustin 7c3738d067 Add set-root-password command
The `set-root-password` command sets up an alternate mount namespace
with a writable `/etc` directory and then runs `passwd` in it.  This
allows `passwd` to create its lock files and backup files, without
requiring that the real `/etc` to be mutable.  After `passwd` finishes
and has updated its private copy of `/etc/shadow`, the script rewrites
the real one with its contents.
2023-03-15 21:21:29 -05:00
Dustin eb8f4c3b40 Make /etc/shadow writable
In order for users to be able to log in locally or via SSH without an
authorized key, they will need to have passwords set in `/etc/shadow`.
We do not really want to make all of `/etc` writable, so we will store
the actual `shadow` file on the persistent data volume, in a separate
Btrfs subvolume, and then bind-mount it at `/etc/shadow`.

While this makes `/etc/shadow` mutable, it does not actually let the
`passwd` program modify it.  This is because `passwd` creates lock files
and backup files in `/etc`.  We will ultimately need a wrapper to
"trick" `passwd` into modifying `/etc/shadow`, without making the whole
`/etc` directory mutable.
2023-03-15 21:17:18 -05:00
Dustin c259aad165 Allow root to log in w/ password on serial console
These additional SELinux policy rules are required to allow *root* to
log in on the serial console and directly assume the `sysadm_r` role.
2023-03-15 21:16:22 -05:00
Dustin 292a4d2268 init-storage: Copy file contexts from rootfs
Apparently, BusyBox's `cp` does NOT copy SELinux contexts when the `-a`
argument is specified.  This differs from GNU coreutils's `cp`, and
explains why the files copied from the rootfs image to the persistent
storage volume were not being labelled correctly.  The `-c` argument is
required.

Now that files are labelled correctly when they are copied, the step to
run `restorecon` is no longer necessary.
2023-03-15 21:14:33 -05:00
Dustin 31d8a98f64 build: Implement CONFIGDIR setting
In effort to support different builds of Aimee OS using the same
scripts, without necessarily having to fork this repository, the build
system now supports a `CONFIGDIR` setting.  When this variable is set,
files defining the target environment, such as the lists of packages to
install, the kernel configuration, the Portage configuration, etc. are
found in the path it specifes.

The reference build, for the Home Assistant Yellow board, is configured
in the `yellow` directory.  To build it, run:

```sh
CONFIGDIR=yellow ./vm-build.sh
```
2023-03-15 21:12:04 -05:00
Dustin 1914b3aba0 Remove old, unused build scripts 2023-03-14 10:40:10 -05:00
Dustin 2b6b777282 Omit more unnecessary files from rootfs.squashfs
These are related to making SELinux policy changes at runtime.
2023-03-12 21:35:37 -05:00
Dustin e9b21b0ca0 Switch to "mcs" SELinux policy
We're going to want the ability for processes to have unique categories,
to enforce separation of container processes.  Gentoo's SELinux policy
supports both Multi-Category Security and Multi-Level Security modes,
although the latter does not seem to work out of the box.
2023-03-12 21:34:15 -05:00
Dustin cb7e0a5819 init-storage: Set SELinux context for /var
This label needs to be applied before the subvolume is mounted initially
to prevent AVC denials.
2023-03-12 12:53:16 -05:00