Skip to content

Commit

Permalink
feat(user accounts): new ghaf user account setup
Browse files Browse the repository at this point in the history
  - introducing userborn
  - disabling mutable users
  - re-factoring ghaf account to admin account
  - introducing login user account with homed + auxiliary accounts

  - impermanence flake input pinned to userborn patch
  - /etc/machine-id (gui-vm) is currently hardcoded as login user identity file depends on it.
    It should be generated on first boot and persistet. Workaround is available upstream (after
    userborn patch) in impermanence but does not seem to work with our setup, investigation required

Signed-off-by: Manuel Bluhm <[email protected]>
  • Loading branch information
mbssrc committed Dec 11, 2024
1 parent ad828e5 commit 8f41052
Show file tree
Hide file tree
Showing 37 changed files with 816 additions and 321 deletions.
7 changes: 4 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
};

impermanence = {
url = "github:nix-community/impermanence";
url = "github:nix-community/impermanence/32b1094d28d5fbedcc85a403bc08c8877b396255";
};

givc = {
Expand Down
2 changes: 1 addition & 1 deletion modules/common/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
./firewall
./profiles
./security
./users/accounts.nix
./users
./version
./virtualization/docker.nix
./systemd
Expand Down
1 change: 0 additions & 1 deletion modules/common/profiles/debug.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ in
config = lib.mkIf cfg.enable {
# Enable default accounts and passwords
ghaf = {
users.accounts.enable = true;
# Enable development on target
development = {
nix-setup.enable = true;
Expand Down
2 changes: 1 addition & 1 deletion modules/common/profiles/release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ in
# TODO this needs to be refined when we define a policy for the
# processes and the UID/groups that should be enabled by default
# if not already covered by systemd
ghaf.users.accounts.enable = true;
# ghaf.users.admin.enable = true;
};
}
7 changes: 0 additions & 7 deletions modules/common/services/audio.nix
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,6 @@ in
};
};

# Allow ghaf user to access pulseaudio and pipewire
users.extraUsers.ghaf.extraGroups = [
"audio"
"video"
"pipewire"
];

# Start pipewire on system boot
systemd.services.pipewire.wantedBy = [ "multi-user.target" ];

