diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 914f9a878b0..11bb900f7bb 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -691,6 +691,8 @@ ./services/networking/skydns.nix ./services/networking/shadowsocks.nix ./services/networking/shairport-sync.nix + ./services/networking/shorewall.nix + ./services/networking/shorewall6.nix ./services/networking/shout.nix ./services/networking/sniproxy.nix ./services/networking/smokeping.nix diff --git a/nixos/modules/services/monitoring/nagios.nix b/nixos/modules/services/monitoring/nagios.nix index 4128bc12030..94f378bebc3 100644 --- a/nixos/modules/services/monitoring/nagios.nix +++ b/nixos/modules/services/monitoring/nagios.nix @@ -17,32 +17,39 @@ let preferLocalBuild = true; } "mkdir -p $out; ln -s $nagiosObjectDefs $out/"; - nagiosCfgFile = pkgs.writeText "nagios.cfg" - '' - # Paths for state and logs. - log_file=${nagiosLogDir}/current - log_archive_path=${nagiosLogDir}/archive - status_file=${nagiosState}/status.dat - object_cache_file=${nagiosState}/objects.cache - temp_file=${nagiosState}/nagios.tmp - lock_file=/run/nagios.lock # Not used I think. - state_retention_file=${nagiosState}/retention.dat - query_socket=${nagiosState}/nagios.qh - check_result_path=${nagiosState} - command_file=${nagiosState}/nagios.cmd - - # Configuration files. - #resource_file=resource.cfg - cfg_dir=${nagiosObjectDefsDir} - - # Uid/gid that the daemon runs under. - nagios_user=nagios - nagios_group=nagios - - # Misc. options. - illegal_macro_output_chars=`~$&|'"<> - retain_state_information=1 - ''; # " + nagiosCfgFile = let + default = { + log_file="${nagiosLogDir}/current"; + log_archive_path="${nagiosLogDir}/archive"; + status_file="${nagiosState}/status.dat"; + object_cache_file="${nagiosState}/objects.cache"; + temp_file="${nagiosState}/nagios.tmp"; + lock_file="/run/nagios.lock"; + state_retention_file="${nagiosState}/retention.dat"; + query_socket="${nagiosState}/nagios.qh"; + check_result_path="${nagiosState}"; + command_file="${nagiosState}/nagios.cmd"; + cfg_dir="${nagiosObjectDefsDir}"; + nagios_user="nagios"; + nagios_group="nagios"; + illegal_macro_output_chars="`~$&|'\"<>"; + retain_state_information="1"; + }; + lines = mapAttrsToList (key: value: "${key}=${value}") (default // cfg.extraConfig); + content = concatStringsSep "\n" lines; + file = pkgs.writeText "nagios.cfg" content; + validated = pkgs.runCommand "nagios-checked.cfg" {preferLocalBuild=true;} '' + cp ${file} nagios.cfg + # nagios checks the existence of /var/lib/nagios, but + # it does not exists in the build sandbox, so we fake it + mkdir lib + lib=$(readlink -f lib) + sed -i s@=${nagiosState}@=$lib@ nagios.cfg + ${pkgs.nagios}/bin/nagios -v nagios.cfg && cp ${file} $out + ''; + defaultCfgFile = if cfg.validateConfig then validated else file; + in + if cfg.mainConfigFile == null then defaultCfgFile else cfg.mainConfigFile; # Plain configuration for the Nagios web-interface with no # authentication. @@ -77,16 +84,11 @@ in (mkRemovedOptionModule [ "services" "nagios" "urlPath" ] "The urlPath option has been removed as it is hard coded to /nagios in the nagios package.") ]; + meta.maintainers = with lib.maintainers; [ symphorien ]; + options = { services.nagios = { - enable = mkOption { - default = false; - description = " - Whether to use Nagios to monitor - your system or network. - "; - }; + enable = mkEnableOption "Nagios to monitor your system or network."; objectDefs = mkOption { description = " @@ -94,12 +96,14 @@ in the hosts, host groups, services and contacts for the network that you want Nagios to monitor. "; + type = types.listOf types.path; + example = literalExample "[ ./objects.cfg ]"; }; plugins = mkOption { type = types.listOf types.package; - default = [pkgs.nagiosPluginsOfficial pkgs.ssmtp]; - defaultText = "[pkgs.nagiosPluginsOfficial pkgs.ssmtp]"; + default = with pkgs; [ nagiosPluginsOfficial ssmtp mailutils ]; + defaultText = "[pkgs.nagiosPluginsOfficial pkgs.ssmtp pkgs.mailutils]"; description = " Packages to be added to the Nagios PATH. Typically used to add plugins, but can be anything. @@ -107,14 +111,29 @@ in }; mainConfigFile = mkOption { - type = types.package; - default = nagiosCfgFile; - defaultText = "nagiosCfgFile"; + type = types.nullOr types.package; + default = null; description = " - Derivation for the main configuration file of Nagios. + If non-null, overrides the main configuration file of Nagios. "; }; + extraConfig = mkOption { + type = types.attrsOf types.str; + example = { + debug_level = "-1"; + debug_file = "/var/log/nagios/debug.log"; + }; + default = {}; + description = "Configuration to add to /etc/nagios.cfg"; + }; + + validateConfig = mkOption { + type = types.bool; + default = pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform; + description = "if true, the syntax of the nagios configuration file is checked at build time"; + }; + cgiConfigFile = mkOption { type = types.package; default = nagiosCGICfgFile; @@ -126,6 +145,7 @@ in }; enableWebInterface = mkOption { + type = types.bool; default = false; description = " Whether to enable the Nagios web interface. You should also @@ -165,7 +185,7 @@ in # This isn't needed, it's just so that the user can type "nagiostats # -c /etc/nagios.cfg". environment.etc = [ - { source = cfg.mainConfigFile; + { source = nagiosCfgFile; target = "nagios.cfg"; } ]; @@ -173,7 +193,7 @@ in environment.systemPackages = [ pkgs.nagios ]; systemd.services.nagios = { description = "Nagios monitoring daemon"; - path = [ pkgs.nagios ]; + path = [ pkgs.nagios ] ++ cfg.plugins; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; @@ -184,14 +204,9 @@ in RestartSec = 2; LogsDirectory = "nagios"; StateDirectory = "nagios"; + ExecStart = "${pkgs.nagios}/bin/nagios /etc/nagios.cfg"; + X-ReloadIfChanged = nagiosCfgFile; }; - - script = '' - for i in ${toString cfg.plugins}; do - export PATH=$i/bin:$i/sbin:$i/libexec:$PATH - done - exec ${pkgs.nagios}/bin/nagios ${cfg.mainConfigFile} - ''; }; services.httpd.virtualHosts = optionalAttrs cfg.enableWebInterface { diff --git a/nixos/modules/services/networking/shorewall.nix b/nixos/modules/services/networking/shorewall.nix new file mode 100644 index 00000000000..0f94d414fcf --- /dev/null +++ b/nixos/modules/services/networking/shorewall.nix @@ -0,0 +1,75 @@ +{ config, lib, pkgs, ... }: +let + types = lib.types; + cfg = config.services.shorewall; +in { + options = { + services.shorewall = { + enable = lib.mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable Shorewall IPv4 Firewall. + + + Enabling this service WILL disable the existing NixOS + firewall! Default firewall rules provided by packages are not + considered at the moment. + + + ''; + }; + package = lib.mkOption { + type = types.package; + default = pkgs.shorewall; + defaultText = "pkgs.shorewall"; + description = "The shorewall package to use."; + }; + configs = lib.mkOption { + type = types.attrsOf types.str; + default = {}; + description = '' + This option defines the Shorewall configs. + The attribute name defines the name of the config, + and the attribute value defines the content of the config. + ''; + apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text); + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.firewall.enable = false; + systemd.services.shorewall = { + description = "Shorewall IPv4 Firewall"; + after = [ "ipset.target" ]; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + reloadIfChanged = true; + restartTriggers = lib.attrValues cfg.configs; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = "${cfg.package}/bin/shorewall start"; + ExecReload = "${cfg.package}/bin/shorewall reload"; + ExecStop = "${cfg.package}/bin/shorewall stop"; + }; + preStart = '' + install -D -d -m 750 /var/lib/shorewall + install -D -d -m 755 /var/lock/subsys + touch /var/log/shorewall.log + chown 750 /var/log/shorewall.log + ''; + }; + environment = { + etc = lib.mapAttrsToList + (name: file: + { source = file; + target = "shorewall/${name}"; + }) + cfg.configs; + systemPackages = [ cfg.package ]; + }; + }; +} diff --git a/nixos/modules/services/networking/shorewall6.nix b/nixos/modules/services/networking/shorewall6.nix new file mode 100644 index 00000000000..9c22a037c0b --- /dev/null +++ b/nixos/modules/services/networking/shorewall6.nix @@ -0,0 +1,75 @@ +{ config, lib, pkgs, ... }: +let + types = lib.types; + cfg = config.services.shorewall6; +in { + options = { + services.shorewall6 = { + enable = lib.mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable Shorewall IPv6 Firewall. + + + Enabling this service WILL disable the existing NixOS + firewall! Default firewall rules provided by packages are not + considered at the moment. + + + ''; + }; + package = lib.mkOption { + type = types.package; + default = pkgs.shorewall; + defaultText = "pkgs.shorewall"; + description = "The shorewall package to use."; + }; + configs = lib.mkOption { + type = types.attrsOf types.str; + default = {}; + description = '' + This option defines the Shorewall configs. + The attribute name defines the name of the config, + and the attribute value defines the content of the config. + ''; + apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text); + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.firewall.enable = false; + systemd.services.shorewall6 = { + description = "Shorewall IPv6 Firewall"; + after = [ "ipset.target" ]; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + reloadIfChanged = true; + restartTriggers = lib.attrValues cfg.configs; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = "${cfg.package}/bin/shorewall6 start"; + ExecReload = "${cfg.package}/bin/shorewall6 reload"; + ExecStop = "${cfg.package}/bin/shorewall6 stop"; + }; + preStart = '' + install -D -d -m 750 /var/lib/shorewall6 + install -D -d -m 755 /var/lock/subsys + touch /var/log/shorewall6.log + chown 750 /var/log/shorewall6.log + ''; + }; + environment = { + etc = lib.mapAttrsToList + (name: file: + { source = file; + target = "shorewall6/${name}"; + }) + cfg.configs; + systemPackages = [ cfg.package ]; + }; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 111643ad69c..0bbf0d9ab41 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -179,6 +179,7 @@ in mysql = handleTest ./mysql.nix {}; mysqlBackup = handleTest ./mysql-backup.nix {}; mysqlReplication = handleTest ./mysql-replication.nix {}; + nagios = handleTest ./nagios.nix {}; nat.firewall = handleTest ./nat.nix { withFirewall = true; }; nat.firewall-conntrack = handleTest ./nat.nix { withFirewall = true; withConntrackHelpers = true; }; nat.standalone = handleTest ./nat.nix { withFirewall = false; }; diff --git a/nixos/tests/nagios.nix b/nixos/tests/nagios.nix new file mode 100644 index 00000000000..6f5d4447287 --- /dev/null +++ b/nixos/tests/nagios.nix @@ -0,0 +1,116 @@ +import ./make-test-python.nix ( + { pkgs, ... }: { + name = "nagios"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ symphorien ]; + }; + + machine = { lib, ... }: let + writer = pkgs.writeShellScript "write" '' + set -x + echo "$@" >> /tmp/notifications + ''; + in + { + # tested service + services.sshd.enable = true; + # nagios + services.nagios = { + enable = true; + # make state transitions faster + extraConfig.interval_length = "5"; + objectDefs = + (map (x: "${pkgs.nagios}/etc/objects/${x}.cfg") [ "templates" "timeperiods" "commands" ]) ++ [ + ( + pkgs.writeText "objects.cfg" '' + # notifications are written to /tmp/notifications + define command { + command_name notify-host-by-file + command_line ${writer} "$HOSTNAME is $HOSTSTATE$" + } + define command { + command_name notify-service-by-file + command_line ${writer} "$SERVICEDESC$ is $SERVICESTATE$" + } + + # nagios boilerplate + define contact { + contact_name alice + alias alice + host_notifications_enabled 1 + service_notifications_enabled 1 + service_notification_period 24x7 + host_notification_period 24x7 + service_notification_options w,u,c,r,f,s + host_notification_options d,u,r,f,s + service_notification_commands notify-service-by-file + host_notification_commands notify-host-by-file + email foo@example.com + } + define contactgroup { + contactgroup_name admins + alias Admins + members alice + } + define hostgroup{ + hostgroup_name allhosts + alias All hosts + } + + # monitored objects + define host { + use generic-host + host_name localhost + alias localhost + address localhost + hostgroups allhosts + contact_groups admins + # make state transitions faster. + max_check_attempts 2 + check_interval 1 + retry_interval 1 + } + define service { + use generic-service + host_name localhost + service_description ssh + check_command check_ssh + # make state transitions faster. + max_check_attempts 2 + check_interval 1 + retry_interval 1 + } + '' + ) + ]; + }; + }; + + testScript = { ... }: '' + with subtest("ensure sshd starts"): + machine.wait_for_unit("sshd.service") + + + with subtest("ensure nagios starts"): + machine.wait_for_file("/var/log/nagios/current") + + + def assert_notify(text): + machine.wait_for_file("/tmp/notifications") + real = machine.succeed("cat /tmp/notifications").strip() + print(f"got {real!r}, expected {text!r}") + assert text == real + + + with subtest("ensure we get a notification when sshd is down"): + machine.succeed("systemctl stop sshd") + assert_notify("ssh is CRITICAL") + + + with subtest("ensure tests can succeed"): + machine.succeed("systemctl start sshd") + machine.succeed("rm /tmp/notifications") + assert_notify("ssh is OK") + ''; + } +) diff --git a/pkgs/applications/virtualization/bochs/default.nix b/pkgs/applications/virtualization/bochs/default.nix index 48ff2d3cf49..f6e202ac499 100644 --- a/pkgs/applications/virtualization/bochs/default.nix +++ b/pkgs/applications/virtualization/bochs/default.nix @@ -28,7 +28,7 @@ stdenv.mkDerivation rec { patches = [ ./bochs-2.6.10-glibc-2.26.patch ]; - buildInputs = with stdenv.lib; + buildInputs = [ pkgconfig libtool gtk2 libGLU libGL readline libX11 libXpm docbook_xml_dtd_45 docbook_xsl ] ++ optionals termSupport [ ncurses ] ++ optionals sdlSupport [ SDL2 ] @@ -118,7 +118,7 @@ stdenv.mkDerivation rec { in C++, that runs on most popular platforms. It includes emulation of the Intel x86 CPU, common I/O devices, and a custom BIOS. ''; - homepage = http://bochs.sourceforge.net/; + homepage = "http://bochs.sourceforge.net/"; license = licenses.lgpl2Plus; maintainers = with maintainers; [ AndersonTorres ]; platforms = platforms.unix; diff --git a/pkgs/development/tools/build-managers/gradle/default.nix b/pkgs/development/tools/build-managers/gradle/default.nix index 5e01438844c..a15eb275231 100644 --- a/pkgs/development/tools/build-managers/gradle/default.nix +++ b/pkgs/development/tools/build-managers/gradle/default.nix @@ -54,12 +54,12 @@ rec { gradle_latest = gradle_5_6; gradle_5_6 = gradleGen rec { - name = "gradle-5.6.1"; + name = "gradle-5.6.4"; nativeVersion = "0.18"; src = fetchurl { url = "http://services.gradle.org/distributions/${name}-bin.zip"; - sha256 = "04pccfcry5c59xwm6rr4r3baanwbfr5yrwhxv4r5v8z4414291h9"; + sha256 = "1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d"; }; }; diff --git a/pkgs/servers/monitoring/nagios/default.nix b/pkgs/servers/monitoring/nagios/default.nix index 8df30645725..006d91ef74e 100644 --- a/pkgs/servers/monitoring/nagios/default.nix +++ b/pkgs/servers/monitoring/nagios/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, perl, php, gd, libpng, zlib, unzip }: +{ stdenv, fetchurl, perl, php, gd, libpng, zlib, unzip, nixosTests }: stdenv.mkDerivation rec { pname = "nagios"; @@ -19,7 +19,17 @@ stdenv.mkDerivation rec { preInstall = '' substituteInPlace Makefile --replace '$(MAKE) install-basic' "" ''; - installTargets = [ "install" "install-config" ]; + installTargets = "install install-config"; + postInstall = '' + # don't make default files use hardcoded paths to commands + sed -i 's@command_line *[^ ]*/\([^/]*\) @command_line \1 @' $out/etc/objects/commands.cfg + sed -i 's@/usr/bin/@@g' $out/etc/objects/commands.cfg + sed -i 's@/bin/@@g' $out/etc/objects/commands.cfg + ''; + + passthru.tests = { + inherit (nixosTests) nagios; + }; meta = { description = "A host, service and network monitoring program"; diff --git a/pkgs/tools/networking/shorewall/default.nix b/pkgs/tools/networking/shorewall/default.nix new file mode 100644 index 00000000000..8e62aa735a4 --- /dev/null +++ b/pkgs/tools/networking/shorewall/default.nix @@ -0,0 +1,130 @@ +{ coreutils +, ebtables +, fetchurl +, gnugrep +, gnused +, iproute +, ipset +, iptables +, perl +, perlPackages +, stdenv +, tree +, utillinux +}: +let + PATH = stdenv.lib.concatStringsSep ":" + [ "${coreutils}/bin" + "${iproute}/bin" + "${iptables}/bin" + "${ipset}/bin" + "${ebtables}/bin" + "${utillinux}/bin" + "${gnugrep}/bin" + "${gnused}/bin" + ]; +in +stdenv.mkDerivation rec { + pname = "shorewall"; + version = "5.2.3.3"; + + srcs = [ + (fetchurl { + url = "http://www.shorewall.net/pub/shorewall/5.2/shorewall-5.2.3/shorewall-core-${version}.tar.bz2"; + sha256 = "1gg2yfxzm3y9qqjrrg5nq2ggi1c6yfxx0s7fvwjw70b185mwa5p5"; + }) + (fetchurl { + url = "http://www.shorewall.net/pub/shorewall/5.2/shorewall-5.2.3/shorewall-${version}.tar.bz2"; + sha256 = "1ka70pa3s0cnvc83rlm57r05cdv9idnxnq0vmxi6nr7razak5f3b"; + }) + (fetchurl { + url = "http://www.shorewall.net/pub/shorewall/5.2/shorewall-5.2.3/shorewall6-${version}.tar.bz2"; + sha256 = "0mhs4m6agwk082h1n69gnyfsjpycdd8215r4r9rzb3czs5xi087n"; + }) + ]; + sourceRoot = "."; + + buildInputs = [ + coreutils + iproute + ipset + iptables + ebtables + utillinux + gnugrep + gnused + perl + ] ++ (with perlPackages; [ + DigestSHA1 + ]); + prePatch = '' + # Patch configure and install.sh files + patchShebangs . + + # Remove hardcoded PATH + sed -i shorewall-core-${version}/lib.cli \ + -e '/^ *PATH=.*/d' + ''; + configurePhase = '' + shorewall-core-${version}/configure \ + HOST=linux \ + PREFIX=$out \ + CONFDIR=\$PREFIX/etc-example \ + SBINDIR=\$PREFIX/sbin \ + SYSCONFDIR= \ + SHAREDIR=\$PREFIX/share \ + LIBEXECDIR=\$SHAREDIR \ + PERLLIBDIR=\$SHAREDIR/shorewall \ + MANDIR=$out/man \ + VARLIB=/var/lib \ + INITSOURCE= \ + INITDIR= \ + INITFILE= \ + DEFAULT_PAGER= + ''; + installPhase = '' + export DESTDIR=/ + shorewall-core-${version}/install.sh + + ln -s ../shorewall-core-${version}/shorewallrc shorewall-${version}/ + shorewall-${version}/install.sh + + ln -s ../shorewall-core-${version}/shorewallrc shorewall6-${version}/ + shorewall6-${version}/install.sh + + # Patch the example shorewall{,6}.conf in case it is included + # in services.shorewall{,6}.configs + sed -i $out/etc-example/shorewall/shorewall.conf \ + $out/etc-example/shorewall6/shorewall6.conf \ + -e 's|^LOGFILE=.*|LOGFILE=/var/log/shorewall.log|' \ + -e 's|^PATH=.*|PATH=${PATH}|' \ + -e 's|^PERL=.*|PERL=${perl}/bin/perl|' \ + -e 's|^SHOREWALL_SHELL=.*|SHOREWALL_SHELL=${stdenv.shell}|' + sed -i $out/etc-example/shorewall6/shorewall6.conf \ + -e 's|^CONFIG_PATH=.*|CONFIG_PATH=:''${CONFDIR}/shorewall6:''${SHAREDIR}/shorewall6:''${SHAREDIR}/shorewall|' + # FIXME: the default GEOIPDIR=/usr/share/xt_geoip/LE may require attention. + + # Redirect CONFDIR to /etc where services.shorewall{,6}.configs + # will generate the config files. + sed -i $out/share/shorewall/shorewallrc \ + -e 's~^CONFDIR=.*~CONFDIR=/etc~' + ''; + + meta = { + homepage = http://www.shorewall.net/; + description = "An IP gateway/firewall configuration tool for GNU/Linux"; + longDescription = '' + Shorewall is a high-level tool for configuring Netfilter. You describe your + firewall/gateway requirements using entries in a set of configuration + files. Shorewall reads those configuration files and with the help of the + iptables, iptables-restore, ip and tc utilities, Shorewall configures + Netfilter and the Linux networking subsystem to match your requirements. + Shorewall can be used on a dedicated firewall system, a multi-function + gateway/router/server or on a standalone GNU/Linux system. Shorewall does + not use Netfilter's ipchains compatibility mode and can thus take + advantage of Netfilter's connection state tracking capabilities. + ''; + license = stdenv.lib.licenses.gpl2Plus; + platforms = stdenv.lib.platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 2194fcbc56c..8c19ab0e8d0 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6285,6 +6285,8 @@ in shocco = callPackage ../tools/text/shocco { }; + shorewall = callPackage ../tools/networking/shorewall { }; + shotwell = callPackage ../applications/graphics/shotwell { }; shout = nodePackages.shout;