diff options
Diffstat (limited to 'nixos')
21 files changed, 937 insertions, 96 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2103.xml b/nixos/doc/manual/release-notes/rl-2103.xml index 374933d30127..2b0144a69c22 100644 --- a/nixos/doc/manual/release-notes/rl-2103.xml +++ b/nixos/doc/manual/release-notes/rl-2103.xml @@ -265,6 +265,28 @@ located in <literal>/run/rspamd</literal> instead of <literal>/run</literal>. </para> </listitem> + <listitem> + <para> + Enabling the Tor client no longer silently also enables and + configures Privoxy, and the + <varname>services.tor.client.privoxy.enable</varname> option has + been removed. To enable Privoxy, and to configure it to use + Tor's faster port, use the following configuration: + </para> + <programlisting> + <xref linkend="opt-services.privoxy.enable" /> = true; + <xref linkend="opt-services.privoxy.enableTor" /> = true; + </programlisting> + </listitem> + <listitem> + <para> + The options <literal>services.slurm.dbdserver.storagePass</literal> + and <literal>services.slurm.dbdserver.configFile</literal> have been removed. + Use <literal>services.slurm.dbdserver.storagePassFile</literal> instead to provide the database password. + Extra config options can be given via the option <literal>services.slurm.dbdserver.extraConfig</literal>. The actual configuration file is created on the fly on startup of the service. + This avoids that the password gets exposed in the nix store. + </para> + </listitem> </itemizedlist> </section> @@ -278,6 +300,19 @@ <itemizedlist> <listitem> <para> + The Mailman NixOS module (<literal>services.mailman</literal>) has a new + option <xref linkend="opt-services.mailman.enablePostfix" />, defaulting + to true, that controls integration with Postfix. + </para> + <para> + If this option is disabled, default MTA config becomes not set and you + should set the options in <literal>services.mailman.settings.mta</literal> + according to the desired configuration as described in + <link xlink:href="https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html">Mailman documentation</link>. + </para> + </listitem> + <listitem> + <para> The default-version of <literal>nextcloud</literal> is <package>nextcloud20</package>. Please note that it's <emphasis>not</emphasis> possible to upgrade <literal>nextcloud</literal> across multiple major versions! This means that it's e.g. not possible to upgrade @@ -359,6 +394,13 @@ </listitem> <listitem> <para> + The <literal>services.dnscrypt-proxy2</literal> module now takes the upstream's example configuration and updates it with the user's settings. + + An option has been added to restore the old behaviour if you prefer to declare the configuration from scratch. + </para> + </listitem> + <listitem> + <para> NixOS now defaults to the unified cgroup hierarchy (cgroupsv2). See the <link xlink:href="https://www.redhat.com/sysadmin/fedora-31-control-group-v2">Fedora Article for 31</link> for details on why this is desirable, and how it impacts containers. diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix index 13abfb9a111d..6192be1cd053 100644 --- a/nixos/lib/testing-python.nix +++ b/nixos/lib/testing-python.nix @@ -67,6 +67,8 @@ rec { LOGFILE=/dev/null tests='exec(os.environ["testScript"])' ${driver}/bin/nixos-test-driver ''; + + passthru = driver.passthru; }; @@ -76,6 +78,7 @@ rec { , name ? "unnamed" # Skip linting (mainly intended for faster dev cycles) , skipLint ? false + , passthru ? {} , ... } @ t: let @@ -137,7 +140,7 @@ rec { testScript = testScript'; preferLocalBuild = true; testName = name; - passthru = { + passthru = passthru // { inherit nodes; }; } diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index d3f6e85327bc..bbc8b49c43f5 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -876,6 +876,7 @@ ./services/web-apps/moodle.nix ./services/web-apps/nextcloud.nix ./services/web-apps/nexus.nix + ./services/web-apps/plantuml-server.nix ./services/web-apps/pgpkeyserver-lite.nix ./services/web-apps/matomo.nix ./services/web-apps/moinmoin.nix diff --git a/nixos/modules/services/computing/slurm/slurm.nix b/nixos/modules/services/computing/slurm/slurm.nix index 705390a21d4e..302f058926c8 100644 --- a/nixos/modules/services/computing/slurm/slurm.nix +++ b/nixos/modules/services/computing/slurm/slurm.nix @@ -34,13 +34,12 @@ let ${cfg.extraCgroupConfig} ''; - slurmdbdConf = pkgs.writeTextDir "slurmdbd.conf" + slurmdbdConf = pkgs.writeText "slurmdbd.conf" '' DbdHost=${cfg.dbdserver.dbdHost} SlurmUser=${cfg.user} StorageType=accounting_storage/mysql StorageUser=${cfg.dbdserver.storageUser} - ${optionalString (cfg.dbdserver.storagePass != null) "StoragePass=${cfg.dbdserver.storagePass}"} ${cfg.dbdserver.extraConfig} ''; @@ -95,26 +94,12 @@ in ''; }; - storagePass = mkOption { - type = types.nullOr types.str; + storagePassFile = mkOption { + type = with types; nullOr str; default = null; description = '' - Database password. Note that this password will be publicable - readable in the nix store. Use <option>configFile</option> - to store the and config file and password outside the nix store. - ''; - }; - - configFile = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Path to <literal>slurmdbd.conf</literal>. The password for the database connection - is stored in the config file. Use this option to specfify a path - outside the nix store. If this option is unset a configuration file - will be generated. See also: - <citerefentry><refentrytitle>slurmdbd.conf</refentrytitle> - <manvolnum>8</manvolnum></citerefentry>. + Path to file with database password. The content of this will be used to + create the password for the <literal>StoragePass</literal> option. ''; }; @@ -122,7 +107,9 @@ in type = types.lines; default = ""; description = '' - Extra configuration for <literal>slurmdbd.conf</literal> + Extra configuration for <literal>slurmdbd.conf</literal> See also: + <citerefentry><refentrytitle>slurmdbd.conf</refentrytitle> + <manvolnum>8</manvolnum></citerefentry>. ''; }; }; @@ -292,6 +279,16 @@ in }; + imports = [ + (mkRemovedOptionModule [ "services" "slurm" "dbdserver" "storagePass" ] '' + This option has been removed so that the database password is not exposed via the nix store. + Use services.slurm.dbdserver.storagePassFile to provide the database password. + '') + (mkRemovedOptionModule [ "services" "slurm" "dbdserver" "configFile" ] '' + This option has been removed. Use services.slurm.dbdserver.storagePassFile + and services.slurm.dbdserver.extraConfig instead. + '') + ]; ###### implementation @@ -386,23 +383,34 @@ in ''; }; - systemd.services.slurmdbd = mkIf (cfg.dbdserver.enable) { + systemd.services.slurmdbd = let + # slurm strips the last component off the path + configPath = "$RUNTIME_DIRECTORY/slurmdbd.conf"; + in mkIf (cfg.dbdserver.enable) { path = with pkgs; [ wrappedSlurm munge coreutils ]; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "munged.service" "mysql.service" ]; requires = [ "munged.service" "mysql.service" ]; - # slurm strips the last component off the path - environment.SLURM_CONF = - if (cfg.dbdserver.configFile == null) then - "${slurmdbdConf}/slurm.conf" - else - cfg.dbdserver.configFile; + preStart = '' + cp ${slurmdbdConf} ${configPath} + chmod 600 ${configPath} + chown ${cfg.user} ${configPath} + ${optionalString (cfg.dbdserver.storagePassFile != null) '' + echo "StoragePass=$(cat ${cfg.dbdserver.storagePassFile})" \ + >> ${configPath} + ''} + ''; + + script = '' + export SLURM_CONF=${configPath} + exec ${cfg.package}/bin/slurmdbd -D + ''; serviceConfig = { - Type = "forking"; - ExecStart = "${cfg.package}/bin/slurmdbd"; + RuntimeDirectory = "slurmdbd"; + Type = "simple"; PIDFile = "/run/slurmdbd.pid"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; }; diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix index 18a607f5e2c1..bf19da32324a 100644 --- a/nixos/modules/services/mail/mailman.nix +++ b/nixos/modules/services/mail/mailman.nix @@ -38,7 +38,7 @@ let webSettingsJSON = pkgs.writeText "settings.json" (builtins.toJSON webSettings); # TODO: Should this be RFC42-ised so that users can set additional options without modifying the module? - mtaConfig = pkgs.writeText "mailman-postfix.cfg" '' + postfixMtaConfig = pkgs.writeText "mailman-postfix.cfg" '' [postfix] postmap_command: ${pkgs.postfix}/bin/postmap transport_file_type: hash @@ -81,7 +81,7 @@ in { enable = mkOption { type = types.bool; default = false; - description = "Enable Mailman on this host. Requires an active Postfix installation."; + description = "Enable Mailman on this host. Requires an active MTA on the host (e.g. Postfix)."; }; package = mkOption { @@ -92,6 +92,20 @@ in { description = "Mailman package to use"; }; + enablePostfix = mkOption { + type = types.bool; + default = true; + example = false; + description = '' + Enable Postfix integration. Requires an active Postfix installation. + + If you want to use another MTA, set this option to false and configure + settings in services.mailman.settings.mta. + + Refer to the Mailman manual for more info. + ''; + }; + siteOwner = mkOption { type = types.str; example = "postmaster@example.org"; @@ -182,7 +196,7 @@ in { pid_file = "/run/mailman/master.pid"; }; - mta.configuration = lib.mkDefault "${mtaConfig}"; + mta.configuration = lib.mkDefault (if cfg.enablePostfix then "${postfixMtaConfig}" else throw "When Mailman Postfix integration is disabled, set `services.mailman.settings.mta.configuration` to the path of the config file required to integrate with your MTA."); "archiver.hyperkitty" = lib.mkIf cfg.hyperkitty.enable { class = "mailman_hyperkitty.Archiver"; @@ -211,14 +225,22 @@ in { See <https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html>. ''; }; - in [ + in (lib.optionals cfg.enablePostfix [ { assertion = postfix.enable; - message = "Mailman requires Postfix"; + message = '' + Mailman's default NixOS configuration requires Postfix to be enabled. + + If you want to use another MTA, set services.mailman.enablePostfix + to false and configure settings in services.mailman.settings.mta. + + Refer to <https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html> + for more info. + ''; } (requirePostfixHash [ "relayDomains" ] "postfix_domains") (requirePostfixHash [ "config" "transport_maps" ] "postfix_lmtp") (requirePostfixHash [ "config" "local_recipient_maps" ] "postfix_lmtp") - ]; + ]); users.users.mailman = { description = "GNU Mailman"; @@ -275,7 +297,7 @@ in { ''; }) ]; - services.postfix = { + services.postfix = lib.mkIf cfg.enablePostfix { recipientDelimiter = "+"; # bake recipient addresses in mail envelopes via VERP config = { owner_request_special = "no"; # Mailman handles -owner addresses on its own diff --git a/nixos/modules/services/mail/mailman.xml b/nixos/modules/services/mail/mailman.xml index cbe50ed0b917..8da491ccbe9f 100644 --- a/nixos/modules/services/mail/mailman.xml +++ b/nixos/modules/services/mail/mailman.xml @@ -13,9 +13,9 @@ </para> <section xml:id="module-services-mailman-basic-usage"> - <title>Basic usage</title> + <title>Basic usage with Postfix</title> <para> - For a basic configuration, the following settings are suggested: + For a basic configuration with Postfix as the MTA, the following settings are suggested: <programlisting>{ config, ... }: { services.postfix = { enable = true; @@ -56,4 +56,39 @@ necessary, but outside the scope of the Mailman module. </para> </section> + <section xml:id="module-services-mailman-other-mtas"> + <title>Using with other MTAs</title> + <para> + Mailman also supports other MTA, though with a little bit more configuration. For example, to use Mailman with Exim, you can use the following settings: + <programlisting>{ config, ... }: { + services = { + mailman = { + enable = true; + siteOwner = "mailman@example.org"; + <link linkend="opt-services.mailman.enablePostfix">enablePostfix</link> = false; + settings.mta = { + incoming = "mailman.mta.exim4.LMTP"; + outgoing = "mailman.mta.deliver.deliver"; + lmtp_host = "localhost"; + lmtp_port = "8024"; + smtp_host = "localhost"; + smtp_port = "25"; + configuration = "python:mailman.config.exim4"; + }; + }; + exim = { + enable = true; + # You can configure Exim in a separate file to reduce configuration.nix clutter + config = builtins.readFile ./exim.conf; + }; + }; +}</programlisting> + </para> + <para> + The exim config needs some special additions to work with Mailman. Currently + NixOS can't manage Exim config with such granularity. Please refer to + <link xlink:href="https://mailman.readthedocs.io/en/latest/src/mailman/docs/mta.html">Mailman documentation</link> + for more info on configuring Mailman for working with Exim. + </para> + </section> </chapter> diff --git a/nixos/modules/services/networking/dnscrypt-proxy2.nix b/nixos/modules/services/networking/dnscrypt-proxy2.nix index dda61212216c..ff8a2ab30774 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy2.nix +++ b/nixos/modules/services/networking/dnscrypt-proxy2.nix @@ -27,6 +27,16 @@ in default = {}; }; + upstreamDefaults = mkOption { + description = '' + Whether to base the config declared in <literal>services.dnscrypt-proxy2.settings</literal> on the upstream example config (<link xlink:href="https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml"/>) + + Disable this if you want to declare your dnscrypt config from scratch. + ''; + type = types.bool; + default = true; + }; + configFile = mkOption { description = '' Path to TOML config file. See: <link xlink:href="https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml"/> @@ -38,7 +48,13 @@ in json = builtins.toJSON cfg.settings; passAsFile = [ "json" ]; } '' - ${pkgs.remarshal}/bin/json2toml < $jsonPath > $out + ${if cfg.upstreamDefaults then '' + ${pkgs.remarshal}/bin/toml2json ${pkgs.dnscrypt-proxy2.src}/dnscrypt-proxy/example-dnscrypt-proxy.toml > example.json + ${pkgs.jq}/bin/jq --slurp add example.json $jsonPath > config.json # merges the two + '' else '' + cp $jsonPath config.json + ''} + ${pkgs.remarshal}/bin/json2toml < config.json > $out ''; defaultText = literalExample "TOML file generated from services.dnscrypt-proxy2.settings"; }; diff --git a/nixos/modules/services/networking/privoxy.nix b/nixos/modules/services/networking/privoxy.nix index 1f41c720adf5..e3b34cb0c616 100644 --- a/nixos/modules/services/networking/privoxy.nix +++ b/nixos/modules/services/networking/privoxy.nix @@ -8,15 +8,22 @@ let cfg = config.services.privoxy; - confFile = pkgs.writeText "privoxy.conf" '' + confFile = pkgs.writeText "privoxy.conf" ('' user-manual ${privoxy}/share/doc/privoxy/user-manual confdir ${privoxy}/etc/ listen-address ${cfg.listenAddress} enable-edit-actions ${if (cfg.enableEditActions == true) then "1" else "0"} ${concatMapStrings (f: "actionsfile ${f}\n") cfg.actionsFiles} ${concatMapStrings (f: "filterfile ${f}\n") cfg.filterFiles} + '' + optionalString cfg.enableTor '' + forward-socks4a / ${config.services.tor.client.socksListenAddressFaster} . + toggle 1 + enable-remote-toggle 0 + enable-edit-actions 0 + enable-remote-http-toggle 0 + '' + '' ${cfg.extraConfig} - ''; + ''); in @@ -72,6 +79,15 @@ in ''; }; + enableTor = mkOption { + type = types.bool; + default = false; + description = '' + Whether to configure Privoxy to use Tor's faster SOCKS port, + suitable for HTTP. + ''; + }; + extraConfig = mkOption { type = types.lines; default = "" ; diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix index b4b544a2413d..b6afd83a9abd 100644 --- a/nixos/modules/services/networking/tinc.nix +++ b/nixos/modules/services/networking/tinc.nix @@ -1,13 +1,156 @@ { config, lib, pkgs, ... }: with lib; - let - cfg = config.services.tinc; -in + mkValueString = value: + if value == true then "yes" + else if value == false then "no" + else generators.mkValueStringDefault { } value; + + toTincConf = generators.toKeyValue { + listsAsDuplicateKeys = true; + mkKeyValue = generators.mkKeyValueDefault { inherit mkValueString; } "="; + }; + + tincConfType = with types; + let + valueType = oneOf [ bool str int ]; + in + attrsOf (either valueType (listOf valueType)); + + addressSubmodule = { + options = { + address = mkOption { + type = types.str; + description = "The external IP address or hostname where the host can be reached."; + }; + + port = mkOption { + type = types.nullOr types.port; + default = null; + description = '' + The port where the host can be reached. + + If no port is specified, the default Port is used. + ''; + }; + }; + }; + + subnetSubmodule = { + options = { + address = mkOption { + type = types.str; + description = '' + The subnet of this host. + + Subnets can either be single MAC, IPv4 or IPv6 addresses, in which case + a subnet consisting of only that single address is assumed, or they can + be a IPv4 or IPv6 network address with a prefix length. + + IPv4 subnets are notated like 192.168.1.0/24, IPv6 subnets are notated + like fec0:0:0:1::/64. MAC addresses are notated like 0:1a:2b:3c:4d:5e. + + Note that subnets like 192.168.1.1/24 are invalid. + ''; + }; + + prefixLength = mkOption { + type = with types; nullOr (addCheck int (n: n >= 0 && n <= 128)); + default = null; + description = '' + The prefix length of the subnet. + + If null, a subnet consisting of only that single address is assumed. + + This conforms to standard CIDR notation as described in RFC1519. + ''; + }; + + weight = mkOption { + type = types.ints.unsigned; + default = 10; + description = '' + Indicates the priority over identical Subnets owned by different nodes. + + Lower values indicate higher priority. Packets will be sent to the + node with the highest priority, unless that node is not reachable, in + which case the node with the next highest priority will be tried, and + so on. + ''; + }; + }; + }; + + hostSubmodule = { config, ... }: { + options = { + addresses = mkOption { + type = types.listOf (types.submodule addressSubmodule); + default = [ ]; + description = '' + The external address where the host can be reached. This will set this + host's <option>settings.Address</option> option. + + This variable is only required if you want to connect to this host. + ''; + }; + + subnets = mkOption { + type = types.listOf (types.submodule subnetSubmodule); + default = [ ]; + description = '' + The subnets which this tinc daemon will serve. This will set this + host's <option>settings.Subnet</option> option. + Tinc tries to look up which other daemon it should send a packet to by + searching the appropriate subnet. If the packet matches a subnet, it + will be sent to the daemon who has this subnet in his host + configuration file. + ''; + }; + + rsaPublicKey = mkOption { + type = types.str; + default = ""; + description = '' + Legacy RSA public key of the host in PEM format, including start and + end markers. + + This will be appended as-is in the host's configuration file. + + The ed25519 public key can be specified using the + <option>settings.Ed25519PublicKey</option> option instead. + ''; + }; + + settings = mkOption { + default = { }; + type = types.submodule { freeformType = tincConfType; }; + description = '' + Configuration for this host. + + See <link xlink:href="https://tinc-vpn.org/documentation-1.1/Host-configuration-variables.html"/> + for supported values. + ''; + }; + }; + + config.settings = { + Address = mkDefault (map + (address: "${address.address} ${toString address.port}") + config.addresses); + + Subnet = mkDefault (map + (subnet: + if subnet.prefixLength == null then "${subnet.address}#${toString subnet.weight}" + else "${subnet.address}/${toString subnet.prefixLength}#${toString subnet.weight}") + config.subnets); + }; + }; + +in { ###### interface @@ -18,7 +161,7 @@ in networks = mkOption { default = { }; - type = with types; attrsOf (submodule { + type = with types; attrsOf (submodule ({ config, ... }: { options = { extraConfig = mkOption { @@ -26,6 +169,9 @@ in type = types.lines; description = '' Extra lines to add to the tinc service configuration file. + + Note that using the declarative <option>service.tinc.networks.<name>.settings</option> + option is preferred. ''; }; @@ -72,6 +218,40 @@ in description = '' The name of the host in the network as well as the configuration for that host. This name should only contain alphanumerics and underscores. + + Note that using the declarative <option>service.tinc.networks.<name>.hostSettings</option> + option is preferred. + ''; + }; + + hostSettings = mkOption { + default = { }; + example = literalExample '' + { + host1 = { + addresses = [ + { address = "192.168.1.42"; } + { address = "192.168.1.42"; port = 1655; } + ]; + subnets = [ { address = "10.0.0.42"; } ]; + rsaPublicKey = "..."; + settings = { + Ed25519PublicKey = "..."; + }; + }; + host2 = { + subnets = [ { address = "10.0.1.0"; prefixLength = 24; weight = 2; } ]; + rsaPublicKey = "..."; + settings = { + Compression = 10; + }; + }; + } + ''; + type = types.attrsOf (types.submodule hostSubmodule); + description = '' + The name of the host in the network as well as the configuration for that host. + This name should only contain alphanumerics and underscores. ''; }; @@ -79,7 +259,7 @@ in default = "tun"; type = types.enum [ "tun" "tap" ]; description = '' - The type of virtual interface used for the network connection + The type of virtual interface used for the network connection. ''; }; @@ -118,8 +298,44 @@ in Note that tinc can't run scripts anymore (such as tinc-down or host-up), unless it is setup to be runnable inside chroot environment. ''; }; + + settings = mkOption { + default = { }; + type = types.submodule { freeformType = tincConfType; }; + example = literalExample '' + { + Interface = "custom.interface"; + DirectOnly = true; + Mode = "switch"; + } + ''; + description = '' + Configuration of the Tinc daemon for this network. + + See <link xlink:href="https://tinc-vpn.org/documentation-1.1/Main-configuration-variables.html"/> + for supported values. + ''; + }; + }; + + config = { + hosts = mapAttrs + (hostname: host: '' + ${toTincConf host.settings} + ${host.rsaPublicKey} + '') + config.hostSettings; + + settings = { + DeviceType = mkDefault config.interfaceType; + Name = mkDefault (if config.name == null then "$HOST" else config.name); + Ed25519PrivateKeyFile = mkIf (config.ed25519PrivateKeyFile != null) (mkDefault config.ed25519PrivateKeyFile); + PrivateKeyFile = mkIf (config.rsaPrivateKeyFile != null) (mkDefault config.rsaPrivateKeyFile); + ListenAddress = mkIf (config.listenAddress != null) (mkDefault config.listenAddress); + BindToAddress = mkIf (config.bindToAddress != null) (mkDefault config.bindToAddress); + }; }; - }); + })); description = '' Defines the tinc networks which will be started. @@ -144,13 +360,7 @@ in "tinc/${network}/tinc.conf" = { mode = "0444"; text = '' - Name = ${if data.name == null then "$HOST" else data.name} - DeviceType = ${data.interfaceType} - ${optionalString (data.ed25519PrivateKeyFile != null) "Ed25519PrivateKeyFile = ${data.ed25519PrivateKeyFile}"} - ${optionalString (data.rsaPrivateKeyFile != null) "PrivateKeyFile = ${data.rsaPrivateKeyFile}"} - ${optionalString (data.listenAddress != null) "ListenAddress = ${data.listenAddress}"} - ${optionalString (data.bindToAddress != null) "BindToAddress = ${data.bindToAddress}"} - Interface = tinc.${network} + ${toTincConf ({ Interface = "tinc.${network}"; } // data.settings)} ${data.extraConfig} |