2022-07-15 04:53:28 +00:00
|
|
|
{ config, pkgs, lib, ... }:
|
2022-05-22 08:27:02 +00:00
|
|
|
|
|
|
|
# installer docs: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix
|
2022-07-31 18:35:15 +00:00
|
|
|
with lib;
|
|
|
|
let
|
2022-08-01 07:23:49 +00:00
|
|
|
cfg = config.sane.users;
|
2022-08-03 07:41:59 +00:00
|
|
|
# see nixpkgs/nixos/modules/services/networking/dhcpcd.nix
|
|
|
|
hasDHCP = config.networking.dhcpcd.enable &&
|
|
|
|
(config.networking.useDHCP || any (i: i.useDHCP == true) (attrValues config.networking.interfaces));
|
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
in
|
2022-05-22 08:27:02 +00:00
|
|
|
{
|
2022-07-31 18:35:15 +00:00
|
|
|
options = {
|
2022-08-01 07:23:49 +00:00
|
|
|
sane.users.guest.enable = mkOption {
|
2022-07-31 18:35:15 +00:00
|
|
|
default = false;
|
|
|
|
type = types.bool;
|
|
|
|
};
|
2022-05-22 08:27:02 +00:00
|
|
|
};
|
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
config = {
|
|
|
|
# Users are exactly these specified here;
|
|
|
|
# old ones will be deleted (from /etc/passwd, etc) upon upgrade.
|
|
|
|
users.mutableUsers = false;
|
2022-05-22 08:27:02 +00:00
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
# docs: https://nixpkgs-manual-sphinx-markedown-example.netlify.app/generated/options-db.xml.html#users-users
|
|
|
|
users.users.colin = {
|
|
|
|
# sets group to "users" (?)
|
|
|
|
isNormalUser = true;
|
|
|
|
home = "/home/colin";
|
2022-12-22 11:33:13 +00:00
|
|
|
createHome = true;
|
|
|
|
homeMode = "700";
|
2022-08-01 07:23:49 +00:00
|
|
|
uid = config.sane.allocations.colin-uid;
|
2022-07-31 18:35:15 +00:00
|
|
|
# i don't get exactly what this is, but nixos defaults to this non-deterministically
|
|
|
|
# in /var/lib/nixos/auto-subuid-map and i don't want that.
|
|
|
|
subUidRanges = [
|
|
|
|
{ startUid=100000; count=1; }
|
|
|
|
];
|
|
|
|
group = "users";
|
|
|
|
extraGroups = [
|
|
|
|
"wheel"
|
|
|
|
"nixbuild"
|
|
|
|
"networkmanager"
|
|
|
|
# phosh/mobile. XXX colin: unsure if necessary
|
|
|
|
"video"
|
|
|
|
"feedbackd"
|
|
|
|
"dialout" # required for modem access
|
|
|
|
];
|
2022-10-23 13:48:39 +00:00
|
|
|
|
|
|
|
# initial password is empty, in case anything goes wrong.
|
|
|
|
# if `colin-passwd` (a password hash) is successfully found/decrypted, that becomes the password at boot.
|
2022-07-31 18:35:15 +00:00
|
|
|
initialPassword = lib.mkDefault "";
|
2022-10-23 13:48:39 +00:00
|
|
|
passwordFile = lib.mkIf (config.sops.secrets ? "colin-passwd") config.sops.secrets.colin-passwd.path;
|
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
shell = pkgs.zsh;
|
2022-11-22 04:29:17 +00:00
|
|
|
openssh.authorizedKeys.keys = builtins.attrValues (import ../../modules/pubkeys.nix).users;
|
2022-10-18 12:29:36 +00:00
|
|
|
|
2022-12-28 09:30:29 +00:00
|
|
|
# some other nix pam users:
|
|
|
|
# - <https://github.com/g00pix/nixconf/blob/32c04f6fa843fed97639dd3f09e157668d3eea1f/profiles/sshfs.nix>
|
|
|
|
# - <https://github.com/lourkeur/distro/blob/11173454c6bb50f7ccab28cc2c757dca21446d1d/nixos/profiles/users/louis-full.nix>
|
|
|
|
# - <https://github.com/dnr/sample-nix-code/blob/03494480c1fae550c033aa54fd96aeb3827761c5/nixos/laptop.nix>
|
2022-10-18 12:29:36 +00:00
|
|
|
pamMount = {
|
|
|
|
# mount encrypted stuff at login
|
|
|
|
# requires that login password == fs encryption password
|
2022-12-28 09:30:29 +00:00
|
|
|
fstype = "fuse";
|
|
|
|
path = "gocryptfs#/nix/persist/home/colin/private";
|
2022-10-18 12:29:36 +00:00
|
|
|
# path = "${pkgs.gocryptfs}/bin/gocryptfs#/nix/persist/home/colin/private";
|
2022-12-28 09:30:29 +00:00
|
|
|
# fstype = "fuse.gocryptfs";
|
|
|
|
# path = "/nix/persist/home/colin/private";
|
2022-10-18 12:29:36 +00:00
|
|
|
mountpoint = "/home/colin/private";
|
2022-12-28 09:30:29 +00:00
|
|
|
# without allow_other, *root* isn't allowed to list anything in ~/private.
|
|
|
|
# which is weird (root can just `su colin`), but probably doesn't *hurt* anything -- right?
|
|
|
|
options="nodev,nosuid,quiet"; # allow_other
|
2022-10-18 12:29:36 +00:00
|
|
|
};
|
2022-07-31 18:35:15 +00:00
|
|
|
};
|
|
|
|
|
2022-12-28 09:30:29 +00:00
|
|
|
# required for PAM to find gocryptfs
|
|
|
|
security.pam.mount.additionalSearchPaths = [ pkgs.gocryptfs ];
|
|
|
|
security.pam.mount.enable = true;
|
|
|
|
# security.pam.mount.debugLevel = 1;
|
|
|
|
# security.pam.enableSSHAgentAuth = true; # ??
|
|
|
|
# needed for `allow_other` in e.g. gocryptfs mounts
|
|
|
|
# or i guess going through mount.fuse sets suid so that's not necessary?
|
|
|
|
# programs.fuse.userAllowOther = true;
|
|
|
|
|
2022-10-22 13:09:53 +00:00
|
|
|
sane.impermanence.home-dirs = [
|
|
|
|
# cache is probably too big to fit on the tmpfs
|
2022-12-29 16:38:58 +00:00
|
|
|
# { directory = ".cache"; encryptedClearOnBoot = true; }
|
|
|
|
{ directory = ".cache/mozilla"; encryptedClearOnBoot = true; }
|
2022-10-22 13:09:53 +00:00
|
|
|
".cargo"
|
|
|
|
".rustup"
|
2022-12-28 09:30:29 +00:00
|
|
|
# TODO: move this to ~/private!
|
2022-10-22 13:09:53 +00:00
|
|
|
".local/share/keyrings"
|
|
|
|
];
|
|
|
|
|
2022-12-28 03:42:14 +00:00
|
|
|
sane.impermanence.dirs = mkIf cfg.guest.enable [
|
2022-07-31 18:35:15 +00:00
|
|
|
{ user = "guest"; group = "users"; directory = "/home/guest"; }
|
|
|
|
];
|
|
|
|
users.users.guest = mkIf cfg.guest.enable {
|
|
|
|
isNormalUser = true;
|
|
|
|
home = "/home/guest";
|
2022-08-01 07:23:49 +00:00
|
|
|
uid = config.sane.allocations.guest-uid;
|
2022-07-31 18:35:15 +00:00
|
|
|
subUidRanges = [
|
|
|
|
{ startUid=200000; count=1; }
|
|
|
|
];
|
|
|
|
group = "users";
|
|
|
|
initialPassword = lib.mkDefault "";
|
|
|
|
shell = pkgs.zsh;
|
|
|
|
openssh.authorizedKeys.keys = [
|
|
|
|
# TODO: insert pubkeys that should be allowed in
|
|
|
|
];
|
|
|
|
};
|
2022-07-15 04:53:28 +00:00
|
|
|
|
2022-08-03 07:41:59 +00:00
|
|
|
users.users.dhcpcd = mkIf hasDHCP {
|
|
|
|
uid = config.sane.allocations.dhcpcd-uid;
|
|
|
|
};
|
|
|
|
users.groups.dhcpcd = mkIf hasDHCP {
|
|
|
|
gid = config.sane.allocations.dhcpcd-gid;
|
|
|
|
};
|
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
security.sudo = {
|
|
|
|
enable = true;
|
|
|
|
wheelNeedsPassword = false;
|
|
|
|
};
|
2022-07-15 04:53:28 +00:00
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
services.openssh = {
|
|
|
|
enable = true;
|
|
|
|
permitRootLogin = "no";
|
|
|
|
passwordAuthentication = false;
|
|
|
|
};
|
2022-07-15 04:53:28 +00:00
|
|
|
|
2022-07-31 18:35:15 +00:00
|
|
|
# affix some UIDs which were historically auto-generated
|
2022-08-01 07:23:49 +00:00
|
|
|
users.users.sshd.uid = config.sane.allocations.sshd-uid;
|
|
|
|
users.groups.polkituser.gid = config.sane.allocations.polkituser-gid;
|
|
|
|
users.groups.sshd.gid = config.sane.allocations.sshd-gid;
|
|
|
|
users.groups.systemd-coredump.gid = config.sane.allocations.systemd-coredump-gid;
|
2022-09-19 01:01:21 +00:00
|
|
|
users.users.nscd.uid = config.sane.allocations.nscd-uid;
|
|
|
|
users.groups.nscd.gid = config.sane.allocations.nscd-gid;
|
2022-09-29 21:03:13 +00:00
|
|
|
users.users.systemd-oom.uid = config.sane.allocations.systemd-oom-uid;
|
|
|
|
users.groups.systemd-oom.gid = config.sane.allocations.systemd-oom-gid;
|
2022-07-31 18:35:15 +00:00
|
|
|
|
|
|
|
# guarantee determinism in uid/gid generation for users:
|
|
|
|
assertions = let
|
|
|
|
uidAssertions = builtins.attrValues (builtins.mapAttrs (name: user: {
|
|
|
|
assertion = user.uid != null;
|
|
|
|
message = "non-deterministic uid detected for: ${name}";
|
|
|
|
}) config.users.users);
|
|
|
|
gidAssertions = builtins.attrValues (builtins.mapAttrs (name: group: {
|
|
|
|
assertion = group.gid != null;
|
|
|
|
message = "non-deterministic gid detected for: ${name}";
|
|
|
|
}) config.users.groups);
|
|
|
|
autoSubAssertions = builtins.attrValues (builtins.mapAttrs (name: user: {
|
|
|
|
assertion = !user.autoSubUidGidRange;
|
|
|
|
message = "non-deterministic subUids/Guids detected for: ${name}";
|
|
|
|
}) config.users.users);
|
|
|
|
in uidAssertions ++ gidAssertions ++ autoSubAssertions;
|
|
|
|
};
|
2022-05-22 08:27:02 +00:00
|
|
|
}
|