diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-01-10 01:11:23 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-01-10 01:11:23 +0100 |
commit | c8d05d8abadb244bc4e6cee75d450978d1f09a61 (patch) | |
tree | 2d710425b8e3f78e84d5e46abb3397cb1b34ec18 /nixpkgs/nixos/modules/services | |
parent | ad899504860973e98351c922ecb934595f2c0f19 (diff) | |
parent | 0ed96eed101462bf05e1e99e1bbadcd49b4eb302 (diff) | |
download | nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.tar nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.tar.gz nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.tar.bz2 nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.tar.lz nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.tar.xz nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.tar.zst nixlib-c8d05d8abadb244bc4e6cee75d450978d1f09a61.zip |
Merge branch 'nixos-unstable-small' of https://github.com/NixOS/nixpkgs
Diffstat (limited to 'nixpkgs/nixos/modules/services')
-rw-r--r-- | nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix | 105 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/services/security/bitwarden-directory-connector-cli.nix | 323 |
2 files changed, 428 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix b/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix new file mode 100644 index 000000000000..daf85153d339 --- /dev/null +++ b/nixpkgs/nixos/modules/services/development/nixseparatedebuginfod.nix @@ -0,0 +1,105 @@ +{ pkgs, lib, config, ... }: +let + cfg = config.services.nixseparatedebuginfod; + url = "127.0.0.1:${toString cfg.port}"; +in +{ + options = { + services.nixseparatedebuginfod = { + enable = lib.mkEnableOption "separatedebuginfod, a debuginfod server providing source and debuginfo for nix packages"; + port = lib.mkOption { + description = "port to listen"; + default = 1949; + type = lib.types.port; + }; + nixPackage = lib.mkOption { + type = lib.types.package; + default = pkgs.nix; + defaultText = lib.literalExpression "pkgs.nix"; + description = '' + The version of nix that nixseparatedebuginfod should use as client for the nix daemon. It is strongly advised to use nix version >= 2.18, otherwise some debug info may go missing. + ''; + }; + allowOldNix = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Do not fail evaluation when {option}`services.nixseparatedebuginfod.nixPackage` is older than nix 2.18. + ''; + }; + }; + }; + config = lib.mkIf cfg.enable { + assertions = [ { + assertion = cfg.allowOldNix || (lib.versionAtLeast cfg.nixPackage.version "2.18"); + message = "nixseparatedebuginfod works better when `services.nixseparatedebuginfod.nixPackage` is set to nix >= 2.18 (instead of ${cfg.nixPackage.name}). Set `services.nixseparatedebuginfod.allowOldNix` to bypass."; + } ]; + + systemd.services.nixseparatedebuginfod = { + wantedBy = [ "multi-user.target" ]; + wants = [ "nix-daemon.service" ]; + after = [ "nix-daemon.service" ]; + path = [ cfg.nixPackage ]; + serviceConfig = { + ExecStart = [ "${pkgs.nixseparatedebuginfod}/bin/nixseparatedebuginfod -l ${url}" ]; + Restart = "on-failure"; + CacheDirectory = "nixseparatedebuginfod"; + # nix does not like DynamicUsers in allowed-users + User = "nixseparatedebuginfod"; + Group = "nixseparatedebuginfod"; + + # hardening + # Filesystem stuff + ProtectSystem = "strict"; # Prevent writing to most of / + ProtectHome = true; # Prevent accessing /home and /root + PrivateTmp = true; # Give an own directory under /tmp + PrivateDevices = true; # Deny access to most of /dev + ProtectKernelTunables = true; # Protect some parts of /sys + ProtectControlGroups = true; # Remount cgroups read-only + RestrictSUIDSGID = true; # Prevent creating SETUID/SETGID files + PrivateMounts = true; # Give an own mount namespace + RemoveIPC = true; + UMask = "0077"; + + # Capabilities + CapabilityBoundingSet = ""; # Allow no capabilities at all + NoNewPrivileges = true; # Disallow getting more capabilities. This is also implied by other options. + + # Kernel stuff + ProtectKernelModules = true; # Prevent loading of kernel modules + SystemCallArchitectures = "native"; # Usually no need to disable this + ProtectKernelLogs = true; # Prevent access to kernel logs + ProtectClock = true; # Prevent setting the RTC + + # Networking + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6"; + + # Misc + LockPersonality = true; # Prevent change of the personality + ProtectHostname = true; # Give an own UTS namespace + RestrictRealtime = true; # Prevent switching to RT scheduling + MemoryDenyWriteExecute = true; # Maybe disable this for interpreters like python + RestrictNamespaces = true; + }; + }; + + users.users.nixseparatedebuginfod = { + isSystemUser = true; + group = "nixseparatedebuginfod"; + }; + + users.groups.nixseparatedebuginfod = { }; + + nix.settings.extra-allowed-users = [ "nixseparatedebuginfod" ]; + + environment.variables.DEBUGINFOD_URLS = "http://${url}"; + + environment.systemPackages = [ + # valgrind support requires debuginfod-find on PATH + (lib.getBin pkgs.elfutils) + ]; + + environment.etc."gdb/gdbinit.d/nixseparatedebuginfod.gdb".text = "set debuginfod enabled on"; + + }; +} diff --git a/nixpkgs/nixos/modules/services/security/bitwarden-directory-connector-cli.nix b/nixpkgs/nixos/modules/services/security/bitwarden-directory-connector-cli.nix new file mode 100644 index 000000000000..18c02e22fd7e --- /dev/null +++ b/nixpkgs/nixos/modules/services/security/bitwarden-directory-connector-cli.nix @@ -0,0 +1,323 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + cfg = config.services.bitwarden-directory-connector-cli; +in { + options.services.bitwarden-directory-connector-cli = { + enable = mkEnableOption "Bitwarden Directory Connector"; + + package = mkPackageOption pkgs "bitwarden-directory-connector-cli" {}; + + domain = mkOption { + type = types.str; + description = lib.mdDoc "The domain the Bitwarden/Vaultwarden is accessible on."; + example = "https://vaultwarden.example.com"; + }; + + user = mkOption { + type = types.str; + description = lib.mdDoc "User to run the program."; + default = "bwdc"; + }; + + interval = mkOption { + type = types.str; + default = "*:0,15,30,45"; + description = lib.mdDoc "The interval when to run the connector. This uses systemd's OnCalendar syntax."; + }; + + ldap = mkOption { + description = lib.mdDoc '' + Options to configure the LDAP connection. + If you used the desktop application to test the configuration you can find the settings by searching for `ldap` in `~/.config/Bitwarden\ Directory\ Connector/data.json`. + ''; + default = {}; + type = types.submodule ({ + config, + options, + ... + }: { + freeformType = types.attrsOf (pkgs.formats.json {}).type; + + config.finalJSON = builtins.toJSON (removeAttrs config (filter (x: x == "finalJSON" || ! options.${x}.isDefined or false) (attrNames options))); + + options = { + finalJSON = mkOption { + type = (pkgs.formats.json {}).type; + internal = true; + readOnly = true; + visible = false; + }; + + ssl = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether to use TLS."; + }; + startTls = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether to use STARTTLS."; + }; + + hostname = mkOption { + type = types.str; + description = lib.mdDoc "The host the LDAP is accessible on."; + example = "ldap.example.com"; + }; + + port = mkOption { + type = types.port; + default = 389; + description = lib.mdDoc "Port LDAP is accessible on."; + }; + + ad = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether the LDAP Server is an Active Directory."; + }; + + pagedSearch = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether the LDAP server paginates search results."; + }; + + rootPath = mkOption { + type = types.str; + description = lib.mdDoc "Root path for LDAP."; + example = "dc=example,dc=com"; + }; + + username = mkOption { + type = types.str; + description = lib.mdDoc "The user to authenticate as."; + example = "cn=admin,dc=example,dc=com"; + }; + }; + }); + }; + + sync = mkOption { + description = lib.mdDoc '' + Options to configure what gets synced. + If you used the desktop application to test the configuration you can find the settings by searching for `sync` in `~/.config/Bitwarden\ Directory\ Connector/data.json`. + ''; + default = {}; + type = types.submodule ({ + config, + options, + ... + }: { + freeformType = types.attrsOf (pkgs.formats.json {}).type; + + config.finalJSON = builtins.toJSON (removeAttrs config (filter (x: x == "finalJSON" || ! options.${x}.isDefined or false) (attrNames options))); + + options = { + finalJSON = mkOption { + type = (pkgs.formats.json {}).type; + internal = true; + readOnly = true; + visible = false; + }; + + removeDisabled = mkOption { + type = types.bool; + default = true; + description = lib.mdDoc "Remove users from bitwarden groups if no longer in the ldap group."; + }; + + overwriteExisting = mkOption { + type = types.bool; + default = false; + description = + lib.mdDoc "Remove and re-add users/groups, See https://bitwarden.com/help/user-group-filters/#overwriting-syncs for more details."; + }; + + largeImport = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Enable if you are syncing more than 2000 users/groups."; + }; + + memberAttribute = mkOption { + type = types.str; + description = lib.mdDoc "Attribute that lists members in a LDAP group."; + example = "uniqueMember"; + }; + + creationDateAttribute = mkOption { + type = types.str; + description = lib.mdDoc "Attribute that lists a user's creation date."; + example = "whenCreated"; + }; + + useEmailPrefixSuffix = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "If a user has no email address, combine a username prefix with a suffix value to form an email."; + }; + emailPrefixAttribute = mkOption { + type = types.str; + description = lib.mdDoc "The attribute that contains the users username."; + example = "accountName"; + }; + emailSuffix = mkOption { + type = types.str; + description = lib.mdDoc "Suffix for the email, normally @example.com."; + example = "@example.com"; + }; + + users = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Sync users."; + }; + userPath = mkOption { + type = types.str; + description = lib.mdDoc "User directory, relative to root."; + default = "ou=users"; + }; + userObjectClass = mkOption { + type = types.str; + description = lib.mdDoc "Class that users must have."; + default = "inetOrgPerson"; + }; + userEmailAttribute = mkOption { + type = types.str; + description = lib.mdDoc "Attribute for a users email."; + default = "mail"; + }; + userFilter = mkOption { + type = types.str; + description = lib.mdDoc "LDAP filter for users."; + example = "(memberOf=cn=sales,ou=groups,dc=example,dc=com)"; + default = ""; + }; + + groups = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether to sync ldap groups into BitWarden."; + }; + groupPath = mkOption { + type = types.str; + description = lib.mdDoc "Group directory, relative to root."; + default = "ou=groups"; + }; + groupObjectClass = mkOption { + type = types.str; + description = lib.mdDoc "A class that groups will have."; + default = "groupOfNames"; + }; + groupNameAttribute = mkOption { + type = types.str; + description = lib.mdDoc "Attribute for a name of group."; + default = "cn"; + }; + groupFilter = mkOption { + type = types.str; + description = lib.mdDoc "LDAP filter for groups."; + example = "(cn=sales)"; + default = ""; + }; + }; + }); + }; + + secrets = { + ldap = mkOption { + type = types.str; + description = "Path to file that contains LDAP password for user in {option}`ldap.username"; + }; + + bitwarden = { + client_path_id = mkOption { + type = types.str; + description = "Path to file that contains Client ID."; + }; + client_path_secret = mkOption { + type = types.str; + description = "Path to file that contains Client Secret."; + }; + }; + }; + }; + + config = mkIf cfg.enable { + users.groups."${cfg.user}" = {}; + users.users."${cfg.user}" = { + isSystemUser = true; + group = cfg.user; + }; + + systemd = { + timers.bitwarden-directory-connector-cli = { + description = "Sync timer for Bitwarden Directory Connector"; + wantedBy = ["timers.target"]; + after = ["network-online.target"]; + timerConfig = { + OnCalendar = cfg.interval; + Unit = "bitwarden-directory-connector-cli.service"; + Persistent = true; + }; + }; + + services.bitwarden-directory-connector-cli = { + description = "Main process for Bitwarden Directory Connector"; + path = [pkgs.jq]; + + environment = { + BITWARDENCLI_CONNECTOR_APPDATA_DIR = "/tmp"; + BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS = "true"; + }; + + serviceConfig = { + Type = "oneshot"; + User = "${cfg.user}"; + PrivateTmp = true; + preStart = '' + set -eo pipefail + + # create the config file + ${lib.getExe cfg.package} data-file + touch /tmp/data.json.tmp + chmod 600 /tmp/data.json{,.tmp} + + ${lib.getExe cfg.package} config server ${cfg.domain} + + # now login to set credentials + export BW_CLIENTID="$(< ${escapeShellArg cfg.secrets.bitwarden.client_path_id})" + export BW_CLIENTSECRET="$(< ${escapeShellArg cfg.secrets.bitwarden.client_path_secret})" + ${lib.getExe cfg.package} login + + jq '.authenticatedAccounts[0] as $account + | .[$account].directoryConfigurations.ldap |= $ldap_data + | .[$account].directorySettings.organizationId |= $orgID + | .[$account].directorySettings.sync |= $sync_data' \ + --argjson ldap_data ${escapeShellArg cfg.ldap.finalJSON} \ + --arg orgID "''${BW_CLIENTID//organization.}" \ + --argjson sync_data ${escapeShellArg cfg.sync.finalJSON} \ + /tmp/data.json \ + > /tmp/data.json.tmp + + mv -f /tmp/data.json.tmp /tmp/data.json + + # final config + ${lib.getExe cfg.package} config directory 0 + ${lib.getExe cfg.package} config ldap.password --secretfile ${cfg.secrets.ldap} + ''; + + ExecStart = "${lib.getExe cfg.package} sync"; + }; + }; + }; + }; + + meta.maintainers = with maintainers; [Silver-Golden]; +} |