From 33754edb3e7cae6e54d85bb01fa0b5e228b283cf Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Fri, 5 Oct 2012 21:39:56 -0700 Subject: [PATCH 01/43] - add a hostapd module --- modules/module-list.nix | 1 + modules/services/networking/hostapd.nix | 154 ++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 modules/services/networking/hostapd.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index e480ee9767e..0cca6a95544 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -129,6 +129,7 @@ ./services/networking/gnunet.nix ./services/networking/gogoclient.nix ./services/networking/gvpe.nix + ./services/networking/hostapd.nix ./services/networking/ifplugd.nix ./services/networking/ircd-hybrid/default.nix ./services/networking/nat.nix diff --git a/modules/services/networking/hostapd.nix b/modules/services/networking/hostapd.nix new file mode 100644 index 00000000000..712b1a6824c --- /dev/null +++ b/modules/services/networking/hostapd.nix @@ -0,0 +1,154 @@ +{ config, pkgs, ... }: + +# TODO: +# +# asserts +# ensure that the nl80211 module is loaded/compiled in the kernel +# hwMode must be a/b/g +# channel must be between 1 and 13 (maybe) +# wpa_supplicant and hostapd on the same wireless interface doesn't make any sense +# perhaps an assertion that there is a dhcp server and a dns server on the IP address serviced by the hostapd? + +with pkgs.lib; + +let + + cfg = config.services.hostapd; + + configFile = pkgs.writeText "hostapd.conf" + '' + interface=${cfg.interface} + driver=${cfg.driver} + ssid=${cfg.ssid} + hw_mode=${cfg.hwMode} + channel=${toString cfg.channel} + + # logging (debug level) + logger_syslog=-1 + logger_syslog_level=2 + logger_stdout=-1 + logger_stdout_level=2 + + ctrl_interface=/var/run/hostapd + ctrl_interface_group=${cfg.group} + + ${if cfg.wpa then '' + wpa=1 + wpa_passphrase=${cfg.wpaPassphrase} + '' else ""} + + ${cfg.extraCfg} + '' ; + +in + +{ + ###### interface + + options = { + + services.hostapd = { + + enable = mkOption { + default = false; + description = '' + enable putting a wireless interface into infrastructure mode, + allowing other wireless devices to associate with the wireless interface and do + wireless networking. A simple access point will enable hostapd.wpa, and + hostapd.wpa_passphrase, hostapd.ssid, dhcpd on the wireless interface to + provide IP addresses to the associated stations, and nat (from the wireless + interface to an upstream interface). + ''; + }; + + interface = mkOption { + default = ""; + example = "wlan0"; + description = '' + The interfaces hostapd will use. + ''; + }; + + driver = mkOption { + default = "nl80211"; + example = "hostapd"; + type = types.string; + description = "Which driver hostapd will use. Most things will probably use the default."; + }; + + ssid = mkOption { + default = "nixos"; + example = "mySpecialSSID"; + type = types.string; + description = "SSID to be used in IEEE 802.11 management frames."; + }; + + hwMode = mkOption { + default = "b"; + example = "g"; + type = types.string; + description = "Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g"; + }; + + channel = mkOption { + default = 7; + example = 11; + type = types.int; + description = + '' + Channel number (IEEE 802.11) + Please note that some drivers do not use this value from hostapd and the + channel will need to be configured separately with iwconfig. + ''; + }; + + group = mkOption { + default = "wheel"; + example = "network"; + type = types.string; + description = "members of this group can control hostapd"; + }; + + wpa = mkOption { + default = true; + description = "enable WPA (IEEE 802.11i/D3.0) to authenticate to the access point"; + }; + + wpaPassphrase = mkOption { + default = "my_sekret"; + example = "any_64_char_string"; + type = types.string; + description = "WPA-PSK (pre-shared-key) passphrase. Clients will need this passphrase to associate with this access point"; + }; + + extraCfg = mkOption { + default = ""; + example = '' + auth_algo=0 + ieee80211n=1 + ht_capab=[HT40-][SHORT-GI-40][DSSS_CCK-40] + ''; + type = types.string; + description = "Extra configuration options to put in the hostapd.conf"; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.hostapd ]; + + jobs.hostapd = + { startOn = "started network-interfaces"; + stopOn = "stopping network-interfaces"; + + script = + '' + exec ${pkgs.hostapd}/bin/hostapd ${configFile} + ''; + }; + }; +} From a24e4b4af20a0b95c13edfbf4b5705a27ff8f045 Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Fri, 5 Oct 2012 22:10:38 -0700 Subject: [PATCH 02/43] nat: enable NAT for multiple networks --- modules/services/networking/nat.nix | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/services/networking/nat.nix b/modules/services/networking/nat.nix index c51eeb54be7..ff6ff02f7e9 100644 --- a/modules/services/networking/nat.nix +++ b/modules/services/networking/nat.nix @@ -1,4 +1,6 @@ # This module enables Network Address Translation (NAT). +# XXX: todo: support multiple upstream links +# see http://yesican.chsoft.biz/lartc/MultihomedLinuxNetworking.html { config, pkgs, ... }: @@ -25,11 +27,11 @@ in }; networking.nat.internalIPs = mkOption { - example = "192.168.1.0/24"; + example = [ "192.168.1.0/24" ] ; description = '' - The IP address range for which to perform NAT. Packets - coming from these addresses and destined for the external + The IP address ranges for which to perform NAT. Packets + coming from these networks and destined for the external interface will be rewritten. ''; }; @@ -76,13 +78,17 @@ in '' iptables -t nat -F POSTROUTING iptables -t nat -X - + '' + + (concatMapStrings (network: + '' iptables -t nat -A POSTROUTING \ - -s ${cfg.internalIPs} -o ${cfg.externalInterface} \ + -s ${network} -o ${cfg.externalInterface} \ ${if cfg.externalIP == "" then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"} - + '' + ) cfg.internalIPs) + + '' echo 1 > /proc/sys/net/ipv4/ip_forward ''; @@ -91,7 +97,5 @@ in iptables -t nat -F POSTROUTING ''; }; - }; - } From be3e8124394e3c2a452e168fc3cb18411eb56ecd Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Fri, 5 Oct 2012 22:11:16 -0700 Subject: [PATCH 03/43] Wrong branch. Revert " nat: enable NAT for multiple networks" This reverts commit a24e4b4af20a0b95c13edfbf4b5705a27ff8f045. --- modules/services/networking/nat.nix | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/modules/services/networking/nat.nix b/modules/services/networking/nat.nix index ff6ff02f7e9..c51eeb54be7 100644 --- a/modules/services/networking/nat.nix +++ b/modules/services/networking/nat.nix @@ -1,6 +1,4 @@ # This module enables Network Address Translation (NAT). -# XXX: todo: support multiple upstream links -# see http://yesican.chsoft.biz/lartc/MultihomedLinuxNetworking.html { config, pkgs, ... }: @@ -27,11 +25,11 @@ in }; networking.nat.internalIPs = mkOption { - example = [ "192.168.1.0/24" ] ; + example = "192.168.1.0/24"; description = '' - The IP address ranges for which to perform NAT. Packets - coming from these networks and destined for the external + The IP address range for which to perform NAT. Packets + coming from these addresses and destined for the external interface will be rewritten. ''; }; @@ -78,17 +76,13 @@ in '' iptables -t nat -F POSTROUTING iptables -t nat -X - '' - + (concatMapStrings (network: - '' + iptables -t nat -A POSTROUTING \ - -s ${network} -o ${cfg.externalInterface} \ + -s ${cfg.internalIPs} -o ${cfg.externalInterface} \ ${if cfg.externalIP == "" then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"} - '' - ) cfg.internalIPs) + - '' + echo 1 > /proc/sys/net/ipv4/ip_forward ''; @@ -97,5 +91,7 @@ in iptables -t nat -F POSTROUTING ''; }; + }; + } From 87bb6b1c6dbfbe128b8181e5c55ffa7c36de4771 Mon Sep 17 00:00:00 2001 From: Marc Weber Date: Sun, 7 Oct 2012 17:24:42 +0200 Subject: [PATCH 04/43] making ati proprietary drivers work again However SLIM is still broken and you have to create a /usr/lib/dri/fglrx_dri.so symlink pointing to /run/opengl-driver/lib/fglrx_dri.so At least fgl_glxgears shows 10 times more frames per second now --- modules/services/x11/xserver.nix | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 97424308c27..1aa432afdfc 100644 --- a/modules/services/x11/xserver.nix +++ b/modules/services/x11/xserver.nix @@ -343,7 +343,8 @@ in optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions ++ optional (elem "ati_unfree" driverNames) kernelPackages.ati_drivers_x11; - environment.etc = optionals cfg.exportConfiguration + environment.etc = + (optionals cfg.exportConfiguration [ { source = "${configFile}"; target = "X11/xorg.conf"; } @@ -351,7 +352,15 @@ in { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; target = "X11/xkb"; } - ]; + ]) + ++ (optionals (elem "ati_unfree" driverNames) [ + + # according toiive on #ati you don't need the pcs, it is like registry... keeps old stuff to make your + # life harder ;) Still it seems to be required + { source = "${kernelPackages.ati_drivers_x11}/etc/ati"; + target = "ati"; + } + ]); environment.x11Packages = [ xorg.xorgserver @@ -420,6 +429,8 @@ in "ln -sf ${kernelPackages.nvidia_x11_legacy96} /run/opengl-driver" else if elem "nvidiaLegacy173" driverNames then "ln -sf ${kernelPackages.nvidia_x11_legacy173} /run/opengl-driver" + else if elem "ati_unfree" driverNames then + "ln -sf ${kernelPackages.ati_drivers_x11} /run/opengl-driver" else if cfg.driSupport then "ln -sf ${pkgs.mesa} /run/opengl-driver" else "" From 01b8c48c3288243e17cfe1d4b298f4fc2c8bceb5 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Mon, 8 Oct 2012 16:00:05 +0200 Subject: [PATCH 05/43] logcheck: add some options to ease setting up ignore-rules The special handling for cronjobs should probably move to the cron module (logcheckIgnore = bool option) in the future, as it's more natural to just declare a cronjob, and mark it as "log-ignored", instead of adding cronjobs through logcheck. But as systemCronjobs is not an attrset yet (just simple strings), this would require adding an attrset for cronjobs or parsing strings in the nix language to get hold of the cron-user and command. So for now, I keep the interface within logcheck's module. --- modules/services/logging/logcheck.nix | 124 ++++++++++++++++++++++---- 1 file changed, 108 insertions(+), 16 deletions(-) diff --git a/modules/services/logging/logcheck.nix b/modules/services/logging/logcheck.nix index 40d736255ec..23f21b6a754 100644 --- a/modules/services/logging/logcheck.nix +++ b/modules/services/logging/logcheck.nix @@ -5,16 +5,13 @@ with pkgs.lib; let cfg = config.services.logcheck; - rulesDir = pkgs.runCommand "logcheck-rules-dir" - {} ( - '' - mkdir $out - cp -prd ${pkgs.logcheck}/etc/logcheck/* $out/ - rm $out/logcheck.* - chmod u+w $out/* - '' + optionalString (! builtins.isNull cfg.extraRulesDir) '' - cp -prd ${cfg.extraRulesDir}/* $out/ - '' ); + defaultRules = pkgs.runCommand "logcheck-default-rules" {} '' + cp -prd ${pkgs.logcheck}/etc/logcheck $out + chmod u+w $out + rm $out/logcheck.* + ''; + + rulesDir = pkgs.symlinkJoin "logcheck-rules-dir" ([ defaultRules ] ++ cfg.extraRulesDirs); configFile = pkgs.writeText "logcheck.conf" cfg.config; @@ -33,6 +30,74 @@ let 2 ${cfg.timeOfDay} * * * logcheck env PATH=/var/setuid-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} ''; + writeIgnoreRule = name: {level, regex, ...}: + pkgs.writeTextFile + { inherit name; + destination = "/ignore.d.${level}/${name}"; + text = '' + ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ${regex} + ''; + }; + + writeIgnoreCronRule = name: {level, user, regex, cmdline, ...}: + let escapeRegex = escape (stringToCharacters "\\[]{}()^$?*+|."); + cmdline_ = builtins.unsafeDiscardStringContext cmdline; + re = if regex != "" then regex else if cmdline_ == "" then ".*" else escapeRegex cmdline_; + in writeIgnoreRule "cron-${name}" { + inherit level; + regex = '' + (/usr/bin/)?cron\[[0-9]+\]: \(${user}\) CMD \(${re}\)$ + ''; + }; + + levelOption = mkOption { + default = "server"; + type = types.uniq types.string; + description = '' + Set the logcheck level. Either "workstation", "server", or "paranoid". + ''; + }; + + ignoreOptions = { + level = levelOption; + + regex = mkOption { + default = ""; + type = types.uniq types.string; + description = '' + Regex specifying which log lines to ignore. + ''; + }; + }; + + ignoreCronOptions = { + user = mkOption { + default = "root"; + type = types.uniq types.string; + description = '' + User that runs the cronjob. + ''; + }; + + cmdline = mkOption { + default = ""; + type = types.uniq types.string; + description = '' + Command line for the cron job. Will be turned into a regex for the logcheck ignore rule. + ''; + }; + + timeArgs = mkOption { + default = null; + type = types.nullOr (types.uniq types.string); + example = "02 06 * * *"; + description = '' + "min hr dom mon dow" crontab time args, to auto-create a cronjob too. + Leave at null to not do this and just add a logcheck ignore rule. + ''; + }; + }; + in { options = { @@ -98,16 +163,33 @@ in ''; }; - extraRulesDir = mkOption { - default = null; + extraRulesDirs = mkOption { + default = []; example = "/etc/logcheck"; - type = types.nullOr types.path; + type = types.listOf types.path; description = '' - Directory with extra rules. - Will be merged with bundled rules, so it's possible to override certain behaviour. + Directories with extra rules. ''; }; + ignore = mkOption { + default = {}; + description = '' + This option defines extra ignore rules. + ''; + type = types.loaOf types.optionSet; + options = [ ignoreOptions ]; + }; + + ignoreCron = mkOption { + default = {}; + description = '' + This option defines extra ignore rules for cronjobs. + ''; + type = types.loaOf types.optionSet; + options = [ ignoreOptions ignoreCronOptions ]; + }; + extraGroups = mkOption { default = []; type = types.listOf types.string; @@ -122,6 +204,10 @@ in }; config = mkIf cfg.enable { + services.logcheck.extraRulesDirs = + mapAttrsToList writeIgnoreRule cfg.ignore + ++ mapAttrsToList writeIgnoreCronRule cfg.ignoreCron; + users.extraUsers = singleton { name = cfg.user; shell = "/bin/sh"; @@ -134,6 +220,12 @@ in chown ${cfg.user} /var/{lib,lock}/logcheck ''; - services.cron.systemCronJobs = [ cronJob ]; + services.cron.systemCronJobs = + let withTime = name: {timeArgs, ...}: ! (builtins.isNull timeArgs); + mkCron = name: {user, cmdline, timeArgs, ...}: '' + ${timeArgs} ${user} ${cmdline} + ''; + in mapAttrsToList mkCron (filterAttrs withTime cfg.ignoreCron) + ++ [ cronJob ]; }; } From e8d8b6b39997fdd9b0796fd79fffad9750c37774 Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Fri, 5 Oct 2012 22:02:47 -0700 Subject: [PATCH 06/43] smartd: Add options for each device being monitored --- modules/services/monitoring/smartd.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/services/monitoring/smartd.nix b/modules/services/monitoring/smartd.nix index 2427f29020e..7ca5625bfe7 100644 --- a/modules/services/monitoring/smartd.nix +++ b/modules/services/monitoring/smartd.nix @@ -24,7 +24,7 @@ let smartdConf = pkgs.writeText "smartd.conf" (concatMapStrings (device: '' - ${device} -a -m root -M exec ${smartdMail} + ${device} -a -m root -M exec ${smartdMail} ${cfg.deviceOpts} '' ) cfg.devices); @@ -50,6 +50,17 @@ in ''; }; + deviceOpts = mkOption { + default = ""; + type = types.string; + example = "-o on -s (S/../.././02|L/../../7/04)"; + description = '' + Additional options for each device that is monitored. The example + turns on SMART Automatic Offline Testing on startup, and schedules short + self-tests daily, and long self-tests weekly. + ''; + }; + devices = mkOption { default = []; example = ["/dev/sda" "/dev/sdb"]; From e40146de16a8edf5e63b92057d0a7abca745182d Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Fri, 5 Oct 2012 22:11:57 -0700 Subject: [PATCH 07/43] nat: enable NAT for multiple networks --- modules/services/networking/nat.nix | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/services/networking/nat.nix b/modules/services/networking/nat.nix index c51eeb54be7..ff6ff02f7e9 100644 --- a/modules/services/networking/nat.nix +++ b/modules/services/networking/nat.nix @@ -1,4 +1,6 @@ # This module enables Network Address Translation (NAT). +# XXX: todo: support multiple upstream links +# see http://yesican.chsoft.biz/lartc/MultihomedLinuxNetworking.html { config, pkgs, ... }: @@ -25,11 +27,11 @@ in }; networking.nat.internalIPs = mkOption { - example = "192.168.1.0/24"; + example = [ "192.168.1.0/24" ] ; description = '' - The IP address range for which to perform NAT. Packets - coming from these addresses and destined for the external + The IP address ranges for which to perform NAT. Packets + coming from these networks and destined for the external interface will be rewritten. ''; }; @@ -76,13 +78,17 @@ in '' iptables -t nat -F POSTROUTING iptables -t nat -X - + '' + + (concatMapStrings (network: + '' iptables -t nat -A POSTROUTING \ - -s ${cfg.internalIPs} -o ${cfg.externalInterface} \ + -s ${network} -o ${cfg.externalInterface} \ ${if cfg.externalIP == "" then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"} - + '' + ) cfg.internalIPs) + + '' echo 1 > /proc/sys/net/ipv4/ip_forward ''; @@ -91,7 +97,5 @@ in iptables -t nat -F POSTROUTING ''; }; - }; - } From 71e6eca5675a9a32d245ace3b29154409a4700bf Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Tue, 9 Oct 2012 12:19:09 -0700 Subject: [PATCH 08/43] - fix indention, clarify parameter descriptions, and use 'exec' instead of 'script' in the hostapd job --- modules/services/networking/hostapd.nix | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/services/networking/hostapd.nix b/modules/services/networking/hostapd.nix index 712b1a6824c..42779494b4b 100644 --- a/modules/services/networking/hostapd.nix +++ b/modules/services/networking/hostapd.nix @@ -52,7 +52,7 @@ in enable = mkOption { default = false; description = '' - enable putting a wireless interface into infrastructure mode, + Enable putting a wireless interface into infrastructure mode, allowing other wireless devices to associate with the wireless interface and do wireless networking. A simple access point will enable hostapd.wpa, and hostapd.wpa_passphrase, hostapd.ssid, dhcpd on the wireless interface to @@ -107,19 +107,24 @@ in example = "network"; type = types.string; description = "members of this group can control hostapd"; - }; + }; wpa = mkOption { default = true; description = "enable WPA (IEEE 802.11i/D3.0) to authenticate to the access point"; - }; + }; wpaPassphrase = mkOption { default = "my_sekret"; example = "any_64_char_string"; type = types.string; - description = "WPA-PSK (pre-shared-key) passphrase. Clients will need this passphrase to associate with this access point"; - }; + description = + '' + WPA-PSK (pre-shared-key) passphrase. Clients will need this + passphrase to associate with this access point. Warning: This passphrase will + get put into a world-readable file in the nix store. + ''; + }; extraCfg = mkOption { default = ""; @@ -130,9 +135,9 @@ in ''; type = types.string; description = "Extra configuration options to put in the hostapd.conf"; - }; }; }; + }; ###### implementation @@ -144,11 +149,7 @@ in jobs.hostapd = { startOn = "started network-interfaces"; stopOn = "stopping network-interfaces"; - - script = - '' - exec ${pkgs.hostapd}/bin/hostapd ${configFile} - ''; + exec = "${pkgs.hostapd}/bin/hostapd ${configFile}"; }; }; } From 5181ca4a3f980c504e2a368ebd7ae87995985f64 Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 9 Oct 2012 23:21:45 -0700 Subject: [PATCH 09/43] Change the default value of programs.ssh.forwardX11 to false. Forwarding X11 to untrusted servers is extremely insecure; see for example http://www.hackinglinuxexposed.com/articles/20040705.html --- modules/programs/ssh.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index 5c4b8c3a9a1..45d518e73f7 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -16,11 +16,13 @@ in programs.ssh = { forwardX11 = mkOption { - default = cfgd.forwardX11; + default = false; description = '' Whether to request X11 forwarding on outgoing connections by default. This is useful for running graphical programs on the remote machine and have them display to your local X11 server. Historically, this value has depended on the value used by the local sshd daemon, but there really isn't a relation between the two. + Warning: never enable X11 forwarding unless you are connecting to a machine you trust! + To enable or disable forwarding on a per-connection basis, see the -X and -x options to ssh. ''; }; From 6c62de6a31a17951d06981a2f6e21d8324c07786 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Fri, 12 Oct 2012 13:09:19 +0200 Subject: [PATCH 10/43] firewall: option to enable the rpfilter netfilter module This is meant to replace /proc/sys/net/ipv4/conf/*/rp_filter, which only works for ipv4. Furthermore, it's nicer to handle this kind of filtering in the firewall. There are some more subtle differences, please see: https://home.regit.org/netfilter-en/secure-use-of-helpers/ I chose to enable this by default (when the firewall is enabled) as it's a good idea in general. Only people with advanced routing needs might not want this, but I guess they don't use the nixos firewall anyway and use a custom solution. Furthermore, the option only becomes available in kernel 3.3+, so conservative nixos users that just stick to the default kernel will not need to act now just yet. --- modules/services/networking/firewall.nix | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index e6ae725f85f..7ea4e593cd1 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -39,6 +39,11 @@ let } ''; + kernelPackages = config.boot.kernelPackages; + kernelHasRPFilter = kernelPackages.kernel ? features + && kernelPackages.kernel.features ? netfilterRPFilter + && kernelPackages.kernel.features.netfilterRPFilter; + in { @@ -140,6 +145,22 @@ in ''; }; + networking.firewall.checkReversePath = mkOption { + default = kernelHasRPFilter; + type = types.bool; + description = + '' + Performs a reverse path filter test on a packet. + If a reply to the packet would not be sent via the same interface + that the packet arrived on, it is refused. + + If using asymmetric routing or other complicated routing, + disable this setting and setup your own counter-measures. + + (needs kernel 3.3+) + ''; + }; + networking.firewall.extraCommands = mkOption { default = ""; example = "iptables -A INPUT -p icmp -j ACCEPT"; @@ -170,6 +191,9 @@ in boot.kernelModules = [ "nf_conntrack_ftp" ]; + assertions = [ { assertion = ! cfg.checkReversePath || kernelHasRPFilter; + message = "This kernel does not support rpfilter"; } ]; + jobs.firewall = { startOn = "started network-interfaces"; @@ -233,6 +257,12 @@ in # The "nixos-fw" chain does the actual work. ip46tables -N nixos-fw + # Perform a reverse-path test to refuse spoofers + # For now, we just drop, as the raw table doesn't have a log-refuse yet + ${optionalString (kernelHasRPFilter && cfg.checkReversePath) '' + ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP + ''} + # Accept all traffic on the trusted interfaces. ${flip concatMapStrings cfg.trustedInterfaces (iface: '' ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept From 97a3a99b40a2f3183f6c87af4c27664cbd030065 Mon Sep 17 00:00:00 2001 From: Mathijs Kwik Date: Fri, 12 Oct 2012 13:16:33 +0200 Subject: [PATCH 11/43] firewall: options to select connection-tracking helpers My main reason for adding this is the ability to turn off helpers altogether. If you are not using any of the special protocols, keeping them turned off is safest, and in case you do want to use them, it's best to configure them through the new CT target for your network topology. Perhaps some sane defaults for nixos can be examined in the future. This change has no impact if you don't touch the added options, so no need to adapt. --- modules/services/networking/firewall.nix | 45 ++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index 7ea4e593cd1..8ddeacf1a0f 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -44,6 +44,10 @@ let && kernelPackages.kernel.features ? netfilterRPFilter && kernelPackages.kernel.features.netfilterRPFilter; + kernelCanDisableHelpers = kernelPackages.kernel ? features + && kernelPackages.kernel.features ? canDisableNetfilterConntrackHelpers + && kernelPackages.kernel.features.canDisableNetfilterConntrackHelpers; + in { @@ -161,6 +165,37 @@ in ''; }; + networking.firewall.connectionTrackingModules = mkOption { + default = [ "ftp" ]; + example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ]; + type = types.list types.string; + description = + '' + List of connection-tracking helpers that are auto-loaded. + The complete list of possible values is given in the example. + + As helpers can pose as a security risk, it is adviced to + set this to an empty list and disable the setting + networking.firewall.autoLoadConntrackHelpers + + Loading of helpers is recommended to be done through the new + CT target. More info: + https://home.regit.org/netfilter-en/secure-use-of-helpers/ + ''; + }; + + networking.firewall.autoLoadConntrackHelpers = mkOption { + default = true; + type = types.bool; + description = + '' + Whether to auto-load connection-tracking helpers. + See the description at networking.firewall.connectionTrackingModules + + (needs kernel 3.5+) + ''; + }; + networking.firewall.extraCommands = mkOption { default = ""; example = "iptables -A INPUT -p icmp -j ACCEPT"; @@ -189,10 +224,16 @@ in environment.systemPackages = [ pkgs.iptables ]; - boot.kernelModules = [ "nf_conntrack_ftp" ]; + boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules; + boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) '' + options nf_conntrack nf_conntrack_helper=0 + ''; assertions = [ { assertion = ! cfg.checkReversePath || kernelHasRPFilter; - message = "This kernel does not support rpfilter"; } ]; + message = "This kernel does not support rpfilter"; } + { assertion = cfg.autoLoadConntrackHelpers || kernelCanDisableHelpers; + message = "This kernel does not support disabling conntrack helpers"; } + ]; jobs.firewall = { startOn = "started network-interfaces"; From f4329320ab39f43f6ec4a9eeec3d06eda881df6b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 14 Oct 2012 22:07:15 -0400 Subject: [PATCH 12/43] Forward compatibility with the systemd branch --- lib/eval-config.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/eval-config.nix b/lib/eval-config.nix index ffc0db1c7ea..f99f3fbedbb 100644 --- a/lib/eval-config.nix +++ b/lib/eval-config.nix @@ -31,6 +31,7 @@ rec { inherit pkgs modules baseModules; modulesPath = ../modules; pkgs_i686 = import { system = "i686-linux"; }; + utils = {}; # forward compatibility }; # Import Nixpkgs, allowing the NixOS option nixpkgs.config to From 8499d7555fff04594f58267858258d714fe5c6e5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 16 Oct 2012 11:28:30 -0400 Subject: [PATCH 13/43] =?UTF-8?q?Backward=20compatibility=20hack=20for=20?= =?UTF-8?q?=E2=80=98networking.nat.internalIPs=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/services/networking/nat.nix | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/services/networking/nat.nix b/modules/services/networking/nat.nix index ff6ff02f7e9..9d62a764f06 100644 --- a/modules/services/networking/nat.nix +++ b/modules/services/networking/nat.nix @@ -34,6 +34,9 @@ in coming from these networks and destined for the external interface will be rewritten. ''; + # Backward compatibility: this used to be a single range instead + # of a list. + apply = x: if isList x then x else [x]; }; networking.nat.externalInterface = mkOption { @@ -78,8 +81,8 @@ in '' iptables -t nat -F POSTROUTING iptables -t nat -X - '' - + (concatMapStrings (network: + '' + + (concatMapStrings (network: '' iptables -t nat -A POSTROUTING \ -s ${network} -o ${cfg.externalInterface} \ From efc104c4c8dd8eb0f2eb2de13d36a2d0c47012df Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Tue, 16 Oct 2012 18:23:28 +0200 Subject: [PATCH 14/43] modules/programs/bash: improve bash completion support The new configuration.nix option 'environment.enableBashCompletion' determines whether bash completion is automatically enabled system-wide for all interactive shells or not. The default setting is 'off'. --- modules/programs/bash/bash.nix | 31 ++++++++++++++++++++++++++++++- modules/programs/bash/bashrc.sh | 10 +--------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 51654b164a0..9eefb8e686f 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -7,6 +7,25 @@ with pkgs.lib; let + initBashCompletion = optionalString config.environment.enableBashCompletion '' + # Check whether we're running a version of Bash that has support for + # programmable completion. If we do, enable all modules installed in + # the system (and user profile). + if shopt -q progcomp &>/dev/null; then + . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh" + nullglobStatus=$(shopt -p nullglob) + shopt -s nullglob + for p in $NIX_PROFILES /run/current-system/sw; do + for m in "$p/etc/bash_completion.d/"*; do + echo enable bash completion module $m + . $m + done + done + eval "$nullglobStatus" + fi + ''; + + options = { environment.shellInit = mkOption { @@ -18,6 +37,12 @@ let type = with pkgs.lib.types; string; }; + environment.enableBashCompletion = mkOption { + default = false; + description = "Enable bash-completion for all interactive shells."; + type = with pkgs.lib.types; bool; + }; + }; in @@ -38,7 +63,10 @@ in { # /etc/bashrc: executed every time a bash starts. Sources # /etc/profile to ensure that the system environment is # configured properly. - source = ./bashrc.sh; + source = pkgs.substituteAll { + src = ./bashrc.sh; + inherit initBashCompletion; + }; target = "bashrc"; } @@ -59,4 +87,5 @@ in mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh ''; + environment.pathsToLink = optional config.environment.enableBashCompletion "/etc/bash_completion.d"; } diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index 74550656151..4382e7ee9d8 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -27,15 +27,7 @@ if test "$TERM" = "xterm"; then PS1="\[\033]2;\h:\u:\w\007\]$PS1" fi -# Check whether we're running a version of Bash that has support for -# programmable completion. If we do, and if the current user has -# installed the package 'bash-completion' in her $HOME/.nix-profile, -# then completion is enabled automatically. -if [ -f "$HOME/.nix-profile/etc/profile.d/bash_completion.sh" ]; then - if shopt -q progcomp &>/dev/null; then - . "$HOME/.nix-profile/etc/profile.d/bash_completion.sh" - fi -fi +@initBashCompletion@ # Some aliases. alias ls="ls --color=tty" From 04a8642b4bf4bb998a6218275e19dd8970c03914 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Tue, 16 Oct 2012 18:41:20 +0200 Subject: [PATCH 15/43] modules/programs/bash: clean-up variables used in initialization of bash-completion --- modules/programs/bash/bash.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 9eefb8e686f..ca825d7ab94 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -17,11 +17,11 @@ let shopt -s nullglob for p in $NIX_PROFILES /run/current-system/sw; do for m in "$p/etc/bash_completion.d/"*; do - echo enable bash completion module $m . $m done done eval "$nullglobStatus" + unset nullglobStatus p m fi ''; From 56f90da276b93b6af16c6ac94f0e452a2da94927 Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Tue, 16 Oct 2012 19:07:19 +0200 Subject: [PATCH 16/43] modules/programs/bash: '/run/current-system/sw' is already a part of $NIX_PROFILES --- modules/programs/bash/bash.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index ca825d7ab94..441d30f1e9f 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -15,7 +15,7 @@ let . "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh" nullglobStatus=$(shopt -p nullglob) shopt -s nullglob - for p in $NIX_PROFILES /run/current-system/sw; do + for p in $NIX_PROFILES; do for m in "$p/etc/bash_completion.d/"*; do . $m done From 18076e001a54c86c42a3a74a2ef45e1f1dbb4c91 Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 15:11:53 +0200 Subject: [PATCH 17/43] apache-httpd: Use authn_core for version >= 2.3. Beginning with version 2.3, the authn were refactored. As a result, authn_alias is now part of the new module authn_core, so let's use authn_core instead of authn_alias. For details please see: http://httpd.apache.org/docs/2.4/upgrading.html#misc Signed-off-by: aszlig --- modules/services/web-servers/apache-httpd/default.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 9ceb66a85a0..4a5362436b0 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -101,7 +101,8 @@ let "auth_basic" "auth_digest" # Authentication: is the user who he claims to be? - "authn_file" "authn_dbm" "authn_anon" "authn_alias" + "authn_file" "authn_dbm" "authn_anon" + (if versionOlder httpd.version "2.3" then "authn_alias" else "authn_core") # Authorization: is the user allowed access? "authz_user" "authz_groupfile" "authz_host" From 3ad8fac5a25b549bd28d5bc5c4f461a52f109c6a Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 15:17:48 +0200 Subject: [PATCH 18/43] apache-httpd: Dynamically load MPM module in v2.4. Now, MPMs can be loaded at runtime and it's no longer required to compile in one of the MPM modules statically. So, if version is >= 2.4, load the MPM module corresponding to the multiProcessingModule value of the service module. For details, please see: http://httpd.apache.org/docs/2.4/mpm.html Signed-off-by: aszlig --- modules/services/web-servers/apache-httpd/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 4a5362436b0..b70ed3933aa 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -114,6 +114,7 @@ let "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling" "userdir" "alias" "rewrite" "proxy" "proxy_http" ] + ++ optional (!versionOlder httpd.version "2.4") "mpm_${mainCfg.multiProcessingModule}" ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ]) ++ optional enableSSL "ssl" ++ extraApacheModules; From 3acd98b040517cae680c8ca4273c0613f8af82ce Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 15:21:32 +0200 Subject: [PATCH 19/43] apache-httpd: Add unixd for 2.4, needed by "User". Beginning with 2.4 mod_unixd is needed to supply Unix usernames and groups for the web server. For details please have a look at: http://httpd.apache.org/docs/2.4/upgrading.html#commonproblems Signed-off-by: aszlig --- modules/services/web-servers/apache-httpd/default.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index b70ed3933aa..05fada720ba 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -114,7 +114,10 @@ let "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling" "userdir" "alias" "rewrite" "proxy" "proxy_http" ] - ++ optional (!versionOlder httpd.version "2.4") "mpm_${mainCfg.multiProcessingModule}" + ++ optionals (!versionOlder httpd.version "2.4") [ + "mpm_${mainCfg.multiProcessingModule}" + "unixd" + ] ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ]) ++ optional enableSSL "ssl" ++ extraApacheModules; From a88453fbaa8104502975d40c1b53738f71168b70 Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 16:57:18 +0200 Subject: [PATCH 20/43] apache-httpd: Properly wrap access directives. The Order/Deny directives are deprecated in version 2.4, so we're going to define two wrappers for allDenied and allGranted in order to properly generate configurations for both version 2.2 and 2.4. For more information an access control changes, see: http://httpd.apache.org/docs/2.4/upgrading.html#access Signed-off-by: aszlig --- .../web-servers/apache-httpd/default.nix | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 05fada720ba..29a20cae162 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -116,6 +116,7 @@ let ] ++ optionals (!versionOlder httpd.version "2.4") [ "mpm_${mainCfg.multiProcessingModule}" + "authz_core" "unixd" ] ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ]) @@ -123,6 +124,21 @@ let ++ extraApacheModules; + allDenied = if versionOlder httpd.version "2.4" then '' + Order deny,allow + Deny from all + '' else '' + Require all denied + ''; + + allGranted = if versionOlder httpd.version "2.4" then '' + Order allow,deny + Allow from all + '' else '' + Require all granted + ''; + + loggingConf = '' ErrorLog ${mainCfg.logDir}/error_log @@ -191,8 +207,7 @@ let Options Indexes FollowSymLinks AllowOverride None - Order allow,deny - Allow from all + ${allGranted} ''; @@ -246,12 +261,10 @@ let AllowOverride FileInfo AuthConfig Limit Indexes Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec - Order allow,deny - Allow from all + ${allGranted} - Order deny,allow - Deny from all + ${allDenied} @@ -273,8 +286,7 @@ let Alias ${elem.urlPath} ${elem.dir}/ Options +Indexes - Order allow,deny - Allow from all + ${allGranted} AllowOverride All ''; @@ -326,8 +338,7 @@ let AddHandler type-map var - Order allow,deny - Deny from all + ${allDenied} ${mimeConf} @@ -345,16 +356,14 @@ let Options FollowSymLinks AllowOverride None - Order deny,allow - Deny from all + ${allDenied} # But do allow access to files in the store so that we don't have # to generate clauses for every generated file that we # want to serve. - Order allow,deny - Allow from all + ${allGranted} # Generate directives for the main server. From 5655ec0efa3839217dae12742d585c11d25dd693 Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 17:03:50 +0200 Subject: [PATCH 21/43] apache-httpd: Avoid NameVirtualHost in >= v2.4. NameVirtualHost no longer has any effect on version 2.4 and just emits ugly warnings, so let's not use it if we use 2.4. More information: http://httpd.apache.org/docs/2.4/upgrading.html#misc Signed-off-by: aszlig --- modules/services/web-servers/apache-httpd/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 29a20cae162..9a3a3a10541 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -373,7 +373,9 @@ let ${let ports = map getPort allHosts; uniquePorts = uniqList {inputList = ports;}; - in concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts + isNeeded = versionOlder httpd.version "2.4"; + directives = concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts; + in optionalString isNeeded directives } ${let From 919e6e55a9c6c98fe408831905a8b91587af0503 Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 17:38:43 +0200 Subject: [PATCH 22/43] apache-httpd: Create runtime dir for version 2.4. By default the path is determined related to ServerRoot. Unfortunately ServerRoot is pointing to the Nix store and the web server can't write to it. We now create a directory called "runtime" withen the stateDir and point DefaultRuntimeDir to it. For more information on the DefaultRuntimeDir directive, please see: http://httpd.apache.org/docs/2.4/mod/core.html#defaultruntimedir Signed-off-by: aszlig --- modules/services/web-servers/apache-httpd/default.nix | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 9a3a3a10541..89fd491fd22 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -303,6 +303,10 @@ let ServerRoot ${httpd} + ${optionalString (!versionOlder httpd.version "2.4") '' + DefaultRuntimeDir ${mainCfg.stateDir}/runtime + ''} + PidFile ${mainCfg.stateDir}/httpd.pid ${optionalString (mainCfg.multiProcessingModule != "prefork") '' @@ -636,6 +640,10 @@ in '' mkdir -m 0750 -p ${mainCfg.stateDir} chown root.${mainCfg.group} ${mainCfg.stateDir} + ${optionalString (!versionOlder httpd.version "2.4") '' + mkdir -m 0750 -p "${mainCfg.stateDir}/runtime" + chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime" + ''} mkdir -m 0700 -p ${mainCfg.logDir} ${optionalString (mainCfg.documentRoot != null) From f9831a94c984b1bfdff598299a1b66341a1f9cd2 Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 17 Oct 2012 17:47:30 +0200 Subject: [PATCH 23/43] apache-httpd: Simplify all versionOlder calls. We now just have a simple attribute called "version24" which replaces all those pesky versionOlder that were spreading throughout the file and makes things way more readable. Signed-off-by: aszlig --- .../web-servers/apache-httpd/default.nix | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 89fd491fd22..1729850421a 100644 --- a/modules/services/web-servers/apache-httpd/default.nix +++ b/modules/services/web-servers/apache-httpd/default.nix @@ -8,6 +8,8 @@ let httpd = mainCfg.package; + version24 = !versionOlder httpd.version "2.4"; + httpdConf = mainCfg.configFile; php = pkgs.php.override { apacheHttpd = httpd; }; @@ -102,7 +104,7 @@ let # Authentication: is the user who he claims to be? "authn_file" "authn_dbm" "authn_anon" - (if versionOlder httpd.version "2.3" then "authn_alias" else "authn_core") + (if version24 then "authn_core" else "authn_alias") # Authorization: is the user allowed access? "authz_user" "authz_groupfile" "authz_host" @@ -114,7 +116,7 @@ let "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling" "userdir" "alias" "rewrite" "proxy" "proxy_http" ] - ++ optionals (!versionOlder httpd.version "2.4") [ + ++ optionals version24 [ "mpm_${mainCfg.multiProcessingModule}" "authz_core" "unixd" @@ -124,18 +126,18 @@ let ++ extraApacheModules; - allDenied = if versionOlder httpd.version "2.4" then '' + allDenied = if version24 then '' + Require all denied + '' else '' Order deny,allow Deny from all - '' else '' - Require all denied ''; - allGranted = if versionOlder httpd.version "2.4" then '' + allGranted = if version24 then '' + Require all granted + '' else '' Order allow,deny Allow from all - '' else '' - Require all granted ''; @@ -303,7 +305,7 @@ let ServerRoot ${httpd} - ${optionalString (!versionOlder httpd.version "2.4") '' + ${optionalString version24 '' DefaultRuntimeDir ${mainCfg.stateDir}/runtime ''} @@ -377,9 +379,8 @@ let ${let ports = map getPort allHosts; uniquePorts = uniqList {inputList = ports;}; - isNeeded = versionOlder httpd.version "2.4"; directives = concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts; - in optionalString isNeeded directives + in optionalString (!version24) directives } ${let @@ -640,7 +641,7 @@ in '' mkdir -m 0750 -p ${mainCfg.stateDir} chown root.${mainCfg.group} ${mainCfg.stateDir} - ${optionalString (!versionOlder httpd.version "2.4") '' + ${optionalString version24 '' mkdir -m 0750 -p "${mainCfg.stateDir}/runtime" chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime" ''} From 1cbad692c3156163b01268270a4efa261e479206 Mon Sep 17 00:00:00 2001 From: Jack Cummings Date: Sun, 21 Oct 2012 21:46:05 -0700 Subject: [PATCH 24/43] Add an option to add 'option=single-request' to /etc/resolv.conf. --- modules/config/networking.nix | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/config/networking.nix b/modules/config/networking.nix index c6ea171bf3d..3905f28b610 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -16,6 +16,18 @@ let ''; }; + networking.dnsSingleRequest = pkgs.lib.mkOption { + default = false; + description = '' + Recent versions of glibc will issue both ipv4 (A) and ipv6 (AAAA) + address queries at the same time, from the same port. Sometimes upstream + routers will systemically drop the ipv4 queries. The symptom of this problem is + that 'getent hosts example.com' only returns ipv6 (or perhaps only ipv4) addresses. The + workaround for this is to specify the option 'single-request' in + /etc/resolve.conf. This option enables that. + ''; + }; + }; in @@ -60,6 +72,9 @@ in # Invalidate the nscd cache whenever resolv.conf is # regenerated. libc_restart='${pkgs.upstart}/sbin/start invalidate-nscd' + '' + optionalString cfg.dnsSingleRequest '' + # only send one DNS request at a time + resolv_conf_options='single-request' '' + optionalString config.services.bind.enable '' # This hosts runs a full-blown DNS resolver. name_servers='127.0.0.1' From c76fc27afffb60e9a744d70a9caf1f2e6b47afea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Mon, 1 Oct 2012 23:16:12 +0200 Subject: [PATCH 25/43] dnsmasq: Setting fixed order in DNS name resolution. That fits better my setup; if anyone doesn't need this, we can write an option for the fixed order queries. --- modules/services/networking/dnsmasq.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/networking/dnsmasq.nix b/modules/services/networking/dnsmasq.nix index 389d5c22e82..0d786add881 100644 --- a/modules/services/networking/dnsmasq.nix +++ b/modules/services/networking/dnsmasq.nix @@ -49,7 +49,7 @@ in daemonType = "daemon"; - exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam}"; + exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam} -o"; }; }; From 82d39c9ca4162d2d88a6a6596e5ca30acddad6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Wed, 24 Oct 2012 21:49:10 +0200 Subject: [PATCH 26/43] Fixing stage1 about getting a shell with job control in case of error It's a busybox faq: http://www.busybox.net/FAQ.html#job_control --- modules/system/boot/stage-1-init.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 53d528fcd56..c6fc87bf32a 100644 --- a/modules/system/boot/stage-1-init.sh +++ b/modules/system/boot/stage-1-init.sh @@ -40,10 +40,10 @@ EOF case $reply in f) - exec setsid @shell@ < /dev/$console >/dev/$console 2>/dev/$console ;; + exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" ;; i) echo "Starting interactive shell..." - setsid @shell@ < /dev/$console >/dev/$console 2>/dev/$console || fail + setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail ;; *) echo "Continuing...";; From cd372c62eabe6cefebbe74bc25f5b91775b7357c Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Wed, 24 Oct 2012 19:01:27 +0200 Subject: [PATCH 27/43] modules/services/networking/ssh/sshd.nix: configure AddressFamily properly Explicitly restrict sshd to use of IPv4 addresses if IPv6 support is not enabled. --- modules/services/networking/ssh/sshd.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix index ea60e591c14..830559f3e9d 100644 --- a/modules/services/networking/ssh/sshd.nix +++ b/modules/services/networking/ssh/sshd.nix @@ -356,6 +356,7 @@ in UsePAM ${if cfg.usePAM then "yes" else "no"} + AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} ${concatMapStrings (port: '' Port ${toString port} '') cfg.ports} From 64540fb4534245fbca58b0918f85e80274ff74dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Sun, 4 Nov 2012 22:13:19 +0100 Subject: [PATCH 28/43] Adding quick instructions in system-tarball-pc to use it as chroot. I also split the readme into a file apart. --- .../cd-dvd/system-tarball-pc-readme.txt | 89 +++++++++++++++++++ .../installer/cd-dvd/system-tarball-pc.nix | 49 +--------- 2 files changed, 90 insertions(+), 48 deletions(-) create mode 100644 modules/installer/cd-dvd/system-tarball-pc-readme.txt diff --git a/modules/installer/cd-dvd/system-tarball-pc-readme.txt b/modules/installer/cd-dvd/system-tarball-pc-readme.txt new file mode 100644 index 00000000000..c4a0a111cd3 --- /dev/null +++ b/modules/installer/cd-dvd/system-tarball-pc-readme.txt @@ -0,0 +1,89 @@ +Let all the files in the system tarball sit in a directory served by NFS (the +NFS root) like this in exportfs: + /home/pcroot 192.168.1.0/24(rw,no_root_squash,no_all_squash) + +Run "exportfs -a" after editing /etc/exportfs, for the nfs server to be aware +of the changes. + +Use a tftp server serving the root of boot/ (from the system tarball). + +In order to have PXE boot, use the boot/dhcpd.conf-example file for your dhcpd +server, as it will point your PXE clients to pxelinux.0 from the tftp server. +Adapt the configuration to your network. + +Adapt the pxelinux configuration (boot/pxelinux.cfg/default) to set the path to +your nfrroot. If you use ip=dhcp in the kernel, the nfs server ip will be taken +from dhcp and so you don't have to specify it. + +The linux in bzImage includes network drivers for some usual cards. + + +QEMU Testing +--------------- + +You can test qemu pxe boot without having a DHCP server adapted, but having +nfsroot, like this: + qemu-system-x86_64 -tftp /home/pcroot/boot -net nic -net user,bootfile=pxelinux.0 -boot n + +I don't know how to use NFS through the qemu '-net user' though. + + +QEMU Testing with NFS root and bridged network +------------------------------------------------- + +This allows testing with qemu as any other host in your LAN. + +Testing with the real dhcpd server requires setting up a bridge and having a +tap device. + tunctl -t tap0 + brctl addbr br0 + brctl addif br0 eth0 + brctl addif tap0 eth0 + ifconfig eth0 0.0.0.0 up + ifconfig tap0 0.0.0.0 up + ifconfig br0 up # With your ip configuration + +Then you can run qemu: + qemu-system-x86_64 -boot n -net tap,ifname=tap0,script=no -net nic,model=e1000 + + +Using the system-tarball-pc in a chroot +-------------------------------------------------- + +Installation: + mkdir nixos-chroot && cd nixos-chroot + tar xf your-system-tarball.tar.xz + mkdir sys dev proc tmp root var run + mount --bind /sys sys + mount --bind /dev dev + mount --bind /proc proc + +Activate the system: look for a directory in nix/store similar to: + "/nix/store/y0d1lcj9fppli0hl3x0m0ba5g1ndjv2j-nixos-feb97bx-53f008" +Having found it, activate that nixos system *twice*: + chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate + chroot . /nix/store/SOMETHING-nixos-SOMETHING/activate + +This runs a 'hostname' command. Restore your old hostname with: + hostname OLDHOSTNAME + +Copy your system resolv.conf to the /etc/resolv.conf inside the chroot: + cp /etc/resolv.conf etc + +Then you can get an interactive shell in the nixos chroot. '*' means +to run inside the chroot interactive shell + chroot . /bin/sh +* source /etc/profile + +Populate the nix database: that should be done in the init script if you +had booted this nixos. Run: +* `grep local-cmds run/current-system/init` + +Then you can proceed normally subscribing to a nixos channel: + nix-channel --add http://nixos.org/releases/nixos/channels/nixos-unstable + nix-channel --update + +Testing: + nix-env -i hello + which hello + hello diff --git a/modules/installer/cd-dvd/system-tarball-pc.nix b/modules/installer/cd-dvd/system-tarball-pc.nix index 2bc6ce78d94..e98a8c215f9 100644 --- a/modules/installer/cd-dvd/system-tarball-pc.nix +++ b/modules/installer/cd-dvd/system-tarball-pc.nix @@ -60,54 +60,7 @@ let } ''; - readme = pkgs.writeText "readme.txt" '' - Let all the files in the system tarball sit in a directory served by NFS (the NFS root) - like this in exportfs: - /home/pcroot 192.168.1.0/24(rw,no_root_squash,no_all_squash) - - Run "exportfs -a" after editing /etc/exportfs, for the nfs server to be aware of the - changes. - - Use a tftp server serving the root of boot/ (from the system tarball). - - In order to have PXE boot, use the boot/dhcpd.conf-example file for your dhcpd server, - as it will point your PXE clients to pxelinux.0 from the tftp server. Adapt the - configuration to your network. - - Adapt the pxelinux configuration (boot/pxelinux.cfg/default) to set the path to your - nfrroot. If you use ip=dhcp in the kernel, the nfs server ip will be taken from - dhcp and so you don't have to specify it. - - The linux in bzImage includes network drivers for some usual cards. - - - QEMU Testing - --------------- - - You can test qemu pxe boot without having a DHCP server adapted, but having nfsroot, - like this: - qemu-system-x86_64 -tftp /home/pcroot/boot -net nic -net user,bootfile=pxelinux.0 -boot n - - I don't know how to use NFS through the qemu '-net user' though. - - - QEMU Testing with NFS root and bridged network - ------------------------------------------------- - - This allows testing with qemu as any other host in your LAN. - - Testing with the real dhcpd server requires setting up a bridge and having a tap device. - tunctl -t tap0 - brctl addbr br0 - brctl addif br0 eth0 - brctl addif tap0 eth0 - ifconfig eth0 0.0.0.0 up - ifconfig tap0 0.0.0.0 up - ifconfig br0 up # With your ip configuration - - Then you can run qemu: - qemu-system-x86_64 -boot n -net tap,ifname=tap0,script=no -net nic,model=e1000 - ''; + readme = builtins.readFile ./system-tarball-pc-readme.txt; in From 6e6ee3278c132818ce85963a68ec43069af488d1 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 5 Nov 2012 09:35:01 +0100 Subject: [PATCH 29/43] pam: Add default configuration for GNU screen. This is needed in order to properly lock your screen using the C-a C-x (lockscreen) command _and_ being back to re-login, because the "other" PAM service/fallback is to deny authentication. Signed-off-by: aszlig --- modules/security/pam.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/security/pam.nix b/modules/security/pam.nix index dc18ffd7d02..4aab32e1dec 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -239,6 +239,7 @@ in { name = "vlock"; } { name = "xlock"; } { name = "xscreensaver"; } + { name = "screen"; } ]; }; From 1c28b8674935e173c8179316f131d11948b70227 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 5 Nov 2012 09:41:24 +0100 Subject: [PATCH 30/43] pam: Douchebag commit, fix alphabetical order. Yes, I'm going to get back to school and learn the alphabet. I promise! Signed-off-by: aszlig --- modules/security/pam.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/security/pam.nix b/modules/security/pam.nix index 4aab32e1dec..a77b7697379 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -235,11 +235,11 @@ in { name = "i3lock"; } { name = "lshd"; } { name = "samba"; } + { name = "screen"; } { name = "sshd"; } { name = "vlock"; } { name = "xlock"; } { name = "xscreensaver"; } - { name = "screen"; } ]; }; From e078117c726b9840b053ff3e90b2ce0801b43497 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 19 Oct 2012 15:21:06 -0400 Subject: [PATCH 31/43] firewall.nix: Don't fail if IPv6 is disabled --- modules/services/networking/firewall.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index 8ddeacf1a0f..9f7db27c738 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -340,9 +340,11 @@ in # Accept all ICMPv6 messages except redirects and node # information queries (type 139). See RFC 4890, section # 4.4. - ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP - ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP - ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept + ${optionalString config.networking.enableIPv6 '' + ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP + ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP + ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept + ''} ${cfg.extraCommands} From 2f833bc88dc8c1111bdedf1355a0920c9d5fb823 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Thu, 8 Nov 2012 13:04:20 -0500 Subject: [PATCH 32/43] Remove unnecessary toPath that breaks with recent nixUnstable --- modules/services/hardware/pommed.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/hardware/pommed.nix b/modules/services/hardware/pommed.nix index 63c783f5c6d..32599554fc1 100644 --- a/modules/services/hardware/pommed.nix +++ b/modules/services/hardware/pommed.nix @@ -13,7 +13,7 @@ with pkgs.lib; }; configFile = mkOption { - default = builtins.toPath "${pkgs.pommed}/etc/pommed.conf"; + default = "${pkgs.pommed}/etc/pommed.conf"; description = '' The contents of the pommed.conf file. ''; From 02e0d7dbc349e8d59a58f1cc23497b1c1d3ff3c4 Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Mon, 12 Nov 2012 17:58:48 +0100 Subject: [PATCH 33/43] dnsmasq: Add extraConfig option --- modules/services/networking/dnsmasq.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/services/networking/dnsmasq.nix b/modules/services/networking/dnsmasq.nix index 0d786add881..b726493d421 100644 --- a/modules/services/networking/dnsmasq.nix +++ b/modules/services/networking/dnsmasq.nix @@ -8,6 +8,10 @@ let serversParam = concatMapStrings (s: "-S ${s} ") cfg.servers; + dnsmasqConf = pkgs.writeText "dnsmasq.conf" '' + ${cfg.extraConfig} + ''; + in { @@ -33,6 +37,15 @@ in ''; }; + extraConfig = mkOption { + type = types.string; + default = ""; + description = '' + Extra configuration directives that should be added to + dnsmasq.conf + ''; + }; + }; }; @@ -49,7 +62,7 @@ in daemonType = "daemon"; - exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam} -o"; + exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam} -o -C ${dnsmasqConf}"; }; }; From 3afa5f86c172acf28bc439bfcb7c585a0e10750c Mon Sep 17 00:00:00 2001 From: James Cook Date: Sun, 18 Nov 2012 11:05:18 -0800 Subject: [PATCH 34/43] Fixed the documentation for programs.ssh.forwardX11 to account for the X11 SECURITY extension. --- modules/programs/ssh.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index 45d518e73f7..6f607c43368 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -21,8 +21,10 @@ in Whether to request X11 forwarding on outgoing connections by default. This is useful for running graphical programs on the remote machine and have them display to your local X11 server. Historically, this value has depended on the value used by the local sshd daemon, but there really isn't a relation between the two. - Warning: never enable X11 forwarding unless you are connecting to a machine you trust! + Note: there are some security risks to forwarding an X11 connection. + NixOS's X server is built with the SECURITY extension, which prevents some obvious attacks. To enable or disable forwarding on a per-connection basis, see the -X and -x options to ssh. + The -Y option to ssh enables trusted forwarding, which bypasses the SECURITY extension. ''; }; From a22c3621555137a39ffe3e40b836c65baaa79001 Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Wed, 25 Jul 2012 16:53:46 +0200 Subject: [PATCH 35/43] Add option for specifying shell aliases, environment.shellAliases. --- modules/module-list.nix | 1 + modules/programs/bash/bash.nix | 20 +++++++++++++++----- modules/programs/bash/bashrc.sh | 6 +----- modules/programs/shell.nix | 25 +++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 modules/programs/shell.nix diff --git a/modules/module-list.nix b/modules/module-list.nix index 0cca6a95544..f2811fd2f5f 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -39,6 +39,7 @@ ./programs/blcr.nix ./programs/info.nix ./programs/shadow.nix + ./programs/shell.nix ./programs/ssh.nix ./programs/ssmtp.nix ./programs/wvdial.nix diff --git a/modules/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 441d30f1e9f..2ba275c7409 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -25,6 +25,9 @@ let fi ''; + shellAliases = concatStringsSep "\n" ( + mapAttrsFlatten (k: v: "alias ${k}='${v}'") config.environment.shellAliases + ); options = { @@ -63,11 +66,11 @@ in { # /etc/bashrc: executed every time a bash starts. Sources # /etc/profile to ensure that the system environment is # configured properly. - source = pkgs.substituteAll { - src = ./bashrc.sh; - inherit initBashCompletion; - }; - target = "bashrc"; + source = pkgs.substituteAll { + src = ./bashrc.sh; + inherit initBashCompletion shellAliases; + }; + target = "bashrc"; } { # Configuration for readline in bash. @@ -76,6 +79,13 @@ in } ]; + environment.shellAliases = { + ls = "ls --color=tty"; + ll = "ls -l"; + l = "ls -alh"; + which = "type -P"; + }; + system.build.binsh = pkgs.bashInteractive; system.activationScripts.binsh = stringAfter [ "stdio" ] diff --git a/modules/programs/bash/bashrc.sh b/modules/programs/bash/bashrc.sh index 4382e7ee9d8..b1ecb278b93 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -29,8 +29,4 @@ fi @initBashCompletion@ -# Some aliases. -alias ls="ls --color=tty" -alias ll="ls -l" -alias l="ls -alh" -alias which="type -P" +@shellAliases@ diff --git a/modules/programs/shell.nix b/modules/programs/shell.nix new file mode 100644 index 00000000000..8348c4c25a1 --- /dev/null +++ b/modules/programs/shell.nix @@ -0,0 +1,25 @@ +# This module defines global configuration for the shells. + +{ config, pkgs, ... }: + +with pkgs.lib; + +{ + options = { + environment.shellAliases = mkOption { + type = types.attrs; # types.attrsOf types.stringOrPath; + default = {}; + example = { + ll = "ls -lh"; + }; + description = '' + An attribute set that maps aliases (the top level attribute names in + this option) to command strings or directly to build outputs. The + aliases are added to all users' shells. + ''; + }; + }; + + config = { + }; +} From 611ebeb1d0531a607b14bb10aadcafcfbc8c884d Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Sun, 16 Sep 2012 18:43:25 +0200 Subject: [PATCH 36/43] Add nslcd (nss-pam-ldapd) uid and gid --- modules/misc/ids.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index f26501105b1..92e9bb90893 100644 --- a/modules/misc/ids.nix +++ b/modules/misc/ids.nix @@ -74,6 +74,7 @@ in bind = 53; wwwrun = 54; spamd = 56; + nslcd = 58; # When adding a uid, make sure it doesn't match an existing gid. @@ -129,6 +130,7 @@ in adm = 55; spamd = 56; networkmanager = 57; + nslcd = 58; # When adding a gid, make sure it doesn't match an existing uid. From 6099451662ae156676b4969b0e665ea5b9e045d5 Mon Sep 17 00:00:00 2001 From: Rickard Nilsson Date: Sun, 16 Sep 2012 19:14:19 +0200 Subject: [PATCH 37/43] Add support for nslcd (nss-pam-ldapd) as users.ldap.daemon option --- modules/config/ldap.nix | 177 +++++++++++++++++++++++++++--------- modules/config/nsswitch.nix | 11 +-- modules/security/pam.nix | 4 +- 3 files changed, 142 insertions(+), 50 deletions(-) diff --git a/modules/config/ldap.nix b/modules/config/ldap.nix index 3821482361f..1e115943f23 100644 --- a/modules/config/ldap.nix +++ b/modules/config/ldap.nix @@ -1,8 +1,13 @@ {pkgs, config, ...}: +with pkgs.lib; +with pkgs; + ###### interface let - inherit (pkgs.lib) mkOption mkIf optionalString stringAfter; + inherit mkOption mkIf optionalString stringAfter singleton; + + cfg = config.users.ldap; options = { users = { @@ -41,7 +46,7 @@ let timeLimit = mkOption { default = 0; - type = with pkgs.lib.types; int; + type = types.int; description = " Specifies the time limit (in seconds) to use when performing searches. A value of zero (0), which is the default, is to @@ -49,11 +54,36 @@ let "; }; + daemon = { + enable = mkOption { + default = false; + description = '' + Whether to let the nslcd daemon (nss-pam-ldapd) handle the + LDAP lookups for NSS and PAM. This can improve performance, + and if you need to bind to the LDAP server with a password, + it increases security, since only the nslcd user needs to + have access to the bindpw file, not everyone that uses NSS + and/or PAM. If this option is enabled, a local nscd user is + created automatically, and the nslcd service is started + automatically when the network get up. + ''; + }; + + extraConfig = mkOption { + default = ""; + type = types.string; + description = '' + Extra configuration options that will be added verbatim at + the end of the nslcd configuration file (nslcd.conf). + '' ; + } ; + }; + bind = { distinguishedName = mkOption { default = ""; example = "cn=admin,dc=example,dc=com"; - type = with pkgs.lib.types; string; + type = types.string; description = " The distinguished name to bind to the LDAP server with. If this is not specified, an anonymous bind will be done. @@ -62,7 +92,7 @@ let password = mkOption { default = "/etc/ldap/bind.password"; - type = with pkgs.lib.types; string; + type = types.string; description = " The path to a file containing the credentials to use when binding to the LDAP server (if not binding anonymously). @@ -71,7 +101,7 @@ let timeLimit = mkOption { default = 30; - type = with pkgs.lib.types; int; + type = types.int; description = " Specifies the time limit (in seconds) to use when connecting to the directory server. This is distinct from the time limit @@ -82,7 +112,7 @@ let policy = mkOption { default = "hard_open"; - type = with pkgs.lib.types; string; + type = types.string; description = " Specifies the policy to use for reconnecting to an unavailable LDAP server. The default is hard_open, which @@ -99,55 +129,120 @@ let }; }; + extraConfig = mkOption { + default = "" ; + type = types.string ; + description = '' + Extra configuration options that will be added verbatim at + the end of the ldap configuration file (ldap.conf). + If users.ldap.daemon is enabled, this + configuration will not be used. In that case, use + users.ldap.daemon.extraConfig instead. + '' ; + }; + }; }; }; + + # Careful: OpenLDAP seems to be very picky about the indentation of + # this file. Directives HAVE to start in the first column! + ldapConfig = { + target = "ldap.conf"; + source = writeText "ldap.conf" '' + uri ${config.users.ldap.server} + base ${config.users.ldap.base} + timelimit ${toString config.users.ldap.timeLimit} + bind_timelimit ${toString config.users.ldap.bind.timeLimit} + bind_policy ${config.users.ldap.bind.policy} + ${optionalString config.users.ldap.useTLS '' + ssl start_tls + tls_checkpeer no + ''} + ${optionalString (config.users.ldap.bind.distinguishedName != "") '' + binddn ${config.users.ldap.bind.distinguishedName} + ''} + ${optionalString (cfg.extraConfig != "") cfg.extraConfig } + ''; + }; + + nslcdConfig = { + target = "nslcd.conf"; + source = writeText "nslcd.conf" '' + uid nslcd + gid nslcd + uri ${cfg.server} + base ${cfg.base} + timelimit ${toString cfg.timeLimit} + bind_timelimit ${toString cfg.bind.timeLimit} + ${optionalString (cfg.bind.distinguishedName != "") + "binddn ${cfg.bind.distinguishedName}" } + ${optionalString (cfg.daemon.extraConfig != "") cfg.daemon.extraConfig } + ''; + }; + + insertLdapPassword = !config.users.ldap.daemon.enable && + config.users.ldap.bind.distinguishedName != ""; + in ###### implementation - -mkIf config.users.ldap.enable { +mkIf cfg.enable { require = [ options ]; - # LDAP configuration. - environment = { - etc = [ + environment.etc = if cfg.daemon.enable then [nslcdConfig] else [ldapConfig]; - # Careful: OpenLDAP seems to be very picky about the indentation of - # this file. Directives HAVE to start in the first column! - { source = pkgs.writeText "ldap.conf" - '' - uri ${config.users.ldap.server} - base ${config.users.ldap.base} - timelimit ${toString config.users.ldap.timeLimit} - bind_timelimit ${toString config.users.ldap.bind.timeLimit} - bind_policy ${config.users.ldap.bind.policy} - - ${optionalString config.users.ldap.useTLS '' - ssl start_tls - tls_checkpeer no - ''} - - ${optionalString (config.users.ldap.bind.distinguishedName != "") '' - binddn ${config.users.ldap.bind.distinguishedName} - ''} - ''; - target = "ldap.conf"; - } - - ]; - }; - - system.activationScripts.ldap = stringAfter [ "etc" ] ( - optionalString (config.users.ldap.bind.distinguishedName != "") '' - if test -f "${config.users.ldap.bind.password}" ; then - echo "bindpw $(cat ${config.users.ldap.bind.password})" | cat /etc/ldap.conf - > /etc/ldap.conf.bindpw + system.activationScripts = mkIf insertLdapPassword { + ldap = stringAfter [ "etc" "groups" "users" ] '' + if test -f "${cfg.bind.password}" ; then + echo "bindpw "$(cat ${cfg.bind.password})"" | cat ${ldapConfig} - > /etc/ldap.conf.bindpw mv -fT /etc/ldap.conf.bindpw /etc/ldap.conf chmod 600 /etc/ldap.conf fi - '' + ''; + }; + + system.nssModules = singleton ( + if cfg.daemon.enable then nss_pam_ldapd else nss_ldap ); + users = mkIf cfg.daemon.enable { + extraGroups.nslcd = { + gid = config.ids.gids.nslcd; + }; + + extraUsers.nslcd = { + uid = config.ids.uids.nslcd; + description = "nslcd user."; + group = "nslcd"; + }; + }; + + jobs = mkIf cfg.daemon.enable { + nslcd = { + startOn = "filesystem"; + + stopOn = "stopping network-interfaces"; + + daemonType = "fork"; + + path = [ nss_pam_ldapd ]; + + preStart = '' + mkdir -p /run/nslcd + chown nslcd.nslcd /run/nslcd + ${optionalString (cfg.bind.distinguishedName != "") '' + if test -s "${cfg.bind.password}" ; then + ln -sfT "${cfg.bind.password}" /run/nslcd/bindpw + fi + ''} + ''; + + postStop = "rm -f /run/nslcd/nslcd.pid"; + + exec = "nslcd"; + }; + }; } diff --git a/modules/config/nsswitch.nix b/modules/config/nsswitch.nix index 806ff876303..4660bf7c92d 100644 --- a/modules/config/nsswitch.nix +++ b/modules/config/nsswitch.nix @@ -19,14 +19,9 @@ let "; merge = mergeListOption; apply = list: - let - list2 = - list - # !!! this should be in the LDAP module - ++ optional config.users.ldap.enable pkgs.nss_ldap; - in { - list = list2; - path = makeLibraryPath list2; + { + inherit list; + path = makeLibraryPath list; }; }; diff --git a/modules/security/pam.nix b/modules/security/pam.nix index a77b7697379..d3dd4ef9ac0 100644 --- a/modules/security/pam.nix +++ b/modules/security/pam.nix @@ -7,7 +7,9 @@ with pkgs.lib; let - inherit (pkgs) pam_ldap pam_krb5 pam_ccreds; + inherit (pkgs) pam_krb5 pam_ccreds; + + pam_ldap = if config.users.ldap.daemon.enable then pkgs.nss_pam_ldapd else pkgs.pam_ldap; otherService = pkgs.writeText "other.pam" '' From f0a6911929ad15054e27e471274e0c304d690670 Mon Sep 17 00:00:00 2001 From: Rob Vermaas Date: Wed, 21 Nov 2012 12:19:38 -0500 Subject: [PATCH 38/43] Add ec2.metadata (default false) option whether to allow access to EC2 metadata API. --- modules/virtualisation/ec2-data.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix index 65f40826225..e094ae54093 100644 --- a/modules/virtualisation/ec2-data.nix +++ b/modules/virtualisation/ec2-data.nix @@ -5,8 +5,19 @@ { config, pkgs, ... }: with pkgs.lib; - +let + options = { + ec2.metadata = mkOption { + type = types.bool; + default = false; + description = '' + Whether to allow access to EC2 metadata. + ''; + }; + }; +in { + require = [options]; jobs.fetchEC2Data = { name = "fetch-ec2-data"; @@ -56,9 +67,11 @@ with pkgs.lib; echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub fi + ${optionalString (! config.ec2.metadata) '' # Since the user data is sensitive, prevent it from being # accessed from now on. ip route add blackhole 169.254.169.254/32 + ''} ''; }; From 6b6b245693365ddf3bf255e7b814773c4ce0775f Mon Sep 17 00:00:00 2001 From: Peter Simons Date: Mon, 26 Nov 2012 16:19:45 +0100 Subject: [PATCH 39/43] sane: update name of the snapshot version of the backends --- modules/services/hardware/sane.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/hardware/sane.nix b/modules/services/hardware/sane.nix index e9f32a2662c..6849b3a7bc8 100644 --- a/modules/services/hardware/sane.nix +++ b/modules/services/hardware/sane.nix @@ -24,7 +24,7 @@ with pkgs.lib; ###### implementation config = let pkg = if config.hardware.sane.snapshot - then pkgs.saneBackendsSnapshot + then pkgs.saneBackendsGit else pkgs.saneBackends; in mkIf config.hardware.sane.enable { environment.systemPackages = [ pkg ]; From a9e5d1ab50451bbd6cedc6391b7b56df1fdc7fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Wed, 5 Sep 2012 09:55:02 +0200 Subject: [PATCH 40/43] Changing the kernel parameters for crashump I think that these enable more checks, and make more NMIs happen. --- modules/misc/crashdump.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/misc/crashdump.nix b/modules/misc/crashdump.nix index 98b2140a23d..6e6bc9dec0f 100644 --- a/modules/misc/crashdump.nix +++ b/modules/misc/crashdump.nix @@ -6,6 +6,7 @@ let crashdump = config.boot.crashDump; kernelParams = concatStringsSep " " crashdump.kernelParams; + in ###### interface { @@ -55,6 +56,8 @@ in kernelParams = [ "crashkernel=64M" "nmi_watchdog=panic" + "softlockup_panic=1" + "idle=poll" ]; kernelPackages = mkOverride 50 (crashdump.kernelPackages // { kernel = crashdump.kernelPackages.kernel.override From 04963cf80261c7e6c3280c0332ae332840f4b124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Batlle=20i=20Rossell?= Date: Thu, 29 Nov 2012 11:29:15 +0100 Subject: [PATCH 41/43] system-tarball-pc: fixing the readme inclusion --- modules/installer/cd-dvd/system-tarball-pc.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/installer/cd-dvd/system-tarball-pc.nix b/modules/installer/cd-dvd/system-tarball-pc.nix index e98a8c215f9..1046786c6df 100644 --- a/modules/installer/cd-dvd/system-tarball-pc.nix +++ b/modules/installer/cd-dvd/system-tarball-pc.nix @@ -60,7 +60,7 @@ let } ''; - readme = builtins.readFile ./system-tarball-pc-readme.txt; + readme = ./system-tarball-pc-readme.txt; in From 9eb81d2578c96dd0408dd2b90c4092c0d6561e67 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 29 Nov 2012 15:16:30 +0100 Subject: [PATCH 42/43] Renamed tcpWrapper -> tcp_wrappers --- modules/services/system/kerberos.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/services/system/kerberos.nix b/modules/services/system/kerberos.nix index 2a47b904589..8fb5debd20e 100644 --- a/modules/services/system/kerberos.nix +++ b/modules/services/system/kerberos.nix @@ -41,7 +41,7 @@ in flags = "REUSE NAMEINARGS"; protocol = "tcp"; user = "root"; - server = "${pkgs.tcpWrapper}/sbin/tcpd"; + server = "${pkgs.tcp_wrappers}/sbin/tcpd"; serverArgs = "${pkgs.heimdal}/sbin/kadmind"; }; From 7435db4f898233f9615b7818c07bbbcf30d44d63 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 30 Nov 2012 15:07:39 +0100 Subject: [PATCH 43/43] Get rid of the last uses of mkAlways mkAlways is an insane function, mkMerge is much saner. --- doc/manual/development.xml | 21 +--- modules/config/pulseaudio.nix | 99 ++++++++++--------- .../services/network-filesystems/samba.nix | 82 +++++++-------- 3 files changed, 96 insertions(+), 106 deletions(-) diff --git a/doc/manual/development.xml b/doc/manual/development.xml index 017a0f007fa..0b02c7f60c6 100644 --- a/doc/manual/development.xml +++ b/doc/manual/development.xml @@ -150,7 +150,7 @@ $ nixos-rebuild switch -I /my/sources definitions. This conditional values can be distinguished in two categories. The condition which are local to the current configuration and conditions which are dependent on others configurations. Local - properties are mkIf, mkAlways + properties are mkIf and mkAssert. Global properties are mkOverride, mkDefault and mkOrder. @@ -158,12 +158,7 @@ $ nixos-rebuild switch -I /my/sources mkIf is used to remove the option definitions which are below it if the condition is evaluated to false. mkAssert expects the condition to be evaluated - to true otherwise it raises an error message. mkAlways - is used to ignore all the mkIf - and mkAssert which have been made - previously. mkAlways and mkAssert - are often used together to set an option value and to ensure that it has - not been masked by another one. + to true otherwise it raises an error message. mkOverride is used to mask previous definitions if the current value has a lower mask number. The mask value is 100 (default) @@ -223,14 +218,6 @@ let locatedb = "/var/cache/locatedb"; logfile = "/var/log/updatedb"; cmd =''root updatedb --localuser=nobody --output=${locatedb} > ${logfile}''; - - mkCheck = x: - mkIf cfg.enable ( - mkAssert config.services.cron.enable '' - The cron daemon is not enabled, required by services.locate.enable. - '' - x - ) in { @@ -260,9 +247,9 @@ in }; }; - config = mkCheck { + config = mkIf cfg.enable { services.cron = { - enable = mkAlways cfg.enable; + enable = true; systemCronJobs = "${cfg.period} root ${cmd}"; }; }; diff --git a/modules/config/pulseaudio.nix b/modules/config/pulseaudio.nix index 71bf0081e4e..5dffd9d3afb 100644 --- a/modules/config/pulseaudio.nix +++ b/modules/config/pulseaudio.nix @@ -28,64 +28,65 @@ let cfg = config.hardware.pulseaudio; in }; - config = mkIf cfg.enable { + config = mkMerge + [ # Create pulse/client.conf even if PulseAudio is disabled so + # that we can disable the autospawn feature in programs that + # are built with PulseAudio support (like KDE). + { environment.etc = singleton + { target = "pulse/client.conf"; + source = pkgs.writeText "client.conf" + '' + autospawn=${if cfg.enable then "yes" else "no"} + ${optionalString cfg.enable '' + daemon-binary=${cfg.package}/bin/pulseaudio + ''} + ''; + }; + } - environment.systemPackages = - [ cfg.package ]; + (mkIf cfg.enable { - environment.etc = mkAlways ( - [ # Create pulse/client.conf even if PulseAudio is disabled so - # that we can disable the autospawn feature in programs that - # are built with PulseAudio support (like KDE). - { target = "pulse/client.conf"; - source = pkgs.writeText "client.conf" - '' - autospawn=${if cfg.enable then "yes" else "no"} - ${optionalString cfg.enable '' - daemon-binary=${cfg.package}/bin/pulseaudio - ''} - ''; - } + environment.systemPackages = [ cfg.package ]; - ] ++ optionals cfg.enable - [ # Write an /etc/asound.conf that causes all ALSA applications to - # be re-routed to the PulseAudio server through ALSA's Pulse - # plugin. - { target = "asound.conf"; - source = pkgs.writeText "asound.conf" - '' - pcm_type.pulse { - lib ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so - } + environment.etc = + [ # Write an /etc/asound.conf that causes all ALSA applications to + # be re-routed to the PulseAudio server through ALSA's Pulse + # plugin. + { target = "asound.conf"; + source = pkgs.writeText "asound.conf" + '' + pcm_type.pulse { + lib ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so + } - pcm.!default { - type pulse - hint.description "Default Audio Device (via PulseAudio)" - } + pcm.!default { + type pulse + hint.description "Default Audio Device (via PulseAudio)" + } - ctl_type.pulse { - lib ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so - } + ctl_type.pulse { + lib ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so + } - ctl.!default { - type pulse - } - ''; - } + ctl.!default { + type pulse + } + ''; + } - { target = "pulse/default.pa"; - source = "${cfg.package}/etc/pulse/default.pa"; - } + { target = "pulse/default.pa"; + source = "${cfg.package}/etc/pulse/default.pa"; + } - { target = "pulse/system.pa"; - source = "${cfg.package}/etc/pulse/system.pa"; - } + { target = "pulse/system.pa"; + source = "${cfg.package}/etc/pulse/system.pa"; + } + ]; - ]); + # Allow PulseAudio to get realtime priority using rtkit. + security.rtkit.enable = true; - # Allow PulseAudio to get realtime priority using rtkit. - security.rtkit.enable = true; - - }; + }) + ]; } diff --git a/modules/services/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix index 2cf4e8c11ff..93c07df7cc6 100644 --- a/modules/services/network-filesystems/samba.nix +++ b/modules/services/network-filesystems/samba.nix @@ -154,23 +154,23 @@ in defaultShare = { enable = mkOption { - description = "Whether to share /home/smbd as 'default'."; - default = false; - }; + description = "Whether to share /home/smbd as 'default'."; + default = false; + }; writeable = mkOption { - description = "Whether to allow write access to default share."; - default = false; - }; + description = "Whether to allow write access to default share."; + default = false; + }; guest = mkOption { - description = "Whether to allow guest access to default share."; - default = true; - }; + description = "Whether to allow guest access to default share."; + default = true; + }; }; securityType = mkOption { description = "Samba security type"; - default = "user"; - example = "share"; + default = "user"; + example = "share"; }; }; @@ -180,43 +180,45 @@ in ###### implementation - config = mkIf config.services.samba.enable { + config = mkMerge + [ { # Always provide a smb.conf to shut up programs like smbclient and smbspool. + environment.etc = singleton + { source = + if cfg.enable then configFile + else pkgs.writeText "smb-dummy.conf" "# Samba is disabled."; + target = "samba/smb.conf"; + }; + } - users.extraUsers = singleton - { name = user; - description = "Samba service user"; - group = group; - }; + (mkIf config.services.samba.enable { + users.extraUsers = singleton + { name = user; + description = "Samba service user"; + group = group; + }; - users.extraGroups = singleton - { name = group; - }; + users.extraGroups = singleton + { name = group; + }; - # always provide a smb.conf to shut up programs like smbclient and smbspool. - environment.etc = mkAlways (singleton - { source = - if cfg.enable then configFile - else pkgs.writeText "smb-dummy.conf" "# Samba is disabled."; - target = "samba/smb.conf"; - }); - # Dummy job to start the real Samba daemons (nmbd, smbd, winbindd). - jobs.sambaControl = - { name = "samba"; - description = "Samba server"; + # Dummy job to start the real Samba daemons (nmbd, smbd, winbindd). + jobs.sambaControl = + { name = "samba"; + description = "Samba server"; - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; + startOn = "started network-interfaces"; + stopOn = "stopping network-interfaces"; - preStart = setupScript; - }; + preStart = setupScript; + }; - jobs.nmbd = daemonJob "nmbd" "-D"; + jobs.nmbd = daemonJob "nmbd" "-D"; - jobs.smbd = daemonJob "smbd" "-D"; + jobs.smbd = daemonJob "smbd" "-D"; - jobs.winbindd = daemonJob "winbindd" "-D"; - - }; + jobs.winbindd = daemonJob "winbindd" "-D"; + }) + ]; }