diff options
Diffstat (limited to 'nixos')
56 files changed, 1431 insertions, 1525 deletions
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 3b01f4fed35..c51c30065a3 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -139,7 +139,7 @@ let manual-combined = runCommand "nixos-manual-combined" { inherit sources; - nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; meta.description = "The NixOS manual as plain docbook XML"; } '' @@ -194,7 +194,7 @@ let olinkDB = runCommand "manual-olinkdb" { inherit sources; - nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; } '' xsltproc \ @@ -244,7 +244,7 @@ in rec { # Generate the NixOS manual. manual = runCommand "nixos-manual" { inherit sources; - nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; meta.description = "The NixOS manual in HTML format"; allowedReferences = ["out"]; } @@ -272,7 +272,7 @@ in rec { manualEpub = runCommand "nixos-manual-epub" { inherit sources; - buildInputs = [ libxml2 libxslt zip ]; + buildInputs = [ libxml2.bin libxslt.bin zip ]; } '' # Generate the epub manual. @@ -302,7 +302,7 @@ in rec { # Generate the NixOS manpages. manpages = runCommand "nixos-manpages" { inherit sources; - nativeBuildInputs = [ buildPackages.libxml2 buildPackages.libxslt ]; + nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ]; allowedReferences = ["out"]; } '' diff --git a/nixos/doc/manual/release-notes/rl-1803.xml b/nixos/doc/manual/release-notes/rl-1803.xml index b755245a69f..60c17c60413 100644 --- a/nixos/doc/manual/release-notes/rl-1803.xml +++ b/nixos/doc/manual/release-notes/rl-1803.xml @@ -322,6 +322,43 @@ following incompatible changes:</para> <link xlink:href="https://github.com/rvl/pump.io-nixos">external module</link>. </para> </listitem> + <listitem> + <para> + The Prosody XMPP server has received a major update. The following modules were renamed: + <itemizedlist> + <listitem> + <para> + <option>services.prosody.modules.httpserver</option> is now <option>services.prosody.modules.http_files</option> + </para> + </listitem> + <listitem> + <para> + <option>services.prosody.modules.console</option> is now <option>services.prosody.modules.admin_telnet</option> + </para> + </listitem> + </itemizedlist> + </para> + + <para> + Many new modules are now core modules, most notably <option>services.prosody.modules.carbons</option> + and <option>services.prosody.modules.mam</option>. + </para> + + <para> + The better-performing <literal>libevent</literal> backend is now enabled by default. + </para> + + <para> + <literal>withCommunityModules</literal> now passes through the modules to <option>services.prosody.extraModules</option>. + Use <literal>withOnlyInstalledCommunityModules</literal> for modules that should not be enabled directly, e.g <literal>lib_ldap</literal>. + </para> + </listitem> + <listitem> + <para> + All prometheus exporter modules are now defined as submodules. + The exporters are configured using <literal>services.prometheus.exporters</literal>. + </para> + </listitem> </itemizedlist> </section> diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix index b9d5b2b903e..a20910353f3 100644 --- a/nixos/modules/config/no-x-libs.nix +++ b/nixos/modules/config/no-x-libs.nix @@ -32,7 +32,6 @@ with lib; networkmanager-l2tp = pkgs.networkmanager-l2tp.override { withGnome = false; }; networkmanager-openconnect = pkgs.networkmanager-openconnect.override { withGnome = false; }; networkmanager-openvpn = pkgs.networkmanager-openvpn.override { withGnome = false; }; - networkmanager-pptp = pkgs.networkmanager-pptp.override { withGnome = false; }; networkmanager-vpnc = pkgs.networkmanager-vpnc.override { withGnome = false; }; networkmanager-iodine = pkgs.networkmanager-iodine.override { withGnome = false; }; pinentry = pkgs.pinentry_ncurses; diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix index eafc9869315..a1f1cef07ad 100644 --- a/nixos/modules/hardware/video/nvidia.nix +++ b/nixos/modules/hardware/video/nvidia.nix @@ -16,8 +16,6 @@ let kernelPackages.nvidia_x11 else if elem "nvidiaBeta" drivers then kernelPackages.nvidia_x11_beta - else if elem "nvidiaLegacy173" drivers then - kernelPackages.nvidia_x11_legacy173 else if elem "nvidiaLegacy304" drivers then kernelPackages.nvidia_x11_legacy304 else if elem "nvidiaLegacy340" drivers then diff --git a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix index ba84cd51098..6d4ba96dba0 100644 --- a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix +++ b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix @@ -54,7 +54,7 @@ in environment.systemPackages = [ pkgs.w3m # needed for the manual anyway pkgs.testdisk # useful for repairing boot problems - pkgs.mssys # for writing Microsoft boot sectors / MBRs + pkgs.ms-sys # for writing Microsoft boot sectors / MBRs pkgs.parted pkgs.ddrescue pkgs.ccrypt diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 39a24cfecc5..c5dee2ca97a 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -106,7 +106,7 @@ freenet = 79; ircd = 80; bacula = 81; - almir = 82; + #almir = 82; # removed 2018-03-25, the almir package was removed in 30291227f2411abaca097773eedb49b8f259e297 during 2017-08 deluge = 83; mysql = 84; rabbitmq = 85; @@ -393,7 +393,7 @@ freenet = 79; ircd = 80; bacula = 81; - almir = 82; + #almir = 82; # removed 2018-03-25, the almir package was removed in 30291227f2411abaca097773eedb49b8f259e297 during 2017-08 deluge = 83; mysql = 84; rabbitmq = 85; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index e0c0ec2711b..9e232ce1f4e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -158,7 +158,6 @@ ./services/audio/slimserver.nix ./services/audio/squeezelite.nix ./services/audio/ympd.nix - ./services/backup/almir.nix ./services/backup/bacula.nix ./services/backup/borgbackup.nix ./services/backup/crashplan.nix @@ -363,6 +362,7 @@ ./services/misc/rippled.nix ./services/misc/ripple-data-api.nix ./services/misc/rogue.nix + ./services/misc/serviio.nix ./services/misc/siproxd.nix ./services/misc/snapper.nix ./services/misc/sonarr.nix @@ -398,16 +398,7 @@ ./services/monitoring/osquery.nix ./services/monitoring/prometheus/default.nix ./services/monitoring/prometheus/alertmanager.nix - ./services/monitoring/prometheus/blackbox-exporter.nix - ./services/monitoring/prometheus/collectd-exporter.nix - ./services/monitoring/prometheus/fritzbox-exporter.nix - ./services/monitoring/prometheus/json-exporter.nix - ./services/monitoring/prometheus/minio-exporter.nix - ./services/monitoring/prometheus/nginx-exporter.nix - ./services/monitoring/prometheus/node-exporter.nix - ./services/monitoring/prometheus/snmp-exporter.nix - ./services/monitoring/prometheus/unifi-exporter.nix - ./services/monitoring/prometheus/varnish-exporter.nix + ./services/monitoring/prometheus/exporters.nix ./services/monitoring/riemann.nix ./services/monitoring/riemann-dash.nix ./services/monitoring/riemann-tools.nix @@ -640,7 +631,6 @@ ./services/web-apps/atlassian/jira.nix ./services/web-apps/frab.nix ./services/web-apps/mattermost.nix - ./services/web-apps/nixbot.nix ./services/web-apps/nexus.nix ./services/web-apps/pgpkeyserver-lite.nix ./services/web-apps/matomo.nix diff --git a/nixos/modules/profiles/base.nix b/nixos/modules/profiles/base.nix index 39b8553976e..3bf06a95119 100644 --- a/nixos/modules/profiles/base.nix +++ b/nixos/modules/profiles/base.nix @@ -9,7 +9,7 @@ environment.systemPackages = [ pkgs.w3m-nox # needed for the manual anyway pkgs.testdisk # useful for repairing boot problems - pkgs.mssys # for writing Microsoft boot sectors / MBRs + pkgs.ms-sys # for writing Microsoft boot sectors / MBRs pkgs.efibootmgr pkgs.efivar pkgs.parted diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 489d7d8b9b5..b0ca274b939 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -240,5 +240,11 @@ with lib; # Xen (mkRenamedOptionModule [ "virtualisation" "xen" "qemu-package" ] [ "virtualisation" "xen" "package-qemu" ]) - ]; + ] ++ (flip map [ "blackboxExporter" "collectdExporter" "fritzboxExporter" + "jsonExporter" "minioExporter" "nginxExporter" "nodeExporter" + "snmpExporter" "unifiExporter" "varnishExporter" ] + (opt: mkRemovedOptionModule [ "services" "prometheus" "${opt}" ] '' + The prometheus exporters are now configured using `services.prometheus.exporters'. + See the 18.03 release notes for more information. + '' )); } diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix index 0736239ed2c..e9676d9dfb1 100644 --- a/nixos/modules/security/acme.nix +++ b/nixos/modules/security/acme.nix @@ -140,14 +140,6 @@ in ''; }; - tosHash = mkOption { - type = types.string; - default = "cc88d8d9517f490191401e7b54e9ffd12a2b9082ec7a1d4cec6101f9f1647e7b"; - description = '' - SHA256 of the Terms of Services document. This changes once in a while. - ''; - }; - production = mkOption { type = types.bool; default = true; @@ -196,7 +188,7 @@ in let cpath = "${cfg.directory}/${cert}"; rights = if data.allowKeysForGroup then "750" else "700"; - cmdline = [ "-v" "-d" data.domain "--default_root" data.webroot "--valid_min" cfg.validMin "--tos_sha256" cfg.tosHash ] + cmdline = [ "-v" "-d" data.domain "--default_root" data.webroot "--valid_min" cfg.validMin ] ++ optionals (data.email != null) [ "--email" data.email ] ++ concatMap (p: [ "-f" p ]) data.plugins ++ concatLists (mapAttrsToList (name: root: [ "-d" (if root == null then name else "${name}:${root}")]) data.extraDomains) diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index 9ca818e86ff..df6108dede7 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -25,14 +25,14 @@ let loginCfgFile = optional cfg.ssh.enable { source = pkgs.writeText "login_duo.conf" configFile; mode = "0600"; - uid = config.ids.uids.sshd; + user = "sshd"; target = "duo/login_duo.conf"; }; pamCfgFile = optional cfg.pam.enable { source = pkgs.writeText "pam_duo.conf" configFile; mode = "0600"; - uid = config.ids.uids.sshd; + user = "sshd"; target = "duo/pam_duo.conf"; }; in diff --git a/nixos/modules/services/backup/almir.nix b/nixos/modules/services/backup/almir.nix deleted file mode 100644 index fbb4ff4034f..00000000000 --- a/nixos/modules/services/backup/almir.nix +++ /dev/null @@ -1,173 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.services.almir; - - bconsoleconf = pkgs.writeText "bconsole.conf" - '' - Director { - Name = ${cfg.director_name} - DIRport = ${toString cfg.director_port} - address = ${cfg.director_address} - Password = "${cfg.director_password}" - } - ''; - - productionini = pkgs.writeText "production.ini" - '' -[app:main] -use = egg:almir - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.debug_templates = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_exclog -exclog.extra_info = true - -sqlalchemy.url = ${cfg.sqlalchemy_engine_url} -timezone = ${cfg.timezone} -bconsole_config = ${bconsoleconf} - -[server:main] -use = egg:waitress#main -host = 127.0.0.1 -port = ${toString cfg.port} - - -# Begin logging configuration - -[loggers] -keys = root, almir, sqlalchemy, exc_logger - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_almir] -level = WARN -handlers = -qualname = almir - -[logger_exc_logger] -level = ERROR -handlers = -qualname = exc_logger - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - ''; -in { - options = { - services.almir = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Enable Almir web server. Also configures postgresql database and installs bacula. - ''; - }; - - port = mkOption { - default = 35000; - type = types.int; - description = '' - Port for Almir web server to listen on. - ''; - }; - - timezone = mkOption { - description = '' - Timezone as specified in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - ''; - example = "Europe/Ljubljana"; - }; - - sqlalchemy_engine_url = mkOption { - default = "postgresql:///bacula"; - example = '' - postgresql://bacula:bacula@localhost:5432/bacula - mysql+mysqlconnector://<user>:<password>@<hostname>/<database>' - sqlite:////var/lib/bacula/bacula.db' - ''; - description = '' - Define SQL database connection to bacula catalog as specified in http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls - ''; - }; - - director_name = mkOption { - description = '' - Name of the Director to connect with bconsole. - ''; - }; - - director_password = mkOption { - description = '' - Password for Director to connect with bconsole. - ''; - }; - - director_port = mkOption { - default = 9101; - type = types.int; - description = '' - Port for Director to connect with bconsole. - ''; - }; - - director_address = mkOption { - default = "127.0.0.1"; - description = '' - IP/Hostname for Director to connect with bconsole. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - systemd.services.almir = { - after = [ "network.target" "postgresql.service" ]; - description = "Almir web app"; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.pythonPackages.almir ]; - environment.PYTHONPATH = "${pkgs.pythonPackages.almir}/lib/${pkgs.pythonPackages.python.libPrefix}/site-packages"; - serviceConfig.ExecStart = "${pkgs.pythonPackages.pyramid}/bin/pserve ${productionini}"; - }; - - environment.systemPackages = [ pkgs.pythonPackages.almir ]; - - users.extraUsers.almir = { - group = "almir"; - uid = config.ids.uids.almir; - createHome = true; - shell = "${pkgs.bash}/bin/bash"; - }; - - users.extraGroups.almir.gid = config.ids.gids.almir; - }; -} diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix index 59e9d122fb5..4fc7c24813a 100644 --- a/nixos/modules/services/backup/tarsnap.nix +++ b/nixos/modules/services/backup/tarsnap.nix @@ -238,6 +238,20 @@ in Whether to produce verbose logging output. ''; }; + explicitSymlinks = mkOption { + type = types.bool; + default = false; + description = '' + Whether to follow symlinks specified as archives. + ''; + }; + followSymlinks = mkOption { + type = types.bool; + default = false; + description = '' + Whether to follow all symlinks in archive trees. + ''; + }; }; } )); @@ -285,12 +299,12 @@ in }) gcfg.archives); systemd.services = - mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { + (mapAttrs' (name: cfg: nameValuePair "tarsnap-${name}" { description = "Tarsnap archive '${name}'"; requires = [ "network-online.target" ]; after = [ "network-online.target" ]; - path = [ pkgs.iputils pkgs.tarsnap pkgs.utillinux ]; + path = with pkgs; [ iputils tarsnap utillinux ]; # In order for the persistent tarsnap timer to work reliably, we have to # make sure that the tarsnap server is reachable after systemd starts up @@ -300,10 +314,12 @@ in while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done ''; - script = - let run = ''tarsnap --configfile "/etc/tarsnap/${name}.conf" \ - -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \ + script = let + tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"''; + run = ''${tarsnap} -c -f "${name}-$(date +"%Y%m%d%H%M%S")" \ ${optionalString cfg.verbose "-v"} \ + ${optionalString cfg.explicitSymlinks "-H"} \ + ${optionalString cfg.followSymlinks "-L"} \ ${concatStringsSep " " cfg.directories}''; in if (cfg.cachedir != null) then '' mkdir -p ${cfg.cachedir} @@ -313,7 +329,7 @@ in if [ ! -e ${cfg.cachedir}/firstrun ]; then ( flock 10 flock -u 9 - tarsnap --configfile "/etc/tarsnap/${name}.conf" --fsck + ${tarsnap} --fsck flock 9 ) 10>${cfg.cachedir}/firstrun fi @@ -329,7 +345,44 @@ in CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; PermissionsStartOnly = "true"; }; - }) gcfg.archives; + }) gcfg.archives) // + + (mapAttrs' (name: cfg: nameValuePair "tarsnap-restore-${name}"{ + description = "Tarsnap restore '${name}'"; + requires = [ "network-online.target" ]; + + path = with pkgs; [ iputils tarsnap utillinux ]; + + script = let + tarsnap = ''tarsnap --configfile "/etc/tarsnap/${name}.conf"''; + lastArchive = ''$(${tarsnap} --list-archives | sort | tail -1)''; + run = ''${tarsnap} -x -f "${lastArchive}" ${optionalString cfg.verbose "-v"}''; + + in if (cfg.cachedir != null) then '' + mkdir -p ${cfg.cachedir} + chmod 0700 ${cfg.cachedir} + + ( flock 9 + if [ ! -e ${cfg.cachedir}/firstrun ]; then + ( flock 10 + flock -u 9 + ${tarsnap} --fsck + flock 9 + ) 10>${cfg.cachedir}/firstrun + fi + ) 9>${cfg.cachedir}/lockf + + exec flock ${cfg.cachedir}/firstrun ${run} + '' else "exec ${run}"; + + serviceConfig = { + Type = "oneshot"; + IOSchedulingClass = "idle"; + NoNewPrivileges = "true"; + CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ]; + PermissionsStartOnly = "true"; + }; + }) gcfg.archives); # Note: the timer must be Persistent=true, so that systemd will start it even # if e.g. your laptop was asleep while the latest interval occurred. diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix index 762bb4b3867..3d133f82d20 100644 --- a/nixos/modules/services/backup/znapzend.nix +++ b/nixos/modules/services/backup/znapzend.nix @@ -386,7 +386,7 @@ in echo Resetting znapzend zetups ${pkgs.znapzend}/bin/znapzendzetup list \ | grep -oP '(?<=\*\*\* backup plan: ).*(?= \*\*\*)' \ - | xargs ${pkgs.znapzend}/bin/znapzendzetup delete + | xargs -I{} ${pkgs.znapzend}/bin/znapzendzetup delete "{}" '' + concatStringsSep "\n" (mapAttrsToList (dataset: config: '' echo Importing znapzend zetup ${config} for dataset ${dataset} ${pkgs.znapzend}/bin/znapzendzetup import --write ${dataset} ${config} diff --git a/nixos/modules/services/cluster/kubernetes/default.nix b/nixos/modules/services/cluster/kubernetes/default.nix index 4a2c6f0833e..39c5d78d419 100644 --- a/nixos/modules/services/cluster/kubernetes/default.nix +++ b/nixos/modules/services/cluster/kubernetes/default.nix @@ -279,7 +279,7 @@ in { tokenAuthFile = mkOption { description = '' Kubernetes apiserver token authentication file. See - <link xlink:href="http://kubernetes.io/docs/admin/authentication.html"/> + <link xlink:href="https://kubernetes.io/docs/admin/authentication.html"/> ''; default = null; type = types.nullOr types.path; @@ -288,7 +288,7 @@ in { basicAuthFile = mkOption { description = '' Kubernetes apiserver basic authentication file. See - <link xlink:href="http://kubernetes.io/docs/admin/authentication.html"/> + <link xlink:href="https://kubernetes.io/docs/admin/authentication.html"/> ''; default = pkgs.writeText "users" '' kubernetes,admin,0 @@ -299,7 +299,7 @@ in { authorizationMode = mkOption { description = '' Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC/RBAC). See - <link xlink:href="http://kubernetes.io/docs/admin/authorization.html"/> + <link xlink:href="https://kubernetes.io/docs/admin/authorization.html"/> ''; default = ["RBAC" "Node"]; type = types.listOf (types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC" "RBAC" "Node"]); @@ -308,7 +308,7 @@ in { authorizationPolicy = mkOption { description = '' Kubernetes apiserver authorization policy file. See - <link xlink:href="http://kubernetes.io/docs/admin/authorization.html"/> + <link xlink:href="https://kubernetes.io/docs/admin/authorization.html"/> ''; default = []; type = types.listOf types.attrs; @@ -332,7 +332,7 @@ in { runtimeConfig = mkOption { description = '' Api runtime configuration. See - <link xlink:href="http://kubernetes.io/docs/admin/cluster-management.html"/> + <link xlink:href="https://kubernetes.io/docs/admin/cluster-management.html"/> ''; default = "authentication.k8s.io/v1beta1=true"; example = "api/all=false,api/v1=true"; @@ -342,7 +342,7 @@ in { admissionControl = mkOption { description = '' Kubernetes admission control plugins to use. See - <link xlink:href="http://kubernetes.io/docs/admin/admission-controllers/"/> + <link xlink:href="https://kubernetes.io/docs/admin/admission-controllers/"/> ''; default = ["NamespaceLifecycle" "LimitRanger" "ServiceAccount" "ResourceQuota" "DefaultStorageClass" "DefaultTolerationSeconds" "NodeRestriction"]; example = [ diff --git a/nixos/modules/services/logging/graylog.nix b/nixos/modules/services/logging/graylog.nix index a0dc0d6d089..95f31829882 100644 --- a/nixos/modules/services/logging/graylog.nix +++ b/nixos/modules/services/logging/graylog.nix @@ -141,7 +141,7 @@ in JAVA_HOME = jre; GRAYLOG_CONF = "${confFile}"; }; - path = [ pkgs.openjdk8 pkgs.which pkgs.procps ]; + path = [ pkgs.jre_headless pkgs.which pkgs.procps ]; preStart = '' mkdir -p /var/lib/graylog -m 755 diff --git a/nixos/modules/services/misc/defaultUnicornConfig.rb b/nixos/modules/services/misc/defaultUnicornConfig.rb index 84622622db7..0b58c59c7a5 100644 --- a/nixos/modules/services/misc/defaultUnicornConfig.rb +++ b/nixos/modules/services/misc/defaultUnicornConfig.rb @@ -1,205 +1,69 @@ -# The following was taken from github.com/crohr/syslogger and is BSD -# licensed. -require 'syslog' -require 'logger' -require 'thread' +worker_processes 3 -class Syslogger - - VERSION = "1.6.0" - - attr_reader :level, :ident, :options, :facility, :max_octets - attr_accessor :formatter - - MAPPING = { - Logger::DEBUG => Syslog::LOG_DEBUG, - Logger::INFO => Syslog::LOG_INFO, - Logger::WARN => Syslog::LOG_WARNING, - Logger::ERROR => Syslog::LOG_ERR, - Logger::FATAL => Syslog::LOG_CRIT, - Logger::UNKNOWN => Syslog::LOG_ALERT - } - - # - # Initializes default options for the logger - # <tt>ident</tt>:: the name of your program [default=$0]. - # <tt>options</tt>:: syslog options [default=<tt>Syslog::LOG_PID | Syslog::LOG_CONS</tt>]. - # Correct values are: - # LOG_CONS : writes the message on the console if an error occurs when sending the message; - # LOG_NDELAY : no delay before sending the message; - # LOG_PERROR : messages will also be written on STDERR; - # LOG_PID : adds the process number to the message (just after the program name) - # <tt>facility</tt>:: the syslog facility [default=nil] Correct values include: - # Syslog::LOG_DAEMON - # Syslog::LOG_USER - # Syslog::LOG_SYSLOG - # Syslog::LOG_LOCAL2 - # Syslog::LOG_NEWS - # etc. - # - # Usage: - # logger = Syslogger.new("my_app", Syslog::LOG_PID | Syslog::LOG_CONS, Syslog::LOG_LOCAL0) - # logger.level = Logger::INFO # use Logger levels - # logger.warn "warning message" - # logger.debug "debug message" - # - def initialize(ident = $0, options = Syslog::LOG_PID | Syslog::LOG_CONS, facility = nil) - @ident = ident - @options = options || (Syslog::LOG_PID | Syslog::LOG_CONS) - @facility = facility - @level = Logger::INFO - @mutex = Mutex.new - @formatter = Logger::Formatter.new - end - - %w{debug info warn error fatal unknown}.each do |logger_method| - # Accepting *args as message could be nil. - # Default params not supported in ruby 1.8.7 - define_method logger_method.to_sym do |*args, &block| - return true if @level > Logger.const_get(logger_method.upcase) - message = args.first || block && block.call - add(Logger.const_get(logger_method.upcase), message) - end - - unless logger_method == 'unknown' - define_method "#{logger_method}?".to_sym do - @level <= Logger.const_get(logger_method.upcase) - end - end - end - - # Log a message at the Logger::INFO level. Useful for use with Rack::CommonLogger - def write(msg) - add(Logger::INFO, msg) - end - - # Logs a message at the Logger::INFO level. - def <<(msg) - add(Logger::INFO, msg) - end - - # Low level method to add a message. - # +severity+:: the level of the message. One of Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN - # +message+:: the message string. - # If nil, the method will call the block and use the result as the message string. - # If both are nil or no block is given, it will use the progname as per the behaviour of both the standard Ruby logger, and the Rails BufferedLogger. - # +progname+:: optionally, overwrite the program name that appears in the log message. - def add(severity, message = nil, progname = nil, &block) - if message.nil? && block.nil? && !progname.nil? - message, progname = progname, nil - end - progname ||= @ident - - @mutex.synchronize do - Syslog.open(progname, @options, @facility) do |s| - s.mask = Syslog::LOG_UPTO(MAPPING[@level]) - communication = clean(message || block && block.call) - if self.max_octets - buffer = "#{tags_text}" - communication.bytes do |byte| - buffer.concat(byte) - # if the last byte we added is potentially part of an escape, we'll go ahead and add another byte - if buffer.bytesize >= self.max_octets && !['%'.ord,'\\'.ord].include?(byte) - s.log(MAPPING[severity],buffer) - buffer = "" - end - end - s.log(MAPPING[severity],buffer) unless buffer.empty? - else - s.log(MAPPING[severity],"#{tags_text}#{communication}") - end - end - end - end - - # Set the max octets of the messages written to the log - def max_octets=(max_octets) - @max_octets = max_octets - end - - # Sets the minimum level for messages to be written in the log. - # +level+:: one of <tt>Logger::DEBUG</tt>, <tt>Logger::INFO</tt>, <tt>Logger::WARN</tt>, <tt>Logger::ERROR</tt>, <tt>Logger::FATAL</tt>, <tt>Logger::UNKNOWN</tt> - def level=(level) - level = Logger.const_get(level.to_s.upcase) if level.is_a?(Symbol) - - unless level.is_a?(Fixnum) - raise ArgumentError.new("Invalid logger level `#{level.inspect}`") - end - - @level = level - end - - # Sets the ident string passed along to Syslog - def ident=(ident) - @ident = ident - end - - # Tagging code borrowed from ActiveSupport gem - def tagged(*tags) - new_tags = push_tags(*tags) - yield self - ensure - pop_tags(new_tags.size) - end - - def push_tags(*tags) - tags.flatten.reject{ |i| i.respond_to?(:empty?) ? i.empty? : !i }.tap do |new_tags| - current_tags.concat new_tags - end - end - - def pop_tags(size = 1) - current_tags.pop size - end - - def clear_tags! - current_tags.clear - end - - protected - - # Borrowed from SyslogLogger. - def clean(message) - message = message.to_s.dup - message.strip! # remove whitespace - message.gsub!(/\n/, '\\n') # escape newlines - message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf) - message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes - message - end - - private - - def tags_text - tags = current_tags - if tags.any? - tags.collect { |tag| "[#{tag}] " }.join - end - end - - def current_tags - Thread.current[:syslogger_tagged_logging_tags] ||= [] - end -end +listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024 +listen "/run/gitlab/gitlab.socket", :backlog => 1024 -worker_processes 2 working_directory ENV["GITLAB_PATH"] -pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid" -listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024 +pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid" timeout 60 -logger Syslogger.new - +# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings +# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow preload_app true - GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true check_client_connection false +before_fork do |server, worker| + # the following is highly recommended for Rails + "preload_app true" + # as there's no need for the master process to hold a connection + defined?(ActiveRecord::Base) and + ActiveRecord::Base.connection.disconnect! + + # The following is only recommended for memory/DB-constrained + # installations. It is not needed if your system can house + # twice as many worker_processes as you have configured. + # + # This allows a new master process to incrementally + # phase out the old master process with SIGTTOU to avoid a + # thundering herd (especially in the "preload_app false" case) + # when doing a transparent upgrade. The last worker spawned + # will then kill off the old master process with a SIGQUIT. + old_pid = "#{server.config[:pid]}.oldbin" + if old_pid != server.pid + begin + sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU + Process.kill(sig, File.read(old_pid).to_i) + rescue Errno::ENOENT, Errno::ESRCH + end + end + + # Throttle the master from forking too quickly by sleeping. Due + # to the implementation of standard Unix signal handlers, this + # helps (but does not completely) prevent identical, repeated signals + # from being lost when the receiving process is busy. + # sleep 1 +end + after_fork do |server, worker| + # per-process listener ports for debugging/admin/migrations + # addr = "127.0.0.1:#{9293 + worker.nr}" + # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true) + + # the following is *required* for Rails + "preload_app true", defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection + + # reset prometheus client, this will cause any opened metrics files to be closed + defined?(::Prometheus::Client.reinitialize_on_pid_change) && + Prometheus::Client.reinitialize_on_pid_change + + # if preload_app is true, then you may also want to check and + # restart any other shared sockets/descriptors such as Memcached, + # and Redis. TokyoCabinet file handles are safe to reuse + # between any number of forked children (assuming your kernel + # correctly implements pread()/pwrite() system calls) end diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index 9ed5875a019..20d7ec90dcc 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -143,6 +143,7 @@ let GITLAB_PATH = "${cfg.packages.gitlab}/share/gitlab/"; GITLAB_STATE_PATH = "${cfg.statePath}"; GITLAB_UPLOADS_PATH = "${cfg.statePath}/uploads"; + SCHEMA = "${cfg.statePath}/db/schema.rb"; GITLAB_LOG_PATH = "${cfg.statePath}/log"; GITLAB_SHELL_PATH = "${cfg.packages.gitlab-shell}"; GITLAB_SHELL_CONFIG_PATH = "${cfg.statePath}/shell/config.yml"; @@ -500,7 +501,7 @@ in { Type = "simple"; User = cfg.user; Group = cfg.group; - TimeoutSec = "300"; + TimeoutSec = "infinity"; Restart = "on-failure"; WorkingDirectory = gitlabEnv.HOME; ExecStart = "${cfg.packages.gitaly}/bin/gitaly ${gitalyToml}"; @@ -566,6 +567,7 @@ in { mkdir -p ${cfg.statePath}/tmp/pids mkdir -p ${cfg.statePath}/tmp/sockets mkdir -p ${cfg.statePath}/shell + mkdir -p ${cfg.statePath}/db rm -rf ${cfg.statePath}/config ${cfg.statePath}/shell/hooks mkdir -p ${cfg.statePath}/config @@ -580,6 +582,7 @@ in { ln -sf ${cfg.statePath}/log /run/gitlab/log ln -sf ${cfg.statePath}/uploads /run/gitlab/uploads ln -sf ${cfg.statePath}/tmp /run/gitlab/tmp + ln -sf $GITLAB_SHELL_CONFIG_PATH /run/gitlab/shell-config.yml chown -R ${cfg.user}:${cfg.group} /run/gitlab # Prepare home directory @@ -587,6 +590,7 @@ in { touch ${gitlabEnv.HOME}/.ssh/authorized_keys chown -R ${cfg.user}:${cfg.group} ${gitlabEnv.HOME}/ + cp -rf ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db cp -rf ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config ${optionalString cfg.smtp.enable '' ln -sf ${smtpSettings} ${cfg.statePath}/config/initializers/smtp_settings.rb diff --git a/nixos/modules/services/misc/serviio.nix b/nixos/modules/services/misc/serviio.nix new file mode 100644 index 00000000000..a6612e9c6ad --- /dev/null +++ b/nixos/modules/services/misc/serviio.nix @@ -0,0 +1,92 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.serviio; + + serviioStart = pkgs.writeScript "serviio.sh" '' + #!${pkgs.bash}/bin/sh + + SERVIIO_HOME=${pkgs.serviio} + + # Setup the classpath + SERVIIO_CLASS_PATH="$SERVIIO_HOME/lib/*:$SERVIIO_HOME/config" + + # Setup Serviio specific properties + JAVA_OPTS="-Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -Dorg.restlet.engine.loggerFacadeClass=org.restlet.ext.slf4j.Slf4jLoggerFacade + -Dderby.system.home=${cfg.dataDir}/library -Dserviio.home=${cfg.dataDir} -Dffmpeg.location=${pkgs.ffmpeg}/bin/ffmpeg -Ddcraw.location=${pkgs.dcraw}/bin/dcraw" + + # Execute the JVM in the foreground + exec ${pkgs.jre}/bin/java -Xmx512M -Xms20M -XX:+UseG1GC -XX:GCTimeRatio=1 -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 $JAVA_OPTS -classpath "$SERVIIO_CLASS_PATH" org.serviio.MediaServer "$@" + ''; + +in { + + ###### interface + options = { + services.serviio = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the Serviio Media Server. + ''; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/serviio"; + description = '' + The directory where serviio stores its state, data, etc. + ''; + }; + + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + systemd.services.serviio = { + description = "Serviio Media Server"; + after = [ "local-fs.target" "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.serviio ]; + serviceConfig = { + User = "serviio"; + Group = "serviio"; + ExecStart = "${serviioStart}"; + ExecStop = "${serviioStart} -stop"; + }; + }; + + users.extraUsers = [ + { + name = "serviio"; + group = "serviio"; + home = cfg.dataDir; + description = "Serviio Media Server User"; + createHome = true; + isSystemUser = true; + } + ]; + + users.extraGroups = [ + { name = "serviio";} + ]; + + networking.firewall = { + allowedTCPPorts = [ + 8895 # serve UPnP responses + 23423 # console + 23424 # mediabrowser + ]; + allowedUDPPorts = [ + 1900 # UPnP service discovey + ]; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/blackbox-exporter.nix b/nixos/modules/services/monitoring/prometheus/blackbox-exporter.nix deleted file mode 100644 index ce2e1cf2d74..00000000000 --- a/nixos/modules/services/monitoring/prometheus/blackbox-exporter.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.blackboxExporter; -in { - options = { - services.prometheus.blackboxExporter = { - enable = mkEnableOption "prometheus blackbox exporter"; - - configFile = mkOption { - type = types.path; - description = '' - Path to configuration file. - ''; - }; - - port = mkOption { - type = types.int; - default = 9115; - description = '' - Port to listen on. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the blackbox exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-blackbox-exporter = { - description = "Prometheus exporter for blackbox probes"; - unitConfig.Documentation = "https://github.com/prometheus/blackbox_exporter"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - AmbientCapabilities = [ "CAP_NET_RAW" ]; # for ping probes - ExecStart = '' - ${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \ - --web.listen-address :${toString cfg.port} \ - --config.file ${cfg.configFile} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/collectd-exporter.nix b/nixos/modules/services/monitoring/prometheus/collectd-exporter.nix deleted file mode 100644 index f8a5b9576a1..00000000000 --- a/nixos/modules/services/monitoring/prometheus/collectd-exporter.nix +++ /dev/null @@ -1,128 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.collectdExporter; - - collectSettingsArgs = if (cfg.collectdBinary.enable) then '' - -collectd.listen-address ${optionalString (cfg.collectdBinary.listenAddress != null) cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \ - -collectd.security-level ${cfg.collectdBinary.securityLevel} \ - '' else ""; - -in { - options = { - services.prometheus.collectdExporter = { - enable = mkEnableOption "prometheus collectd exporter"; - - port = mkOption { - type = types.int; - default = 9103; - description = '' - Port to listen on. - This is used for scraping as well as the to receive collectd data via the write_http plugin. - ''; - }; - - listenAddress = mkOption { - type = types.nullOr types.str; - default = null; - example = "0.0.0.0"; - description = '' - Address to listen on for web interface, telemetry and collectd JSON data. - ''; - }; - - collectdBinary = { - enable = mkEnableOption "collectd binary protocol receiver"; - - authFile = mkOption { - default = null; - type = types.nullOr types.path; - description = "File mapping user names to pre-shared keys (passwords)."; - }; - - port = mkOption { - type = types.int; - default = 25826; - description = ''Network address on which to accept collectd binary network packets.''; - }; - - listenAddress = mkOption { - type = types.nullOr types.str; - default = null; - example = "0.0.0.0"; - description = '' - Address to listen on for binary network packets. - ''; - }; - - securityLevel = mkOption { - type = types.enum ["None" "Sign" "Encrypt"]; - default = "None"; - description = '' - Minimum required security level for accepted packets. - ''; - }; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the collectd exporter. - ''; - }; - - logFormat = mkOption { - type = types.str; - default = "logger:stderr"; - example = "logger:syslog?appname=bob&local=7 or logger:stdout?json=true"; - description = '' - Set the log target and format. - ''; - }; - - logLevel = mkOption { - type = types.enum ["debug" "info" "warn" "error" "fatal"]; - default = "info"; - description = '' - Only log messages with the given severity or above. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = (optional cfg.openFirewall cfg.port) ++ - (optional (cfg.openFirewall && cfg.collectdBinary.enable) cfg.collectdBinary.port); - - systemd.services.prometheus-collectd-exporter = { - description = "Prometheus exporter for Collectd metrics"; - unitConfig.Documentation = "https://github.com/prometheus/collectd_exporter"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - DynamicUser = true; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecStart = '' - ${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \ - -log.format ${cfg.logFormat} \ - -log.level ${cfg.logLevel} \ - -web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \ - ${collectSettingsArgs} \ - ${concatStringsSep " " cfg.extraFlags} - ''; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/exporters.nix b/nixos/modules/services/monitoring/prometheus/exporters.nix new file mode 100644 index 00000000000..8d6ca1e40a1 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters.nix @@ -0,0 +1,172 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.prometheus.exporters; + + # each attribute in `exporterOpts` is expected to have specified: + # - port (types.int): port on which the exporter listens + # - serviceOpts (types.attrs): config that is merged with the + # default definition of the exporter's + # systemd service + # - extraOpts (types.attrs): extra configuration options to + # configure the exporter with, which + # are appended to the default options + # + # Note that `extraOpts` is optional, but a script for the exporter's + # systemd service must be provided by specifying either + # `serviceOpts.script` or `serviceOpts.serviceConfig.ExecStart` + exporterOpts = { + blackbox = import ./exporters/blackbox.nix { inherit config lib pkgs; }; + collectd = import ./exporters/collectd.nix { inherit config lib pkgs; }; + fritzbox = import ./exporters/fritzbox.nix { inherit config lib pkgs; }; + json = import ./exporters/json.nix { inherit config lib pkgs; }; + minio = import ./exporters/minio.nix { inherit config lib pkgs; }; + nginx = import ./exporters/nginx.nix { inherit config lib pkgs; }; + node = import ./exporters/node.nix { inherit config lib pkgs; }; + postfix = import ./exporters/postfix.nix { inherit config lib pkgs; }; + snmp = import ./exporters/snmp.nix { inherit config lib pkgs; }; + unifi = import ./exporters/unifi.nix { inherit config lib pkgs; }; + varnish = import ./exporters/varnish.nix { inherit config lib pkgs; }; + }; + + mkExporterOpts = ({ name, port }: { + enable = mkEnableOption "the prometheus ${name} exporter"; + port = mkOption { + type = types.int; + default = port; + description = '' + Port to listen on. + ''; + }; + listenAddress = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + Address to listen on. + ''; + }; + extraFlags = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Extra commandline options to pass to the ${name} exporter. + ''; + }; + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open port in firewall for incoming connections. + ''; + }; + firewallFilter = mkOption { + type = types.str; + default = "-p tcp -m tcp --dport ${toString port}"; + example = literalExample '' + "-i eth0 -p tcp -m tcp --dport ${toString port}" + ''; + description = '' + Specify a filter for iptables to use when + <option>services.prometheus.exporters.${name}.openFirewall</option> + is true. It is used as `ip46tables -I INPUT <option>firewallFilter</option> -j ACCEPT`. + ''; + }; + user = mkOption { + type = types.str; + default = "nobody"; + description = '' + User name under which the ${name} exporter shall be run. + Has no effect when <option>systemd.services.prometheus-${name}-exporter.serviceConfig.DynamicUser</option> is true. + ''; + }; + group = mkOption { + type = types.str; + default = "nobody"; + description = '' + Group under which the ${name} exporter shall be run. + Has no effect when <option>systemd.services.prometheus-${name}-exporter.serviceConfig.DynamicUser</option> is true. + ''; + }; + }); + + mkSubModule = { name, port, extraOpts, serviceOpts }: { + ${name} = mkOption { + type = types.submodule { + options = (mkExporterOpts { + inherit name port; + } // extraOpts); + }; + internal = true; + default = {}; + }; + }; + + mkSubModules = (foldl' (a: b: a//b) {} + (mapAttrsToList (name: opts: mkSubModule { + inherit name; + inherit (opts) port serviceOpts; + extraOpts = opts.extraOpts or {}; + }) exporterOpts) + ); + + mkExporterConf = { name, conf, serviceOpts }: + mkIf conf.enable { + networking.firewall.extraCommands = mkIf conf.openFirewall '' + ip46tables -I INPUT ${conf.firewallFilter} -j ACCEPT + ''; + systemd.services."prometheus-${name}-exporter" = mkMerge ([{ + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + Restart = mkDefault "always"; + PrivateTmp = mkDefault true; + WorkingDirectory = mkDefault /tmp; + } // mkIf (!(serviceOpts.serviceConfig.DynamicUser or false)) { + User = conf.user; + Group = conf.group; + }; + } serviceOpts ]); + }; +in +{ + options.services.prometheus.exporters = mkOption { + type = types.submodule { + options = (mkSubModules); + }; + description = "Prometheus exporter configuration"; + default = {}; + example = literalExample '' + { + node = { + enable = true; + enabledCollectors = [ "systemd" ]; + }; + varnish.enable = true; + } + ''; + }; + + config = mkMerge ([{ + assertions = [{ + assertion = (cfg.snmp.configurationPath == null) != (cfg.snmp.configuration == null); + message = '' + Please ensure you have either `services.prometheus.exporters.snmp.configuration' + or `services.prometheus.exporters.snmp.configurationPath' set! + ''; + }]; + }] ++ [(mkIf config.services.minio.enable { + services.prometheus.exporters.minio.minioAddress = mkDefault "http://localhost:9000"; + services.prometheus.exporters.minio.minioAccessKey = mkDefault config.services.minio.accessKey; + services.prometheus.exporters.minio.minioAccessSecret = mkDefault config.services.minio.secretKey; + })] ++ (mapAttrsToList (name: conf: + mkExporterConf { + inherit name; + inherit (conf) serviceOpts; + conf = cfg.${name}; + }) exporterOpts) + ); + + meta.doc = ./exporters.xml; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters.xml b/nixos/modules/services/monitoring/prometheus/exporters.xml new file mode 100644 index 00000000000..4f0bcb29810 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters.xml @@ -0,0 +1,135 @@ +<chapter xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:xi="http://www.w3.org/2001/XInclude" + version="5.0" + xml:id="module-services-prometheus-exporters"> + +<title>Prometheus exporters</title> + +<para>Prometheus exporters provide metrics for the <link xlink:href="https://prometheus.io">prometheus monitoring system</link>.</para> + +<section><title>Configuration</title> + <para>One of the most common exporters is the <link xlink:href="https://github.com/prometheus/node_exporter">node exporter</link>, it provides hardware and OS metrics from the host it's running on. The exporter could be configured as follows: +<programlisting> + services.promtheus.exporters.node = { + enable = true; + enabledCollectors = [ + "logind" + "systemd" + ]; + disabledCollectors = [ + "textfile" + ]; + openFirewall = true; + firewallFilter = "-i br0 -p tcp -m tcp --dport 9100"; + }; +</programlisting> +It should now serve all metrics from the collectors +that are explicitly enabled and the ones that are +<link xlink:href="https://github.com/prometheus/node_exporter#enabled-by-default">enabled by default</link>, via http under <literal>/metrics</literal>. In this example the firewall should just +allow incoming connections to the exporter's port on the bridge interface <literal>br0</literal> +(this would have to be configured seperately of course). +For more information about configuration see <literal>man configuration.nix</literal> or +search through the <link xlink:href="https://nixos.org/nixos/options.html#prometheus.exporters">available options</link>. +</para> +</section> +<section><title>Adding a new exporter</title> + <para>To add a new exporter, it has to be packaged first (see <literal>nixpkgs/pkgs/servers/monitoring/prometheus/</literal> for examples), then a module can be added. The postfix exporter is used in this example:</para> +<itemizedlist> + <listitem> + <para> + Some default options for all exporters are provided by + <literal>nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix</literal>: + </para> + </listitem> + <listitem override='none'> + <itemizedlist> + <listitem><para><literal>enable</literal></para></listitem> + <listitem><para><literal>port</literal></para></listitem> + <listitem><para><literal>listenAddress</literal></para></listitem> + <listitem><para><literal>extraFlags</literal></para></listitem> + <listitem><para><literal>openFirewall</literal></para></listitem> + <listitem><para><literal>firewallFilter</literal></para></listitem> + <listitem><para><literal>user</literal></para></listitem> + <listitem><para><literal>group</literal></para></listitem> + </itemizedlist> + </listitem> + <listitem> + <para>As there is already a package available, the module can now be added. + This is accomplished by adding a new file to the + <literal>nixos/modules/services/monitoring/prometheus/exporters/</literal> directory, + which will be called postfix.nix and contains all exporter specific options + and configuration: + <programlisting> + # nixpgs/nixos/modules/services/prometheus/exporters/postfix.nix + { config, lib, pkgs }: + + with lib; + + let + # for convenience we define cfg here + cfg = config.services.prometheus.exporters.postfix; + in + { + port = 9154; # The postfix exporter listens on this port by default + + # `extraOpts` is an attribute set which contains additional options + # (and optional overrides for default options). + # Note that this attribute is optional. + extraOpts = { + telemetryPath = mkOption { + type = types.str; + default = "/metrics"; + description = '' + Path under which to expose metrics. + ''; + }; + logfilePath = mkOption { + type = types.path; + default = /var/log/postfix_exporter_input.log; + example = /var/log/mail.log; + description = '' + Path where Postfix writes log entries. + This file will be truncated by this exporter! + ''; + }; + showqPath = mkOption { + type = types.path; + default = /var/spool/postfix/public/showq; + example = /var/lib/postfix/queue/public/showq; + description = '' + Path at which Postfix places its showq socket. + ''; + }; + }; + + # `serviceOpts` is an attribute set which contains configuration + # for the exporter's systemd service. One of + # `serviceOpts.script` and `serviceOpts.serviceConfig.ExecStart` + # has to be specified here. This will be merged with the default + # service confiuration. + serviceOpts = { + serviceConfig = { + ExecStart = '' + ${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \ + --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + --web.telemetry-path ${cfg.telemetryPath} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; + } + </programlisting> + </para> + </listitem> + <listitem> + <para> + This should already be enough for the postfix exporter. Additionally one could + now add assertions and conditional default values. This can be done in the + 'meta-module' that combines all exporter definitions and generates the submodules: + <literal>nixpkgs/nixos/modules/services/prometheus/exporters.nix</literal> + </para> + </listitem> +</itemizedlist> +</section> +</chapter> diff --git a/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix b/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix new file mode 100644 index 00000000000..d09d1c4f366 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.blackbox; +in +{ + port = 9115; + extraOpts = { + configFile = mkOption { + type = types.path; + description = '' + Path to configuration file. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + AmbientCapabilities = [ "CAP_NET_RAW" ]; # for ping probes + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-blackbox-exporter}/bin/blackbox_exporter \ + --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + --config.file ${cfg.configFile} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix b/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix new file mode 100644 index 00000000000..0eba3527162 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix @@ -0,0 +1,78 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.collectd; +in +{ + port = 9103; + extraOpts = { + collectdBinary = { + enable = mkEnableOption "collectd binary protocol receiver"; + + authFile = mkOption { + default = null; + type = types.nullOr types.path; + description = "File mapping user names to pre-shared keys (passwords)."; + }; + + port = mkOption { + type = types.int; + default = 25826; + description = ''Network address on which to accept collectd binary network packets.''; + }; + + listenAddress = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + Address to listen on for binary network packets. + ''; + }; + + securityLevel = mkOption { + type = types.enum ["None" "Sign" "Encrypt"]; + default = "None"; + description = '' + Minimum required security level for accepted packets. + ''; + }; + }; + + logFormat = mkOption { + type = types.str; + default = "logger:stderr"; + example = "logger:syslog?appname=bob&local=7 or logger:stdout?json=true"; + description = '' + Set the log target and format. + ''; + }; + + logLevel = mkOption { + type = types.enum ["debug" "info" "warn" "error" "fatal"]; + default = "info"; + description = '' + Only log messages with the given severity or above. + ''; + }; + }; + serviceOpts = let + collectSettingsArgs = if (cfg.collectdBinary.enable) then '' + -collectd.listen-address ${cfg.collectdBinary.listenAddress}:${toString cfg.collectdBinary.port} \ + -collectd.security-level ${cfg.collectdBinary.securityLevel} \ + '' else ""; + in { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-collectd-exporter}/bin/collectd_exporter \ + -log.format ${cfg.logFormat} \ + -log.level ${cfg.logLevel} \ + -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + ${collectSettingsArgs} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix b/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix new file mode 100644 index 00000000000..a3f1d9d3132 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.fritzbox; +in +{ + port = 9133; + extraOpts = { + gatewayAddress = mkOption { + type = types.str; + default = "fritz.box"; + description = '' + The hostname or IP of the FRITZ!Box. + ''; + }; + + gatewayPort = mkOption { + type = types.int; + default = 49000; + description = '' + The port of the FRITZ!Box UPnP service. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \ + -listen-address ${cfg.listenAddress}:${toString cfg.port} \ + -gateway-address ${cfg.gatewayAddress} \ + -gateway-port ${toString cfg.gatewayPort} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/json.nix b/nixos/modules/services/monitoring/prometheus/exporters/json.nix new file mode 100644 index 00000000000..a5494e85e01 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/json.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.json; +in +{ + port = 7979; + extraOpts = { + url = mkOption { + type = types.str; + description = '' + URL to scrape JSON from. + ''; + }; + configFile = mkOption { + type = types.path; + description = '' + Path to configuration file. + ''; + }; + listenAddress = {}; # not used + }; + serviceOpts = { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-json-exporter}/bin/prometheus-json-exporter \ + --port ${toString cfg.port} \ + ${cfg.url} ${cfg.configFile} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/minio.nix b/nixos/modules/services/monitoring/prometheus/exporters/minio.nix new file mode 100644 index 00000000000..3cc4ffdbc8f --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/minio.nix @@ -0,0 +1,65 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.minio; +in +{ + port = 9290; + extraOpts = { + minioAddress = mkOption { + type = types.str; + example = "https://10.0.0.1:9000"; + description = '' + The URL of the minio server. + Use HTTPS if Minio accepts secure connections only. + By default this connects to the local minio server if enabled. + ''; + }; + + minioAccessKey = mkOption { + type = types.str; + example = "yourMinioAccessKey"; + description = '' + The value of the Minio access key. + It is required in order to connect to the server. + By default this uses the one from the local minio server if enabled + and <literal>config.services.minio.accessKey</literal>. + ''; + }; + + minioAccessSecret = mkOption { + type = types.str; + description = '' + The value of the Minio access secret. + It is required in order to connect to the server. + By default this uses the one from the local minio server if enabled + and <literal>config.services.minio.secretKey</literal>. + ''; + }; + + minioBucketStats = mkOption { + type = types.bool; + default = false; + description = '' + Collect statistics about the buckets and files in buckets. + It requires more computation, use it carefully in case of large buckets.. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-minio-exporter}/bin/minio-exporter \ + -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + -minio.server ${cfg.minioAddress} \ + -minio.access-key ${cfg.minioAccessKey} \ + -minio.access-secret ${cfg.minioAccessSecret} \ + ${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix b/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix new file mode 100644 index 00000000000..6a3ba2d0457 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.nginx; +in +{ + port = 9113; + extraOpts = { + scrapeUri = mkOption { + type = types.string; + default = "http://localhost/nginx_status"; + description = '' + Address to access the nginx status page. + Can be enabled with services.nginx.statusPage = true. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-nginx-exporter}/bin/nginx_exporter \ + -nginx.scrape_uri '${cfg.scrapeUri}' \ + -telemetry.address ${cfg.listenAddress}:${toString cfg.port} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/node.nix b/nixos/modules/services/monitoring/prometheus/exporters/node.nix new file mode 100644 index 00000000000..c85f5f9cfb2 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/node.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.node; +in +{ + port = 9100; + extraOpts = { + enabledCollectors = mkOption { + type = types.listOf types.string; + default = []; + example = ''[ "systemd" ]''; + description = '' + Collectors to enable. The collectors listed here are enabled in addition to the default ones. + ''; + }; + disabledCollectors = mkOption { + type = types.listOf types.str; + default = []; + example = ''[ "timex" ]''; + description = '' + Collectors to disable which are enabled by default. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + ExecStart = '' + ${pkgs.prometheus-node-exporter}/bin/node_exporter \ + ${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \ + ${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \ + --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix b/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix new file mode 100644 index 00000000000..1e909aa27d8 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.postfix; +in +{ + port = 9154; + extraOpts = { + telemetryPath = mkOption { + type = types.str; + default = "/metrics"; + description = '' + Path under which to expose metrics. + ''; + }; + logfilePath = mkOption { + type = types.path; + default = "/var/log/postfix_exporter_input.log"; + example = "/var/log/mail.log"; + description = '' + Path where Postfix writes log entries. + This file will be truncated by this exporter! + ''; + }; + showqPath = mkOption { + type = types.path; + default = "/var/spool/postfix/public/showq"; + example = "/var/lib/postfix/queue/public/showq"; + description = '' + Path where Postfix places it's showq socket. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + ExecStart = '' + ${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \ + --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + --web.telemetry-path ${cfg.telemetryPath} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix new file mode 100644 index 00000000000..404cd0a1896 --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix @@ -0,0 +1,71 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.snmp; +in +{ + port = 9116; + extraOpts = { + configurationPath = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option. + ''; + example = "./snmp.yml"; + }; + + configuration = mkOption { + type = types.nullOr types.attrs; + default = {}; + description = '' + Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option. + ''; + example = '' + { + "default" = { + "version" = 2; + "auth" = { + "community" = "public"; + }; + }; + }; + ''; + }; + + logFormat = mkOption { + type = types.str; + default = "logger:stderr"; + description = '' + Set the log target and format. + ''; + }; + + logLevel = mkOption { + type = types.enum ["debug" "info" "warn" "error" "fatal"]; + default = "info"; + description = '' + Only log messages with the given severity or above. + ''; + }; + }; + serviceOpts = let + configFile = if cfg.configurationPath != null + then cfg.configurationPath + else "${pkgs.writeText "snmp-eporter-conf.yml" (builtins.toJSON cfg.configuration)}"; + in { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \ + -config.file ${configFile} \ + -log.format ${cfg.logFormat} \ + -log.level ${cfg.logLevel} \ + -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix b/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix new file mode 100644 index 00000000000..011dcbe208e --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.unifi; +in +{ + port = 9130; + extraOpts = { + unifiAddress = mkOption { + type = types.str; + example = "https://10.0.0.1:8443"; + description = '' + URL of the UniFi Controller API. + ''; + }; + + unifiInsecure = mkOption { + type = types.bool; + default = false; + description = '' + If enabled skip the verification of the TLS certificate of the UniFi Controller API. + Use with caution. + ''; + }; + + unifiUsername = mkOption { + type = types.str; + example = "ReadOnlyUser"; + description = '' + username for authentication against UniFi Controller API. + ''; + }; + + unifiPassword = mkOption { + type = types.str; + description = '' + Password for authentication against UniFi Controller API. + ''; + }; + + unifiTimeout = mkOption { + type = types.str; + default = "5s"; + example = "2m"; + description = '' + Timeout including unit for UniFi Controller API requests. + ''; + }; + }; + serviceOpts = { + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \ + -telemetry.addr ${cfg.listenAddress}:${toString cfg.port} \ + -unifi.addr ${cfg.unifiAddress} \ + -unifi.username ${cfg.unifiUsername} \ + -unifi.password ${cfg.unifiPassword} \ + -unifi.timeout ${cfg.unifiTimeout} \ + ${optionalString cfg.unifiInsecure "-unifi.insecure" } \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix b/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix new file mode 100644 index 00000000000..b439a83e7aa --- /dev/null +++ b/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix @@ -0,0 +1,21 @@ +{ config, lib, pkgs }: + +with lib; + +let + cfg = config.services.prometheus.exporters.varnish; +in +{ + port = 9131; + serviceOpts = { + path = [ pkgs.varnish ]; + serviceConfig = { + DynamicUser = true; + ExecStart = '' + ${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \ + -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ + ${concatStringsSep " \\\n " cfg.extraFlags} + ''; + }; + }; +} diff --git a/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix b/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix deleted file mode 100644 index 6da39b6519c..00000000000 --- a/nixos/modules/services/monitoring/prometheus/fritzbox-exporter.nix +++ /dev/null @@ -1,76 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.fritzboxExporter; -in { - options = { - services.prometheus.fritzboxExporter = { - enable = mkEnableOption "prometheus fritzbox exporter"; - - port = mkOption { - type = types.int; - default = 9133; - description = '' - Port to listen on. - ''; - }; - - gatewayAddress = mkOption { - type = types.str; - default = "fritz.box"; - description = '' - The hostname or IP of the FRITZ!Box. - ''; - }; - - gatewayPort = mkOption { - type = types.int; - default = 49000; - description = '' - The port of the FRITZ!Box UPnP service. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the fritzbox exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-fritzbox-exporter = { - description = "Prometheus exporter for FRITZ!Box via UPnP"; - unitConfig.Documentation = "https://github.com/ndecker/fritzbox_exporter"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecStart = '' - ${pkgs.prometheus-fritzbox-exporter}/bin/fritzbox_exporter \ - -listen-address :${toString cfg.port} \ - -gateway-address ${cfg.gatewayAddress} \ - -gateway-port ${toString cfg.gatewayPort} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/json-exporter.nix b/nixos/modules/services/monitoring/prometheus/json-exporter.nix deleted file mode 100644 index 6bc56df9834..00000000000 --- a/nixos/modules/services/monitoring/prometheus/json-exporter.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.jsonExporter; -in { - options = { - services.prometheus.jsonExporter = { - enable = mkEnableOption "prometheus JSON exporter"; - - url = mkOption { - type = types.str; - description = '' - URL to scrape JSON from. - ''; - }; - - configFile = mkOption { - type = types.path; - description = '' - Path to configuration file. - ''; - }; - - port = mkOption { - type = types.int; - default = 7979; - description = '' - Port to listen on. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the JSON exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-json-exporter = { - description = "Prometheus exporter for JSON over HTTP"; - unitConfig.Documentation = "https://github.com/kawamuray/prometheus-json-exporter"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecStart = '' - ${pkgs.prometheus-json-exporter}/bin/prometheus-json-exporter \ - --port ${toString cfg.port} \ - ${cfg.url} ${cfg.configFile} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/minio-exporter.nix b/nixos/modules/services/monitoring/prometheus/minio-exporter.nix deleted file mode 100644 index 4314671523c..00000000000 --- a/nixos/modules/services/monitoring/prometheus/minio-exporter.nix +++ /dev/null @@ -1,117 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.minioExporter; -in { - options = { - services.prometheus.minioExporter = { - enable = mkEnableOption "prometheus minio exporter"; - - port = mkOption { - type = types.int; - default = 9290; - description = '' - Port to listen on. - ''; - }; - - listenAddress = mkOption { - type = types.nullOr types.str; - default = null; - example = "0.0.0.0"; - description = '' - Address to listen on for web interface and telemetry. - ''; - }; - - minioAddress = mkOption { - type = types.str; - example = "https://10.0.0.1:9000"; - default = if config.services.minio.enable then "http://localhost:9000" else null; - description = '' - The URL of the minio server. - Use HTTPS if Minio accepts secure connections only. - By default this connects to the local minio server if enabled. - ''; - }; - - minioAccessKey = mkOption ({ - type = types.str; - example = "BKIKJAA5BMMU2RHO6IBB"; - description = '' - The value of the Minio access key. - It is required in order to connect to the server. - By default this uses the one from the local minio server if enabled - and <literal>config.services.minio.accessKey</literal>. - ''; - } // optionalAttrs (config.services.minio.enable && config.services.minio.accessKey != "") { - default = config.services.minio.accessKey; - }); - - minioAccessSecret = mkOption ({ - type = types.str; - description = '' - The calue of the Minio access secret. - It is required in order to connect to the server. - By default this uses the one from the local minio server if enabled - and <literal>config.services.minio.secretKey</literal>. - ''; - } // optionalAttrs (config.services.minio.enable && config.services.minio.secretKey != "") { - default = config.services.minio.secretKey; - }); - - minioBucketStats = mkOption { - type = types.bool; - default = false; - description = '' - Collect statistics about the buckets and files in buckets. - It requires more computation, use it carefully in case of large buckets.. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the minio exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-minio-exporter = { - description = "Prometheus exporter for Minio server metrics"; - unitConfig.Documentation = "https://github.com/joe-pll/minio-exporter"; - wantedBy = [ "multi-user.target" ]; - after = optional config.services.minio.enable "minio.service"; - serviceConfig = { - DynamicUser = true; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecStart = '' - ${pkgs.prometheus-minio-exporter}/bin/minio-exporter \ - -web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} \ - -minio.server ${cfg.minioAddress} \ - -minio.access-key ${cfg.minioAccessKey} \ - -minio.access-secret ${cfg.minioAccessSecret} \ - ${optionalString cfg.minioBucketStats "-minio.bucket-stats"} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/nginx-exporter.nix b/nixos/modules/services/monitoring/prometheus/nginx-exporter.nix deleted file mode 100644 index 1ccafee3b18..00000000000 --- a/nixos/modules/services/monitoring/prometheus/nginx-exporter.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.nginxExporter; -in { - options = { - services.prometheus.nginxExporter = { - enable = mkEnableOption "prometheus nginx exporter"; - - port = mkOption { - type = types.int; - default = 9113; - description = '' - Port to listen on. - ''; - }; - - listenAddress = mkOption { - type = types.string; - default = "0.0.0.0"; - description = '' - Address to listen on. - ''; - }; - - scrapeUri = mkOption { - type = types.string; - default = "http://localhost/nginx_status"; - description = '' - Address to access the nginx status page. - Can be enabled with services.nginx.statusPage = true. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the nginx exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-nginx-exporter = { - after = [ "network.target" "nginx.service" ]; - description = "Prometheus exporter for nginx metrics"; - unitConfig.Documentation = "https://github.com/discordianfish/nginx_exporter"; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecStart = '' - ${pkgs.prometheus-nginx-exporter}/bin/nginx_exporter \ - -nginx.scrape_uri '${cfg.scrapeUri}' \ - -telemetry.address ${cfg.listenAddress}:${toString cfg.port} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/node-exporter.nix b/nixos/modules/services/monitoring/prometheus/node-exporter.nix deleted file mode 100644 index bad4389ce79..00000000000 --- a/nixos/modules/services/monitoring/prometheus/node-exporter.nix +++ /dev/null @@ -1,87 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.nodeExporter; -in { - options = { - services.prometheus.nodeExporter = { - enable = mkEnableOption "prometheus node exporter"; - - port = mkOption { - type = types.int; - default = 9100; - description = '' - Port to listen on. - ''; - }; - - listenAddress = mkOption { - type = types.string; - default = "0.0.0.0"; - description = '' - Address to listen on. - ''; - }; - - enabledCollectors = mkOption { - type = types.listOf types.string; - default = []; - example = ''[ "systemd" ]''; - description = '' - Collectors to enable. The collectors listed here are enabled in addition to the default ones. - ''; - }; - - disabledCollectors = mkOption { - type = types.listOf types.str; - default = []; - example = ''[ "timex" ]''; - description = '' - Collectors to disable which are enabled by default. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the node exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-node-exporter = { - description = "Prometheus exporter for machine metrics"; - unitConfig.Documentation = "https://github.com/prometheus/node_exporter"; - wantedBy = [ "multi-user.target" ]; - script = '' - exec ${pkgs.prometheus-node-exporter}/bin/node_exporter \ - ${concatMapStringsSep " " (x: "--collector." + x) cfg.enabledCollectors} \ - ${concatMapStringsSep " " (x: "--no-collector." + x) cfg.disabledCollectors} \ - --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/snmp-exporter.nix b/nixos/modules/services/monitoring/prometheus/snmp-exporter.nix deleted file mode 100644 index fe33f8c1f04..00000000000 --- a/nixos/modules/services/monitoring/prometheus/snmp-exporter.nix +++ /dev/null @@ -1,127 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.snmpExporter; - mkConfigFile = pkgs.writeText "snmp.yml" (if cfg.configurationPath == null then builtins.toJSON cfg.configuration else builtins.readFile cfg.configurationPath); -in { - options = { - services.prometheus.snmpExporter = { - enable = mkEnableOption "Prometheus snmp exporter"; - - user = mkOption { - type = types.str; - default = "nobody"; - description = '' - User name under which snmp exporter shall be run. - ''; - }; - - group = mkOption { - type = types.str; - default = "nogroup"; - description = '' - Group under which snmp exporter shall be run. - ''; - }; - - port = mkOption { - type = types.int; - default = 9116; - description = '' - Port to listen on. - ''; - }; - - listenAddress = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Address to listen on for web interface and telemetry. - ''; - }; - - configurationPath = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Path to a snmp exporter configuration file. Mutually exclusive with 'configuration' option. - ''; - example = "./snmp.yml"; - }; - - configuration = mkOption { - type = types.nullOr types.attrs; - default = {}; - description = '' - Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option. - ''; - example = '' - { - "default" = { - "version" = 2; - "auth" = { - "community" = "public"; - }; - }; - }; - ''; - }; - - logFormat = mkOption { - type = types.str; - default = "logger:stderr"; - description = '' - Set the log target and format. - ''; - }; - - logLevel = mkOption { - type = types.enum ["debug" "info" "warn" "error" "fatal"]; - default = "info"; - description = '' - Only log messages with the given severity or above. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - assertions = singleton - { - assertion = (cfg.configurationPath == null) != (cfg.configuration == null); - message = "Please ensure you have either 'configuration' or 'configurationPath' set!"; - }; - - systemd.services.prometheus-snmp-exporter = { - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - script = '' - ${pkgs.prometheus-snmp-exporter.bin}/bin/snmp_exporter \ - -config.file ${mkConfigFile} \ - -log.format ${cfg.logFormat} \ - -log.level ${cfg.logLevel} \ - -web.listen-address ${optionalString (cfg.listenAddress != null) cfg.listenAddress}:${toString cfg.port} - ''; - - serviceConfig = { - User = cfg.user; - Group = cfg.group; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = "/tmp"; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/unifi-exporter.nix b/nixos/modules/services/monitoring/prometheus/unifi-exporter.nix deleted file mode 100644 index 0a56d6ae95a..00000000000 --- a/nixos/modules/services/monitoring/prometheus/unifi-exporter.nix +++ /dev/null @@ -1,105 +0,0 @@ -{ config, pkgs, lib, ... }: - -with lib; - -let - cfg = config.services.prometheus.unifiExporter; -in { - options = { - services.prometheus.unifiExporter = { - enable = mkEnableOption "prometheus unifi exporter"; - - port = mkOption { - type = types.int; - default = 9130; - description = '' - Port to listen on. - ''; - }; - - unifiAddress = mkOption { - type = types.str; - example = "https://10.0.0.1:8443"; - description = '' - URL of the UniFi Controller API. - ''; - }; - - unifiInsecure = mkOption { - type = types.bool; - default = false; - description = '' - If enabled skip the verification of the TLS certificate of the UniFi Controller API. - Use with caution. - ''; - }; - - unifiUsername = mkOption { - type = types.str; - example = "ReadOnlyUser"; - description = '' - username for authentication against UniFi Controller API. - ''; - }; - - unifiPassword = mkOption { - type = types.str; - description = '' - Password for authentication against UniFi Controller API. - ''; - }; - - unifiTimeout = mkOption { - type = types.str; - default = "5s"; - example = "2m"; - description = '' - Timeout including unit for UniFi Controller API requests. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the unifi exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-unifi-exporter = { - description = "Prometheus exporter for UniFi Controller metrics"; - unitConfig.Documentation = "https://github.com/mdlayher/unifi_exporter"; - wantedBy = [ "multi-user.target" ]; - after = optional config.services.unifi.enable "unifi.service"; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecStart = '' - ${pkgs.prometheus-unifi-exporter}/bin/unifi_exporter \ - -telemetry.addr :${toString cfg.port} \ - -unifi.addr ${cfg.unifiAddress} \ - -unifi.username ${cfg.unifiUsername} \ - -unifi.password ${cfg.unifiPassword} \ - -unifi.timeout ${cfg.unifiTimeout} \ - ${optionalString cfg.unifiInsecure "-unifi.insecure" } \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - }; - }; - }; -} diff --git a/nixos/modules/services/monitoring/prometheus/varnish-exporter.nix b/nixos/modules/services/monitoring/prometheus/varnish-exporter.nix deleted file mode 100644 index 143ebb62aea..00000000000 --- a/nixos/modules/services/monitoring/prometheus/varnish-exporter.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ config, pkgs, lib, ... }: - -# Shamelessly cribbed from nginx-exporter.nix. ~ C. -with lib; - -let - cfg = config.services.prometheus.varnishExporter; -in { - options = { - services.prometheus.varnishExporter = { - enable = mkEnableOption "prometheus Varnish exporter"; - - port = mkOption { - type = types.int; - default = 9131; - description = '' - Port to listen on. - ''; - }; - - extraFlags = mkOption { - type = types.listOf types.str; - default = []; - description = '' - Extra commandline options when launching the Varnish exporter. - ''; - }; - - openFirewall = mkOption { - type = types.bool; - default = false; - description = '' - Open port in firewall for incoming connections. - ''; - }; - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.port; - - systemd.services.prometheus-varnish-exporter = { - description = "Prometheus exporter for Varnish metrics"; - unitConfig.Documentation = "https://github.com/jonnenauha/prometheus_varnish_exporter"; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.varnish ]; - script = '' - exec ${pkgs.prometheus-varnish-exporter}/bin/prometheus_varnish_exporter \ - -web.listen-address :${toString cfg.port} \ - ${concatStringsSep " \\\n " cfg.extraFlags} - ''; - serviceConfig = { - User = "nobody"; - Restart = "always"; - PrivateTmp = true; - WorkingDirectory = /tmp; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - }; - }; - }; -} diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index f83fb7a6d5d..10e96eb4036 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -135,8 +135,7 @@ in { default = { inherit networkmanager modemmanager wpa_supplicant networkmanager-openvpn networkmanager-vpnc networkmanager-openconnect networkmanager-fortisslvpn - networkmanager-pptp networkmanager-l2tp - networkmanager-iodine; }; + networkmanager-l2tp networkmanager-iodine; }; internal = true; }; @@ -267,8 +266,6 @@ in { message = "You can not use networking.networkmanager with networking.wireless"; }]; - boot.kernelModules = [ "ppp_mppe" ]; # Needed for most (all?) PPTP VPN connections. - environment.etc = with cfg.basePackages; [ { source = configFile; target = "NetworkManager/NetworkManager.conf"; @@ -285,9 +282,6 @@ in { { source = "${networkmanager-fortisslvpn}/etc/NetworkManager/VPN/nm-fortisslvpn-service.name"; target = "NetworkManager/VPN/nm-fortisslvpn-service.name"; } - { source = "${networkmanager-pptp}/etc/NetworkManager/VPN/nm-pptp-service.name"; - target = "NetworkManager/VPN/nm-pptp-service.name"; - } { source = "${networkmanager-l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name"; target = "NetworkManager/VPN/nm-l2tp-service.name"; } diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix index 9d7e6d6018a..d57ebb61f63 100644 --- a/nixos/modules/services/networking/prosody.nix +++ b/nixos/modules/services/networking/prosody.nix @@ -15,6 +15,7 @@ let description = "Path to the key file."; }; + # TODO: rename to certificate to match the prosody config cert = mkOption { type = types.path; description = "Path to the certificate file."; @@ -30,7 +31,7 @@ let }; moduleOpts = { - + # Generally required roster = mkOption { type = types.bool; default = true; @@ -61,12 +62,38 @@ let description = "Service discovery"; }; - legacyauth = mkOption { + # Not essential, but recommended + carbons = mkOption { type = types.bool; default = true; - description = "Legacy authentication. Only used by some old clients and bots"; + description = "Keep multiple clients in sync"; + }; + + pep = mkOption { + type = types.bool; + default = true; + description = "Enables users to publish their mood, activity, playing music and more"; + }; + + private = mkOption { + type = types.bool; + default = true; + description = "Private XML storage (for room bookmarks, etc.)"; + }; + + blocklist = mkOption { + type = types.bool; + default = true; + description = "Allow users to block communications with other users"; }; + vcard = mkOption { + type = types.bool; + default = true; + description = "Allow users to set vCards"; + }; + + # Nice to have version = mkOption { type = types.bool; default = true; @@ -91,36 +118,112 @@ let description = "Replies to XMPP pings with pongs"; }; - console = mkOption { + register = mkOption { + type = types.bool; + default = true; + description = "Allow users to register on this server using a client and change passwords"; + }; + + mam = mkOption { type = types.bool; default = false; - description = "telnet to port 5582"; + description = "Store messages in an archive and allow users to access it"; }; + # Admin interfaces + admin_adhoc = mkOption { + type = types.bool; + default = true; + description = "Allows administration via an XMPP client that supports ad-hoc commands"; + }; + + admin_telnet = mkOption { + type = types.bool; + default = false; + description = "Opens telnet console interface on localhost port 5582"; + }; + + # HTTP modules bosh = mkOption { type = types.bool; default = false; description = "Enable BOSH clients, aka 'Jabber over HTTP'"; }; - httpserver = mkOption { + websocket = mkOption { + type = types.bool; + default = false; + description = "Enable WebSocket support"; + }; + + http_files = mkOption { type = types.bool; default = false; description = "Serve static files from a directory over HTTP"; }; - websocket = mkOption { + # Other specific functionality + limits = mkOption { type = types.bool; default = false; - description = "Enable WebSocket support"; + description = "Enable bandwidth limiting for XMPP connections"; + }; + + groups = mkOption { + type = types.bool; + default = false; + description = "Shared roster support"; + }; + + server_contact_info = mkOption { + type = types.bool; + default = false; + description = "Publish contact information for this service"; + }; + + announce = mkOption { + type = types.bool; + default = false; + description = "Send announcement to all online users"; + }; + + welcome = mkOption { + type = types.bool; + default = false; + description = "Welcome users who register accounts"; + }; + + watchregistrations = mkOption { + type = types.bool; + default = false; + description = "Alert admins of registrations"; + }; + + motd = mkOption { + type = types.bool; + default = false; + description = "Send a message to users when they log in"; + }; + + legacyauth = mkOption { + type = types.bool; + default = false; + description = "Legacy authentication. Only used by some old clients and bots"; + }; + + proxy65 = mkOption { + type = types.bool; + default = false; + description = "Enables a file transfer proxy service which clients behind NAT can use"; }; }; toLua = x: if builtins.isString x then ''"${x}"'' - else if builtins.isBool x then toString x + else if builtins.isBool x then (if x == true then "true" else "false") else if builtins.isInt x then toString x + else if builtins.isList x then ''{ ${lib.concatStringsSep ", " (map (n: toLua n) x) } }'' else throw "Invalid Lua value"; createSSLOptsStr = o: '' @@ -198,6 +301,59 @@ in description = "Allow account creation"; }; + c2sRequireEncryption = mkOption { + type = types.bool; + default = true; + description = '' + Force clients to use encrypted connections? This option will + prevent clients from authenticating unless they are using encryption. + ''; + }; + + s2sRequireEncryption = mkOption { + type = types.bool; + default = true; + description = '' + Force servers to use encrypted connections? This option will + prevent servers from authenticating unless they are using encryption. + Note that this is different from authentication. + ''; + }; + + s2sSecureAuth = mkOption { + type = types.bool; + default = false; + description = '' + Force certificate authentication for server-to-server connections? + This provides ideal security, but requires servers you communicate + with to support encryption AND present valid, trusted certificates. + For more information see https://prosody.im/doc/s2s#security + ''; + }; + + s2sInsecureDomains = mkOption { + type = types.listOf types.str; + default = []; + example = [ "insecure.example.com" ]; + description = '' + Some servers have invalid or self-signed certificates. You can list + remote domains here that will not be required to authenticate using + certificates. They will be authenticated using DNS instead, even + when s2s_secure_auth is enabled. + ''; + }; + + s2sSecureDomains = mkOption { + type = types.listOf types.str; + default = []; + example = [ "jabber.org" ]; + description = '' + Even if you leave s2s_secure_auth disabled, you can still require valid + certificates for some domains by specifying a list here. + ''; + }; + + modules = moduleOpts; extraModules = mkOption { @@ -206,6 +362,12 @@ in description = "Enable custom modules"; }; + extraPluginPaths = mkOption { + type = types.listOf types.path; + default = []; + description = "Addtional path in which to look find plugins/modules"; + }; + virtualHosts = mkOption { description = "Define the virtual hosts"; @@ -255,37 +417,47 @@ in config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.prosody ]; + environment.systemPackages = [ cfg.package ]; environment.etc."prosody/prosody.cfg.lua".text = '' pidfile = "/var/lib/prosody/prosody.pid" - log = "*syslog" data_path = "/var/lib/prosody" - - allow_registration = ${boolToString cfg.allowRegistration}; - - ${ optionalString cfg.modules.console "console_enabled = true;" } + plugin_paths = { + ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.extraPluginPaths) } + } ${ optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl) } - admins = { ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.admins) } }; + admins = ${toLua cfg.admins} + + -- we already build with libevent, so we can just enable it for a more performant server + use_libevent = true modules_enabled = { ${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList - (name: val: optionalString val ''"${name}";'') + (name: val: optionalString val "${toLua name};") cfg.modules) } + ${ lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.package.communityModules)} + ${ lib.concatStringsSep "\n" (map (x: "${toLua x};") cfg.extraModules)} + }; - ${ optionalString cfg.allowRegistration "\"register\"\;" } + allow_registration = ${toLua cfg.allowRegistration} - ${ lib.concatStringsSep "\n" (map (x: "\"${x}\";") cfg.extraModules)} + c2s_require_encryption = ${toLua cfg.c2sRequireEncryption} + + s2s_require_encryption = ${toLua cfg.s2sRequireEncryption} + + s2s_secure_auth = ${toLua cfg.s2sSecureAuth} + + s2s_insecure_domains = ${toLua cfg.s2sInsecureDomains} + + s2s_secure_domains = ${toLua cfg.s2sSecureDomains} - "posix"; - }; ${ cfg.extraConfig } diff --git a/nixos/modules/services/security/hologram-server.nix b/nixos/modules/services/security/hologram-server.nix index bb56e2df09b..bad02c7440b 100644 --- a/nixos/modules/services/security/hologram-server.nix +++ b/nixos/modules/services/security/hologram-server.nix @@ -23,8 +23,9 @@ let account = cfg.awsAccount; defaultrole = cfg.awsDefaultRole; }; - stats = cfg.statsAddress; - listen = cfg.listenAddress; + stats = cfg.statsAddress; + listen = cfg.listenAddress; + cachetimeout = cfg.cacheTimeoutSeconds; }); in { options = { @@ -106,6 +107,12 @@ in { default = ""; description = "Address of statsd server"; }; + + cacheTimeoutSeconds = mkOption { + type = types.int; + default = 3600; + description = "How often (in seconds) to refresh the LDAP cache"; + }; }; }; diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix index fed91756e76..2c727de2102 100644 --- a/nixos/modules/services/security/tor.nix +++ b/nixos/modules/services/security/tor.nix @@ -5,6 +5,7 @@ with lib; let cfg = config.services.tor; torDirectory = "/var/lib/tor"; + torRunDirectory = "/run/tor"; opt = name: value: optionalString (value != null) "${name} ${value}"; optint = name: value: optionalString (value != null && value != 0) "${name} ${toString value}"; @@ -38,6 +39,7 @@ let ''} ${optint "ControlPort" cfg.controlPort} + ${optionalString cfg.controlSocket.enable "ControlSocket ${torRunDirectory}/control GroupWritable RelaxDirModeCheck"} '' # Client connection config + optionalString cfg.client.enable '' @@ -140,6 +142,17 @@ in ''; }; + controlSocket = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Wheter to enable Tor control socket. Control socket is created + in <literal>${torRunDirectory}/control</literal> + ''; + }; + }; + client = { enable = mkOption { type = types.bool; @@ -692,7 +705,7 @@ in # Translated from the upstream contrib/dist/tor.service.in preStart = '' - install -o tor -g tor -d ${torDirectory}/onion + install -o tor -g tor -d ${torDirectory}/onion ${torRunDirectory} ${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config ''; @@ -716,7 +729,7 @@ in DevicePolicy = "closed"; InaccessibleDirectories = "/home"; ReadOnlyDirectories = "/"; - ReadWriteDirectories = torDirectory; + ReadWriteDirectories = [torDirectory torRunDirectory]; NoNewPrivileges = "yes"; }; }; diff --git a/nixos/modules/services/web-apps/nixbot.nix b/nixos/modules/services/web-apps/nixbot.nix deleted file mode 100644 index 0592d01bf36..00000000000 --- a/nixos/modules/services/web-apps/nixbot.nix +++ /dev/null @@ -1,149 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.services.nixbot; - pyramidIni = '' - ### - # app configuration - # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html - ### - - [app:main] - use = egg:nixbot - - nixbot.github_token = ${cfg.githubToken} - nixbot.bot_name = ${cfg.botName} - nixbot.repo = ${cfg.repo} - nixbot.pr_repo = ${cfg.prRepo} - nixbot.hydra_jobsets_repo = ${cfg.hydraJobsetsRepo} - nixbot.github_secret = justnotsorandom - nixbot.public_url = ${cfg.publicUrl} - nixbot.repo_dir = ${cfg.repoDir} - - pyramid.reload_templates = false - pyramid.debug_authorization = false - pyramid.debug_notfound = false - pyramid.debug_routematch = false - pyramid.default_locale_name = en - - # By default, the toolbar only appears for clients from IP addresses - # '127.0.0.1' and '::1'. - # debugtoolbar.hosts = 127.0.0.1 ::1 - - ### - # wsgi server configuration - ### - - [server:main] - use = egg:waitress#main - host = 0.0.0.0 - port = 6543 - - ### - # logging configuration - # http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html - ### - - [loggers] - keys = root, nixbot - - [handlers] - keys = console - - [formatters] - keys = generic - - [logger_root] - level = INFO - handlers = console - - [logger_nixbot] - level = INFO - handlers = - qualname = nixbot - - [handler_console] - class = StreamHandler - args = (sys.stderr,) - level = NOTSET - formatter = generic - - [formatter_generic] - format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s - ''; -in { - options = { - services.nixbot = { - enable = mkEnableOption "nixbot"; - - botName = mkOption { - type = types.str; - description = "The bot's github user account name."; - default = "nixbot"; - }; - - githubToken = mkOption { - type = types.str; - description = "The bot's github user account token."; - example = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - }; - - repo = mkOption { - type = types.str; - description = "The github repository to check for PRs."; - example = "nixos/nixpkgs"; - }; - - prRepo = mkOption { - type = types.str; - description = "The github repository to push the testing branches to."; - example = "nixos/nixpkgs-pr"; - }; - - hydraJobsetsRepo = mkOption { - type = types.str; - description = "The github repository to push the hydra jobset definitions to."; - example = "nixos/hydra-jobsets"; - }; - - publicUrl = mkOption { - type = types.str; - description = "The public URL the bot is reachable at (Github hook endpoint)."; - example = "https://nixbot.nixos.org"; - }; - - repoDir = mkOption { - type = types.path; - description = "The directory the repositories are stored in."; - default = "/var/lib/nixbot"; - }; - }; - }; - - config = mkIf cfg.enable { - users.extraUsers.nixbot = { - createHome = true; - home = cfg.repoDir; - }; - - systemd.services.nixbot = let - env = pkgs.python3.buildEnv.override { - extraLibs = [ pkgs.nixbot ]; - }; - in { - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - script = '' - ${env}/bin/pserve ${pkgs.writeText "production.ini" pyramidIni} - ''; - - serviceConfig = { - User = "nixbot"; - Group = "nogroup"; - PermissionsStartOnly = true; - }; - }; - }; -} diff --git a/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix b/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix index 1d53ce65900..4bbd041b6e0 100644 --- a/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix +++ b/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix @@ -118,7 +118,7 @@ with lib; default = []; example = [ { urlPath = "/foo/bar.png"; - files = "/home/eelco/some-file.png"; + file = "/home/eelco/some-file.png"; } ]; description = '' diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 7256013d5d8..10e8ef0ed38 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -182,8 +182,7 @@ in { { inherit (pkgs) networkmanager modemmanager wpa_supplicant; inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc networkmanager-openconnect networkmanager-fortisslvpn - networkmanager-pptp networkmanager-iodine - networkmanager-l2tp; }; + networkmanager-iodine networkmanager-l2tp; }; # Needed for themes and backgrounds environment.pathsToLink = [ "/share" ]; diff --git a/nixos/modules/system/boot/kexec.nix b/nixos/modules/system/boot/kexec.nix index 14ebe66e632..3fc1af28f62 100644 --- a/nixos/modules/system/boot/kexec.nix +++ b/nixos/modules/system/boot/kexec.nix @@ -1,7 +1,7 @@ { config, pkgs, lib, ... }: { - config = lib.mkIf (pkgs.kexectools != null) { + config = lib.mkIf (pkgs.kexectools.meta.available) { environment.systemPackages = [ pkgs.kexectools ]; systemd.services."prepare-kexec" = diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 92c9ee0c469..b8a2d42e0fb 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -524,6 +524,14 @@ in ''; }; + systemd.enableCgroupAccounting = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable cgroup accounting. + ''; + }; + systemd.extraConfig = mkOption { default = ""; type = types.lines; @@ -725,6 +733,13 @@ in "systemd/system.conf".text = '' [Manager] + ${optionalString config.systemd.enableCgroupAccounting '' + DefaultCPUAccounting=yes + DefaultIOAccounting=yes + DefaultBlockIOAccounting=yes + DefaultMemoryAccounting=yes + DefaultTasksAccounting=yes + ''} ${config.systemd.extraConfig} ''; diff --git a/nixos/release.nix b/nixos/release.nix index 0b8d7318cd8..9b4aa4b0399 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -344,6 +344,7 @@ in rec { tests.predictable-interface-names = callSubTests tests/predictable-interface-names.nix {}; tests.printing = callTest tests/printing.nix {}; tests.prometheus = callTest tests/prometheus.nix {}; + tests.prosody = callTest tests/prosody.nix {}; tests.proxy = callTest tests/proxy.nix {}; # tests.quagga = callTest tests/quagga.nix {}; tests.quake3 = callTest tests/quake3.nix {}; diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index c12919540a3..acf248d0a5a 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -69,13 +69,20 @@ let let iface = if grubVersion == 1 then "ide" else "virtio"; isEfi = bootLoader == "systemd-boot" || (bootLoader == "grub" && grubUseEfi); + + # FIXME don't duplicate the -enable-kvm etc. flags here yet again! qemuFlags = (if system == "x86_64-linux" then "-m 768 " else "-m 512 ") + - (optionalString (system == "x86_64-linux") "-cpu kvm64 "); + (optionalString (system == "x86_64-linux") "-cpu kvm64 ") + + (optionalString (system == "aarch64-linux") "-enable-kvm -machine virt,gic-version=host -cpu host "); + hdFlags = ''hda => "vm-state-machine/machine.qcow2", hdaInterface => "${iface}", '' - + optionalString isEfi ''bios => "${pkgs.OVMF.fd}/FV/OVMF.fd", ''; - in - '' + + optionalString isEfi (if pkgs.stdenv.isAarch64 + then ''bios => "${pkgs.OVMF.fd}/FV/QEMU_EFI.fd", '' + else ''bios => "${pkgs.OVMF.fd}/FV/OVMF.fd", ''); + in if !isEfi && !(pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then + throw "Non-EFI boot methods are only supported on i686 / x86_64" + else '' $machine->start; # Make sure that we get a login prompt etc. diff --git a/nixos/tests/misc.nix b/nixos/tests/misc.nix index 4fd9466dc50..179c95e7643 100644 --- a/nixos/tests/misc.nix +++ b/nixos/tests/misc.nix @@ -96,7 +96,7 @@ import ./make-test.nix ({ pkgs, ...} : rec { $machine->succeed("systemctl start systemd-udev-settle.service"); subtest "udev-auto-load", sub { $machine->waitForUnit('systemd-udev-settle.service'); - $machine->succeed('lsmod | grep psmouse'); + $machine->succeed('lsmod | grep mousedev'); }; # Test whether systemd-tmpfiles-clean works. diff --git a/nixos/tests/openldap.nix b/nixos/tests/openldap.nix index 1178701c609..1bef867c57b 100644 --- a/nixos/tests/openldap.nix +++ b/nixos/tests/openldap.nix @@ -28,8 +28,8 @@ import ./make-test.nix { }; testScript = '' - $machine->succeed('systemctl status openldap.service'); $machine->waitForUnit('openldap.service'); + $machine->succeed('systemctl status openldap.service'); $machine->succeed('ldapsearch -LLL -D "cn=root,dc=example" -w notapassword -b "dc=example"'); ''; } diff --git a/nixos/tests/prosody.nix b/nixos/tests/prosody.nix new file mode 100644 index 00000000000..fcebfaf74e1 --- /dev/null +++ b/nixos/tests/prosody.nix @@ -0,0 +1,75 @@ +import ./make-test.nix { + name = "prosody"; + + machine = { config, pkgs, ... }: { + services.prosody = { + enable = true; + # TODO: use a self-signed certificate + c2sRequireEncryption = false; + }; + environment.systemPackages = let + sendMessage = pkgs.writeScriptBin "send-message" '' + #!/usr/bin/env python3 + # Based on the sleekxmpp send_client example, look there for more details: + # https://github.com/fritzy/SleekXMPP/blob/develop/examples/send_client.py + import sleekxmpp + + class SendMsgBot(sleekxmpp.ClientXMPP): + """ + A basic SleekXMPP bot that will log in, send a message, + and then log out. + """ + def __init__(self, jid, password, recipient, message): + sleekxmpp.ClientXMPP.__init__(self, jid, password) + + self.recipient = recipient + self.msg = message + + self.add_event_handler("session_start", self.start, threaded=True) + + def start(self, event): + self.send_presence() + self.get_roster() + + self.send_message(mto=self.recipient, + mbody=self.msg, + mtype='chat') + + self.disconnect(wait=True) + + + if __name__ == '__main__': + xmpp = SendMsgBot("test1@localhost", "test1", "test2@localhost", "Hello World!") + xmpp.register_plugin('xep_0030') # Service Discovery + xmpp.register_plugin('xep_0199') # XMPP Ping + + # TODO: verify certificate + # If you want to verify the SSL certificates offered by a server: + # xmpp.ca_certs = "path/to/ca/cert" + + if xmpp.connect(('localhost', 5222)): + xmpp.process(block=True) + else: + print("Unable to connect.") + sys.exit(1) + ''; + in [ (pkgs.python3.withPackages (ps: [ ps.sleekxmpp ])) sendMessage ]; + }; + + testScript = '' + $machine->waitForUnit('prosody.service'); + $machine->succeed('prosodyctl status') =~ /Prosody is running/; + + # set password to 'test' (it's asked twice) + $machine->succeed('yes test1 | prosodyctl adduser test1@localhost'); + # set password to 'y' + $machine->succeed('yes | prosodyctl adduser test2@localhost'); + # correct password to 'test2' + $machine->succeed('yes test2 | prosodyctl passwd test2@localhost'); + + $machine->succeed("send-message"); + + $machine->succeed('prosodyctl deluser test1@localhost'); + $machine->succeed('prosodyctl deluser test2@localhost'); + ''; +} |