Expand Down
23 changes: 2 additions & 21 deletions modules/common/services/fprint.nix
Original file line number Diff line number Diff line change
Expand Up @@ -46,38 +46,19 @@ in
// Allow user to verify fingerprints
polkit.addRule(function(action, subject) {
if (action.id == "net.reactivated.fprint.device.verify" &&
subject.user == "ghaf") {
subject.isInGroup ("users")) {
return polkit.Result.YES;
}
});
// Allow user to enroll fingerprints
polkit.addRule(function(action, subject) {
if (action.id == "net.reactivated.fprint.device.enroll" &&
subject.user == "ghaf") {
subject.isInGroup ("users")) {
return polkit.Result.YES;
}
});
'';
};
# PAM rules for swaylock fingerprint reader
pam.services = {
swaylock.text = ''
# Account management.
account required pam_unix.so
# Authentication management.
auth sufficient pam_unix.so likeauth try_first_pass
auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so
auth required pam_deny.so
# Password management.
password sufficient pam_unix.so nullok sha512
# Session management.
session required pam_env.so conffile=/etc/pam/environment readenv=0
session required pam_unix.so
'';
};
};
};
}
4 changes: 1 addition & 3 deletions modules/common/services/xdgopener.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ let
# into all targets
ghaf-xdg-open = pkgs.callPackage ../../../packages/ghaf-xdg-open {
inherit (config.ghaf.security.sshKeys) sshKeyPath;
user = config.ghaf.users.appUser.name;
};
in
{
Expand Down Expand Up @@ -51,9 +52,6 @@ in
services."xdg@" = {
description = "XDG opener";
serviceConfig = {
# The user 'ghaf' is used here to access SSH keys for the scp command
# This is required to copy files to the zathuravm
User = "ghaf";
ExecStart = "${ghaf-xdg-open}/bin/ghaf-xdg-open";
StandardInput = "socket";
StandardOutput = "journal";
Expand Down
10 changes: 9 additions & 1 deletion modules/common/systemd/base.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ let
inherit (cfg) withAudit;
withCompression = true;
withCoredump = cfg.withDebug || cfg.withMachines;
inherit (cfg) withCryptsetup;
withCryptsetup = cfg.withCryptsetup || cfg.withHomed;
inherit (cfg) withEfi;
inherit (cfg) withBootloader;
inherit (cfg) withFido2;
inherit (cfg) withHomed;
inherit (cfg) withHostnamed;
withImportd = cfg.withMachines;
withKexectools = cfg.withDebug;
Expand All @@ -55,6 +56,7 @@ let
inherit (cfg) withTimesyncd;
inherit (cfg) withTpm2Tss;
inherit (cfg) withUkify;
withUserDb = cfg.withHomed;
withUtmp = cfg.withJournal || cfg.withAudit;
}
// lib.optionalAttrs (lib.strings.versionAtLeast pkgs.systemdMinimal.version "255.0") {
Expand Down Expand Up @@ -230,6 +232,12 @@ in
default = false;
};

withHomed = mkOption {
description = "Enable systemd homed for users home functionality.";
type = types.bool;
default = false;
};

withHostnamed = mkOption {
description = "Enable systemd hostname daemon.";
type = types.bool;
Expand Down
101 changes: 101 additions & 0 deletions modules/common/users/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Ghaf user setup

## Rationale
The changes address the separation between declarative and runtime
users. Declarative user definitions are appropriate if their
configuration should be the same across different machines.
Non-declarative users are introduced that allow changes without
re-building the configuration, and are purely device specific.

For more consistent declarative user management, 'userborn' is
introduced, which increases consistency by managing user parameter
changes across re-builds. It is enabled for host and all VMs by default.
The NixOS configuration `users.mutableUsers` is set to false, thus
the generic user tools cannot be used at runtime (`passwd`, `useradd`,
etc.).

To manage non-declarative users, 'systemd-homed' is used. It offers a
variety of concepts that are in line with our requirements such as
on-the-fly user creation, encryption, CIFS-integration, and more.

## Code structure

common.nix - common settings
admin.nix - admin account settings
desktop.nix - user accounts to manage desktop
other.nix - template to add other declarative users

## Accounts
All accounts are available to be configured. Note that they are only
available in the respective VM where they are specifically enabled, with
exception for the admin account.

### Admin account
The 'ghaf' user account is now the admin account (+wheel), and enabled by
default in host and all VMs. As this account is for administrative
purposes, it should not run a desktop session. This currently works with
some limitations, but at the moment we do not run a full-fletched multi-user
system.

### Login/desktop user account
The 'loginUser' account can be enabled and sets up a non-declarative
user with a reserved UID. It is a self-contained account, that currently
runs the user desktop session.

### Auxiliary accounts
Two auxiliary accounts are available that share the login users UID to
keep these UIDs consistent across VMs:
1) Proxy user
This user is used in system VMs that provide services. These services
are currently accessible via the dbus proxy, and require the same UID.
2) App user
This user is used in app VMs to run the user sessions (including applications).
The shared UID is helpful to map access rights across machines and support
legacy functionality.

### Other (declarative/managed) user accounts
While any additional user accounts may be freely created and administered, a template
for configuration managed users is provided.

## Future work
This patch introduces new account management on Ghaf. Based on the changes,
future work is required to extend it.

### Extending login-user functionality
Currently, a minimalistic setup script runs on first GUI-VM boot. The login
user setup may be extended with:

- Improvement of user creation script
- Graphical interface for user creation
- Feature integration: (supported by homed)
- CIFS/remote user storage integration
- FIDO token integration
- User ssh keys
- Avatar/Background/Locale/Timezone/Location
- External home support (e.g., USB or network storage)
- Potential re-work to run graphical session as static user
- Potential multi-user system with migratable data

### Overall user account improvements

- removing (hardcoded) ssh dependencies
- removing ssh root access, e.g., update user (PoC available)
- centralized mechanism (profiles) to administer declarative user account data (e.g., passwords)
- password policies mechanism, especially considering declarative users passwords are in nix store

### User data implications
While the login user setup provides some containment, currently user data is still
spread across the system, such as
- Persistent user-related platform data (e.g., wifi passwords)
- Persistent user data in app VMs (e.g., browser profiles/passwords)
- File sharing between VMs

Respective mechanisms are currently under investigation.

## Implementation notes

- VM storage shares have been re-named for consistency (<name>-vm)
- impermanence flake input pinned to userborn patch
- /etc/machine-id (gui-vm) is currently hardcoded as login user identity file depends on it.
It should be generated on first boot and persistet. Workaround is available upstream (after
userborn patch) in impermanence but does not seem to work with our setup, investigation required
66 changes: 0 additions & 66 deletions modules/common/users/accounts.nix

This file was deleted.

Loading

0 comments on commit 8f41052

Please sign in to comment.