{
config,
lib,
pkgs,
...
}:
let
cfg = config.mjm.desktop;
in
{
options.mjm.desktop = {
<<options>>
};
config = lib.mkIf (cfg.enable && cfg.autoLogin.enable) {
<<config>>
};
_class = "nixos";
}My preferred way to secure my workstations is to only require a passphrase for unlocking the encrypted disk. No other interaction should be needed until reaching the desktop. This module enables that behavior.
autoLogin.enable = lib.mkEnableOption "auto-login with keyring unlocking";
Auto-login is not enabled by default because it requires some additional setup on the machine. The disk must be set up to prompt for some credential, ideally a FIDO2 or TPM pin, in order to unlock.
autoLogin.keyName = lib.mkOption {
type = lib.types.enum [
"luks2-pin"
"cryptsetup"
];
default = "luks2-pin";
};The keyName option determines the name of the key in the kernel keyring that will be used as the password to unlock gnome-keyring. The default and preferred option is to use a LUKS2 PIN which is used with either a FIDO2 key or a TPM. The "cryptsetup" option is used when unlocking directly with the disk passphrase, but this option lacks some security protections.
services.displayManager.autoLogin.user = "mjm";
The primary user, mjm, is the user that will be automatically logged in when the system boots. Setting a user for this option enables auto-login in the display manager.
security.pam.services.plasmalogin-autologin.rules.auth.systemd-loadkey = {
modulePath = "${config.systemd.package}/lib/security/pam_systemd_loadkey.so";
order = 0;
args = [ "keyname=${cfg.autoLogin.keyName}" ];
control = "optional";
};To get gnome-keyring to unlock automatically, some additional PAM rules in the autologin service are needed.
I'm using pam_systemd_loadkey to copy the PIN or passphrase for the disk and use it as though it was the password that was entered. This rule runs first in the service. The rule is optional, so if it fails the login can still continue. It just won't be able to unlock the keyring.
security.pam.services.plasmalogin-autologin.rules.auth.gnome_keyring = {
order = config.security.pam.services.plasmalogin-autologin.rules.auth.systemd-loadkey.order + 10;
control = "optional";
modulePath = "${pkgs.gnome-keyring}/lib/security/pam_gnome_keyring.so";
};If I was using GDM, this rule would already be there, but I'm not, because GDM (especially in NixOS) is pretty janky. This rule is ordered after the previous one, and takes the password set in the previous rule and tries to unlock gnome-keyring with it. This is also optional: there's no reason to block login on this.
The existing PAM rules for plasmalogin are left untouched.
systemd.services.plasmalogin.serviceConfig.KeyringMode = lib.mkForce "inherit";
The keyring mode on the display manager needs to be changed so that the pam_systemd_loadkey module actually sees the key that was set by systemd-cryptsetup when unlocking the disk.
text/gemini;lang=en-USThis content has been proxied by September (UNKNO).