diff options
Diffstat (limited to 'nixos/modules/security')
-rw-r--r-- | nixos/modules/security/apparmor.nix | 3 | ||||
-rw-r--r-- | nixos/modules/security/auditd.nix | 4 | ||||
-rw-r--r-- | nixos/modules/security/duosec.nix | 6 | ||||
-rw-r--r-- | nixos/modules/security/ipa.nix | 46 | ||||
-rw-r--r-- | nixos/modules/security/pam.nix | 60 | ||||
-rw-r--r-- | nixos/modules/security/sudo-rs.nix | 2 | ||||
-rw-r--r-- | nixos/modules/security/sudo.nix | 2 | ||||
-rw-r--r-- | nixos/modules/security/wrappers/default.nix | 4 | ||||
-rw-r--r-- | nixos/modules/security/wrappers/wrapper.nix | 4 |
9 files changed, 89 insertions, 42 deletions
diff --git a/nixos/modules/security/apparmor.nix b/nixos/modules/security/apparmor.nix index 24b48338ed772..ea1af6c6e2f29 100644 --- a/nixos/modules/security/apparmor.nix +++ b/nixos/modules/security/apparmor.nix @@ -164,7 +164,8 @@ in "local-fs.target" "systemd-journald-audit.socket" ]; - before = [ "sysinit.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; wantedBy = [ "multi-user.target" ]; unitConfig = { Description="Load AppArmor policies"; diff --git a/nixos/modules/security/auditd.nix b/nixos/modules/security/auditd.nix index db4b2701ee2e9..253ee1d4dd0e5 100644 --- a/nixos/modules/security/auditd.nix +++ b/nixos/modules/security/auditd.nix @@ -13,6 +13,8 @@ with lib; systemd.services.auditd = { description = "Linux Audit daemon"; wantedBy = [ "basic.target" ]; + before = [ "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; unitConfig = { ConditionVirtualization = "!container"; @@ -23,7 +25,7 @@ with lib; path = [ pkgs.audit ]; serviceConfig = { - ExecStartPre="${pkgs.coreutils}/bin/mkdir -p /var/log/audit"; + ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/log/audit"; ExecStart = "${pkgs.audit}/bin/auditd -l -n -s nochange"; }; }; diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index 2a855a77e3a39..ef76bfeb6d66a 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -195,7 +195,8 @@ in systemd.services.login-duo = lib.mkIf cfg.ssh.enable { wantedBy = [ "sysinit.target" ]; - before = [ "sysinit.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; unitConfig.DefaultDependencies = false; script = '' if test -f "${cfg.secretKeyFile}"; then @@ -216,7 +217,8 @@ in systemd.services.pam-duo = lib.mkIf cfg.ssh.enable { wantedBy = [ "sysinit.target" ]; - before = [ "sysinit.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; unitConfig.DefaultDependencies = false; script = '' if test -f "${cfg.secretKeyFile}"; then diff --git a/nixos/modules/security/ipa.nix b/nixos/modules/security/ipa.nix index df59d1e754140..3bf8b11f86261 100644 --- a/nixos/modules/security/ipa.nix +++ b/nixos/modules/security/ipa.nix @@ -181,25 +181,33 @@ in { ''; }; - system.activationScripts.ipa = stringAfter ["etc"] '' - # libcurl requires a hard copy of the certificate - if ! ${pkgs.diffutils}/bin/diff ${cfg.certificate} /etc/ipa/ca.crt > /dev/null 2>&1; then - rm -f /etc/ipa/ca.crt - cp ${cfg.certificate} /etc/ipa/ca.crt - fi - - if [ ! -f /etc/krb5.keytab ]; then - cat <<EOF - - In order to complete FreeIPA integration, please join the domain by completing the following steps: - 1. Authenticate as an IPA user authorized to join new hosts, e.g. kinit admin@${cfg.realm} - 2. Join the domain and obtain the keytab file: ipa-join - 3. Install the keytab file: sudo install -m 600 krb5.keytab /etc/ - 4. Restart sssd systemd service: sudo systemctl restart sssd - - EOF - fi - ''; + systemd.services."ipa-activation" = { + wantedBy = [ "sysinit.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; + unitConfig.DefaultDependencies = false; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + script = '' + # libcurl requires a hard copy of the certificate + if ! ${pkgs.diffutils}/bin/diff ${cfg.certificate} /etc/ipa/ca.crt > /dev/null 2>&1; then + rm -f /etc/ipa/ca.crt + cp ${cfg.certificate} /etc/ipa/ca.crt + fi + + if [ ! -f /etc/krb5.keytab ]; then + cat <<EOF + + In order to complete FreeIPA integration, please join the domain by completing the following steps: + 1. Authenticate as an IPA user authorized to join new hosts, e.g. kinit admin@${cfg.realm} + 2. Join the domain and obtain the keytab file: ipa-join + 3. Install the keytab file: sudo install -m 600 krb5.keytab /etc/ + 4. Restart sssd systemd service: sudo systemctl restart sssd + + EOF + fi + ''; + }; services.sssd.config = '' [domain/${cfg.domain}] diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index b5e5dcb24426a..111be7057afc0 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -654,8 +654,8 @@ let { name = "mysql"; enable = cfg.mysqlAuth; control = "sufficient"; modulePath = "${pkgs.pam_mysql}/lib/security/pam_mysql.so"; settings = { config_file = "/etc/security/pam_mysql.conf"; }; } - { name = "ssh_agent_auth"; enable = config.security.pam.enableSSHAgentAuth && cfg.sshAgentAuth; control = "sufficient"; modulePath = "${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so"; settings = { - file = lib.concatStringsSep ":" config.services.openssh.authorizedKeysFiles; + { name = "ssh_agent_auth"; enable = config.security.pam.sshAgentAuth.enable && cfg.sshAgentAuth; control = "sufficient"; modulePath = "${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so"; settings = { + file = lib.concatStringsSep ":" config.security.pam.sshAgentAuth.authorizedKeysFiles; }; } (let p11 = config.security.pam.p11; in { name = "p11"; enable = cfg.p11Auth; control = p11.control; modulePath = "${pkgs.pam_p11}/lib/security/pam_p11.so"; args = [ "${pkgs.opensc}/lib/opensc-pkcs11.so" @@ -943,7 +943,7 @@ let value.source = pkgs.writeText "${name}.pam" service.text; }; - optionalSudoConfigForSSHAgentAuth = optionalString config.security.pam.enableSSHAgentAuth '' + optionalSudoConfigForSSHAgentAuth = optionalString config.security.pam.sshAgentAuth.enable '' # Keep SSH_AUTH_SOCK so that pam_ssh_agent_auth.so can do its magic. Defaults env_keep+=SSH_AUTH_SOCK ''; @@ -956,6 +956,7 @@ in imports = [ (mkRenamedOptionModule [ "security" "pam" "enableU2F" ] [ "security" "pam" "u2f" "enable" ]) + (mkRenamedOptionModule [ "security" "pam" "enableSSHAgentAuth" ] [ "security" "pam" "sshAgentAuth" "enable" ]) ]; ###### interface @@ -1025,16 +1026,34 @@ in ''; }; - security.pam.enableSSHAgentAuth = mkOption { - type = types.bool; - default = false; - description = - lib.mdDoc '' - Enable sudo logins if the user's SSH agent provides a key - present in {file}`~/.ssh/authorized_keys`. - This allows machines to exclusively use SSH keys instead of - passwords. + security.pam.sshAgentAuth = { + enable = mkEnableOption '' + authenticating using a signature performed by the ssh-agent. + This allows using SSH keys exclusively, instead of passwords, for instance on remote machines + ''; + + authorizedKeysFiles = mkOption { + type = with types; listOf str; + description = '' + A list of paths to files in OpenSSH's `authorized_keys` format, containing + the keys that will be trusted by the `pam_ssh_agent_auth` module. + + The following patterns are expanded when interpreting the path: + - `%f` and `%H` respectively expand to the fully-qualified and short hostname ; + - `%u` expands to the username ; + - `~` or `%h` expands to the user's home directory. + + ::: {.note} + Specifying user-writeable files here result in an insecure configuration: a malicious process + can then edit such an authorized_keys file and bypass the ssh-agent-based authentication. + + See [issue #31611](https://github.com/NixOS/nixpkgs/issues/31611) + ::: ''; + example = [ "/etc/ssh/authorized_keys.d/%u" ]; + default = config.services.openssh.authorizedKeysFiles; + defaultText = literalExpression "config.services.openssh.authorizedKeysFiles"; + }; }; security.pam.enableOTPW = mkEnableOption (lib.mdDoc "the OTPW (one-time password) PAM module"); @@ -1456,8 +1475,25 @@ in `security.pam.zfs.enable` requires enabling ZFS (`boot.zfs.enabled` or `boot.zfs.enableUnstable`). ''; } + { + assertion = with config.security.pam.sshAgentAuth; enable -> authorizedKeysFiles != []; + message = '' + `security.pam.enableSSHAgentAuth` requires `services.openssh.authorizedKeysFiles` to be a non-empty list. + Did you forget to set `services.openssh.enable` ? + ''; + } ]; + warnings = optional + (with lib; with config.security.pam.sshAgentAuth; + enable && any (s: hasPrefix "%h" s || hasPrefix "~" s) authorizedKeysFiles) + ''config.security.pam.sshAgentAuth.authorizedKeysFiles contains files in the user's home directory. + + Specifying user-writeable files there result in an insecure configuration: + a malicious process can then edit such an authorized_keys file and bypass the ssh-agent-based authentication. + See https://github.com/NixOS/nixpkgs/issues/31611 + ''; + environment.systemPackages = # Include the PAM modules in the system path mostly for the manpages. [ pkgs.pam ] diff --git a/nixos/modules/security/sudo-rs.nix b/nixos/modules/security/sudo-rs.nix index f991675827efb..b4376562c34d7 100644 --- a/nixos/modules/security/sudo-rs.nix +++ b/nixos/modules/security/sudo-rs.nix @@ -6,8 +6,6 @@ let cfg = config.security.sudo-rs; - inherit (config.security.pam) enableSSHAgentAuth; - toUserString = user: if (isInt user) then "#${toString user}" else "${user}"; toGroupString = group: if (isInt group) then "%#${toString group}" else "%${group}"; diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index 3dd5d2e525d91..6aa9445eab65e 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -6,8 +6,6 @@ let cfg = config.security.sudo; - inherit (config.security.pam) enableSSHAgentAuth; - toUserString = user: if (isInt user) then "#${toString user}" else "${user}"; toGroupString = group: if (isInt group) then "%#${toString group}" else "%${group}"; diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 250f9775be14d..a298686b34e97 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -278,7 +278,9 @@ in systemd.services.suid-sgid-wrappers = { description = "Create SUID/SGID Wrappers"; wantedBy = [ "sysinit.target" ]; - before = [ "sysinit.target" ]; + before = [ "sysinit.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; + after = [ "systemd-sysusers.service" ]; unitConfig.DefaultDependencies = false; unitConfig.RequiresMountsFor = [ "/nix/store" "/run/wrappers" ]; serviceConfig.Type = "oneshot"; diff --git a/nixos/modules/security/wrappers/wrapper.nix b/nixos/modules/security/wrappers/wrapper.nix index 27d46c630af54..ca4b27bff1801 100644 --- a/nixos/modules/security/wrappers/wrapper.nix +++ b/nixos/modules/security/wrappers/wrapper.nix @@ -1,8 +1,8 @@ { stdenv, unsecvars, linuxHeaders, sourceProg, debug ? false }: # For testing: -# $ nix-build -E 'with import <nixpkgs> {}; pkgs.callPackage ./wrapper.nix { parentWrapperDir = "/run/wrappers"; debug = true; }' +# $ nix-build -E 'with import <nixpkgs> {}; pkgs.callPackage ./wrapper.nix { sourceProg = "${pkgs.hello}/bin/hello"; debug = true; }' stdenv.mkDerivation { - name = "security-wrapper"; + name = "security-wrapper-${baseNameOf sourceProg}"; buildInputs = [ linuxHeaders ]; dontUnpack = true; CFLAGS = [ |