diff --git a/doc/manual/development.xml b/doc/manual/development.xml index 017a0f007fab..0b02c7f60c6c 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/ldap.nix b/modules/config/ldap.nix index 3821482361f7..1e115943f231 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/networking.nix b/modules/config/networking.nix index 5fc06c341ad2..e9d04c49904d 100644 --- a/modules/config/networking.nix +++ b/modules/config/networking.nix @@ -18,6 +18,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 @@ -64,6 +76,9 @@ in # Invalidate the nscd cache whenever resolv.conf is # regenerated. libc_restart='${pkgs.systemd}/bin/systemctl reload --no-block nscd.service' + '' + 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' diff --git a/modules/config/nsswitch.nix b/modules/config/nsswitch.nix index 806ff8763038..4660bf7c92d2 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/config/pulseaudio.nix b/modules/config/pulseaudio.nix index 71bf0081e4eb..5dffd9d3afba 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/installer/cd-dvd/system-tarball-pc-readme.txt b/modules/installer/cd-dvd/system-tarball-pc-readme.txt new file mode 100644 index 000000000000..c4a0a111cd3a --- /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 2bc6ce78d943..1046786c6dfb 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 = ./system-tarball-pc-readme.txt; in diff --git a/modules/misc/crashdump.nix b/modules/misc/crashdump.nix index 98b2140a23d5..6e6bc9dec0f3 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 diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix index f26501105b1e..92e9bb908939 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. diff --git a/modules/module-list.nix b/modules/module-list.nix index 3f66ff917fd4..467eac6e00e4 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 @@ -127,6 +128,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 9d52eeebf8e9..a4afb733fa7f 100644 --- a/modules/programs/bash/bash.nix +++ b/modules/programs/bash/bash.nix @@ -25,6 +25,10 @@ let fi ''; + shellAliases = concatStringsSep "\n" ( + mapAttrsFlatten (k: v: "alias ${k}='${v}'") config.environment.shellAliases + ); + options = { environment.promptInit = mkOption { @@ -90,12 +94,12 @@ 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 (config.environment) promptInit; - inherit initBashCompletion; - }; - target = "bashrc"; + source = pkgs.substituteAll { + src = ./bashrc.sh; + inherit (config.environment) promptInit; + inherit initBashCompletion shellAliases; + }; + target = "bashrc"; } { # Configuration for readline in bash. @@ -104,6 +108,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 3542b5f9fd49..4615004d47cc 100644 --- a/modules/programs/bash/bashrc.sh +++ b/modules/programs/bash/bashrc.sh @@ -21,15 +21,4 @@ shopt -s checkwinsize @promptInit@ @initBashCompletion@ - -# Some aliases. -alias ls="ls --color=tty" -alias ll="ls -l" -alias l="ls -alh" -alias which="type -P" - -# Convenience for people used to Upstart. -alias start="systemctl start" -alias stop="systemctl stop" -alias restart="systemctl restart" -alias status="systemctl status" +@shellAliases@ diff --git a/modules/programs/shell.nix b/modules/programs/shell.nix new file mode 100644 index 000000000000..8348c4c25a1c --- /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 = { + }; +} diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix index fc9ba9a92806..f28de02bb4eb 100644 --- a/modules/programs/ssh.nix +++ b/modules/programs/ssh.nix @@ -16,11 +16,15 @@ 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. + 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. ''; }; diff --git a/modules/security/pam.nix b/modules/security/pam.nix index 7293f207ed02..940c596e3670 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" '' @@ -249,6 +251,7 @@ in { name = "i3lock"; } { name = "lshd"; } { name = "samba"; } + { name = "screen"; } { name = "vlock"; } { name = "xlock"; } { name = "xscreensaver"; } diff --git a/modules/services/logging/logcheck.nix b/modules/services/logging/logcheck.nix index 40d736255eca..23f21b6a754d 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 242faa010f29..7e57f90398b7 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/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix index 2cf4e8c11ff0..93c07df7cc60 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"; + }) + ]; } diff --git a/modules/services/networking/dnsmasq.nix b/modules/services/networking/dnsmasq.nix index 389d5c22e827..b726493d421f 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}"; + exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam} -o -C ${dnsmasqConf}"; }; }; diff --git a/modules/services/networking/firewall.nix b/modules/services/networking/firewall.nix index d0119c56fce5..d262f1f76cbc 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"; @@ -232,6 +297,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 000000000000..42779494b4b8 --- /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 c51eeb54be78..9d62a764f060 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/system/kerberos.nix b/modules/services/system/kerberos.nix index 2a47b9045899..8fb5debd20e4 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"; }; diff --git a/modules/services/web-servers/apache-httpd/default.nix b/modules/services/web-servers/apache-httpd/default.nix index 8e4a516ea134..17a8c8216cad 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 @@ -604,6 +625,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) diff --git a/modules/services/x11/xserver.nix b/modules/services/x11/xserver.nix index 992911ca3c4b..1c5a3f75039b 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 @@ -417,6 +426,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 "" diff --git a/modules/system/boot/stage-1-init.sh b/modules/system/boot/stage-1-init.sh index 9c04757e1315..23207babe3fa 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...";; diff --git a/modules/system/boot/systemd.nix b/modules/system/boot/systemd.nix index 86e269e0763a..720c8efc53fa 100644 --- a/modules/system/boot/systemd.nix +++ b/modules/system/boot/systemd.nix @@ -469,5 +469,12 @@ in "CGROUPS" "AUTOFS4_FS" "DEVTMPFS" ]; + environment.shellAliases = + { start = "systemctl start"; + stop = "systemctl stop"; + restart = "systemctl restart"; + status = "systemctl status"; + }; + }; } diff --git a/modules/virtualisation/ec2-data.nix b/modules/virtualisation/ec2-data.nix index 6ca89dd7ac5b..33b8c1e516dc 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]; boot.systemd.services."fetch-ec2-data" = { description = "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 + ''} ''; serviceConfig.Type = "oneshot";