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 diff --git a/modules/config/networking.nix b/modules/config/networking.nix index 2b4be69cc51..c6ea171bf3d 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -18,13 +18,6 @@ let }; - localhostWithDomain = optionalString (cfg.domain != "") - "localhost.${cfg.domain}"; - - hostnameWithDomain = optionalString - (cfg.domain != "" && cfg.hostName != "") - "${cfg.hostName}.${cfg.domain}"; - in { @@ -49,9 +42,8 @@ in { # /etc/hosts: Hostname-to-IP mappings. source = pkgs.writeText "hosts" '' - ${optionalString (cfg.hostName != "") - "127.0.0.1 ${hostnameWithDomain} ${cfg.hostName}"} - 127.0.0.1 localhost ${localhostWithDomain} + 127.0.0.1 localhost + ::1 localhost ${cfg.extraHosts} ''; target = "hosts"; diff --git a/modules/config/nsswitch-mdns.conf b/modules/config/nsswitch-mdns.conf deleted file mode 100644 index 61dd436682d..00000000000 --- a/modules/config/nsswitch-mdns.conf +++ /dev/null @@ -1,11 +0,0 @@ -# NSS configuration files with mDNS enabled (requires running Avahi daemon). - -passwd: ldap files -group: ldap files -shadow: ldap files - -hosts: files mdns_minimal [NOTFOUND=return] dns mdns -networks: files dns - -services: files -protocols: files diff --git a/modules/config/nsswitch.conf b/modules/config/nsswitch.conf deleted file mode 100644 index 44beaf5b44c..00000000000 --- a/modules/config/nsswitch.conf +++ /dev/null @@ -1,10 +0,0 @@ -passwd: files ldap -group: files ldap -shadow: files ldap - -hosts: files dns -networks: files dns -ethers: files - -services: files -protocols: files diff --git a/modules/config/nsswitch.nix b/modules/config/nsswitch.nix index cac6ff382a4..806ff876303 100644 --- a/modules/config/nsswitch.nix +++ b/modules/config/nsswitch.nix @@ -1,13 +1,15 @@ # Configuration for the Name Service Switch (/etc/nsswitch.conf). -{config, pkgs, ...}: +{ config, pkgs, ... }: + +with pkgs.lib; let options = { # NSS modules. Hacky! - system.nssModules = pkgs.lib.mkOption { + system.nssModules = mkOption { internal = true; default = []; description = " @@ -15,48 +17,49 @@ let several DNS resolution methods to be specified via /etc/nsswitch.conf. "; - merge = pkgs.lib.mergeListOption; + merge = mergeListOption; apply = list: let list2 = list # !!! this should be in the LDAP module - ++ pkgs.lib.optional config.users.ldap.enable pkgs.nss_ldap; + ++ optional config.users.ldap.enable pkgs.nss_ldap; in { list = list2; - path = pkgs.lib.makeLibraryPath list2; + path = makeLibraryPath list2; }; }; }; + inherit (config.services.avahi) nssmdns; + in { - require = [options]; + require = [ options ]; environment.etc = [ # Name Service Switch configuration file. Required by the C library. # !!! Factor out the mdns stuff. The avahi module should define # an option used by this module. - { source = - if config.services.avahi.nssmdns - then ./nsswitch-mdns.conf - else ./nsswitch.conf; + { source = pkgs.writeText "nsswitch.conf" + '' + passwd: files ldap + group: files ldap + shadow: files ldap + hosts: files ${optionalString nssmdns "mdns_minimal [NOTFOUND=return]"} dns ${optionalString nssmdns "mdns"} myhostname + networks: files dns + ethers: files + services: files + protocols: files + ''; target = "nsswitch.conf"; } ]; - environment.shellInit = - if config.system.nssModules.path != "" then - '' - LD_LIBRARY_PATH=${config.system.nssModules.path}:$LD_LIBRARY_PATH - '' - else ""; - - # NSS modules need to be in `systemPath' so that (i) the builder - # chroot gets to seem them, and (ii) applications can benefit from - # changes in the list of NSS modules at run-time, without requiring - # a reboot. - environment.systemPackages = [config.system.nssModules.list]; + # Use nss-myhostname to ensure that our hostname always resolves to + # a valid IP address. It returns all locally configured IP + # addresses, or ::1 and 127.0.0.2 as fallbacks. + system.nssModules = [ pkgs.nss_myhostname ]; } 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/programs/bash/bash.nix b/modules/programs/bash/bash.nix index 51654b164a0..441d30f1e9f 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; do + for m in "$p/etc/bash_completion.d/"*; do + . $m + done + done + eval "$nullglobStatus" + unset nullglobStatus p m + 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" 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 ]; }; } 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"]; diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index e6ae725f85f..8ddeacf1a0f 100644 --- a/modules/services/networking/firewall.nix +++ b/modules/services/networking/firewall.nix @@ -39,6 +39,15 @@ let } ''; + kernelPackages = config.boot.kernelPackages; + kernelHasRPFilter = kernelPackages.kernel ? features + && kernelPackages.kernel.features ? netfilterRPFilter + && kernelPackages.kernel.features.netfilterRPFilter; + + kernelCanDisableHelpers = kernelPackages.kernel ? features + && kernelPackages.kernel.features ? canDisableNetfilterConntrackHelpers + && kernelPackages.kernel.features.canDisableNetfilterConntrackHelpers; + in { @@ -140,6 +149,53 @@ 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.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"; @@ -168,7 +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"; } + { assertion = cfg.autoLoadConntrackHelpers || kernelCanDisableHelpers; + message = "This kernel does not support disabling conntrack helpers"; } + ]; jobs.firewall = { startOn = "started network-interfaces"; @@ -233,6 +298,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 diff --git a/modules/services/networking/hostapd.nix b/modules/services/networking/hostapd.nix new file mode 100644 index 00000000000..42779494b4b --- /dev/null +++ b/modules/services/networking/hostapd.nix @@ -0,0 +1,155 @@ +{ 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. Warning: This passphrase will + get put into a world-readable file in the nix store. + ''; + }; + + 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"; + exec = "${pkgs.hostapd}/bin/hostapd ${configFile}"; + }; + }; +} diff --git a/modules/services/networking/nat.nix b/modules/services/networking/nat.nix index c51eeb54be7..9d62a764f06 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,13 +27,16 @@ 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. ''; + # 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 { @@ -76,13 +81,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 +100,5 @@ in iptables -t nat -F POSTROUTING ''; }; - }; - } diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 9ceb66a85a0..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; }; @@ -101,7 +103,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 version24 then "authn_core" else "authn_alias") # Authorization: is the user allowed access? "authz_user" "authz_groupfile" "authz_host" @@ -113,11 +116,31 @@ let "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling" "userdir" "alias" "rewrite" "proxy" "proxy_http" ] + ++ optionals version24 [ + "mpm_${mainCfg.multiProcessingModule}" + "authz_core" + "unixd" + ] ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ]) ++ optional enableSSL "ssl" ++ extraApacheModules; + allDenied = if version24 then '' + Require all denied + '' else '' + Order deny,allow + Deny from all + ''; + + allGranted = if version24 then '' + Require all granted + '' else '' + Order allow,deny + Allow from all + ''; + + loggingConf = '' ErrorLog ${mainCfg.logDir}/error_log @@ -186,8 +209,7 @@ let Options Indexes FollowSymLinks AllowOverride None - Order allow,deny - Allow from all + ${allGranted} ''; @@ -241,12 +263,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} @@ -268,8 +288,7 @@ let Alias ${elem.urlPath} ${elem.dir}/ Options +Indexes - Order allow,deny - Allow from all + ${allGranted} AllowOverride All ''; @@ -286,6 +305,10 @@ let ServerRoot ${httpd} + ${optionalString version24 '' + DefaultRuntimeDir ${mainCfg.stateDir}/runtime + ''} + PidFile ${mainCfg.stateDir}/httpd.pid ${optionalString (mainCfg.multiProcessingModule != "prefork") '' @@ -321,8 +344,7 @@ let AddHandler type-map var - Order allow,deny - Deny from all + ${allDenied} ${mimeConf} @@ -340,16 +362,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. @@ -359,7 +379,8 @@ let ${let ports = map getPort allHosts; uniquePorts = uniqList {inputList = ports;}; - in concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts + directives = concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts; + in optionalString (!version24) directives } ${let @@ -620,6 +641,10 @@ in '' mkdir -m 0750 -p ${mainCfg.stateDir} chown root.${mainCfg.group} ${mainCfg.stateDir} + ${optionalString version24 '' + mkdir -m 0750 -p "${mainCfg.stateDir}/runtime" + chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime" + ''} mkdir -m 0700 -p ${mainCfg.logDir} ${optionalString (mainCfg.documentRoot != null)