Skip to content

Commit

Permalink
Login user setup
Browse files Browse the repository at this point in the history
Signed-off-by: Manuel Bluhm <[email protected]>
  • Loading branch information
mbssrc committed Oct 21, 2024
1 parent 3f08d1c commit b54e20c
Show file tree
Hide file tree
Showing 16 changed files with 155 additions and 68 deletions.
10 changes: 10 additions & 0 deletions modules/common/security/sshkeys.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ in
default = "/run/waypipe-ssh-public-key/id_ed25519.pub";
description = "The Waypipe public key";
};
userToAudiovmSshPublicKeyFiles = mkOption {
type = types.str;
default = "/run/waypipe-ssh-public-key/id_ed25519_ad.pub";
description = "The Waypipe public key";
};
userToNetvmSshPublicKeyFiles = mkOption {
type = types.str;
default = "/run/waypipe-ssh-public-key/id_ed25519_net.pub";
description = "The Waypipe public key";
};
sshKeyPath = mkOption {
type = types.str;
default = "/run/waypipe-ssh/id_ed25519";
Expand Down
7 changes: 0 additions & 7 deletions modules/common/services/audio.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,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
4 changes: 2 additions & 2 deletions modules/common/services/fprint.nix
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ 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;
}
});
Expand Down
83 changes: 63 additions & 20 deletions modules/common/users/accounts.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{ config, lib, ... }:
{
config,
lib,
...
}:
# account for the development time login with sudo rights
let
cfg = config.ghaf.users.accounts;
inherit (lib)
mkEnableOption
mkOption
optionals
optionalAttrs
mkIf
types
;
Expand All @@ -18,37 +23,75 @@ in
enable = mkEnableOption "Default account Setup";
user = mkOption {
default = "ghaf";
type = with types; str;
type = types.str;
description = ''
A default user to create in the system.
The admin account with sudo rights.
'';
};
password = mkOption {
default = "ghaf";
type = with types; str;
type = types.str;
description = ''
Default password for the admin user.
'';
};
enableLoginUser = mkEnableOption "Enable login user setup for UI.";
loginuser = mkOption {
default = "manuel";
type = types.str;
description = ''
Default user account for UI.
'';
};
loginuid = mkOption {
default = 1001;
type = types.int;
description = ''
A default password for the user.
Default UID for the login user.
'';
};
};

config = mkIf cfg.enable {
users = {
mutableUsers = false;
users."${cfg.user}" = {
isNormalUser = true;
inherit (cfg) password;
#TODO add "docker" use "lib.optionals"
extraGroups = [
"wheel"
"video"
"networkmanager"
] ++ optionals config.security.tpm2.enable [ "tss" ];
};
groups."${cfg.user}" = {
name = cfg.user;
members = [ cfg.user ];
};
mutableUsers = cfg.enableLoginUser;
users =
{
"${cfg.user}" = {
isNormalUser = true;
inherit (cfg) password;
extraGroups =
[
"wheel"
"video"
]
++ optionals config.security.tpm2.enable [ "tss" ]
++ optionals config.ghaf.virtualization.docker.daemon.enable [ "docker" ];
};
}
// optionalAttrs cfg.enableLoginUser {
"${cfg.loginuser}" = {
isNormalUser = true;
uid = cfg.loginuid;
inherit (cfg) password;
extraGroups = [
"video"
];
};
};
groups =
{
"${cfg.user}" = {
name = cfg.user;
members = [ cfg.user ];
};
}
// optionalAttrs cfg.enableLoginUser {
"${cfg.loginuser}" = {
name = cfg.loginuser;
members = [ cfg.loginuser ];
};
};
};

# to build ghaf as ghaf-user with caches
Expand Down
2 changes: 1 addition & 1 deletion modules/desktop/graphics/labwc.config.nix
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ in

