diff options
Diffstat (limited to 'nixos/modules/services')
25 files changed, 648 insertions, 156 deletions
diff --git a/nixos/modules/services/development/jupyter/default.nix b/nixos/modules/services/development/jupyter/default.nix new file mode 100644 index 000000000000..9fcc00431865 --- /dev/null +++ b/nixos/modules/services/development/jupyter/default.nix @@ -0,0 +1,184 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.jupyter; + + # NOTE: We don't use top-level jupyter because we don't + # want to pass in JUPYTER_PATH but use .environment instead, + # saving a rebuild. + package = pkgs.python3.pkgs.notebook; + + kernels = (pkgs.jupyter-kernel.create { + definitions = if cfg.kernels != null + then cfg.kernels + else pkgs.jupyter-kernel.default; + }); + + notebookConfig = pkgs.writeText "jupyter_config.py" '' + ${cfg.notebookConfig} + + c.NotebookApp.password = ${cfg.password} + ''; + +in { + meta.maintainers = with maintainers; [ aborsu ]; + + options.services.jupyter = { + enable = mkEnableOption "Jupyter development server"; + + ip = mkOption { + type = types.str; + default = "localhost"; + description = '' + IP address Jupyter will be listening on. + ''; + }; + + port = mkOption { + type = types.int; + default = 8888; + description = '' + Port number Jupyter will be listening on. + ''; + }; + + notebookDir = mkOption { + type = types.str; + default = "~/"; + description = '' + Root directory for notebooks. + ''; + }; + + user = mkOption { + type = types.str; + default = "jupyter"; + description = '' + Name of the user used to run the jupyter service. + For security reason, jupyter should really not be run as root. + If not set (jupyter), the service will create a jupyter user with appropriate settings. + ''; + example = "aborsu"; + }; + + group = mkOption { + type = types.str; + default = "jupyter"; + description = '' + Name of the group used to run the jupyter service. + Use this if you want to create a group of users that are able to view the notebook directory's content. + ''; + example = "users"; + }; + + password = mkOption { + type = types.str; + description = '' + Password to use with notebook. + Can be generated using: + In [1]: from notebook.auth import passwd + In [2]: passwd('test') + Out[2]: 'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba' + NOTE: you need to keep the single quote inside the nix string. + Or you can use a python oneliner: + "open('/path/secret_file', 'r', encoding='utf8').read().strip()" + It will be interpreted at the end of the notebookConfig. + ''; + example = [ + "'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'" + "open('/path/secret_file', 'r', encoding='utf8').read().strip()" + ]; + }; + + notebookConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Raw jupyter config. + ''; + }; + + kernels = mkOption { + type = types.nullOr (types.attrsOf(types.submodule (import ./kernel-options.nix { + inherit lib; + }))); + + default = null; + example = literalExample '' + { + python3 = let + env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [ + ipykernel + pandas + scikitlearn + ])); + in { + displayName = "Python 3 for machine learning"; + argv = [ + "$ {env.interpreter}" + "-m" + "ipykernel_launcher" + "-f" + "{connection_file}" + ]; + language = "python"; + logo32 = "$ {env.sitePackages}/ipykernel/resources/logo-32x32.png"; + logo64 = "$ {env.sitePackages}/ipykernel/resources/logo-64x64.png"; + }; + } + ''; + description = "Declarative kernel config + + Kernels can be declared in any language that supports and has the required + dependencies to communicate with a jupyter server. + In python's case, it means that ipykernel package must always be included in + the list of packages of the targeted environment. + "; + }; + }; + + config = mkMerge [ + (mkIf cfg.enable { + systemd.services.jupyter = { + description = "Jupyter development server"; + + wantedBy = [ "multi-user.target" ]; + + # TODO: Patch notebook so we can explicitly pass in a shell + path = [ pkgs.bash ]; # needed for sh in cell magic to work + + environment = { + JUPYTER_PATH = toString kernels; + }; + + serviceConfig = { + Restart = "always"; + ExecStart = ''${package}/bin/jupyter-notebook \ + --no-browser \ + --ip=${cfg.ip} \ + --port=${toString cfg.port} --port-retries 0 \ + --notebook-dir=${cfg.notebookDir} \ + --NotebookApp.config_file=${notebookConfig} + ''; + User = cfg.user; + Group = cfg.group; + WorkingDirectory = "~"; + }; + }; + }) + (mkIf (cfg.enable && (cfg.group == "jupyter")) { + users.groups.jupyter = {}; + }) + (mkIf (cfg.enable && (cfg.user == "jupyter")) { + users.extraUsers.jupyter = { + extraGroups = [ cfg.group ]; + home = "/var/lib/jupyter"; + createHome = true; + useDefaultShell = true; # needed so that the user can start a terminal. + }; + }) + ]; +} diff --git a/nixos/modules/services/development/jupyter/kernel-options.nix b/nixos/modules/services/development/jupyter/kernel-options.nix new file mode 100644 index 000000000000..03547637449a --- /dev/null +++ b/nixos/modules/services/development/jupyter/kernel-options.nix @@ -0,0 +1,60 @@ +# Options that can be used for creating a jupyter kernel. +{lib }: + +with lib; + +{ + options = { + + displayName = mkOption { + type = types.str; + default = ""; + example = [ + "Python 3" + "Python 3 for Data Science" + ]; + description = '' + Name that will be shown to the user. + ''; + }; + + argv = mkOption { + type = types.listOf types.str; + example = [ + "{customEnv.interpreter}" + "-m" + "ipykernel_launcher" + "-f" + "{connection_file}" + ]; + description = '' + Command and arguments to start the kernel. + ''; + }; + + language = mkOption { + type = types.str; + example = "python"; + description = '' + Language of the environment. Typically the name of the binary. + ''; + }; + + logo32 = mkOption { + type = types.nullOr types.path; + default = null; + example = "{env.sitePackages}/ipykernel/resources/logo-32x32.png"; + description = '' + Path to 32x32 logo png. + ''; + }; + logo64 = mkOption { + type = types.nullOr types.path; + default = null; + example = "{env.sitePackages}/ipykernel/resources/logo-64x64.png"; + description = '' + Path to 64x64 logo png. + ''; + }; + }; +} diff --git a/nixos/modules/services/logging/logstash.nix b/nixos/modules/services/logging/logstash.nix index 28d89a7463ab..aa019d855ea9 100644 --- a/nixos/modules/services/logging/logstash.nix +++ b/nixos/modules/services/logging/logstash.nix @@ -4,25 +4,12 @@ with lib; let cfg = config.services.logstash; - atLeast54 = versionAtLeast (builtins.parseDrvName cfg.package.name).version "5.4"; pluginPath = lib.concatStringsSep ":" cfg.plugins; havePluginPath = lib.length cfg.plugins > 0; ops = lib.optionalString; - verbosityFlag = - if atLeast54 - then "--log.level " + cfg.logLevel - else { - debug = "--debug"; - info = "--verbose"; - warn = ""; # intentionally empty - error = "--quiet"; - fatal = "--silent"; - }."${cfg.logLevel}"; - - pluginsPath = - if atLeast54 - then "--path.plugins ${pluginPath}" - else "--pluginpath ${pluginPath}"; + verbosityFlag = "--log.level " + cfg.logLevel; + + pluginsPath = "--path.plugins ${pluginPath}"; logstashConf = pkgs.writeText "logstash.conf" '' input { @@ -63,7 +50,7 @@ in type = types.package; default = pkgs.logstash; defaultText = "pkgs.logstash"; - example = literalExample "pkgs.logstash"; + example = literalExample "pkgs.logstash5"; description = "Logstash package to use."; }; @@ -95,12 +82,6 @@ in description = "The quantity of filter workers to run."; }; - enableWeb = mkOption { - type = types.bool; - default = false; - description = "Enable the logstash web interface."; - }; - listenAddress = mkOption { type = types.str; default = "127.0.0.1"; @@ -174,16 +155,6 @@ in ###### implementation config = mkIf cfg.enable { - assertions = [ - { assertion = atLeast54 -> !cfg.enableWeb; - message = '' - The logstash web interface is only available for versions older than 5.4. - So either set services.logstash.enableWeb = false, - or set services.logstash.package to an older logstash. - ''; - } - ]; - systemd.services.logstash = with pkgs; { description = "Logstash Daemon"; wantedBy = [ "multi-user.target" ]; @@ -193,14 +164,12 @@ in ExecStartPre = ''${pkgs.coreutils}/bin/mkdir -p "${cfg.dataDir}" ; ${pkgs.coreutils}/bin/chmod 700 "${cfg.dataDir}"''; ExecStart = concatStringsSep " " (filter (s: stringLength s != 0) [ "${cfg.package}/bin/logstash" - (ops (!atLeast54) "agent") "-w ${toString cfg.filterWorkers}" (ops havePluginPath pluginsPath) "${verbosityFlag}" "-f ${logstashConf}" - (ops atLeast54 "--path.settings ${logstashSettingsDir}") - (ops atLeast54 "--path.data ${cfg.dataDir}") - (ops cfg.enableWeb "-- web -a ${cfg.listenAddress} -p ${cfg.port}") + "--path.settings ${logstashSettingsDir}" + "--path.data ${cfg.dataDir}" ]); }; }; diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix index 5d664728e0b5..a222325579fe 100644 --- a/nixos/modules/services/misc/gitea.nix +++ b/nixos/modules/services/misc/gitea.nix @@ -261,7 +261,8 @@ in runConfig = "${cfg.stateDir}/custom/conf/app.ini"; secretKey = "${cfg.stateDir}/custom/conf/secret_key"; in '' - mkdir -p ${cfg.stateDir} + # Make sure that the stateDir exists, as well as the conf dir in there + mkdir -p ${cfg.stateDir}/conf # copy custom configuration and generate a random secret key if needed ${optionalString (cfg.useWizard == false) '' @@ -282,7 +283,7 @@ in mkdir -p ${cfg.repositoryRoot} # update all hooks' binary paths - HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 5 -type f -wholename "*git/hooks/*") + HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 6 -type f -wholename "*git/hooks/*") if [ "$HOOKS" ] then sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gitea,${gitea.bin}/bin/gitea,g' $HOOKS @@ -290,11 +291,13 @@ in sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS fi - if [ ! -d ${cfg.stateDir}/conf/locale ] + # If we have a folder or symlink with gitea locales, remove it + if [ -e ${cfg.stateDir}/conf/locale ] then - mkdir -p ${cfg.stateDir}/conf - cp -r ${gitea.out}/locale ${cfg.stateDir}/conf/locale + rm -r ${cfg.stateDir}/conf/locale fi + # And symlink the current gitea locales in place + ln -s ${gitea.out}/locale ${cfg.stateDir}/conf/locale # update command option in authorized_keys if [ -r ${cfg.stateDir}/.ssh/authorized_keys ] then diff --git a/nixos/modules/services/misc/gitit.nix b/nixos/modules/services/misc/gitit.nix index 0025d96bd37b..1ec030549f98 100644 --- a/nixos/modules/services/misc/gitit.nix +++ b/nixos/modules/services/misc/gitit.nix @@ -10,7 +10,7 @@ let toYesNo = b: if b then "yes" else "no"; - gititShared = with cfg.haskellPackages; gitit + "/share/" + pkgs.stdenv.system + "-" + ghc.name + "/" + gitit.pname + "-" + gitit.version; + gititShared = with cfg.haskellPackages; gitit + "/share/" + pkgs.stdenv.hostPlatform.system + "-" + ghc.name + "/" + gitit.pname + "-" + gitit.version; gititWithPkgs = hsPkgs: extras: hsPkgs.ghcWithPackages (self: with self; [ gitit ] ++ (extras self)); diff --git a/nixos/modules/services/monitoring/datadog-agent.nix b/nixos/modules/services/monitoring/datadog-agent.nix index f8ee34ebdf88..e545e06b3495 100644 --- a/nixos/modules/services/monitoring/datadog-agent.nix +++ b/nixos/modules/services/monitoring/datadog-agent.nix @@ -11,7 +11,7 @@ let api_key = ""; confd_path = "/etc/datadog-agent/conf.d"; additional_checksd = "/etc/datadog-agent/checks.d"; - use_dogstatsd = "yes"; + use_dogstatsd = true; } // optionalAttrs (cfg.logLevel != null) { log_level = cfg.logLevel; } // optionalAttrs (cfg.hostname != null) { inherit (cfg) hostname; } diff --git a/nixos/modules/services/monitoring/incron.nix b/nixos/modules/services/monitoring/incron.nix new file mode 100644 index 000000000000..1789fd9f2051 --- /dev/null +++ b/nixos/modules/services/monitoring/incron.nix @@ -0,0 +1,98 @@ + +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.incron; + +in + +{ + options = { + + services.incron = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the incron daemon. + + Note that commands run under incrontab only support common Nix profiles for the <envar>PATH</envar> provided variable. + ''; + }; + + allow = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + Users allowed to use incrontab. + + If empty then no user will be allowed to have their own incrontab. + If <literal>null</literal> then will defer to <option>deny</option>. + If both <option>allow</option> and <option>deny</option> are null + then all users will be allowed to have their own incrontab. + ''; + }; + + deny = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = "Users forbidden from using incrontab."; + }; + + systab = mkOption { + type = types.lines; + default = ""; + description = "The system incrontab contents."; + example = '' + /var/mail IN_CLOSE_WRITE abc $@/$# + /tmp IN_ALL_EVENTS efg $@/$# $& + ''; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = []; + example = literalExample "[ pkgs.rsync ]"; + description = "Extra packages available to the system incrontab."; + }; + + }; + + }; + + config = mkIf cfg.enable { + + warnings = optional (cfg.allow != null && cfg.deny != null) + ''If `services.incron.allow` is set then `services.incron.deny` will be ignored.''; + + environment.systemPackages = [ pkgs.incron ]; + + security.wrappers.incrontab.source = "${pkgs.incron}/bin/incrontab"; + + # incron won't read symlinks + environment.etc."incron.d/system" = { + mode = "0444"; + text = cfg.systab; + }; + environment.etc."incron.allow" = mkIf (cfg.allow != null) { + text = concatStringsSep "\n" cfg.allow; + }; + environment.etc."incron.deny" = mkIf (cfg.deny != null) { + text = concatStringsSep "\n" cfg.deny; + }; + + systemd.services.incron = { + description = "File System Events Scheduler"; + wantedBy = [ "multi-user.target" ]; + path = cfg.extraPackages; + serviceConfig.PIDFile = "/run/incrond.pid"; + serviceConfig.ExecStartPre = "${pkgs.coreutils}/bin/mkdir -m 710 -p /var/spool/incron"; + serviceConfig.ExecStart = "${pkgs.incron}/bin/incrond --foreground"; + }; + }; + +} diff --git a/nixos/modules/services/monitoring/zabbix-agent.nix b/nixos/modules/services/monitoring/zabbix-agent.nix index 87857225e7d7..426cf9bf86ef 100644 --- a/nixos/modules/services/monitoring/zabbix-agent.nix +++ b/nixos/modules/services/monitoring/zabbix-agent.nix @@ -7,6 +7,8 @@ let cfg = config.services.zabbixAgent; + zabbix = cfg.package; + stateDir = "/var/run/zabbix"; logDir = "/var/log/zabbix"; @@ -44,6 +46,16 @@ in ''; }; + package = mkOption { + type = types.attrs; # Note: pkgs.zabbixXY isn't a derivation, but an attrset of { server = ...; agent = ...; }. + default = pkgs.zabbix; + defaultText = "pkgs.zabbix"; + example = literalExample "pkgs.zabbix34"; + description = '' + The Zabbix package to use. + ''; + }; + server = mkOption { default = "127.0.0.1"; description = '' @@ -87,14 +99,14 @@ in chown zabbix ${stateDir} ${logDir} ''; - serviceConfig.ExecStart = "@${pkgs.zabbix.agent}/sbin/zabbix_agentd zabbix_agentd --config ${configFile}"; + serviceConfig.ExecStart = "@${zabbix.agent}/sbin/zabbix_agentd zabbix_agentd --config ${configFile}"; serviceConfig.Type = "forking"; serviceConfig.RemainAfterExit = true; serviceConfig.Restart = "always"; serviceConfig.RestartSec = 2; }; - environment.systemPackages = [ pkgs.zabbix.agent ]; + environment.systemPackages = [ zabbix.agent ]; }; diff --git a/nixos/modules/services/monitoring/zabbix-server.nix b/nixos/modules/services/monitoring/zabbix-server.nix index f62d55457ed4..5f9fc12832fc 100644 --- a/nixos/modules/services/monitoring/zabbix-server.nix +++ b/nixos/modules/services/monitoring/zabbix-server.nix @@ -103,8 +103,8 @@ in chown zabbix ${stateDir} ${logDir} ${libDir} if ! test -e "${libDir}/db-created"; then - ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole zabbix || true - ${pkgs.postgresql}/bin/createdb --owner zabbix zabbix || true + ${pkgs.su}/bin/su -s "$SHELL" ${config.services.postgresql.superUser} -c '${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole zabbix' || true + ${pkgs.su}/bin/su -s "$SHELL" ${config.services.postgresql.superUser} -c '${pkgs.postgresql}/bin/createdb --owner zabbix zabbix' || true cat ${pkgs.zabbix.server}/share/zabbix/db/schema/postgresql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c '${pkgs.postgresql}/bin/psql zabbix' cat ${pkgs.zabbix.server}/share/zabbix/db/data/images_pgsql.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c '${pkgs.postgresql}/bin/psql zabbix' cat ${pkgs.zabbix.server}/share/zabbix/db/data/data.sql | ${pkgs.su}/bin/su -s "$SHELL" zabbix -c '${pkgs.postgresql}/bin/psql zabbix' diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 36f1dd8d2479..86463f276c65 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -123,7 +123,7 @@ let # Perform a reverse-path test to refuse spoofers # For now, we just drop, as the raw table doesn't have a log-refuse yet ip46tables -t raw -N nixos-fw-rpfilter 2> /dev/null || true - ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN + ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter --validmark ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN # Allows this host to act as a DHCP4 client without first having to use APIPA iptables -t raw -A nixos-fw-rpfilter -p udp --sport 67 --dport 68 -j RETURN diff --git a/nixos/modules/services/networking/iwd.nix b/nixos/modules/services/networking/iwd.nix index cfc536fc5b5f..eb03d2e1d632 100644 --- a/nixos/modules/services/networking/iwd.nix +++ b/nixos/modules/services/networking/iwd.nix @@ -20,14 +20,7 @@ in { services.dbus.packages = [ pkgs.iwd ]; - systemd.services.iwd = { - description = "Wireless daemon"; - before = [ "network.target" ]; - wants = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - - serviceConfig.ExecStart = "${pkgs.iwd}/libexec/iwd"; - }; + systemd.packages = [ pkgs.iwd ]; systemd.tmpfiles.rules = [ "d /var/lib/iwd 0700 root root -" diff --git a/nixos/modules/services/networking/vsftpd.nix b/nixos/modules/services/networking/vsftpd.nix index 1f9107c3ce9c..31e1e65fa9ca 100644 --- a/nixos/modules/services/networking/vsftpd.nix +++ b/nixos/modules/services/networking/vsftpd.nix @@ -99,7 +99,7 @@ let nopriv_user=vsftpd secure_chroot_dir=/var/empty syslog_enable=YES - ${optionalString (pkgs.stdenv.system == "x86_64-linux") '' + ${optionalString (pkgs.stdenv.hostPlatform.system == "x86_64-linux") '' seccomp_sandbox=NO ''} anon_umask=${cfg.anonymousUmask} diff --git a/nixos/modules/services/networking/xrdp.nix b/nixos/modules/services/networking/xrdp.nix index 0e882873b4ba..61f22a366a02 100644 --- a/nixos/modules/services/networking/xrdp.nix +++ b/nixos/modules/services/networking/xrdp.nix @@ -93,10 +93,14 @@ in config = mkIf cfg.enable { - # copied from <nixos/modules/services/x11/xserver.nix> # xrdp can run X11 program even if "services.xserver.enable = false" - environment.pathsToLink = - [ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ]; + xdg = { + autostart.enable = true; + menus.enable = true; + mime.enable = true; + icons.enable = true; + }; + fonts.enableDefaultFonts = mkDefault true; systemd = { diff --git a/nixos/modules/services/networking/zeronet.nix b/nixos/modules/services/networking/zeronet.nix new file mode 100644 index 000000000000..2377cb2c8f11 --- /dev/null +++ b/nixos/modules/services/networking/zeronet.nix @@ -0,0 +1,102 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.zeronet; + + zConfFile = pkgs.writeTextFile { + name = "zeronet.conf"; + + text = '' + [global] + data_dir = ${cfg.dataDir} + log_dir = ${cfg.logDir} + '' + lib.optionalString (cfg.port != null) '' + ui_port = ${toString cfg.port} + '' + cfg.extraConfig; + }; +in with lib; { + options.services.zeronet = { + enable = mkEnableOption "zeronet"; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/zeronet"; + example = "/home/okina/zeronet"; + description = "Path to the zeronet data directory."; + }; + + logDir = mkOption { + type = types.path; + default = "/var/log/zeronet"; + example = "/home/okina/zeronet/log"; + description = "Path to the zeronet log directory."; + }; + + port = mkOption { + type = types.nullOr types.int; + default = null; + example = 15441; + description = "Optional zeronet port."; + }; + + tor = mkOption { + type = types.bool; + default = false; + description = "Use TOR for all zeronet traffic."; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + + description = '' + Extra configuration. Contents will be added verbatim to the + configuration file at the end. + ''; + }; + }; + + config = mkIf cfg.enable { + services.tor = mkIf cfg.tor { + enable = true; + controlPort = 9051; + extraConfig = "CookieAuthentication 1"; + }; + + systemd.services.zeronet = { + description = "zeronet"; + after = [ "network.target" (optionalString cfg.tor "tor.service") ]; + wantedBy = [ "multi-user.target" ]; + + preStart = '' + # Ensure folder exists or create it and permissions are correct + mkdir -p ${escapeShellArg cfg.dataDir} ${escapeShellArg cfg.logDir} + chmod 750 ${escapeShellArg cfg.dataDir} ${escapeShellArg cfg.logDir} + chown zeronet:zeronet ${escapeShellArg cfg.dataDir} ${escapeShellArg cfg.logDir} + ''; + + serviceConfig = { + PermissionsStartOnly = true; + PrivateTmp = "yes"; + User = "zeronet"; + Group = "zeronet"; + ExecStart = "${pkgs.zeronet}/bin/zeronet --config_file ${zConfFile}"; + }; + }; + + users = { + groups.zeronet.gid = config.ids.gids.zeronet; + + users.zeronet = { + description = "zeronet service user"; + home = cfg.dataDir; + createHome = true; + group = "zeronet"; + extraGroups = mkIf cfg.tor [ "tor" ]; + uid = config.ids.uids.zeronet; + }; + }; + }; + + meta.maintainers = with maintainers; [ chiiruno ]; +} diff --git a/nixos/modules/services/search/elasticsearch-curator.nix b/nixos/modules/services/search/elasticsearch-curator.nix new file mode 100644 index 000000000000..43785c392fee --- /dev/null +++ b/nixos/modules/services/search/elasticsearch-curator.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.elasticsearch-curator; + curatorConfig = pkgs.writeTextFile { + name = "config.yaml"; + text = '' + --- + # Remember, leave a key empty if there is no value. None will be a string, + # not a Python "NoneType" + client: + hosts: ${builtins.toJSON cfg.hosts} + port: ${toString cfg.port} + url_prefix: + use_ssl: False + certificate: + client_cert: + client_key: + ssl_no_validate: False + http_auth: + timeout: 30 + master_only: False + logging: + loglevel: INFO + logfile: + logformat: default + blacklist: ['elasticsearch', 'urllib3'] + ''; + }; + curatorAction = pkgs.writeTextFile { + name = "action.yaml"; + text = cfg.actionYAML; + }; +in { + + options.services.elasticsearch-curator = { + + enable = mkEnableOption "elasticsearch curator"; + interval = mkOption { + description = "The frequency to run curator, a systemd.time such as 'hourly'"; + default = "hourly"; + type = types.str; + }; + hosts = mkOption { + description = "a list of elasticsearch hosts to connect to"; + type = types.listOf types.str; + default = ["localhost"]; + }; + port = mkOption { + description = "the port that elasticsearch is listening on"; + type = types.int; + default = 9200; + }; + actionYAML = mkOption { + description = "curator action.yaml file contents, alternatively use curator-cli which takes a simple action command"; + example = '' + --- + actions: + 1: + action: delete_indices + description: >- + Delete indices older than 45 days (based on index name), for logstash- + prefixed indices. Ignore the error if the filter does not result in an + actionable list of indices (ignore_empty_list) and exit cleanly. + options: + ignore_empty_list: True + disable_action: False + filters: + - filtertype: pattern + kind: prefix + value: logstash- + - filtertype: age + source: name + direction: older + timestring: '%Y.%m.%d' + unit: days + unit_count: 45 + ''; + }; + }; + + config = mkIf cfg.enable { + + systemd.services.elasticsearch-curator = { + startAt = cfg.interval; + serviceConfig = { + ExecStart = ''${pkgs.python36Packages.elasticsearch-curator}/bin/curator --config ${curatorConfig} ${curatorAction}''; + }; + }; + }; +} diff --git a/nixos/modules/services/search/elasticsearch.nix b/nixos/modules/services/search/elasticsearch.nix index b0831dcd1ca8..6b688c640d59 100644 --- a/nixos/modules/services/search/elasticsearch.nix +++ b/nixos/modules/services/search/elasticsearch.nix @@ -5,22 +5,14 @@ with lib; let cfg = config.services.elasticsearch; - es5 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "5" >= 0; - es6 = builtins.compareVersions (builtins.parseDrvName cfg.package.name).version "6" >= 0; + es6 = builtins.compareVersions cfg.package.version "6" >= 0; esConfig = '' network.host: ${cfg.listenAddress} cluster.name: ${cfg.cluster_name} - ${if es5 then '' - http.port: ${toString cfg.port} - transport.tcp.port: ${toString cfg.tcp_port} - '' else '' - network.port: ${toString cfg.port} - network.tcp.port: ${toString cfg.tcp_port} - # TODO: find a way to enable security manager - security.manager.enabled: false - ''} + http.port: ${toString cfg.port} + transport.tcp.port: ${toString cfg.tcp_port} ${cfg.extraConf} ''; @@ -32,7 +24,7 @@ let text = esConfig; }; - loggingConfigFilename = if es5 then "log4j2.properties" else "logging.yml"; + loggingConfigFilename = "log4j2.properties"; loggingConfigFile = pkgs.writeTextFile { name = loggingConfigFilename; text = cfg.logging; @@ -41,8 +33,7 @@ let esPlugins = pkgs.buildEnv { name = "elasticsearch-plugins"; paths = cfg.plugins; - # Elasticsearch 5.x won't start when the plugins directory does not exist - postBuild = if es5 then "${pkgs.coreutils}/bin/mkdir -p $out/plugins" else ""; + postBuild = "${pkgs.coreutils}/bin/mkdir -p $out/plugins"; }; in { @@ -58,8 +49,8 @@ in { package = mkOption { description = "Elasticsearch package to use."; - default = pkgs.elasticsearch2; - defaultText = "pkgs.elasticsearch2"; + default = pkgs.elasticsearch; + defaultText = "pkgs.elasticsearch"; type = types.package; }; @@ -100,30 +91,18 @@ in { logging = mkOption { description = "Elasticsearch logging configuration."; - default = - if es5 then '' - logger.action.name = org.elasticsearch.action - logger.action.level = info - - appender.console.type = Console - appender.console.name = console - appender.console.layout.type = PatternLayout - appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n - - rootLogger.level = info - rootLogger.appenderRef.console.ref = console - '' else '' - rootLogger: INFO, console - logger: - action: INFO - com.amazonaws: WARN - appender: - console: - type: console - layout: - type: consolePattern - conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n" - ''; + default = '' + logger.action.name = org.elasticsearch.action + logger.action.level = info + + appender.console.type = Console + appender.console.name = console + appender.console.layout.type = PatternLayout + appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n + + rootLogger.level = info + rootLogger.appenderRef.console.ref = console + ''; type = types.str; }; @@ -204,9 +183,9 @@ in { cp ${elasticsearchYml} ${configDir}/elasticsearch.yml # Make sure the logging configuration for old elasticsearch versions is removed: - rm -f ${if es5 then "${configDir}/logging.yml" else "${configDir}/log4j2.properties"} + rm -f "${configDir}/logging.yml" cp ${loggingConfigFile} ${configDir}/${loggingConfigFilename} - ${optionalString es5 "mkdir -p ${configDir}/scripts"} + mkdir -p ${configDir}/scripts ${optionalString es6 "cp ${cfg.package}/config/jvm.options ${configDir}/jvm.options"} if [ "$(id -u)" = 0 ]; then chown -R elasticsearch:elasticsearch ${cfg.dataDir}; fi diff --git a/nixos/modules/services/search/kibana.nix b/nixos/modules/services/search/kibana.nix index 5885a72c6628..ca36bba58c02 100644 --- a/nixos/modules/services/search/kibana.nix +++ b/nixos/modules/services/search/kibana.nix @@ -5,43 +5,7 @@ with lib; let cfg = config.services.kibana; - atLeast54 = versionAtLeast (builtins.parseDrvName cfg.package.name).version "5.4"; - - cfgFile = if atLeast54 then cfgFile5 else cfgFile4; - - cfgFile4 = pkgs.writeText "kibana.json" (builtins.toJSON ( - (filterAttrsRecursive (n: v: v != null) ({ - host = cfg.listenAddress; - port = cfg.port; - ssl_cert_file = cfg.cert; - ssl_key_file = cfg.key; - - kibana_index = cfg.index; - default_app_id = cfg.defaultAppId; - - elasticsearch_url = cfg.elasticsearch.url; - kibana_elasticsearch_username = cfg.elasticsearch.username; - kibana_elasticsearch_password = cfg.elasticsearch.password; - kibana_elasticsearch_cert = cfg.elasticsearch.cert; - kibana_elasticsearch_key = cfg.elasticsearch.key; - ca = cfg.elasticsearch.ca; - - bundled_plugin_ids = [ - "plugins/dashboard/index" - "plugins/discover/index" - "plugins/doc/index" - "plugins/kibana/index" - "plugins/markdown_vis/index" - "plugins/metric_vis/index" - "plugins/settings/index" - "plugins/table_vis/index" - "plugins/vis_types/index" - "plugins/visualize/index" - ]; - } // cfg.extraConf) - ))); - - cfgFile5 = pkgs.writeText "kibana.json" (builtins.toJSON ( + cfgFile = pkgs.writeText "kibana.json" (builtins.toJSON ( (filterAttrsRecursive (n: v: v != null) ({ server.host = cfg.listenAddress; server.port = cfg.port; diff --git a/nixos/modules/services/security/usbguard.nix b/nixos/modules/services/security/usbguard.nix index 5d469cabe2cb..88d2f69db572 100644 --- a/nixos/modules/services/security/usbguard.nix +++ b/nixos/modules/services/security/usbguard.nix @@ -188,11 +188,14 @@ in { wants = [ "systemd-udevd.service" "local-fs.target" ]; # make sure an empty rule file and required directories exist - preStart = ''mkdir -p $(dirname "${cfg.ruleFile}") "${cfg.IPCAccessControlFiles}" && ([ -f "${cfg.ruleFile}" ] || touch ${cfg.ruleFile})''; + preStart = '' + mkdir -p $(dirname "${cfg.ruleFile}") $(dirname "${cfg.auditFilePath}") "${cfg.IPCAccessControlFiles}" \ + && ([ -f "${cfg.ruleFile}" ] || touch ${cfg.ruleFile}) + ''; serviceConfig = { Type = "simple"; - ExecStart = ''${pkgs.usbguard}/bin/usbguard-daemon -P -d -k -c ${daemonConfFile}''; + ExecStart = ''${pkgs.usbguard}/bin/usbguard-daemon -P -k -c ${daemonConfFile}''; Restart = "on-failure"; }; }; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 355976c4b7cb..b231ee5a3f01 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -16,9 +16,11 @@ let } // (optionalAttrs vhostConfig.enableACME { sslCertificate = "${acmeDirectory}/${serverName}/fullchain.pem"; sslCertificateKey = "${acmeDirectory}/${serverName}/key.pem"; + sslTrustedCertificate = "${acmeDirectory}/${serverName}/full.pem"; }) // (optionalAttrs (vhostConfig.useACMEHost != null) { sslCertificate = "${acmeDirectory}/${vhostConfig.useACMEHost}/fullchain.pem"; sslCertificateKey = "${acmeDirectory}/${vhostConfig.useACMEHost}/key.pem"; + sslTrustedCertificate = "${acmeDirectory}/${vhostConfig.useACMEHost}/full.pem"; }) ) cfg.virtualHosts; enableIPv6 = config.networking.enableIPv6; @@ -92,8 +94,18 @@ let gzip on; gzip_disable "msie6"; gzip_proxied any; - gzip_comp_level 9; - gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + gzip_comp_level 5; + gzip_types + application/atom+xml + application/javascript + application/json + application/xml + application/xml+rss + image/svg+xml + text/css + text/javascript + text/plain + text/xml; gzip_vary on; ''} @@ -218,6 +230,9 @@ let ssl_certificate ${vhost.sslCertificate}; ssl_certificate_key ${vhost.sslCertificateKey}; ''} + ${optionalString (hasSSL && vhost.sslTrustedCertificate != null) '' + ssl_trusted_certificate ${vhost.sslTrustedCertificate}; + ''} ${optionalString (vhost.basicAuthFile != null || vhost.basicAuth != {}) '' auth_basic secured; diff --git a/nixos/modules/services/web-servers/nginx/vhost-options.nix b/nixos/modules/services/web-servers/nginx/vhost-options.nix index 1075b00768fd..6954d932eed4 100644 --- a/nixos/modules/services/web-servers/nginx/vhost-options.nix +++ b/nixos/modules/services/web-servers/nginx/vhost-options.nix @@ -129,6 +129,13 @@ with lib; description = "Path to server SSL certificate key."; }; + sslTrustedCertificate = mkOption { + type = types.path; + default = null; + example = "/var/root.cert"; + description = "Path to root SSL certificate for stapling and client certificates."; + }; + http2 = mkOption { type = types.bool; default = true; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index da3287aaea6e..6fa3ec3b9255 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -33,12 +33,17 @@ in pkgs.xorg.xauth # used by kdesu pkgs.gtk2 # To get GTK+'s themes. pkgs.tango-icon-theme - pkgs.shared-mime-info + pkgs.gnome2.gnomeicontheme pkgs.xorg.xcursorthemes ]; - environment.pathsToLink = [ "/etc/enlightenment" "/etc/xdg" "/share/enlightenment" "/share/elementary" "/share/applications" "/share/locale" "/share/icons" "/share/themes" "/share/mime" "/share/desktop-directories" ]; + environment.pathsToLink = [ + "/etc/enlightenment" + "/share/enlightenment" + "/share/elementary" + "/share/locale" + ]; services.xserver.desktopManager.session = [ { name = "Enlightenment"; diff --git a/nixos/modules/services/x11/desktop-managers/lumina.nix b/nixos/modules/services/x11/desktop-managers/lumina.nix index 5fe84cfb82ec..43fed2572b51 100644 --- a/nixos/modules/services/x11/desktop-managers/lumina.nix +++ b/nixos/modules/services/x11/desktop-managers/lumina.nix @@ -41,9 +41,8 @@ in # Link some extra directories in /run/current-system/software/share environment.pathsToLink = [ - "/share/desktop-directories" - "/share/icons" "/share/lumina" + # FIXME: modules should link subdirs of `/share` rather than relying on this "/share" ]; diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index 83d1957a646a..d1cb962f6ff8 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -174,7 +174,10 @@ in ++ lib.optional config.services.colord.enable colord-kde ++ lib.optionals config.services.samba.enable [ kdenetwork-filesharing pkgs.samba ]; - environment.pathsToLink = [ "/share" ]; + environment.pathsToLink = [ + # FIXME: modules should link subdirs of `/share` rather than relying on this + "/share" + ]; environment.etc = singleton { source = xcfg.xkbDir; diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index ae155470419d..75b9a76e1924 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -59,9 +59,6 @@ in tango-icon-theme xfce4-icon-theme - desktop-file-utils - shared-mime-info - # Needed by Xfce's xinitrc script # TODO: replace with command -v which @@ -100,8 +97,6 @@ in environment.pathsToLink = [ "/share/xfce4" "/share/themes" - "/share/mime" - "/share/desktop-directories" "/share/gtksourceview-2.0" ]; diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index b45e510f6b83..0237dd6f5604 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -616,8 +616,12 @@ in ] ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh; - environment.pathsToLink = - [ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ]; + xdg = { + autostart.enable = true; + menus.enable = true; + mime.enable = true; + icons.enable = true; + }; # The default max inotify watches is 8192. # Nowadays most apps require a good number of inotify watches, |