diff options
Diffstat (limited to 'nixos/modules/security')
-rw-r--r-- | nixos/modules/security/acme/default.nix | 2 | ||||
-rw-r--r-- | nixos/modules/security/ca.nix | 6 | ||||
-rw-r--r-- | nixos/modules/security/ipa.nix | 16 | ||||
-rw-r--r-- | nixos/modules/security/krb5/default.nix | 18 | ||||
-rw-r--r-- | nixos/modules/security/krb5/krb5-conf-format.nix | 73 | ||||
-rw-r--r-- | nixos/modules/security/pam.nix | 2 | ||||
-rw-r--r-- | nixos/modules/security/sudo-rs.nix | 2 | ||||
-rw-r--r-- | nixos/modules/security/systemd-confinement.nix | 36 |
8 files changed, 122 insertions, 33 deletions
diff --git a/nixos/modules/security/acme/default.nix b/nixos/modules/security/acme/default.nix index 5ffafdc37fefb..83581d02840ed 100644 --- a/nixos/modules/security/acme/default.nix +++ b/nixos/modules/security/acme/default.nix @@ -545,7 +545,7 @@ let }; server = mkOption { - type = types.str; + type = types.nullOr types.str; inherit (defaultAndText "server" "https://acme-v02.api.letsencrypt.org/directory") default defaultText; example = "https://acme-staging-v02.api.letsencrypt.org/directory"; description = '' diff --git a/nixos/modules/security/ca.nix b/nixos/modules/security/ca.nix index af5d91b35f2eb..8aae6eb3f29b0 100644 --- a/nixos/modules/security/ca.nix +++ b/nixos/modules/security/ca.nix @@ -26,13 +26,13 @@ in security.pki.useCompatibleBundle = mkEnableOption ''usage of a compatibility bundle. - Such a bundle consist exclusively of `BEGIN CERTIFICATE` and no `BEGIN TRUSTED CERTIFICATE`, - which is a OpenSSL specific PEM format. + Such a bundle consists exclusively of `BEGIN CERTIFICATE` and no `BEGIN TRUSTED CERTIFICATE`, + which is an OpenSSL specific PEM format. It is known to be incompatible with certain software stacks. Nevertheless, enabling this will strip all additional trust rules provided by the - certificates themselves, this can have security consequences depending on your usecases. + certificates themselves. This can have security consequences depending on your usecases ''; security.pki.certificateFiles = mkOption { diff --git a/nixos/modules/security/ipa.nix b/nixos/modules/security/ipa.nix index 543b1abfa672c..e746ca75724a1 100644 --- a/nixos/modules/security/ipa.nix +++ b/nixos/modules/security/ipa.nix @@ -85,6 +85,18 @@ in { description = "Whether to cache credentials."; }; + ipaHostname = mkOption { + type = types.str; + example = "myworkstation.example.com"; + default = if config.networking.domain != null then config.networking.fqdn + else "${config.networking.hostName}.${cfg.domain}"; + defaultText = literalExpression '' + if config.networking.domain != null then config.networking.fqdn + else "''${networking.hostName}.''${security.ipa.domain}" + ''; + description = "Fully-qualified hostname used to identify this host in the IPA domain."; + }; + ifpAllowedUids = mkOption { type = types.listOf types.str; default = ["root"]; @@ -218,7 +230,7 @@ in { ipa_domain = ${cfg.domain} ipa_server = _srv_, ${cfg.server} - ipa_hostname = ${config.networking.hostName}.${cfg.domain} + ipa_hostname = ${cfg.ipaHostname} cache_credentials = ${pyBool cfg.cacheCredentials} krb5_store_password_if_offline = ${pyBool cfg.offlinePasswords} @@ -232,7 +244,6 @@ in { ldap_user_extra_attrs = mail:mail, sn:sn, givenname:givenname, telephoneNumber:telephoneNumber, lock:nsaccountlock [sssd] - debug_level = 65510 services = nss, sudo, pam, ssh, ifp domains = ${cfg.domain} @@ -244,7 +255,6 @@ in { pam_verbosity = 3 [sudo] - debug_level = 65510 [autofs] diff --git a/nixos/modules/security/krb5/default.nix b/nixos/modules/security/krb5/default.nix index 78426c07cbc98..6714c41d8a07c 100644 --- a/nixos/modules/security/krb5/default.nix +++ b/nixos/modules/security/krb5/default.nix @@ -77,8 +77,22 @@ in { }; }; - config = mkIf cfg.enable { - environment = { + config = { + assertions = mkIf (cfg.enable || config.services.kerberos_server.enable) [(let + implementation = cfg.package.passthru.implementation or "<NOT SET>"; + in { + assertion = lib.elem implementation [ "krb5" "heimdal" ]; + message = '' + `security.krb5.package` must be one of: + + - krb5 + - heimdal + + Currently chosen implementation: ${implementation} + ''; + })]; + + environment = mkIf cfg.enable { systemPackages = [ cfg.package ]; etc."krb5.conf".source = format.generate "krb5.conf" cfg.settings; }; diff --git a/nixos/modules/security/krb5/krb5-conf-format.nix b/nixos/modules/security/krb5/krb5-conf-format.nix index 5a6bbed9fd188..3e5e64ae0cb04 100644 --- a/nixos/modules/security/krb5/krb5-conf-format.nix +++ b/nixos/modules/security/krb5/krb5-conf-format.nix @@ -7,17 +7,61 @@ let inherit (lib) boolToString concatMapStringsSep concatStringsSep filter isAttrs isBool isList mapAttrsToList mkOption singleton splitString; - inherit (lib.types) attrsOf bool coercedTo either int listOf oneOf path - str submodule; + inherit (lib.types) attrsOf bool coercedTo either enum int listOf oneOf + path str submodule; in -{ }: { - type = let - section = attrsOf relation; - relation = either (attrsOf value) value; +{ + enableKdcACLEntries ? false +}: rec { + sectionType = let + relation = oneOf [ + (listOf (attrsOf value)) + (attrsOf value) + value + ]; value = either (listOf atom) atom; atom = oneOf [int str bool]; + in attrsOf relation; + + type = let + aclEntry = submodule { + options = { + principal = mkOption { + type = str; + description = "Which principal the rule applies to"; + }; + access = mkOption { + type = either + (listOf (enum ["add" "cpw" "delete" "get" "list" "modify"])) + (enum ["all"]); + default = "all"; + description = "The changes the principal is allowed to make."; + }; + target = mkOption { + type = str; + default = "*"; + description = "The principals that 'access' applies to."; + }; + }; + }; + + realm = submodule ({ name, ... }: { + freeformType = sectionType; + options = { + acl = mkOption { + type = listOf aclEntry; + default = [ + { principal = "*/admin"; access = "all"; } + { principal = "admin"; access = "all"; } + ]; + description = '' + The privileges granted to a user. + ''; + }; + }; + }); in submodule { - freeformType = attrsOf section; + freeformType = attrsOf sectionType; options = { include = mkOption { default = [ ]; @@ -40,7 +84,17 @@ in ''; type = coercedTo path singleton (listOf path); }; - }; + + } + // + (lib.optionalAttrs enableKdcACLEntries { + realms = mkOption { + type = attrsOf realm; + description = '' + The realm(s) to serve keys for. + ''; + }; + }); }; generate = let @@ -71,6 +125,9 @@ in ${name} = { ${indent (concatStringsSep "\n" (mapAttrsToList formatValue relation))} }'' + else if isList relation + then + concatMapStringsSep "\n" (formatRelation name) relation else formatValue name relation; formatValue = name: value: diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 5d3bed2fb02c8..f77e819d0c83a 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -1055,7 +1055,7 @@ in the dp9ik pam module provided by tlsclient. If set, users can be authenticated against the 9front - authentication server given in {option}`security.pam.dp9ik.authserver`. + authentication server given in {option}`security.pam.dp9ik.authserver` ''; control = mkOption { default = "sufficient"; diff --git a/nixos/modules/security/sudo-rs.nix b/nixos/modules/security/sudo-rs.nix index 6ccf42ed7f087..e63a64d4691c0 100644 --- a/nixos/modules/security/sudo-rs.nix +++ b/nixos/modules/security/sudo-rs.nix @@ -41,7 +41,7 @@ in enable = mkEnableOption '' a memory-safe implementation of the {command}`sudo` command, - which allows non-root users to execute commands as root. + which allows non-root users to execute commands as root ''; package = mkPackageOption pkgs "sudo-rs" { }; diff --git a/nixos/modules/security/systemd-confinement.nix b/nixos/modules/security/systemd-confinement.nix index 0304749b8d109..041c900338864 100644 --- a/nixos/modules/security/systemd-confinement.nix +++ b/nixos/modules/security/systemd-confinement.nix @@ -79,13 +79,20 @@ in { description = '' The value `full-apivfs` (the default) sets up private {file}`/dev`, {file}`/proc`, - {file}`/sys` and {file}`/tmp` file systems in a separate user - name space. + {file}`/sys`, {file}`/tmp` and {file}`/var/tmp` file systems + in a separate user name space. If this is set to `chroot-only`, only the file system name space is set up along with the call to {manpage}`chroot(2)`. + In all cases, unless `serviceConfig.PrivateTmp=true` is set, + both {file}`/tmp` and {file}`/var/tmp` paths are added to `InaccessiblePaths=`. + This is to overcome options like `DynamicUser=true` + implying `PrivateTmp=true` without letting it being turned off. + Beware however that giving processes the `CAP_SYS_ADMIN` and `@mount` privileges + can let them undo the effects of `InaccessiblePaths=`. + ::: {.note} This doesn't cover network namespaces and is solely for file system level isolation. @@ -98,8 +105,12 @@ in { wantsAPIVFS = lib.mkDefault (config.confinement.mode == "full-apivfs"); in lib.mkIf config.confinement.enable { serviceConfig = { - RootDirectory = "/var/empty"; - TemporaryFileSystem = "/"; + ReadOnlyPaths = [ "+/" ]; + RuntimeDirectory = [ "confinement/${mkPathSafeName name}" ]; + RootDirectory = "/run/confinement/${mkPathSafeName name}"; + InaccessiblePaths = [ + "-+/run/confinement/${mkPathSafeName name}" + ]; PrivateMounts = lib.mkDefault true; # https://github.com/NixOS/nixpkgs/issues/14645 is a future attempt @@ -148,16 +159,6 @@ in { + " Please either define a separate service or find a way to run" + " commands other than ExecStart within the chroot."; } - { assertion = !cfg.serviceConfig.DynamicUser or false; - message = "${whatOpt "DynamicUser"}. Please create a dedicated user via" - + " the 'users.users' option instead as this combination is" - + " currently not supported."; - } - { assertion = cfg.serviceConfig ? ProtectSystem -> cfg.serviceConfig.ProtectSystem == false; - message = "${whatOpt "ProtectSystem"}. ProtectSystem is not compatible" - + " with service confinement as it fails to remount /usr within" - + " our chroot. Please disable the option."; - } ]) config.systemd.services); config.systemd.packages = lib.concatLists (lib.mapAttrsToList (name: cfg: let @@ -183,6 +184,13 @@ in { echo "BindReadOnlyPaths=$realprog:/bin/sh" >> "$serviceFile" ''} + # If DynamicUser= is enabled, PrivateTmp=true is implied (and cannot be turned off). + # so disable them unless PrivateTmp=true is explicitely set. + ${lib.optionalString (!cfg.serviceConfig.PrivateTmp) '' + echo "InaccessiblePaths=-+/tmp" >> "$serviceFile" + echo "InaccessiblePaths=-+/var/tmp" >> "$serviceFile" + ''} + while read storePath; do if [ -L "$storePath" ]; then # Currently, systemd can't cope with symlinks in Bind(ReadOnly)Paths, |