services.greetd.settings = {
initial_session = lib.mkIf (cfg.autologinUser != null) {
user = "ghaf";
user = config.ghaf.users.accounts.loginuser;
command = "${labwc-session}/bin/labwc-session";
};
};
Expand Down
2 changes: 1 addition & 1 deletion modules/desktop/graphics/labwc.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ in
};
autologinUser = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = config.ghaf.users.accounts.user;
default = config.ghaf.users.accounts.loginuser;
description = ''
Username of the account that will be automatically logged in to the desktop.
If unspecified, the login manager is shown as usual.
Expand Down
11 changes: 11 additions & 0 deletions modules/microvm/virtualization/microvm/audiovm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,17 @@ let
] ++ lib.optional config.ghaf.development.debug.tools.enable pkgs.alsa-utils;
};

users.users."proxy-user-audio" = {
isNormalUser = true;
uid = config.ghaf.users.accounts.loginuid;
createHome = false;
extraGroups = [
"audio"
"video"
"pipewire"
];
};

time.timeZone = config.time.timeZone;
system.stateVersion = lib.trivial.release;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name:
let
cfg = config.ghaf.storagevm;
shared-mountPath = "/tmp/shared/shares";
inherit (config.ghaf.users.accounts) user;
user = config.ghaf.users.accounts.loginuser;
isGuiVm = builtins.stringLength name == 0;
userDir = "/home/${user}" + (if isGuiVm then "/Shares" else "/Unsafe\ share");
in
Expand Down
22 changes: 18 additions & 4 deletions modules/microvm/virtualization/microvm/common/storagevm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@
{ lib, config, ... }:
let
cfg = config.ghaf.storagevm;
inherit (lib)
mkEnableOption
mkOption
mkIf
mkMerge
mkForce
types
optionals
;
mountPath = "/guestStorage";
in
{
options.ghaf.storagevm = with lib; {
options.ghaf.storagevm = {
enable = mkEnableOption "StorageVM support";

name = mkOption {
Expand Down Expand Up @@ -85,9 +94,14 @@ in
environment.persistence.${mountPath} = lib.mkMerge [
{
hideMounts = true;
directories = [
"/var/lib/nixos"
];
directories =
[
"/var/lib/nixos"
]
++ optionals config.ghaf.users.accounts.enableLoginUser [
# TODO Replace with userborn setup
"/etc"
];

files = [
"/etc/ssh/ssh_host_ed25519_key.pub"
Expand Down
20 changes: 10 additions & 10 deletions modules/microvm/virtualization/microvm/guivm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ let
{
ghaf = {
users.accounts.enable = lib.mkDefault config.ghaf.users.accounts.enable;
users.accounts.enableLoginUser = true;
profiles = {
debug.enable = lib.mkDefault config.ghaf.profiles.debug.enable;
applications.enable = false;
Expand Down Expand Up @@ -68,15 +69,7 @@ let
storagevm = {
enable = true;
name = "guivm";
directories = [
{
directory = "/var/lib/private/ollama";
inherit (config.ghaf.users.accounts) user;
group = "ollama";
mode = "u=rwx,g=,o=";
}
];
users.${config.ghaf.users.accounts.user}.directories = [
users.${config.ghaf.users.accounts.loginuser}.directories = [
".cache"
".config"
".local"
Expand All @@ -94,9 +87,16 @@ let
keygenScript = pkgs.writeShellScriptBin "waypipe-ssh-keygen" ''
set -xeuo pipefail
mkdir -p /run/waypipe-ssh
mkdir -p /run/user-ssh
echo -en "\n\n\n" | ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f /run/waypipe-ssh/id_ed25519 -C ""
chown ghaf:ghaf /run/waypipe-ssh/*
chown ${config.ghaf.users.accounts.user}:${config.ghaf.users.accounts.user} /run/waypipe-ssh/*
cp /run/waypipe-ssh/id_ed25519.pub /run/waypipe-ssh-public-key/id_ed25519.pub
echo -en "\n\n\n" | ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f /run/user-ssh/id_ed25519_net -C "proxy-user-network@net-vm"
chown ${config.ghaf.users.accounts.loginuser}:${config.ghaf.users.accounts.loginuser} /run/user-ssh/*
cp /run/user-ssh/id_ed25519_net.pub /run/waypipe-ssh-public-key/id_ed25519_net.pub
echo -en "\n\n\n" | ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f /run/user-ssh/id_ed25519_ad -C "proxy-user-audio@audio-vm"
chown ${config.ghaf.users.accounts.loginuser}:${config.ghaf.users.accounts.loginuser} /run/user-ssh/*
cp /run/user-ssh/id_ed25519_ad.pub /run/waypipe-ssh-public-key/id_ed25519_ad.pub
'';
in
{
Expand Down
28 changes: 17 additions & 11 deletions modules/microvm/virtualization/microvm/microvm-host.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,39 @@
}:
let
cfg = config.ghaf.virtualization.microvm-host;
inherit (lib)
mkEnableOption
mkOption
mkIf
mkMerge
types
;
in
{
imports = [
inputs.impermanence.nixosModules.impermanence
inputs.self.nixosModules.givc-host
];
options.ghaf.virtualization.microvm-host = {
enable = lib.mkEnableOption "MicroVM Host";
networkSupport = lib.mkEnableOption "Network support services to run host applications.";
enable = mkEnableOption "MicroVM Host";
networkSupport = mkEnableOption "Network support services to run host applications.";
sharedVmDirectory = {
enable = lib.mkEnableOption "shared directory" // {
enable = mkEnableOption "shared directory" // {
default = true;
};

vms = lib.mkOption {
vms = mkOption {
description = ''
List of names of virtual machines for which unsafe shared folder will be enabled.
'';
type = lib.types.listOf lib.types.str;
type = types.listOf types.str;
default = [ ];
};
};
};

config = lib.mkMerge [
(lib.mkIf cfg.enable {
config = mkMerge [
(mkIf cfg.enable {
microvm.host.enable = true;
microvm.host.useNotifySockets = true;
ghaf.systemd = {
Expand Down Expand Up @@ -80,23 +87,22 @@ in
};

})
(lib.mkIf cfg.sharedVmDirectory.enable {
(mkIf cfg.sharedVmDirectory.enable {
ghaf.virtualization.microvm.guivm.extraModules = [ (import ./common/shared-directory.nix "") ];

# Create directories required for sharing files with correct permissions.
systemd.tmpfiles.rules =
let
vmDirs = map (
n:
"d /storagevm/shared/shares/Unsafe\\x20${n}\\x20share/ 0700 ${config.ghaf.users.accounts.user} users"
"d /storagevm/shared/shares/Unsafe\\x20${n}\\x20share/ 0760 ${toString config.ghaf.users.accounts.loginuid} users"
) cfg.sharedVmDirectory.vms;
in
[
"d /storagevm/shared 0755 root root"
"d /storagevm/shared/shares 0700 ${config.ghaf.users.accounts.user} users"
"d /storagevm/shared/shares 0760 ${toString config.ghaf.users.accounts.loginuid} users"
]
++ vmDirs;

})
];
}
9 changes: 9 additions & 0 deletions modules/microvm/virtualization/microvm/netvm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ let
${config.ghaf.security.sshKeys.waypipeSshPublicKeyDir}.options = [ "ro" ];
};

users.users."proxy-user-network" = {
isNormalUser = true;
createHome = false;
uid = config.ghaf.users.accounts.loginuid;
extraGroups = [
"networkmanager"
];
};

# SSH is very picky about to file permissions and ownership and will
# accept neither direct path inside /nix/store or symlink that points
# there. Therefore we copy the file to /etc/ssh/get-auth-keys (by
Expand Down
1 change: 1 addition & 0 deletions modules/reference/personalize/authorizedSshKeys.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAHVXc4s7e8j1uFsgHPBzpWvSI/hk5Zf6Btuj79D4hf3 tervis@tervis-servu"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM3w7NzqMuF+OAiIcYWyP9+J3kwvYMKQ+QeY9J8QjAXm [email protected]"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB/iv9RWMN6D9zmEU85XkaU8fAWJreWkv3znan87uqTW humaid@tahr"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICwsW+YJw6ukhoWPEBLN93EFiGhN7H2VJn5yZcKId56W mb@mmm"

# For ghaf-installer automated testing:
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAolaKCuIUBQSBFGFZI1taNX+JTAr8edqUts7A6k2Kv7"
Expand Down
Loading

0 comments on commit b54e20c

Please sign in to comment.