at master 6.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.sssd; 9 10 dataDir = "/var/lib/sssd"; 11 settingsFile = "${dataDir}/sssd.conf"; 12 settingsFileUnsubstituted = pkgs.writeText "${dataDir}/sssd-unsubstituted.conf" cfg.config; 13in 14{ 15 options = { 16 services.sssd = { 17 enable = lib.mkEnableOption "the System Security Services Daemon"; 18 19 config = lib.mkOption { 20 type = lib.types.lines; 21 description = "Contents of {file}`sssd.conf`."; 22 default = '' 23 [sssd] 24 services = nss, pam 25 domains = shadowutils 26 27 [nss] 28 29 [pam] 30 31 [domain/shadowutils] 32 id_provider = proxy 33 proxy_lib_name = files 34 auth_provider = proxy 35 proxy_pam_target = sssd-shadowutils 36 proxy_fast_alias = True 37 ''; 38 }; 39 40 sshAuthorizedKeysIntegration = lib.mkOption { 41 type = lib.types.bool; 42 default = false; 43 description = '' 44 Whether to make sshd look up authorized keys from SSS. 45 For this to work, the `ssh` SSS service must be enabled in the sssd configuration. 46 ''; 47 }; 48 49 kcm = lib.mkOption { 50 type = lib.types.bool; 51 default = false; 52 description = '' 53 Whether to use SSS as a Kerberos Cache Manager (KCM). 54 Kerberos will be configured to cache credentials in SSS. 55 ''; 56 }; 57 environmentFile = lib.mkOption { 58 type = lib.types.nullOr lib.types.path; 59 default = null; 60 description = '' 61 Environment file as defined in {manpage}`systemd.exec(5)`. 62 63 Secrets may be passed to the service without adding them to the world-readable 64 Nix store, by specifying placeholder variables as the option value in Nix and 65 setting these variables accordingly in the environment file. 66 67 ``` 68 # snippet of sssd-related config 69 [domain/LDAP] 70 ldap_default_authtok = $SSSD_LDAP_DEFAULT_AUTHTOK 71 ``` 72 73 ``` 74 # contents of the environment file 75 SSSD_LDAP_DEFAULT_AUTHTOK=verysecretpassword 76 ``` 77 ''; 78 }; 79 }; 80 }; 81 config = lib.mkMerge [ 82 (lib.mkIf cfg.enable { 83 # For `sssctl` to work. 84 environment.etc."sssd/sssd.conf".source = settingsFile; 85 environment.etc."sssd/conf.d".source = "${dataDir}/conf.d"; 86 87 systemd.services.sssd = { 88 description = "System Security Services Daemon"; 89 wantedBy = [ "multi-user.target" ]; 90 before = [ 91 "systemd-user-sessions.service" 92 "nss-user-lookup.target" 93 ]; 94 after = [ 95 "network-online.target" 96 "nscd.service" 97 ]; 98 requires = [ 99 "network-online.target" 100 "nscd.service" 101 ]; 102 wants = [ "nss-user-lookup.target" ]; 103 restartTriggers = [ 104 config.environment.etc."nscd.conf".source 105 settingsFileUnsubstituted 106 ]; 107 environment.LDB_MODULES_PATH = "${pkgs.ldb}/modules/ldb:${pkgs.sssd}/modules/ldb"; 108 serviceConfig = { 109 # systemd needs to start sssd directly for "NotifyAccess=main" to work 110 ExecStart = "${pkgs.sssd}/bin/sssd -i -c ${settingsFile}"; 111 Type = "notify"; 112 NotifyAccess = "main"; 113 PIDFile = "/run/sssd.pid"; 114 CapabilityBoundingSet = [ 115 "CAP_IPC_LOCK" 116 "CAP_CHOWN" 117 "CAP_DAC_READ_SEARCH" 118 "CAP_KILL" 119 "CAP_NET_ADMIN" 120 "CAP_SYS_NICE" 121 "CAP_FOWNER" 122 "CAP_SETGID" 123 "CAP_SETUID" 124 "CAP_SYS_ADMIN" 125 "CAP_SYS_RESOURCE" 126 "CAP_BLOCK_SUSPEND" 127 ]; 128 Restart = "on-abnormal"; 129 StateDirectory = baseNameOf dataDir; 130 # We cannot use LoadCredential here because it's not available in ExecStartPre 131 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; 132 }; 133 unitConfig = { 134 StartLimitIntervalSec = "50s"; 135 StartLimitBurst = 5; 136 }; 137 preStart = '' 138 mkdir -p "${dataDir}/conf.d" 139 [ -f ${settingsFile} ] && rm -f ${settingsFile} 140 old_umask=$(umask) 141 umask 0177 142 ${pkgs.envsubst}/bin/envsubst \ 143 -o ${settingsFile} \ 144 -i ${settingsFileUnsubstituted} 145 umask $old_umask 146 mkdir -p /var/lib/sss/{pubconf,db,mc,pipes,gpo_cache,secrets} /var/lib/sss/pipes/private /var/lib/sss/pubconf/krb5.include.d 147 ''; 148 }; 149 150 system.nssModules = [ pkgs.sssd ]; 151 system.nssDatabases = { 152 group = [ "sss" ]; 153 passwd = [ "sss" ]; 154 services = [ "sss" ]; 155 shadow = [ "sss" ]; 156 }; 157 services.dbus.packages = [ pkgs.sssd ]; 158 }) 159 160 (lib.mkIf cfg.kcm { 161 systemd.services.sssd-kcm = { 162 description = "SSSD Kerberos Cache Manager"; 163 requires = [ "sssd-kcm.socket" ]; 164 serviceConfig = { 165 ExecStartPre = "-${pkgs.sssd}/bin/sssd --genconf-section=kcm"; 166 ExecStart = "${pkgs.sssd}/libexec/sssd/sssd_kcm --uid 0 --gid 0"; 167 CapabilityBoundingSet = [ 168 "CAP_IPC_LOCK" 169 "CAP_CHOWN" 170 "CAP_DAC_READ_SEARCH" 171 "CAP_FOWNER" 172 "CAP_SETGID" 173 "CAP_SETUID" 174 ]; 175 }; 176 restartTriggers = [ 177 settingsFileUnsubstituted 178 ]; 179 }; 180 systemd.sockets.sssd-kcm = { 181 description = "SSSD Kerberos Cache Manager responder socket"; 182 wantedBy = [ "sockets.target" ]; 183 # Matches the default in MIT krb5 and Heimdal: 184 # https://github.com/krb5/krb5/blob/krb5-1.19.3-final/src/include/kcm.h#L43 185 listenStreams = [ "/var/run/.heim_org.h5l.kcm-socket" ]; 186 }; 187 security.krb5.settings.libdefaults.default_ccache_name = "KCM:"; 188 }) 189 190 (lib.mkIf cfg.sshAuthorizedKeysIntegration { 191 # Ugly: sshd refuses to start if a store path is given because /nix/store is group-writable. 192 # So indirect by a symlink. 193 environment.etc."ssh/authorized_keys_command" = { 194 mode = "0755"; 195 text = '' 196 #!/bin/sh 197 exec ${pkgs.sssd}/bin/sss_ssh_authorizedkeys "$@" 198 ''; 199 }; 200 services.openssh.authorizedKeysCommand = "/etc/ssh/authorized_keys_command"; 201 services.openssh.authorizedKeysCommandUser = "nobody"; 202 }) 203 ]; 204 205 meta.maintainers = with lib.maintainers; [ bbigras ]; 206}