diff --git a/config/hosts/clunk.nix b/config/hosts/clunk.nix index 73d4f87..d81387b 100644 --- a/config/hosts/clunk.nix +++ b/config/hosts/clunk.nix @@ -12,16 +12,16 @@ let in { system = { # Don't do unsupervised upgrades... - autoUpgrade.enable = mkForce false; + # autoUpgrade.enable = mkForce false; - # DO force all DNS traffic to use the local server - activationScripts.force-local-dns = let - wifi-ip = - config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address; - in '' - ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53 - ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53 - ''; + # # DO force all DNS traffic to use the local server + # activationScripts.force-local-dns = let + # wifi-ip = + # config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address; + # in '' + # ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53 + # ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53 + # ''; }; fudo.local-network = let @@ -77,6 +77,11 @@ in { enable = true; externalInterface = "enp1s0"; internalInterfaces = [ "intif0" ]; + forwardPorts = [{ + destination = "127.0.0.1:53"; + sourcePort = 53; + proto = "udp"; + }]; }; }; @@ -89,7 +94,7 @@ in { auth.kdc = { enable = true; realm = "RUS.SELBY.CA"; - bind-addresses = [ "10.0.0.1" "127.0.0.1" "[::1]" ]; + bind-addresses = [ "10.0.0.1" "127.0.0.1" "::1" ]; acl = { "niten" = { perms = [ "add" "change-password" "list" ]; }; "*/root" = { perms = [ "all" ]; }; diff --git a/config/profiles/common-ui.nix b/config/profiles/common-ui.nix index 83794cb..b17aa94 100644 --- a/config/profiles/common-ui.nix +++ b/config/profiles/common-ui.nix @@ -12,6 +12,8 @@ in { boot.tmpOnTmpfs = true; + system.autoUpgrade.enable = true; + services.xserver = mkIf enable-gui { enable = true; diff --git a/config/profiles/common.nix b/config/profiles/common.nix index 6884976..45fbe59 100644 --- a/config/profiles/common.nix +++ b/config/profiles/common.nix @@ -3,7 +3,7 @@ with lib; let # Available to all users on the system. Keep it minimal. - global-packages = with pkgs; [ bind git openssh_gssapi vim wget ]; + global-packages = with pkgs; [ bind git heimdal openssh_gssapi vim wget ]; in { environment = { @@ -20,8 +20,6 @@ in { nixpkgs.config.allowUnfree = true; security.acme.acceptTerms = true; - system.autoUpgrade.enable = true; - krb5 = { enable = true; @@ -59,6 +57,16 @@ in { }; }; + lshd = { + enable = true; + portNumber = 2112; + rootLogin = true; + srpKeyExchange = true; + tcpForwarding = false; + publicKeyAuthentication = true; + passwordAuthentication = false; + }; + fail2ban = { enable = true; bantime-increment.enable = true; @@ -74,6 +82,14 @@ in { # udev.packages = with pkgs; [ yubikey-personalization ]; }; + networking.firewall = { + # Allow mosh connections if the firewall is enabled + allowedUDPPortRanges = [{ + from = 60000; + to = 60100; + }]; + }; + console.useXkbConfig = true; i18n.defaultLocale = "en_US.UTF-8"; diff --git a/config/profiles/server.nix b/config/profiles/server.nix index 2a74151..a8cd609 100644 --- a/config/profiles/server.nix +++ b/config/profiles/server.nix @@ -59,6 +59,8 @@ in { # noXlibs = lib.mkForce true; }; + system.autoUpgrade.enable = false; + security = { hideProcessInformation = true; }; networking.networkmanager.enable = mkForce false; diff --git a/config/users.nix b/config/users.nix index f5e77c3..953cc7e 100644 --- a/config/users.nix +++ b/config/users.nix @@ -16,12 +16,13 @@ home-manager-config = import ../home-manager/niten.nix { inherit config lib pkgs; }; k5login = [ - "niten@FUDO.ORG" "niten/root@FUDO.ORG" "niten/admin@FUDO.ORG" "niten@INFORMIS.LAND" "niten/root@INFORMIS.LAND" "niten/admin@INFORMIS.LAND" + "niten@RUS.SELBY.CA" + "niten/root@RUS.SELBY.CA" ]; }; diff --git a/home-manager/niten.nix b/home-manager/niten.nix index 8aae397..0b218bf 100644 --- a/home-manager/niten.nix +++ b/home-manager/niten.nix @@ -88,14 +88,14 @@ in { onChange = "${pkgs.doomEmacsInit}/bin/doom-emacs-init.sh"; }; - ".k5login" = { - source = pkgs.writeText "niten-k5login" '' - niten@FUDO.ORG - niten/root@FUDO.ORG - niten@INFORMIS.LAND - niten/root@INFORMIS.LAND - ''; - }; + # ".k5login" = { + # source = pkgs.writeText "niten-k5login" '' + # niten@FUDO.ORG + # niten/root@FUDO.ORG + # niten@INFORMIS.LAND + # niten/root@INFORMIS.LAND + # ''; + # }; }; sessionVariables = { diff --git a/home-manager/root.nix b/home-manager/root.nix index 35923b5..100585b 100644 --- a/home-manager/root.nix +++ b/home-manager/root.nix @@ -27,6 +27,7 @@ in { source = pkgs.writeText "niten-k5login" '' niten/root@FUDO.ORG niten/root@INFORMIS.LAND + reaper/root@FUDO.ORG ''; }; }; diff --git a/lib/default.nix b/lib/default.nix index 3bfc890..d20bff6 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -36,6 +36,7 @@ with lib; { ./fudo/sites.nix ./fudo/slynk.nix ./fudo/system.nix + ./fudo/system-networking.nix ./fudo/users.nix ./fudo/vpn.nix ./fudo/webmail.nix diff --git a/lib/fudo/kdc.nix b/lib/fudo/kdc.nix index 76ab5e3..3715a37 100644 --- a/lib/fudo/kdc.nix +++ b/lib/fudo/kdc.nix @@ -28,7 +28,7 @@ let (get-domain-hosts (toLower realm)))); initialize-db = - realm: user: group: kdc-conf: key-file: db-name: max-lifetime: max-renewal: primary-keytab: kadmin-keytab: local-hostname: + realm: user: group: kdc-conf: key-file: db-name: max-lifetime: max-renewal: primary-keytab: kadmin-keytab: kpasswd-keytab: local-hostname: pkgs.writeShellScript "initialize-kdc-db.sh" '' if [ ! -e ${key-file} ]; then ${pkgs.heimdalFull}/bin/kstash --key-file=${key-file} --random-key @@ -36,6 +36,8 @@ let ${add-hosts-principals realm kdc-conf} ${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${primary-keytab} */${local-hostname}@${realm} ${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kadmin-keytab} kadmin/admin@${realm} + ${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kpasswd-keytab} kadmin/changepw@${realm} + ${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kpasswd-keytab} kadmin/changepw@${realm} #${pkgs.coreutils}/bin/chown ${user}:${group} ${key-file} #${pkgs.coreutils}/bin/chown ${user}:${group} ${db-name} #${pkgs.coreutils}/bin/chown ${user}:${group} ${iprop-log} @@ -61,7 +63,8 @@ let } [logging] - default = SYSLOG + kdc = FILE:/var/kerberos/kerberos.log + default = FILE:/var/kerberos/kerberos.log ''; aclEntry = { principal, ... }: { @@ -168,6 +171,12 @@ in { default = "/var/kerberos/kadmind.keytab"; }; + kpasswdd-keytab = mkOption { + type = str; + description = "Location of keytab for kpasswdd."; + default = "/var/kerberos/kpasswdd.keytab"; + }; + kdc-internal-port = mkOption { type = port; description = @@ -175,12 +184,12 @@ in { default = 4088; }; - k5login-directory = mkOption { - type = str; - description = - "Directory in which k5login files are stored for local users (equivalent to ~/.k5login)."; - default = "/var/kerberos/k5login"; - }; + # k5login-directory = mkOption { + # type = str; + # description = + # "Directory in which k5login files are stored for local users (equivalent to ~/.k5login)."; + # default = "/var/kerberos/k5login"; + # }; max-ticket-lifetime = mkOption { type = str; @@ -208,13 +217,14 @@ in { krb5 = { libdefaults = { - k5login_directory = cfg.k5login-directory; + # Stick to ~/.k5login + # k5login_directory = cfg.k5login-directory; ticket_lifetime = cfg.max-ticket-lifetime; renew_lifetime = cfg.max-ticket-renewal; }; realms = { ${cfg.realm} = { enable-http = false; }; }; extraConfig = '' - default = SYSLOG + default = FILE:/var/kerberos/kerberos.log ''; }; @@ -232,42 +242,41 @@ in { }; }; - internal-port-map = { - kdc = { - internal-port = cfg.kdc-internal-port; - external-port = 88; - protocols = [ "tcp" "udp" ]; - }; - }; - services = { - heimdal-kdc = { + heimdal-kdc = let + listen-addrs = concatStringsSep " " + (map (addr: "--addresses=${addr}") cfg.bind-addresses); + command = + "${pkgs.heimdalFull}/libexec/heimdal/kdc -c ${kdc-conf} --ports=88 ${listen-addrs}"; + in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; description = "Heimdal Kerberos Key Distribution Center (ticket server)."; - execStart = - "${pkgs.heimdalFull}/libexec/heimdal/kdc -c ${kdc-conf} --ports=${ - toString cfg.kdc-internal-port - } --addresses=127.0.0.1"; - environment = { KRB5_CONFIG = "/etc/krb5.conf"; }; + execStart = command; user = cfg.user; group = cfg.group; workingDirectory = cfg.state-directory; privateNetwork = false; addressFamilies = [ "AF_INET" "AF_INET6" ]; + requiredCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + environment = { KRB5_CONFIG = "/etc/krb5.conf"; }; }; heimdal-kdc-init = { requires = [ "heimdal-kdc.service" ]; + wantedBy = [ "multi-user.target" ]; description = "Initialization script for Heimdal KDC."; type = "oneshot"; execStart = "${initialize-db cfg.realm cfg.user cfg.group kdc-conf cfg.master-key-file database-file cfg.max-ticket-lifetime cfg.max-ticket-renewal cfg.primary-keytab cfg.kadmin-keytab + cfg.kpasswdd-keytab "${config.networking.hostName}.${toLower cfg.realm}"}"; user = cfg.user; group = cfg.group; + protectSystem = "full"; + addressFamilies = [ "AF_INET" "AF_INET6" ]; workingDirectory = cfg.state-directory; environment = { KRB5_CONFIG = "/etc/krb5.conf"; }; }; @@ -295,7 +304,7 @@ in { server = "${pkgs.heimdalFull}/libexec/heimdal/kpasswdd"; protocol = "udp"; serverArgs = - "--config-file=${kdc-conf} --keytab=${cfg.kadmin-keytab}"; + "--config-file=${kdc-conf} --keytab=${cfg.kpasswdd-keytab}"; } ]; }; diff --git a/lib/fudo/ldap.nix b/lib/fudo/ldap.nix index 660495e..2097752 100644 --- a/lib/fudo/ldap.nix +++ b/lib/fudo/ldap.nix @@ -308,10 +308,36 @@ in { systemd.services.openldap = { environment = { KRB5_KTNAME = cfg.kerberos-keytab; }; + # FIXME: THIS IS ALL UNPROVEN + serviceConfig = { + PrivateDevices = true; + PrivateTmp = true; + PrivateMounts = true; + ProtectControlGroups = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectSystem = true; + ProtectHostname = true; + ProtectHome = true; + ProtectClock = true; + ProtectKernelLogs = true; + KeyringMode = "private"; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + Restart = "on-failure"; + LockPersonality = true; + RestrictRealtime = true; + MemoryDenyWriteExecute = true; + SystemCallFilter = + "~@clock @debug @module @mount @raw-io @reboot @swap @privileged @resources @cpu-emulation @obsolete"; + UMask = "7007"; + InaccessiblePaths = [ "/home" "/root" ]; + LimitNOFILE = 49152; + PermissionsStartOnly = true; + }; }; services.openldap = { - enable = true; suffix = cfg.base; rootdn = "cn=admin,${cfg.base}"; diff --git a/lib/fudo/system-networking.nix b/lib/fudo/system-networking.nix new file mode 100644 index 0000000..bb612e9 --- /dev/null +++ b/lib/fudo/system-networking.nix @@ -0,0 +1,158 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.fudo.system; + + portMappingOpts = { name, ... }: { + options = with types; { + internal-port = mkOption { + type = port; + description = "Port on localhost to recieve traffic"; + }; + external-port = mkOption { + type = port; + description = "External port on which to listen for traffic."; + }; + protocols = mkOption { + type = listOf str; + description = + "Protocols for which to forward ports. Default is tcp-only."; + default = [ "tcp" ]; + }; + }; + }; + +in { + options.fudo.system = with types; { + internal-port-map = mkOption { + type = attrsOf (submodule portMappingOpts); + description = + "Sets of external ports to internal (i.e. localhost) ports to forward."; + default = { }; + example = { + sshmap = { + internal-port = 2222; + external-port = 22; + protocol = "udp"; + }; + }; + }; + }; + + config = mkIf (cfg.internal-port-map != { }) { + # FIXME: FUCK ME THIS IS WAY HARDER THAN IT SHOULD BE + # boot.kernel.sysctl = mkIf (cfg.internal-port-map != { }) { + # "net.ipv4.conf.all.route_localnet" = "1"; + # }; + + # fudo.system.services.forward-internal-ports = let + # ip-line = op: src-port: target-port: protocol: '' + # ${ipt} -t nat -${op} PREROUTING -p ${protocol} --dport ${ + # toString src-port + # } -j REDIRECT --to-ports ${toString target-port} + # ${ipt} -t nat -${op} OUTPUT -p ${protocol} -s lo --dport ${ + # toString src-port + # } -j REDIRECT --to-ports ${toString target-port} + # ''; + + # ip-forward-line = ip-line "I"; + + # ip-unforward-line = ip-line "D"; + + # traceOut = obj: builtins.trace obj obj; + + # concatMapAttrsToList = f: attrs: concatLists (mapAttrsToList f attrs); + + # portmap-entries = concatMapAttrsToList (name: opts: + # map (protocol: { + # src = opts.external-port; + # target = opts.internal-port; + # protocol = protocol; + # }) opts.protocols) cfg.internal-port-map; + + # make-entries = f: { src, target, protocol, ... }: f src target protocol; + + # forward-entries = map (make-entries ip-forward-line) portmap-entries; + + # unforward-entries = map (make-entries ip-unforward-line) portmap-entries; + + # forward-ports-script = pkgs.writeShellScript "forward-internal-ports.sh" + # (concatStringsSep "\n" forward-entries); + + # unforward-ports-script = + # pkgs.writeShellScript "unforward-internal-ports.sh" + # (concatStringsSep "\n" + # (map (make-entries ip-unforward-line) portmap-entries)); + # in { + # wantedBy = [ "multi-user.target" ]; + # after = [ "firewall.service" "nat.service" ]; + # type = "oneshot"; + # description = "Rules for forwarding external ports to local ports."; + # execStart = "${forward-ports-script}"; + # execStop = "${unforward-ports-script}"; + # requiredCapabilities = + # [ "CAP_DAC_READ_SEARCH" "CAP_NET_ADMIN" "CAP_NET_RAW" ]; + # }; + + # networking.firewall = let + # iptables = "ip46tables"; + # ip-forward-line = protocols: internal: external: + # concatStringsSep "\n" (map (protocol: '' + # ${iptables} -t nat -I PREROUTING -p ${protocol} --dport ${ + # toString external + # } -j REDIRECT --to-ports ${toString internal} + # ${iptables} -t nat -I OUTPUT -s lo -p ${protocol} --dport ${ + # toString external + # } -j REDIRECT --to-ports ${toString internal} + # '') protocols); + + # ip-unforward-line = protocols: internal: external: + # concatStringsSep "\n" (map (protocol: '' + # ${iptables} -t nat -D PREROUTING -p ${protocol} --dport ${ + # toString external + # } -j REDIRECT --to-ports ${toString internal} + # ${iptables} -t nat -D OUTPUT -s lo -p ${protocol} --dport ${ + # toString external + # } -j REDIRECT --to-ports ${toString internal} + # '') protocols); + # in { + # enable = true; + + # extraCommands = concatStringsSep "\n" (mapAttrsToList (name: opts: + # ip-forward-line opts.protocols opts.internal-port opts.external-port) + # cfg.internal-port-map); + + # extraStopCommands = concatStringsSep "\n" (mapAttrsToList (name: opts: + # ip-unforward-line opts.protocols opts.internal-port opts.external-port) + # cfg.internal-port-map); + # }; + + # networking.nat.forwardPorts = + # let portmaps = (attrValues opts.external-port); + # in concatMap (opts: + # map (protocol: { + # destination = "127.0.0.1:${toString opts.internal-port}"; + # sourcePort = opts.external-port; + # proto = protocol; + # }) opts.protocols) (attrValues cfg.internal-port-map); + + # services.xinetd = mkIf ((length (attrNames cfg.internal-port-map)) > 0) { + # enable = true; + # services = let + # svcs = mapAttrsToList (name: opts: opts // { name = name; }) + # cfg.internal-port-map; + # svcs-protocols = concatMap + # (svc: map (protocol: svc // { protocol = protocol; }) svc.protocols) + # svcs; + # in map (opts: { + # name = opts.name; + # unlisted = true; + # port = opts.external-port; + # server = "${pkgs.coreutils}/bin/false"; + # extraConfig = "redirect = localhost ${toString opts.internal-port}"; + # protocol = opts.protocol; + # }) svcs-protocols; + # }; + }; +} diff --git a/lib/fudo/system.nix b/lib/fudo/system.nix index ee85fed..edd6844 100644 --- a/lib/fudo/system.nix +++ b/lib/fudo/system.nix @@ -154,6 +154,11 @@ let default = null; description = "Command to run to launch the service."; }; + execStop = mkOption { + type = nullOr str; + default = null; + description = "Command to run to launch the service."; + }; protectSystem = mkOption { type = enum [ "true" "false" "full" "strict" true false ]; default = "full"; @@ -355,10 +360,7 @@ let concatStringsSep " " allowed; restrict-address-families = allowed: - if (allowed == [ ]) then - "~${concatStringsSep " " address-families}" - else - concatStringsSep " " allowed; + if (allowed == [ ]) then [ "~AF_INET" "~AF_INET6" ] else allowed; dirOpts = { path, ... }: { options = with types; { @@ -380,25 +382,6 @@ let }; }; - portMappingOpts = { name, ... }: { - options = with types; { - internal-port = mkOption { - type = port; - description = "Port on localhost to recieve traffic"; - }; - external-port = mkOption { - type = port; - description = "External port on which to listen for traffic."; - }; - protocols = mkOption { - type = listOf str; - description = - "Protocols for which to forward ports. Default is tcp-only."; - default = [ "tcp" ]; - }; - }; - }; - in { options.fudo.system = with types; { services = mkOption { @@ -418,86 +401,9 @@ in { description = "A map of required directories to directory properties."; default = { }; }; - - internal-port-map = mkOption { - type = attrsOf (submodule portMappingOpts); - description = - "Sets of external ports to internal (i.e. localhost) ports to forward."; - default = { }; - example = { - sshmap = { - internal-port = 2222; - external-port = 22; - protocol = "udp"; - }; - }; - }; }; config = { - boot.kernel.sysctl = mkIf (cfg.internal-port-map != { }) { - "net.ipv4.conf.all.route_localnet" = "1"; - }; - - # networking.firewall = let - # iptables = "ip46tables"; - # ip-forward-line = protocols: internal: external: - # concatStringsSep "\n" (map (protocol: '' - # ${iptables} -t nat -I PREROUTING -p ${protocol} --dport ${ - # toString external - # } -j REDIRECT --to-ports ${toString internal} - # ${iptables} -t nat -I OUTPUT -s lo -p ${protocol} --dport ${ - # toString external - # } -j REDIRECT --to-ports ${toString internal} - # '') protocols); - - # ip-unforward-line = protocols: internal: external: - # concatStringsSep "\n" (map (protocol: '' - # ${iptables} -t nat -D PREROUTING -p ${protocol} --dport ${ - # toString external - # } -j REDIRECT --to-ports ${toString internal} - # ${iptables} -t nat -D OUTPUT -s lo -p ${protocol} --dport ${ - # toString external - # } -j REDIRECT --to-ports ${toString internal} - # '') protocols); - # in { - # enable = true; - - # extraCommands = concatStringsSep "\n" (mapAttrsToList (name: opts: - # ip-forward-line opts.protocols opts.internal-port opts.external-port) - # cfg.internal-port-map); - - # extraStopCommands = concatStringsSep "\n" (mapAttrsToList (name: opts: - # ip-unforward-line opts.protocols opts.internal-port opts.external-port) - # cfg.internal-port-map); - # }; - - networking.nat.forwardPorts = - let portmaps = (attrValues opts.external-port); - in concatMap (opts: - map (protocol: { - destination = "127.0.0.1:${toString opts.internal-port}"; - sourcePort = opts.external-port; - proto = protocol; - }) opts.protocols) (attrValues cfg.internal-port-map); - - # Services.xinetd = mkIf ((length (attrNames cfg.internal-port-map)) > 0) { - # enable = true; - # services = let - # svcs = mapAttrsToList (name: opts: opts // { name = name; }) - # cfg.internal-port-map; - # svcs-protocols = concatMap - # (svc: map (protocol: svc // { protocol = protocol; }) svc.protocols) - # svcs; - # in map (opts: { - # name = opts.name; - # unlisted = true; - # port = opts.external-port; - # server = "${pkgs.coreutils}/bin/false"; - # extraConfig = "redirect = localhost ${toString opts.internal-port}"; - # protocol = opts.protocol; - # }) svcs-protocols; - # }; systemd.timers = mapAttrs (name: opts: { enable = true; @@ -533,7 +439,7 @@ in { path = opts.path; serviceConfig = { PrivateNetwork = opts.privateNetwork; - PrivateUsers = opts.privateUsers; + PrivateUsers = mkIf (opts.user == null) opts.privateUsers; PrivateDevices = opts.privateDevices; PrivateTmp = opts.privateTmp; PrivateMounts = opts.privateMounts; @@ -546,11 +452,12 @@ in { ProtectClock = opts.protectClock; ProtectKernelLogs = opts.protectKernelLogs; KeyringMode = opts.keyringMode; - EnvironmentFile = opts.environment-file; + EnvironmentFile = + mkIf (opts.environment-file != null) opts.environment-file; # This is more complicated than it looks... - CapabilityBoundingSet = restrict-capabilities opts.requiredCapabilities; - Capabilities = opts.requiredCapabilities; + # CapabilityBoundingSet = restrict-capabilities opts.requiredCapabilities; + AmbientCapabilities = concatStringsSep " " opts.requiredCapabilities; SecureBits = mkIf ((length opts.requiredCapabilities) > 0) "keep-caps"; DynamicUser = mkIf (opts.user == null) opts.dynamicUser; @@ -568,6 +475,7 @@ in { LockPersonality = opts.lockPersonality; RestrictRealtime = opts.restrictRealtime; ExecStart = mkIf (opts.execStart != null) opts.execStart; + ExecStop = mkIf (opts.execStop != null) opts.execStop; MemoryDenyWriteExecute = opts.memoryDenyWriteExecute; SystemCallFilter = restrict-syscalls opts.allowedSyscalls; UMask = opts.maximumUmask; diff --git a/lib/fudo/users.nix b/lib/fudo/users.nix index 92d23bc..29c5498 100644 --- a/lib/fudo/users.nix +++ b/lib/fudo/users.nix @@ -3,20 +3,20 @@ with lib; let systemUserOpts = { username, ... }: { - options = { + options = with types; { username = mkOption { - type = types.str; + type = str; description = "The system user's login name."; default = username; }; description = mkOption { - type = types.str; + type = str; description = "Description of this system user's purpose or role"; }; ldap-hashed-password = mkOption { - type = types.str; + type = str; description = "LDAP-formatted hashed password for this user. Generate with slappasswd."; }; @@ -24,67 +24,67 @@ let }; userOpts = { username, ... }: { - options = { + options = with types; { username = mkOption { - type = types.str; + type = str; description = "The user's login name."; default = username; }; uid = mkOption { - type = types.int; + type = int; description = "Unique UID number for the user."; }; common-name = mkOption { - type = types.str; + type = str; description = "The user's common or given name."; }; primary-group = mkOption { - type = types.str; + type = str; description = "Primary group to which the user belongs."; }; login-shell = mkOption { - type = with types; nullOr shellPackage; + type = nullOr shellPackage; description = "The user's preferred shell."; }; description = mkOption { - type = types.str; + type = str; default = "Fudo Member"; description = "A description of this user's role."; }; ldap-hashed-passwd = mkOption { - type = with types; nullOr str; + type = nullOr str; description = "LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password."; default = null; }; login-hashed-passwd = mkOption { - type = with types; nullOr str; + type = nullOr str; description = "Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password."; default = null; }; ssh-authorized-keys = mkOption { - type = with types; listOf str; + type = listOf str; description = "SSH public keys this user can use to log in."; default = [ ]; }; home-manager-config = mkOption { - type = with types; nullOr attrs; + type = nullOr attrs; description = "Home Manager configuration for the given user."; default = null; }; home-directory = mkOption { - type = with types; nullOr str; + type = nullOr str; description = "Default home directory for the given user."; default = null; }; @@ -98,26 +98,26 @@ let }; groupOpts = { group-name, ... }: { - options = { + options = with types; { group-name = mkOption { - type = with types; nullOr str; + type = nullOr str; default = group-name; description = "Group name."; }; description = mkOption { - type = types.str; + type = str; description = "Description of the group or it's purpose."; }; members = mkOption { - type = with types; listOf str; + type = listOf str; default = [ ]; description = "A list of users who are members of the current group."; }; gid = mkOption { - type = types.int; + type = int; description = "GID number of the group."; }; }; @@ -225,8 +225,15 @@ in { home-manager-users = filterAttrs (username: userOpts: userOpts.home-manager-config != null) local-users; - - in mapAttrs (username: userOpts: userOpts.home-manager-config) + common-user-config = username: { + home.file.".k5login" = { + source = pkgs.writeText "${username}-k5login" '' + ${concatStringsSep "\n" config.fudo.users.${username}.k5login} + ''; + }; + }; + in mapAttrs (username: userOpts: + userOpts.home-manager-config // (common-user-config username)) home-manager-users; }; }