diff options
Diffstat (limited to 'nixos/modules')
18 files changed, 339 insertions, 103 deletions
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh index 27e5b5d8c70..6a08c9b4c6c 100644 --- a/nixos/modules/installer/tools/nixos-rebuild.sh +++ b/nixos/modules/installer/tools/nixos-rebuild.sh @@ -267,6 +267,14 @@ if [ -n "$rollback" -o "$action" = dry-build ]; then buildNix= fi +nixSystem() { + machine="$(uname -m)" + if [[ "$machine" =~ i.86 ]]; then + machine=i686 + fi + echo $machine-linux +} + prebuiltNix() { machine="$1" if [ "$machine" = x86_64 ]; then @@ -286,7 +294,9 @@ if [ -n "$buildNix" ]; then nixDrv= if ! nixDrv="$(nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir/nix.drv --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then if ! nixDrv="$(nix-instantiate '<nixpkgs>' --add-root $tmpDir/nix.drv --indirect -A nix "${extraBuildFlags[@]}")"; then - nixStorePath="$(prebuiltNix "$(uname -m)")" + if ! nixStorePath="$(nix-instantiate --eval '<nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix>' -A $(nixSystem) | sed -e 's/^"//' -e 's/"$//')"; then + nixStorePath="$(prebuiltNix "$(uname -m)")" + fi if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \ --option extra-binary-caches https://cache.nixos.org/; then echo "warning: don't know how to get latest Nix" >&2 diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index 9b2e1235b74..834ac0de912 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, baseModules, ... }: +{ config, lib, pkgs, baseModules, extraModules, modules, ... }: with lib; @@ -6,6 +6,8 @@ let cfg = config.documentation; + manualModules = baseModules ++ optionals cfg.nixos.includeAllModules (extraModules ++ modules); + /* For the purpose of generating docs, evaluate options with each derivation in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}". It isn't perfect, but it seems to cover a vast majority of use cases. @@ -18,7 +20,7 @@ let options = let scrubbedEval = evalModules { - modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules; + modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ manualModules; args = (config._module.args) // { modules = [ ]; }; specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; }; }; @@ -146,6 +148,17 @@ in ''; }; + nixos.includeAllModules = mkOption { + type = types.bool; + default = false; + description = '' + Whether the generated NixOS's documentation should include documentation for all + the options from all the NixOS modules included in the current + <literal>configuration.nix</literal>. Disabling this will make the manual + generator to ignore options defined outside of <literal>baseModules</literal>. + ''; + }; + }; }; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 031a1d52e79..5b95fc8ecc3 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -189,6 +189,7 @@ ./services/backup/duplicati.nix ./services/backup/crashplan.nix ./services/backup/crashplan-small-business.nix + ./services/backup/duplicity.nix ./services/backup/mysql-backup.nix ./services/backup/postgresql-backup.nix ./services/backup/restic.nix @@ -268,6 +269,7 @@ ./services/desktops/gnome3/gnome-online-accounts.nix ./services/desktops/gnome3/gnome-remote-desktop.nix ./services/desktops/gnome3/gnome-online-miners.nix + ./services/desktops/gnome3/gnome-settings-daemon.nix ./services/desktops/gnome3/gnome-terminal-server.nix ./services/desktops/gnome3/gnome-user-share.nix ./services/desktops/gnome3/gpaste.nix diff --git a/nixos/modules/services/backup/duplicity.nix b/nixos/modules/services/backup/duplicity.nix new file mode 100644 index 00000000000..a8d56424862 --- /dev/null +++ b/nixos/modules/services/backup/duplicity.nix @@ -0,0 +1,141 @@ +{ config, lib, pkgs, ...}: + +with lib; + +let + cfg = config.services.duplicity; + + stateDirectory = "/var/lib/duplicity"; + + localTarget = if hasPrefix "file://" cfg.targetUrl + then removePrefix "file://" cfg.targetUrl else null; + +in { + options.services.duplicity = { + enable = mkEnableOption "backups with duplicity"; + + root = mkOption { + type = types.path; + default = "/"; + description = '' + Root directory to backup. + ''; + }; + + include = mkOption { + type = types.listOf types.str; + default = []; + example = [ "/home" ]; + description = '' + List of paths to include into the backups. See the FILE SELECTION + section in <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry> for details on the syntax. + ''; + }; + + exclude = mkOption { + type = types.listOf types.str; + default = []; + description = '' + List of paths to exclude from backups. See the FILE SELECTION section in + <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry> for details on the syntax. + ''; + }; + + targetUrl = mkOption { + type = types.str; + example = "s3://host:port/prefix"; + description = '' + Target url to backup to. See the URL FORMAT section in + <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry> for supported urls. + ''; + }; + + secretFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path of a file containing secrets (gpg passphrase, access key...) in + the format of EnvironmentFile as described by + <citerefentry><refentrytitle>systemd.exec</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>. For example: + <programlisting> + PASSPHRASE=<replaceable>...</replaceable> + AWS_ACCESS_KEY_ID=<replaceable>...</replaceable> + AWS_SECRET_ACCESS_KEY=<replaceable>...</replaceable> + </programlisting> + ''; + }; + + frequency = mkOption { + type = types.nullOr types.str; + default = "daily"; + description = '' + Run duplicity with the given frequency (see + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>7</manvolnum></citerefentry> for the format). + If null, do not run automatically. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + default = []; + example = [ "--full-if-older-than" "1M" ]; + description = '' + Extra command-line flags passed to duplicity. See + <citerefentry><refentrytitle>duplicity</refentrytitle> + <manvolnum>1</manvolnum></citerefentry>. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd = { + services.duplicity = { + description = "backup files with duplicity"; + + environment.HOME = stateDirectory; + + serviceConfig = { + ExecStart = '' + ${pkgs.duplicity}/bin/duplicity ${escapeShellArgs ( + [ + cfg.root + cfg.targetUrl + "--archive-dir" stateDirectory + ] + ++ concatMap (p: [ "--include" p ]) cfg.include + ++ concatMap (p: [ "--exclude" p ]) cfg.exclude + ++ cfg.extraFlags)} + ''; + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = "read-only"; + StateDirectory = baseNameOf stateDirectory; + } // optionalAttrs (localTarget != null) { + ReadWritePaths = localTarget; + } // optionalAttrs (cfg.secretFile != null) { + EnvironmentFile = cfg.secretFile; + }; + } // optionalAttrs (cfg.frequency != null) { + startAt = cfg.frequency; + }; + + tmpfiles.rules = optional (localTarget != null) "d ${localTarget} 0700 root root -"; + }; + + assertions = singleton { + # Duplicity will fail if the last file selection option is an include. It + # is not always possible to detect but this simple case can be caught. + assertion = cfg.include != [] -> cfg.exclude != [] || cfg.extraFlags != []; + message = '' + Duplicity will fail if you only specify included paths ("Because the + default is to include all files, the expression is redundant. Exiting + because this probably isn't what you meant.") + ''; + }; + }; +} diff --git a/nixos/modules/services/desktops/gnome3/gnome-settings-daemon.nix b/nixos/modules/services/desktops/gnome3/gnome-settings-daemon.nix new file mode 100644 index 00000000000..dbf0f4e9b11 --- /dev/null +++ b/nixos/modules/services/desktops/gnome3/gnome-settings-daemon.nix @@ -0,0 +1,45 @@ +# GNOME Settings Daemon + +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.gnome3.gnome-settings-daemon; + +in + +{ + + ###### interface + + options = { + + services.gnome3.gnome-settings-daemon = { + + enable = mkEnableOption "GNOME Settings Daemon."; + + # There are many forks of gnome-settings-daemon + package = mkOption { + type = types.package; + default = pkgs.gnome3.gnome-settings-daemon; + description = "Which gnome-settings-daemon package to use."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + + services.udev.packages = [ cfg.package ]; + + }; + +} diff --git a/nixos/modules/services/hardware/thinkfan.nix b/nixos/modules/services/hardware/thinkfan.nix index d17121ca1c5..7c105e99ca5 100644 --- a/nixos/modules/services/hardware/thinkfan.nix +++ b/nixos/modules/services/hardware/thinkfan.nix @@ -47,6 +47,8 @@ let ${cfg.levels} ''; + thinkfan = pkgs.thinkfan.override { smartSupport = cfg.smartSupport; }; + in { options = { @@ -61,6 +63,15 @@ in { ''; }; + smartSupport = mkOption { + type = types.bool; + default = false; + description = '' + Whether to build thinkfan with SMART support to read temperatures + directly from hard disks. + ''; + }; + sensors = mkOption { type = types.lines; default = '' @@ -77,7 +88,7 @@ in { Which may be provided by any hwmon drivers (keyword hwmon) - S.M.A.R.T. (since 0.9 and requires the USE_ATASMART compilation flag) + S.M.A.R.T. (requires smartSupport to be enabled) Which reads the temperature directly from the hard disk using libatasmart (keyword atasmart) @@ -125,18 +136,17 @@ in { config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.thinkfan ]; + environment.systemPackages = [ thinkfan ]; systemd.services.thinkfan = { description = "Thinkfan"; after = [ "basic.target" ]; wantedBy = [ "multi-user.target" ]; - path = [ pkgs.thinkfan ]; - serviceConfig.ExecStart = "${pkgs.thinkfan}/bin/thinkfan -n -c ${configFile}"; + path = [ thinkfan ]; + serviceConfig.ExecStart = "${thinkfan}/bin/thinkfan -n -c ${configFile}"; }; boot.extraModprobeConfig = "options thinkpad_acpi experimental=1 fan_control=1"; }; - } diff --git a/nixos/modules/services/mail/rmilter.nix b/nixos/modules/services/mail/rmilter.nix index 492c6458321..466365b6b30 100644 --- a/nixos/modules/services/mail/rmilter.nix +++ b/nixos/modules/services/mail/rmilter.nix @@ -8,7 +8,7 @@ let postfixCfg = config.services.postfix; cfg = config.services.rmilter; - inetSocket = addr: port: "inet:[${toString port}@${addr}]"; + inetSocket = addr: port: "inet:${addr}:${toString port}"; unixSocket = sock: "unix:${sock}"; systemdSocket = if cfg.bindSocket.type == "unix" then cfg.bindSocket.path @@ -97,7 +97,7 @@ in bindSocket.address = mkOption { type = types.str; - default = "::1"; + default = "[::1]"; example = "0.0.0.0"; description = '' Inet address to listen on. diff --git a/nixos/modules/services/misc/home-assistant.nix b/nixos/modules/services/misc/home-assistant.nix index 95a7f2ea989..7f8d31bcf0b 100644 --- a/nixos/modules/services/misc/home-assistant.nix +++ b/nixos/modules/services/misc/home-assistant.nix @@ -9,13 +9,13 @@ let configJSON = pkgs.writeText "configuration.json" (builtins.toJSON (if cfg.applyDefaultConfig then (recursiveUpdate defaultConfig cfg.config) else cfg.config)); - configFile = pkgs.runCommand "configuration.yaml" { } '' + configFile = pkgs.runCommand "configuration.yaml" { preferLocalBuild = true; } '' ${pkgs.remarshal}/bin/json2yaml -i ${configJSON} -o $out ''; lovelaceConfigJSON = pkgs.writeText "ui-lovelace.json" (builtins.toJSON cfg.lovelaceConfig); - lovelaceConfigFile = pkgs.runCommand "ui-lovelace.yaml" { } '' + lovelaceConfigFile = pkgs.runCommand "ui-lovelace.yaml" { preferLocalBuild = true; } '' ${pkgs.remarshal}/bin/json2yaml -i ${lovelaceConfigJSON} -o $out ''; @@ -29,14 +29,24 @@ let # platform = "luftdaten"; # ... # } ]; + # + # Beginning with 0.87 Home Assistant is migrating their components to the + # scheme "platform.subComponent", e.g. "hue.light" instead of "light.hue". + # See https://developers.home-assistant.io/blog/2019/02/19/the-great-migration.html. + # Hence, we also check whether we find an entry in the config when interpreting + # the first part of the path as the component. useComponentPlatform = component: let path = splitString "." component; + # old: platform is the last part of path parentConfig = attrByPath (init path) null cfg.config; platform = last path; - in isList parentConfig && any - (item: item.platform or null == platform) - parentConfig; + # new: platform is the first part of the path + parentConfig' = attrByPath (tail path) null cfg.config; + platform' = head path; + in + (isList parentConfig && any (item: item.platform or null == platform) parentConfig) + || (isList parentConfig' && any (item: item.platform or null == platform') parentConfig'); # Returns whether component is used in config useComponent = component: diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix index 98e9c8953c8..c38138d7c97 100644 --- a/nixos/modules/services/misc/redmine.nix +++ b/nixos/modules/services/misc/redmine.nix @@ -234,10 +234,33 @@ in environment.systemPackages = [ cfg.package ]; + # create symlinks for the basic directory layout the redmine package expects + systemd.tmpfiles.rules = [ + "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/cache' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/config' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/files' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/log' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/plugins' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/public' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/public/plugin_assets' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/public/themes' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.stateDir}/tmp' 0750 ${cfg.user} ${cfg.group} - -" + + "d /run/redmine - - - - -" + "d /run/redmine/public - - - - -" + "L+ /run/redmine/config - - - - ${cfg.stateDir}/config" + "L+ /run/redmine/files - - - - ${cfg.stateDir}/files" + "L+ /run/redmine/log - - - - ${cfg.stateDir}/log" + "L+ /run/redmine/plugins - - - - ${cfg.stateDir}/plugins" + "L+ /run/redmine/public/plugin_assets - - - - ${cfg.stateDir}/public/plugin_assets" + "L+ /run/redmine/public/themes - - - - ${cfg.stateDir}/public/themes" + "L+ /run/redmine/tmp - - - - ${cfg.stateDir}/tmp" + ]; + systemd.services.redmine = { after = [ "network.target" (if cfg.database.type == "mysql2" then "mysql.service" else "postgresql.service") ]; wantedBy = [ "multi-user.target" ]; - environment.HOME = "${cfg.package}/share/redmine"; environment.RAILS_ENV = "production"; environment.RAILS_CACHE = "${cfg.stateDir}/cache"; environment.REDMINE_LANG = "en"; @@ -252,28 +275,16 @@ in subversion ]; preStart = '' - # ensure cache directory exists for db:migrate command - mkdir -p "${cfg.stateDir}/cache" - - # create the basic directory layout the redmine package expects - mkdir -p /run/redmine/public - - for i in config files log plugins tmp; do - mkdir -p "${cfg.stateDir}/$i" - ln -fs "${cfg.stateDir}/$i" /run/redmine/ - done - - for i in plugin_assets themes; do - mkdir -p "${cfg.stateDir}/public/$i" - ln -fs "${cfg.stateDir}/public/$i" /run/redmine/public/ - done - + rm -rf "${cfg.stateDir}/plugins/"* + rm -rf "${cfg.stateDir}/public/themes/"* # start with a fresh config directory # the config directory is copied instead of linked as some mutable data is stored in there - rm -rf "${cfg.stateDir}/config/"* + find "${cfg.stateDir}/config" ! -name "secret_token.rb" -type f -exec rm -f {} + cp -r ${cfg.package}/share/redmine/config.dist/* "${cfg.stateDir}/config/" + chmod -R u+w "${cfg.stateDir}/config" + # link in the application configuration ln -fs ${configurationYml} "${cfg.stateDir}/config/configuration.yml" @@ -282,7 +293,6 @@ in # link in all user specified themes - rm -rf "${cfg.stateDir}/public/themes/"* for theme in ${concatStringsSep " " (mapAttrsToList unpackTheme cfg.themes)}; do ln -fs $theme/* "${cfg.stateDir}/public/themes" done @@ -292,16 +302,11 @@ in # link in all user specified plugins - rm -rf "${cfg.stateDir}/plugins/"* for plugin in ${concatStringsSep " " (mapAttrsToList unpackPlugin cfg.plugins)}; do ln -fs $plugin/* "${cfg.stateDir}/plugins/''${plugin##*-redmine-plugin-}" done - # ensure correct permissions for most files - chmod -R ug+rwX,o-rwx+x "${cfg.stateDir}/" - - # handle database.passwordFile & permissions DBPASS=$(head -n1 ${cfg.database.passwordFile}) cp -f ${databaseYml} "${cfg.stateDir}/config/database.yml" @@ -315,25 +320,13 @@ in chmod 440 "${cfg.stateDir}/config/initializers/secret_token.rb" fi - - # ensure everything is owned by ${cfg.user} - chown -R ${cfg.user}:${cfg.group} "${cfg.stateDir}" - - # execute redmine required commands prior to starting the application - # NOTE: su required in case using mysql socket authentication - /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake db:migrate' - /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:plugins:migrate' - /run/wrappers/bin/su -s ${pkgs.bash}/bin/bash -m -l redmine -c '${bundle} exec rake redmine:load_default_data' - - - # log files don't exist until after first command has been executed - # correct ownership of files generated by calling exec rake ... - chown -R ${cfg.user}:${cfg.group} "${cfg.stateDir}/log" + ${bundle} exec rake db:migrate + ${bundle} exec rake redmine:plugins:migrate + ${bundle} exec rake redmine:load_default_data ''; serviceConfig = { - PermissionsStartOnly = true; # preStart must be run as root Type = "simple"; User = cfg.user; Group = cfg.group; @@ -348,7 +341,6 @@ in { name = "redmine"; group = cfg.group; home = cfg.stateDir; - createHome = true; uid = config.ids.uids.redmine; }); diff --git a/nixos/modules/services/monitoring/datadog-agent.nix b/nixos/modules/services/monitoring/datadog-agent.nix index 11673bf8bc7..b4ac0ca184d 100644 --- a/nixos/modules/services/monitoring/datadog-agent.nix +++ b/nixos/modules/services/monitoring/datadog-agent.nix @@ -260,7 +260,7 @@ in { path = [ ]; script = '' export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile}) - ${pkgs.datadog-trace-agent}/bin/trace-agent -config /etc/datadog-agent/datadog.yaml + ${datadogPkg}/bin/trace-agent -config /etc/datadog-agent/datadog.yaml ''; }); diff --git a/nixos/modules/services/networking/mosquitto.nix b/nixos/modules/services/networking/mosquitto.nix index 332dc541345..9974cbd89d1 100644 --- a/nixos/modules/services/networking/mosquitto.nix +++ b/nixos/modules/services/networking/mosquitto.nix @@ -17,7 +17,6 @@ let ''; mosquittoConf = pkgs.writeText "mosquitto.conf" '' - pid_file /run/mosquitto/pid acl_file ${aclFile} persistence true allow_anonymous ${boolToString cfg.allowAnonymous} @@ -196,15 +195,15 @@ in wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - Type = "forking"; + Type = "notify"; + NotifyAccess = "main"; User = "mosquitto"; Group = "mosquitto"; RuntimeDirectory = "mosquitto"; WorkingDirectory = cfg.dataDir; Restart = "on-failure"; - ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf} -d"; + ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - PIDFile = "/run/mosquitto/pid"; }; preStart = '' rm -f ${cfg.dataDir}/passwd @@ -214,7 +213,7 @@ in if c.hashedPassword != null then "echo '${n}:${c.hashedPassword}' >> ${cfg.dataDir}/passwd" else optionalString (c.password != null) - "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} ${c.password}" + "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} '${c.password}'" ) cfg.users); }; diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index 49d8836b8ad..498e3fdb23a 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -5,14 +5,18 @@ with lib; let cfg = config.services.nextcloud; + phpPackage = pkgs.php73; + phpPackages = pkgs.php73Packages; + toKeyValue = generators.toKeyValue { mkKeyValue = generators.mkKeyValueDefault {} " = "; }; phpOptionsExtensions = '' - ${optionalString cfg.caching.apcu "extension=${cfg.phpPackages.apcu}/lib/php/extensions/apcu.so"} - ${optionalString cfg.caching.redis "extension=${cfg.phpPackages.redis}/lib/php/extensions/redis.so"} - ${optionalString cfg.caching.memcached "extension=${cfg.phpPackages.memcached}/lib/php/extensions/memcached.so"} + ${optionalString cfg.caching.apcu "extension=${phpPackages.apcu}/lib/php/extensions/apcu.so"} + ${optionalString cfg.caching.redis "extension=${phpPackages.redis}/lib/php/extensions/redis.so"} + ${optionalString cfg.caching.memcached "extension=${phpPackages.memcached}/lib/php/extensions/memcached.so"} + extension=${phpPackages.imagick}/lib/php/extensions/imagick.so zend_extension = opcache.so opcache.enable = 1 ''; @@ -94,18 +98,6 @@ in { ''; }; - phpPackages = mkOption { - type = types.attrs; - default = pkgs.php71Packages; - defaultText = "pkgs.php71Packages"; - description = '' - Overridable attribute of the PHP packages set to use. If any caching - module is enabled, it will be taken from here. Therefore it should - match the version of PHP given to - <literal>services.phpfpm.phpPackage</literal>. - ''; - }; - phpOptions = mkOption { type = types.attrsOf types.str; default = { @@ -223,6 +215,19 @@ in { <literal>services.nextcloud.hostname</literal> here. ''; }; + + overwriteProtocol = mkOption { + type = types.nullOr (types.enum [ "http" "https" ]); + default = null; + example = "https"; + + description = '' + Force Nextcloud to always use HTTPS i.e. for link generation. Nextcloud + uses the currently used protocol by default, but when behind a reverse-proxy, + it may use <literal>http</literal> for everything although Nextcloud + may be served via HTTPS. + ''; + }; }; caching = { @@ -287,6 +292,7 @@ in { ${optionalString cfg.caching.apcu "'memcache.local' => '\\OC\\Memcache\\APCu',"} 'log_type' => 'syslog', 'log_level' => '${builtins.toString cfg.logLevel}', + ${optionalString (cfg.config.overwriteProtocol != null) "'overwriteprotocol' => '${cfg.config.overwriteProtocol}',"} ]; ''; occInstallCmd = let @@ -359,14 +365,14 @@ in { }; services.phpfpm = { - phpOptions = phpOptionsExtensions; - phpPackage = pkgs.php71; pools.nextcloud = let phpAdminValues = (toKeyValue (foldr (a: b: a // b) {} (mapAttrsToList (k: v: { "php_admin_value[${k}]" = v; }) phpOptions))); in { + phpOptions = phpOptionsExtensions; + phpPackage = phpPackage; listen = "/run/phpfpm/nextcloud"; extraConfig = '' listen.owner = nginx @@ -407,7 +413,7 @@ in { }; "/" = { priority = 200; - extraConfig = "rewrite ^ /index.php$uri;"; + extraConfig = "rewrite ^ /index.php$request_uri;"; }; "~ ^/store-apps" = { priority = 201; @@ -444,22 +450,23 @@ in { fastcgi_read_timeout 120s; ''; }; - "~ ^/(?:updater|ocs-provider)(?:$|/)".extraConfig = '' + "~ ^/(?:updater|ocs-provider|ocm-provider)(?:$|\/)".extraConfig = '' try_files $uri/ =404; index index.php; ''; - "~ \\.(?:css|js|woff|svg|gif)$".extraConfig = '' - try_files $uri /index.php$uri$is_args$args; + "~ \\.(?:css|js|woff2?|svg|gif)$".extraConfig = '' + try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463"; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; + add_header Referrer-Policy no-referrer; access_log off; ''; "~ \\.(?:png|html|ttf|ico|jpg|jpeg)$".extraConfig = '' - try_files $uri /index.php$uri$is_args$args; + try_files $uri /index.php$request_uri; access_log off; ''; }; @@ -469,10 +476,12 @@ in { add_header X-Robots-Tag none; add_header X-Download-Options noopen; add_header X-Permitted-Cross-Domain-Policies none; + add_header Referrer-Policy no-referrer; error_page 403 /core/templates/403.php; error_page 404 /core/templates/404.php; client_max_body_size ${cfg.maxUploadSize}; fastcgi_buffers 64 4K; + fastcgi_hide_header X-Powered-By; gzip on; gzip_vary on; gzip_comp_level 4; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index f688bec1426..1c9fbe048f8 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -194,11 +194,12 @@ let then filter (x: x.ssl) defaultListen else defaultListen; - listenString = { addr, port, ssl, ... }: + listenString = { addr, port, ssl, extraParameters ? [], ... }: "listen ${addr}:${toString port} " + optionalString ssl "ssl " + optionalString (ssl && vhost.http2) "http2 " + optionalString vhost.default "default_server " + + optionalString (extraParameters != []) (concatStringsSep " " extraParameters) + ";"; redirectListen = filter (x: !x.ssl) defaultListen; @@ -491,8 +492,8 @@ in sslProtocols = mkOption { type = types.str; - default = "TLSv1.2"; - example = "TLSv1 TLSv1.1 TLSv1.2"; + default = "TLSv1.2 TLSv1.3"; + example = "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"; description = "Allowed TLS protocol versions."; }; diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix index 6a50d8ed5cd..15b933c984a 100644 --- a/nixos/modules/services/web-servers/nginx/vhost-options.nix +++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix @@ -31,6 +31,7 @@ with lib; addr = mkOption { type = str; description = "IP address."; }; port = mkOption { type = int; description = "Port number."; default = 80; }; ssl = mkOption { type = bool; description = "Enable SSL."; default = false; }; + extraParameters = mkOption { type = listOf str; description = "Extra parameters of this listen directive."; default = []; example = [ "reuseport" "deferred" ]; }; }; }); default = []; example = [ diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 6255dce8276..ea01749349d 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -133,6 +133,7 @@ in { services.gnome3.gnome-keyring.enable = true; services.gnome3.gnome-online-accounts.enable = mkDefault true; services.gnome3.gnome-remote-desktop.enable = mkDefault true; + services.gnome3.gnome-settings-daemon.enable = true; services.gnome3.gnome-terminal-server.enable = mkDefault true; services.gnome3.gnome-user-share.enable = mkDefault true; services.gnome3.gvfs.enable = true; @@ -153,7 +154,6 @@ in { hardware.bluetooth.enable = mkDefault true; services.hardware.bolt.enable = mkDefault true; services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center - services.udev.packages = [ pkgs.gnome3.gnome-settings-daemon ]; systemd.packages = [ pkgs.gnome3.vino ]; services.flatpak.extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; diff --git a/nixos/modules/services/x11/desktop-managers/mate.nix b/nixos/modules/services/x11/desktop-managers/mate.nix index d06f478cf4d..bf6685ff7ea 100644 --- a/nixos/modules/services/x11/desktop-managers/mate.nix +++ b/nixos/modules/services/x11/desktop-managers/mate.nix @@ -56,9 +56,6 @@ in export XDG_MENU_PREFIX=mate- - # Find the mouse - export XCURSOR_PATH=~/.icons:${config.system.path}/share/icons - # Let caja find extensions export CAJA_EXTENSION_DIRS=$CAJA_EXTENSION_DIRS''${CAJA_EXTENSION_DIRS:+:}${config.system.path}/lib/caja/extensions-2.0 @@ -78,9 +75,6 @@ in # Add mate-control-center paths to some XDG variables because its schemas are needed by mate-settings-daemon, and mate-settings-daemon is a dependency for mate-control-center (that is, they are mutually recursive) ${addToXDGDirs pkgs.mate.mate-control-center} - # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/ - ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update - ${pkgs.mate.mate-session-manager}/bin/mate-session ${optionalString cfg.debug "--debug"} & waitPID=$! ''; @@ -90,14 +84,20 @@ in pkgs.mate.basePackages ++ (pkgs.gnome3.removePackagesByName pkgs.mate.extraPackages - config.environment.mate.excludePackages); - - services.dbus.packages = [ - pkgs.gnome3.dconf - pkgs.at-spi2-core - ]; - + config.environment.mate.excludePackages) ++ + [ + pkgs.desktop-file-utils + pkgs.glib + pkgs.gtk3.out + pkgs.shared-mime-info + pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/ + ]; + + programs.dconf.enable = true; + services.gnome3.at-spi2-core.enable = true; services.gnome3.gnome-keyring.enable = true; + services.gnome3.gnome-settings-daemon.enable = true; + services.gnome3.gnome-settings-daemon.package = pkgs.mate.mate-settings-daemon; services.gnome3.gvfs.enable = true; services.upower.enable = config.powerManagement.enable; diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix index 0f49439bf7c..31bbbd55829 100644 --- a/nixos/modules/services/x11/desktop-managers/pantheon.nix +++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -117,11 +117,12 @@ in services.gnome3.file-roller.enable = true; # TODO: gnome-keyring's xdg autostarts will still be in the environment (from elementary-session-settings) if disabled forcefully services.gnome3.gnome-keyring.enable = true; + services.gnome3.gnome-settings-daemon.enable = true; + services.gnome3.gnome-settings-daemon.package = pkgs.pantheon.elementary-settings-daemon; services.gnome3.gvfs.enable = true; services.gnome3.rygel.enable = true; services.gsignond.enable = true; services.gsignond.plugins = with pkgs.gsignondPlugins; [ lastfm mail oauth ]; - services.udev.packages = [ pkgs.pantheon.elementary-settings-daemon ]; services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; services.xserver.libinput.enable = mkDefault true; diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index d84ab3ced6f..c4d5b6a9cde 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -61,7 +61,9 @@ let ''; description = '' Extra lines to append to the <literal>Monitor</literal> section - verbatim. + verbatim. Available options are documented in the MONITOR section in + <citerefentry><refentrytitle>xorg.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>. ''; }; }; @@ -633,7 +635,7 @@ in environment.pathsToLink = [ "/share/X11" ]; - xdg = { + xdg = { autostart.enable = true; menus.enable = true; mime.enable = true; |