diff options
Diffstat (limited to 'nixos/modules')
-rw-r--r-- | nixos/modules/misc/ids.nix | 2 | ||||
-rw-r--r-- | nixos/modules/misc/version.nix | 3 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/networking/wpa_supplicant.nix | 12 | ||||
-rw-r--r-- | nixos/modules/services/security/certmgr.nix | 194 | ||||
-rw-r--r-- | nixos/modules/services/security/vault.nix | 22 | ||||
-rw-r--r-- | nixos/modules/services/web-apps/youtrack.nix | 4 | ||||
-rw-r--r-- | nixos/modules/services/x11/display-managers/sddm.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/x11/window-managers/metacity.nix | 12 | ||||
-rw-r--r-- | nixos/modules/virtualisation/libvirtd.nix | 24 | ||||
-rw-r--r-- | nixos/modules/virtualisation/virtualbox-host.nix | 13 |
11 files changed, 268 insertions, 20 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 40445c3b960..bffd8aff78b 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -325,6 +325,7 @@ hydron = 298; cfssl = 299; cassandra = 300; + qemu-libvirtd = 301; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -610,6 +611,7 @@ hydron = 298; cfssl = 299; cassandra = 300; + qemu-libvirtd = 301; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix index 3be12e4a637..63717e0c6a8 100644 --- a/nixos/modules/misc/version.nix +++ b/nixos/modules/misc/version.nix @@ -76,9 +76,6 @@ in config = { - warnings = lib.optional (options.system.stateVersion.highestPrio > 1000) - "You don't have `system.stateVersion` explicitly set. Expect things to break."; - system.nixos = { # These defaults are set here rather than up there so that # changing them would not rebuild the manual diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 73173dd4e24..e19853efd73 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -623,6 +623,7 @@ ./services/search/hound.nix ./services/search/kibana.nix ./services/search/solr.nix + ./services/security/certmgr.nix ./services/security/cfssl.nix ./services/security/clamav.nix ./services/security/fail2ban.nix diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 4bae05b6dd3..c788528fa47 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -8,6 +8,7 @@ let ${optionalString cfg.userControlled.enable '' ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group} update_config=1''} + ${cfg.extraConfig} ${concatStringsSep "\n" (mapAttrsToList (ssid: config: with config; let key = if psk != null then ''"${psk}"'' @@ -165,6 +166,17 @@ in { description = "Members of this group can control wpa_supplicant."; }; }; + extraConfig = mkOption { + type = types.str; + default = ""; + example = '' + p2p_disabled=1 + ''; + description = '' + Extra lines appended to the configuration file. + See wpa_supplicant.conf(5) for available options. + ''; + }; }; }; diff --git a/nixos/modules/services/security/certmgr.nix b/nixos/modules/services/security/certmgr.nix new file mode 100644 index 00000000000..22d5817ec4f --- /dev/null +++ b/nixos/modules/services/security/certmgr.nix @@ -0,0 +1,194 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.certmgr; + + specs = mapAttrsToList (n: v: rec { + name = n + ".json"; + path = if isAttrs v then pkgs.writeText name (builtins.toJSON v) else v; + }) cfg.specs; + + allSpecs = pkgs.linkFarm "certmgr.d" specs; + + certmgrYaml = pkgs.writeText "certmgr.yaml" (builtins.toJSON { + dir = allSpecs; + default_remote = cfg.defaultRemote; + svcmgr = cfg.svcManager; + before = cfg.validMin; + interval = cfg.renewInterval; + inherit (cfg) metricsPort metricsAddress; + }); + + specPaths = map dirOf (concatMap (spec: + if isAttrs spec then + collect isString (filterAttrsRecursive (n: v: isAttrs v || n == "path") spec) + else + [ spec ] + ) (attrValues cfg.specs)); + + preStart = '' + ${concatStringsSep " \\\n" (["mkdir -p"] ++ map escapeShellArg specPaths)} + ${pkgs.certmgr}/bin/certmgr -f ${certmgrYaml} check + ''; +in +{ + options.services.certmgr = { + enable = mkEnableOption "certmgr"; + + defaultRemote = mkOption { + type = types.str; + default = "127.0.0.1:8888"; + description = "The default CA host:port to use."; + }; + + validMin = mkOption { + default = "72h"; + type = types.str; + description = "The interval before a certificate expires to start attempting to renew it."; + }; + + renewInterval = mkOption { + default = "30m"; + type = types.str; + description = "How often to check certificate expirations and how often to update the cert_next_expires metric."; + }; + + metricsAddress = mkOption { + default = "127.0.0.1"; + type = types.str; + description = "The address for the Prometheus HTTP endpoint."; + }; + + metricsPort = mkOption { + default = 9488; + type = types.ints.u16; + description = "The port for the Prometheus HTTP endpoint."; + }; + + specs = mkOption { + default = {}; + example = literalExample '' + { + exampleCert = + let + domain = "example.com"; + secret = name: "/var/lib/secrets/''${name}.pem"; + in { + service = "nginx"; + action = "reload"; + authority = { + file.path = secret "ca"; + }; + certificate = { + path = secret domain; + }; + private_key = { + owner = "root"; + group = "root"; + mode = "0600"; + path = secret "''${domain}-key"; + }; + request = { + CN = domain; + hosts = [ "mail.''${domain}" "www.''${domain}" ]; + key = { + algo = "rsa"; + size = 2048; + }; + names = { + O = "Example Organization"; + C = "USA"; + }; + }; + }; + otherCert = "/var/certmgr/specs/other-cert.json"; + } + ''; + type = with types; attrsOf (either (submodule { + options = { + service = mkOption { + type = nullOr str; + default = null; + description = "The service on which to perform <action> after fetching."; + }; + + action = mkOption { + type = addCheck str (x: cfg.svcManager == "command" || elem x ["restart" "reload" "nop"]); + default = "nop"; + description = "The action to take after fetching."; + }; + + # These ought all to be specified according to certmgr spec def. + authority = mkOption { + type = attrs; + description = "certmgr spec authority object."; + }; + + certificate = mkOption { + type = nullOr attrs; + description = "certmgr spec certificate object."; + }; + + private_key = mkOption { + type = nullOr attrs; + description = "certmgr spec private_key object."; + }; + + request = mkOption { + type = nullOr attrs; + description = "certmgr spec request object."; + }; + }; + }) path); + description = '' + Certificate specs as described by: + <link xlink:href="https://github.com/cloudflare/certmgr#certificate-specs" /> + These will be added to the Nix store, so they will be world readable. + ''; + }; + + svcManager = mkOption { + default = "systemd"; + type = types.enum [ "circus" "command" "dummy" "openrc" "systemd" "sysv" ]; + description = '' + This specifies the service manager to use for restarting or reloading services. + See: <link xlink:href="https://github.com/cloudflare/certmgr#certmgryaml" />. + For how to use the "command" service manager in particular, + see: <link xlink:href="https://github.com/cloudflare/certmgr#command-svcmgr-and-how-to-use-it" />. + ''; + }; + + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.specs != {}; + message = "Certmgr specs cannot be empty."; + } + { + assertion = !any (hasAttrByPath [ "authority" "auth_key" ]) (attrValues cfg.specs); + message = '' + Inline services.certmgr.specs are added to the Nix store rendering them world readable. + Specify paths as specs, if you want to use include auth_key - or use the auth_key_file option." + ''; + } + ]; + + systemd.services.certmgr = { + description = "certmgr"; + path = mkIf (cfg.svcManager == "command") [ pkgs.bash ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + inherit preStart; + + serviceConfig = { + Restart = "always"; + RestartSec = "10s"; + ExecStart = "${pkgs.certmgr}/bin/certmgr -f ${certmgrYaml}"; + }; + }; + }; +} diff --git a/nixos/modules/services/security/vault.nix b/nixos/modules/services/security/vault.nix index 47c70cf0687..0b28bc89445 100644 --- a/nixos/modules/services/security/vault.nix +++ b/nixos/modules/services/security/vault.nix @@ -1,6 +1,7 @@ { config, lib, pkgs, ... }: with lib; + let cfg = config.services.vault; @@ -24,15 +25,22 @@ let ${cfg.telemetryConfig} } ''} + ${cfg.extraConfig} ''; in + { options = { - services.vault = { - enable = mkEnableOption "Vault daemon"; + package = mkOption { + type = types.package; + default = pkgs.vault; + defaultText = "pkgs.vault"; + description = "This option specifies the vault package to use."; + }; + address = mkOption { type = types.str; default = "127.0.0.1:8200"; @@ -58,7 +66,7 @@ in default = '' tls_min_version = "tls12" ''; - description = "extra configuration"; + description = "Extra text appended to the listener section."; }; storageBackend = mkOption { @@ -84,6 +92,12 @@ in default = ""; description = "Telemetry configuration"; }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = "Extra text appended to <filename>vault.hcl</filename>."; + }; }; }; @@ -122,7 +136,7 @@ in User = "vault"; Group = "vault"; PermissionsStartOnly = true; - ExecStart = "${pkgs.vault}/bin/vault server -config ${configFile}"; + ExecStart = "${cfg.package}/bin/vault server -config ${configFile}"; PrivateDevices = true; PrivateTmp = true; ProtectSystem = "full"; diff --git a/nixos/modules/services/web-apps/youtrack.nix b/nixos/modules/services/web-apps/youtrack.nix index 8c675c64200..6ad38028a64 100644 --- a/nixos/modules/services/web-apps/youtrack.nix +++ b/nixos/modules/services/web-apps/youtrack.nix @@ -118,14 +118,14 @@ in systemd.services.youtrack = { environment.HOME = cfg.statePath; - environment.YOUTRACK_JVM_OPTS = "-Xmx${cfg.maxMemory} -XX:MaxMetaspaceSize=${cfg.maxMetaspaceSize} ${cfg.jvmOpts} ${extraAttr}"; + environment.YOUTRACK_JVM_OPTS = "${extraAttr}"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; User = "youtrack"; Group = "youtrack"; - ExecStart = ''${cfg.package}/bin/youtrack ${cfg.address}:${toString cfg.port}''; + ExecStart = ''${cfg.package}/bin/youtrack --J-Xmx${cfg.maxMemory} --J-XX:MaxMetaspaceSize=${cfg.maxMetaspaceSize} ${cfg.jvmOpts} ${cfg.address}:${toString cfg.port}''; }; }; diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 1b347803932..2b03ed81b5e 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -265,6 +265,7 @@ in }; environment.etc."sddm.conf".source = cfgFile; + environment.pathsToLink = [ "/share/sddm/themes" ]; users.groups.sddm.gid = config.ids.gids.sddm; diff --git a/nixos/modules/services/x11/window-managers/metacity.nix b/nixos/modules/services/x11/window-managers/metacity.nix index 436eccbaf0c..5175fd7f3b1 100644 --- a/nixos/modules/services/x11/window-managers/metacity.nix +++ b/nixos/modules/services/x11/window-managers/metacity.nix @@ -5,9 +5,7 @@ with lib; let cfg = config.services.xserver.windowManager.metacity; - xorg = config.services.xserver.package; - gnome = pkgs.gnome; - + inherit (pkgs) gnome3; in { @@ -20,16 +18,12 @@ in services.xserver.windowManager.session = singleton { name = "metacity"; start = '' - env LD_LIBRARY_PATH=${lib.makeLibraryPath [ xorg.libX11 xorg.libXext ]}:/usr/lib/ - # !!! Hack: load the schemas for Metacity. - GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf.out}/bin/gconftool-2 \ - --makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas # */ - ${gnome.metacity}/bin/metacity & + ${gnome3.metacity}/bin/metacity & waitPID=$! ''; }; - environment.systemPackages = [ gnome.metacity ]; + environment.systemPackages = [ gnome3.metacity ]; }; diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index 3d002bc2232..3e38662f5b0 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -17,6 +17,10 @@ let ${optionalString cfg.qemuOvmf '' nvram = ["/run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd"] ''} + ${optionalString (!cfg.qemuRunAsRoot) '' + user = "qemu-libvirtd" + group = "qemu-libvirtd" + ''} ${cfg.qemuVerbatimConfig} ''; @@ -56,6 +60,18 @@ in { ''; }; + virtualisation.libvirtd.qemuRunAsRoot = mkOption { + type = types.bool; + default = true; + description = '' + If true, libvirtd runs qemu as root. + If false, libvirtd runs qemu as unprivileged user qemu-libvirtd. + Changing this option to false may cause file permission issues + for existing guests. To fix these, manually change ownership + of affected files in /var/lib/libvirt/qemu to qemu-libvirtd. + ''; + }; + virtualisation.libvirtd.qemuVerbatimConfig = mkOption { type = types.lines; default = '' @@ -110,6 +126,14 @@ in { users.groups.libvirtd.gid = config.ids.gids.libvirtd; + # libvirtd runs qemu as this user and group by default + users.extraGroups.qemu-libvirtd.gid = config.ids.gids.qemu-libvirtd; + users.extraUsers.qemu-libvirtd = { + uid = config.ids.uids.qemu-libvirtd; + isNormalUser = false; + group = "qemu-libvirtd"; + }; + systemd.packages = [ pkgs.libvirt ]; systemd.services.libvirtd = { diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index 8adf3aa919d..b69860a199a 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -5,7 +5,7 @@ with lib; let cfg = config.virtualisation.virtualbox.host; - virtualbox = pkgs.virtualbox.override { + virtualbox = cfg.package.override { inherit (cfg) enableExtensionPack enableHardening headless; }; @@ -28,7 +28,14 @@ in ''; }; - enableExtensionPack = mkEnableOption "VirtualBox extension pack"; + package = mkOption { + type = types.package; + default = pkgs.virtualbox; + defaultText = "pkgs.virtualbox"; + description = '' + Which VirtualBox package to use. + ''; + }; addNetworkInterface = mkOption { type = types.bool; @@ -38,6 +45,8 @@ in ''; }; + enableExtensionPack = mkEnableOption "VirtualBox extension pack"; + enableHardening = mkOption { type = types.bool; default = true; |