Merge remote-tracking branch 'origin/master' into systemd

This commit is contained in:
Eelco Dolstra 2012-11-30 16:12:04 +01:00
commit b1da38f564
28 changed files with 853 additions and 272 deletions

View File

@ -150,7 +150,7 @@ $ nixos-rebuild switch -I <replaceable>/my/sources</replaceable>
definitions. This conditional values can be distinguished in two definitions. This conditional values can be distinguished in two
categories. The condition which are local to the current configuration categories. The condition which are local to the current configuration
and conditions which are dependent on others configurations. Local and conditions which are dependent on others configurations. Local
properties are <varname>mkIf</varname>, <varname>mkAlways</varname> properties are <varname>mkIf</varname>
and <varname>mkAssert</varname>. Global properties and <varname>mkAssert</varname>. Global properties
are <varname>mkOverride</varname>, <varname>mkDefault</varname> are <varname>mkOverride</varname>, <varname>mkDefault</varname>
and <varname>mkOrder</varname>.</para> and <varname>mkOrder</varname>.</para>
@ -158,12 +158,7 @@ $ nixos-rebuild switch -I <replaceable>/my/sources</replaceable>
<para><varname>mkIf</varname> is used to remove the option definitions which <para><varname>mkIf</varname> is used to remove the option definitions which
are below it if the condition is evaluated to are below it if the condition is evaluated to
false. <varname>mkAssert</varname> expects the condition to be evaluated false. <varname>mkAssert</varname> expects the condition to be evaluated
to true otherwise it raises an error message. <varname>mkAlways</varname> to true otherwise it raises an error message.</para>
is used to ignore all the <varname>mkIf</varname>
and <varname>mkAssert</varname> which have been made
previously. <varname>mkAlways</varname> and <varname>mkAssert</varname>
are often used together to set an option value and to ensure that it has
not been masked by another one.</para>
<para><varname>mkOverride</varname> is used to mask previous definitions if <para><varname>mkOverride</varname> is used to mask previous definitions if
the current value has a lower mask number. The mask value is 100 (default) the current value has a lower mask number. The mask value is 100 (default)
@ -223,14 +218,6 @@ let
locatedb = "/var/cache/locatedb"; locatedb = "/var/cache/locatedb";
logfile = "/var/log/updatedb"; logfile = "/var/log/updatedb";
cmd =''root updatedb --localuser=nobody --output=${locatedb} > ${logfile}''; 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 in
{ {
@ -260,9 +247,9 @@ in
}; };
}; };
config = mkCheck { config = mkIf cfg.enable {
services.cron = { services.cron = {
enable = mkAlways cfg.enable; enable = true;
systemCronJobs = "${cfg.period} root ${cmd}"; systemCronJobs = "${cfg.period} root ${cmd}";
}; };
}; };

View File

@ -1,8 +1,13 @@
{pkgs, config, ...}: {pkgs, config, ...}:
with pkgs.lib;
with pkgs;
###### interface ###### interface
let let
inherit (pkgs.lib) mkOption mkIf optionalString stringAfter; inherit mkOption mkIf optionalString stringAfter singleton;
cfg = config.users.ldap;
options = { options = {
users = { users = {
@ -41,7 +46,7 @@ let
timeLimit = mkOption { timeLimit = mkOption {
default = 0; default = 0;
type = with pkgs.lib.types; int; type = types.int;
description = " description = "
Specifies the time limit (in seconds) to use when performing Specifies the time limit (in seconds) to use when performing
searches. A value of zero (0), which is the default, is to 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 = { bind = {
distinguishedName = mkOption { distinguishedName = mkOption {
default = ""; default = "";
example = "cn=admin,dc=example,dc=com"; example = "cn=admin,dc=example,dc=com";
type = with pkgs.lib.types; string; type = types.string;
description = " description = "
The distinguished name to bind to the LDAP server with. If this The distinguished name to bind to the LDAP server with. If this
is not specified, an anonymous bind will be done. is not specified, an anonymous bind will be done.
@ -62,7 +92,7 @@ let
password = mkOption { password = mkOption {
default = "/etc/ldap/bind.password"; default = "/etc/ldap/bind.password";
type = with pkgs.lib.types; string; type = types.string;
description = " description = "
The path to a file containing the credentials to use when binding The path to a file containing the credentials to use when binding
to the LDAP server (if not binding anonymously). to the LDAP server (if not binding anonymously).
@ -71,7 +101,7 @@ let
timeLimit = mkOption { timeLimit = mkOption {
default = 30; default = 30;
type = with pkgs.lib.types; int; type = types.int;
description = " description = "
Specifies the time limit (in seconds) to use when connecting Specifies the time limit (in seconds) to use when connecting
to the directory server. This is distinct from the time limit to the directory server. This is distinct from the time limit
@ -82,7 +112,7 @@ let
policy = mkOption { policy = mkOption {
default = "hard_open"; default = "hard_open";
type = with pkgs.lib.types; string; type = types.string;
description = " description = "
Specifies the policy to use for reconnecting to an unavailable Specifies the policy to use for reconnecting to an unavailable
LDAP server. The default is <literal>hard_open</literal>, which LDAP server. The default is <literal>hard_open</literal>, 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 <literal>users.ldap.daemon</literal> is enabled, this
configuration will not be used. In that case, use
<literal>users.ldap.daemon.extraConfig</literal> instead.
'' ;
};
}; };
}; };
}; };
in
###### implementation
mkIf config.users.ldap.enable {
require = [
options
];
# LDAP configuration.
environment = {
etc = [
# Careful: OpenLDAP seems to be very picky about the indentation of # Careful: OpenLDAP seems to be very picky about the indentation of
# this file. Directives HAVE to start in the first column! # this file. Directives HAVE to start in the first column!
{ source = pkgs.writeText "ldap.conf" ldapConfig = {
'' target = "ldap.conf";
source = writeText "ldap.conf" ''
uri ${config.users.ldap.server} uri ${config.users.ldap.server}
base ${config.users.ldap.base} base ${config.users.ldap.base}
timelimit ${toString config.users.ldap.timeLimit} timelimit ${toString config.users.ldap.timeLimit}
bind_timelimit ${toString config.users.ldap.bind.timeLimit} bind_timelimit ${toString config.users.ldap.bind.timeLimit}
bind_policy ${config.users.ldap.bind.policy} bind_policy ${config.users.ldap.bind.policy}
${optionalString config.users.ldap.useTLS '' ${optionalString config.users.ldap.useTLS ''
ssl start_tls ssl start_tls
tls_checkpeer no tls_checkpeer no
''} ''}
${optionalString (config.users.ldap.bind.distinguishedName != "") '' ${optionalString (config.users.ldap.bind.distinguishedName != "") ''
binddn ${config.users.ldap.bind.distinguishedName} binddn ${config.users.ldap.bind.distinguishedName}
''} ''}
${optionalString (cfg.extraConfig != "") cfg.extraConfig }
''; '';
target = "ldap.conf";
}
];
}; };
system.activationScripts.ldap = stringAfter [ "etc" ] ( nslcdConfig = {
optionalString (config.users.ldap.bind.distinguishedName != "") '' target = "nslcd.conf";
if test -f "${config.users.ldap.bind.password}" ; then source = writeText "nslcd.conf" ''
echo "bindpw $(cat ${config.users.ldap.bind.password})" | cat /etc/ldap.conf - > /etc/ldap.conf.bindpw 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 cfg.enable {
require = [
options
];
environment.etc = if cfg.daemon.enable then [nslcdConfig] else [ldapConfig];
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 mv -fT /etc/ldap.conf.bindpw /etc/ldap.conf
chmod 600 /etc/ldap.conf chmod 600 /etc/ldap.conf
fi 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";
};
};
} }

View File

@ -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 in
@ -64,6 +76,9 @@ in
# Invalidate the nscd cache whenever resolv.conf is # Invalidate the nscd cache whenever resolv.conf is
# regenerated. # regenerated.
libc_restart='${pkgs.systemd}/bin/systemctl reload --no-block nscd.service' 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 '' '' + optionalString config.services.bind.enable ''
# This hosts runs a full-blown DNS resolver. # This hosts runs a full-blown DNS resolver.
name_servers='127.0.0.1' name_servers='127.0.0.1'

View File

@ -19,14 +19,9 @@ let
"; ";
merge = mergeListOption; merge = mergeListOption;
apply = list: apply = list:
let {
list2 = inherit list;
list path = makeLibraryPath list;
# !!! this should be in the LDAP module
++ optional config.users.ldap.enable pkgs.nss_ldap;
in {
list = list2;
path = makeLibraryPath list2;
}; };
}; };

View File

@ -28,15 +28,11 @@ let cfg = config.hardware.pulseaudio; in
}; };
config = mkIf cfg.enable { config = mkMerge
environment.systemPackages =
[ cfg.package ];
environment.etc = mkAlways (
[ # Create pulse/client.conf even if PulseAudio is disabled so [ # Create pulse/client.conf even if PulseAudio is disabled so
# that we can disable the autospawn feature in programs that # that we can disable the autospawn feature in programs that
# are built with PulseAudio support (like KDE). # are built with PulseAudio support (like KDE).
{ environment.etc = singleton
{ target = "pulse/client.conf"; { target = "pulse/client.conf";
source = pkgs.writeText "client.conf" source = pkgs.writeText "client.conf"
'' ''
@ -45,9 +41,14 @@ let cfg = config.hardware.pulseaudio; in
daemon-binary=${cfg.package}/bin/pulseaudio daemon-binary=${cfg.package}/bin/pulseaudio
''} ''}
''; '';
};
} }
] ++ optionals cfg.enable (mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.etc =
[ # Write an /etc/asound.conf that causes all ALSA applications to [ # Write an /etc/asound.conf that causes all ALSA applications to
# be re-routed to the PulseAudio server through ALSA's Pulse # be re-routed to the PulseAudio server through ALSA's Pulse
# plugin. # plugin.
@ -80,12 +81,12 @@ let cfg = config.hardware.pulseaudio; in
{ target = "pulse/system.pa"; { target = "pulse/system.pa";
source = "${cfg.package}/etc/pulse/system.pa"; source = "${cfg.package}/etc/pulse/system.pa";
} }
];
]);
# Allow PulseAudio to get realtime priority using rtkit. # Allow PulseAudio to get realtime priority using rtkit.
security.rtkit.enable = true; security.rtkit.enable = true;
}; })
];
} }

View File

@ -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

View File

@ -60,54 +60,7 @@ let
} }
''; '';
readme = pkgs.writeText "readme.txt" '' readme = ./system-tarball-pc-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
'';
in in

View File

@ -6,6 +6,7 @@ let
crashdump = config.boot.crashDump; crashdump = config.boot.crashDump;
kernelParams = concatStringsSep " " crashdump.kernelParams; kernelParams = concatStringsSep " " crashdump.kernelParams;
in in
###### interface ###### interface
{ {
@ -55,6 +56,8 @@ in
kernelParams = [ kernelParams = [
"crashkernel=64M" "crashkernel=64M"
"nmi_watchdog=panic" "nmi_watchdog=panic"
"softlockup_panic=1"
"idle=poll"
]; ];
kernelPackages = mkOverride 50 (crashdump.kernelPackages // { kernelPackages = mkOverride 50 (crashdump.kernelPackages // {
kernel = crashdump.kernelPackages.kernel.override kernel = crashdump.kernelPackages.kernel.override

View File

@ -74,6 +74,7 @@ in
bind = 53; bind = 53;
wwwrun = 54; wwwrun = 54;
spamd = 56; spamd = 56;
nslcd = 58;
# When adding a uid, make sure it doesn't match an existing gid. # When adding a uid, make sure it doesn't match an existing gid.
@ -129,6 +130,7 @@ in
adm = 55; adm = 55;
spamd = 56; spamd = 56;
networkmanager = 57; networkmanager = 57;
nslcd = 58;
# When adding a gid, make sure it doesn't match an existing uid. # When adding a gid, make sure it doesn't match an existing uid.

View File

@ -39,6 +39,7 @@
./programs/blcr.nix ./programs/blcr.nix
./programs/info.nix ./programs/info.nix
./programs/shadow.nix ./programs/shadow.nix
./programs/shell.nix
./programs/ssh.nix ./programs/ssh.nix
./programs/ssmtp.nix ./programs/ssmtp.nix
./programs/wvdial.nix ./programs/wvdial.nix
@ -127,6 +128,7 @@
./services/networking/gnunet.nix ./services/networking/gnunet.nix
./services/networking/gogoclient.nix ./services/networking/gogoclient.nix
./services/networking/gvpe.nix ./services/networking/gvpe.nix
./services/networking/hostapd.nix
./services/networking/ifplugd.nix ./services/networking/ifplugd.nix
./services/networking/ircd-hybrid/default.nix ./services/networking/ircd-hybrid/default.nix
./services/networking/nat.nix ./services/networking/nat.nix

View File

@ -25,6 +25,10 @@ let
fi fi
''; '';
shellAliases = concatStringsSep "\n" (
mapAttrsFlatten (k: v: "alias ${k}='${v}'") config.environment.shellAliases
);
options = { options = {
environment.promptInit = mkOption { environment.promptInit = mkOption {
@ -93,7 +97,7 @@ in
source = pkgs.substituteAll { source = pkgs.substituteAll {
src = ./bashrc.sh; src = ./bashrc.sh;
inherit (config.environment) promptInit; inherit (config.environment) promptInit;
inherit initBashCompletion; inherit initBashCompletion shellAliases;
}; };
target = "bashrc"; target = "bashrc";
} }
@ -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.build.binsh = pkgs.bashInteractive;
system.activationScripts.binsh = stringAfter [ "stdio" ] system.activationScripts.binsh = stringAfter [ "stdio" ]

View File

@ -21,15 +21,4 @@ shopt -s checkwinsize
@promptInit@ @promptInit@
@initBashCompletion@ @initBashCompletion@
@shellAliases@
# 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"

View File

@ -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 = {
};
}

View File

@ -16,11 +16,15 @@ in
programs.ssh = { programs.ssh = {
forwardX11 = mkOption { forwardX11 = mkOption {
default = cfgd.forwardX11; default = false;
description = '' description = ''
Whether to request X11 forwarding on outgoing connections by default. 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. 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. 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.
''; '';
}; };

View File

@ -7,7 +7,9 @@ with pkgs.lib;
let 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" otherService = pkgs.writeText "other.pam"
'' ''
@ -249,6 +251,7 @@ in
{ name = "i3lock"; } { name = "i3lock"; }
{ name = "lshd"; } { name = "lshd"; }
{ name = "samba"; } { name = "samba"; }
{ name = "screen"; }
{ name = "vlock"; } { name = "vlock"; }
{ name = "xlock"; } { name = "xlock"; }
{ name = "xscreensaver"; } { name = "xscreensaver"; }

View File

@ -5,16 +5,13 @@ with pkgs.lib;
let let
cfg = config.services.logcheck; cfg = config.services.logcheck;
rulesDir = pkgs.runCommand "logcheck-rules-dir" defaultRules = pkgs.runCommand "logcheck-default-rules" {} ''
{} ( cp -prd ${pkgs.logcheck}/etc/logcheck $out
'' chmod u+w $out
mkdir $out
cp -prd ${pkgs.logcheck}/etc/logcheck/* $out/
rm $out/logcheck.* rm $out/logcheck.*
chmod u+w $out/* '';
'' + optionalString (! builtins.isNull cfg.extraRulesDir) ''
cp -prd ${cfg.extraRulesDir}/* $out/ rulesDir = pkgs.symlinkJoin "logcheck-rules-dir" ([ defaultRules ] ++ cfg.extraRulesDirs);
'' );
configFile = pkgs.writeText "logcheck.conf" cfg.config; 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} 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 in
{ {
options = { options = {
@ -98,16 +163,33 @@ in
''; '';
}; };
extraRulesDir = mkOption { extraRulesDirs = mkOption {
default = null; default = [];
example = "/etc/logcheck"; example = "/etc/logcheck";
type = types.nullOr types.path; type = types.listOf types.path;
description = '' description = ''
Directory with extra rules. Directories with extra rules.
Will be merged with bundled rules, so it's possible to override certain behaviour.
''; '';
}; };
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 { extraGroups = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.string;
@ -122,6 +204,10 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.logcheck.extraRulesDirs =
mapAttrsToList writeIgnoreRule cfg.ignore
++ mapAttrsToList writeIgnoreCronRule cfg.ignoreCron;
users.extraUsers = singleton users.extraUsers = singleton
{ name = cfg.user; { name = cfg.user;
shell = "/bin/sh"; shell = "/bin/sh";
@ -134,6 +220,12 @@ in
chown ${cfg.user} /var/{lib,lock}/logcheck 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 ];
}; };
} }

View File

@ -24,7 +24,7 @@ let
smartdConf = pkgs.writeText "smartd.conf" (concatMapStrings (device: 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); ) 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 { devices = mkOption {
default = []; default = [];
example = ["/dev/sda" "/dev/sdb"]; example = ["/dev/sda" "/dev/sdb"];

View File

@ -180,8 +180,17 @@ in
###### implementation ###### 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";
};
}
(mkIf config.services.samba.enable {
users.extraUsers = singleton users.extraUsers = singleton
{ name = user; { name = user;
description = "Samba service user"; description = "Samba service user";
@ -192,13 +201,6 @@ in
{ name = group; { 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). # Dummy job to start the real Samba daemons (nmbd, smbd, winbindd).
jobs.sambaControl = jobs.sambaControl =
@ -216,7 +218,7 @@ in
jobs.smbd = daemonJob "smbd" "-D"; jobs.smbd = daemonJob "smbd" "-D";
jobs.winbindd = daemonJob "winbindd" "-D"; jobs.winbindd = daemonJob "winbindd" "-D";
})
}; ];
} }

View File

@ -8,6 +8,10 @@ let
serversParam = concatMapStrings (s: "-S ${s} ") cfg.servers; serversParam = concatMapStrings (s: "-S ${s} ") cfg.servers;
dnsmasqConf = pkgs.writeText "dnsmasq.conf" ''
${cfg.extraConfig}
'';
in in
{ {
@ -33,6 +37,15 @@ in
''; '';
}; };
extraConfig = mkOption {
type = types.string;
default = "";
description = ''
Extra configuration directives that should be added to
<literal>dnsmasq.conf</literal>
'';
};
}; };
}; };
@ -49,7 +62,7 @@ in
daemonType = "daemon"; daemonType = "daemon";
exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam}"; exec = "${dnsmasq}/bin/dnsmasq -R ${serversParam} -o -C ${dnsmasqConf}";
}; };
}; };

View File

@ -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 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 { networking.firewall.extraCommands = mkOption {
default = ""; default = "";
example = "iptables -A INPUT -p icmp -j ACCEPT"; example = "iptables -A INPUT -p icmp -j ACCEPT";
@ -168,7 +224,16 @@ in
environment.systemPackages = [ pkgs.iptables ]; 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 = jobs.firewall =
{ startOn = "started network-interfaces"; { startOn = "started network-interfaces";
@ -232,6 +297,12 @@ in
# The "nixos-fw" chain does the actual work. # The "nixos-fw" chain does the actual work.
ip46tables -N nixos-fw 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. # Accept all traffic on the trusted interfaces.
${flip concatMapStrings cfg.trustedInterfaces (iface: '' ${flip concatMapStrings cfg.trustedInterfaces (iface: ''
ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept

View File

@ -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 <command>hostapd</command> 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}";
};
};
}

View File

@ -1,4 +1,6 @@
# This module enables Network Address Translation (NAT). # This module enables Network Address Translation (NAT).
# XXX: todo: support multiple upstream links
# see http://yesican.chsoft.biz/lartc/MultihomedLinuxNetworking.html
{ config, pkgs, ... }: { config, pkgs, ... }:
@ -25,13 +27,16 @@ in
}; };
networking.nat.internalIPs = mkOption { networking.nat.internalIPs = mkOption {
example = "192.168.1.0/24"; example = [ "192.168.1.0/24" ] ;
description = description =
'' ''
The IP address range for which to perform NAT. Packets The IP address ranges for which to perform NAT. Packets
coming from these addresses and destined for the external coming from these networks and destined for the external
interface will be rewritten. 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 { networking.nat.externalInterface = mkOption {
@ -76,13 +81,17 @@ in
'' ''
iptables -t nat -F POSTROUTING iptables -t nat -F POSTROUTING
iptables -t nat -X iptables -t nat -X
''
+ (concatMapStrings (network:
''
iptables -t nat -A POSTROUTING \ iptables -t nat -A POSTROUTING \
-s ${cfg.internalIPs} -o ${cfg.externalInterface} \ -s ${network} -o ${cfg.externalInterface} \
${if cfg.externalIP == "" ${if cfg.externalIP == ""
then "-j MASQUERADE" then "-j MASQUERADE"
else "-j SNAT --to-source ${cfg.externalIP}"} else "-j SNAT --to-source ${cfg.externalIP}"}
''
) cfg.internalIPs) +
''
echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/ip_forward
''; '';
@ -91,7 +100,5 @@ in
iptables -t nat -F POSTROUTING iptables -t nat -F POSTROUTING
''; '';
}; };
}; };
} }

View File

@ -41,7 +41,7 @@ in
flags = "REUSE NAMEINARGS"; flags = "REUSE NAMEINARGS";
protocol = "tcp"; protocol = "tcp";
user = "root"; user = "root";
server = "${pkgs.tcpWrapper}/sbin/tcpd"; server = "${pkgs.tcp_wrappers}/sbin/tcpd";
serverArgs = "${pkgs.heimdal}/sbin/kadmind"; serverArgs = "${pkgs.heimdal}/sbin/kadmind";
}; };

View File

@ -8,6 +8,8 @@ let
httpd = mainCfg.package; httpd = mainCfg.package;
version24 = !versionOlder httpd.version "2.4";
httpdConf = mainCfg.configFile; httpdConf = mainCfg.configFile;
php = pkgs.php.override { apacheHttpd = httpd; }; php = pkgs.php.override { apacheHttpd = httpd; };
@ -101,7 +103,8 @@ let
"auth_basic" "auth_digest" "auth_basic" "auth_digest"
# Authentication: is the user who he claims to be? # 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? # Authorization: is the user allowed access?
"authz_user" "authz_groupfile" "authz_host" "authz_user" "authz_groupfile" "authz_host"
@ -113,11 +116,31 @@ let
"vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling" "vhost_alias" "negotiation" "dir" "imagemap" "actions" "speling"
"userdir" "alias" "rewrite" "proxy" "proxy_http" "userdir" "alias" "rewrite" "proxy" "proxy_http"
] ]
++ optionals version24 [
"mpm_${mainCfg.multiProcessingModule}"
"authz_core"
"unixd"
]
++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ]) ++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
++ optional enableSSL "ssl" ++ optional enableSSL "ssl"
++ extraApacheModules; ++ 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 = '' loggingConf = ''
ErrorLog ${mainCfg.logDir}/error_log ErrorLog ${mainCfg.logDir}/error_log
@ -186,8 +209,7 @@ let
<Directory "${documentRoot}"> <Directory "${documentRoot}">
Options Indexes FollowSymLinks Options Indexes FollowSymLinks
AllowOverride None AllowOverride None
Order allow,deny ${allGranted}
Allow from all
</Directory> </Directory>
''; '';
@ -241,12 +263,10 @@ let
AllowOverride FileInfo AuthConfig Limit Indexes AllowOverride FileInfo AuthConfig Limit Indexes
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
<Limit GET POST OPTIONS> <Limit GET POST OPTIONS>
Order allow,deny ${allGranted}
Allow from all
</Limit> </Limit>
<LimitExcept GET POST OPTIONS> <LimitExcept GET POST OPTIONS>
Order deny,allow ${allDenied}
Deny from all
</LimitExcept> </LimitExcept>
</Directory> </Directory>
@ -268,8 +288,7 @@ let
Alias ${elem.urlPath} ${elem.dir}/ Alias ${elem.urlPath} ${elem.dir}/
<Directory ${elem.dir}> <Directory ${elem.dir}>
Options +Indexes Options +Indexes
Order allow,deny ${allGranted}
Allow from all
AllowOverride All AllowOverride All
</Directory> </Directory>
''; '';
@ -286,6 +305,10 @@ let
ServerRoot ${httpd} ServerRoot ${httpd}
${optionalString version24 ''
DefaultRuntimeDir ${mainCfg.stateDir}/runtime
''}
PidFile ${mainCfg.stateDir}/httpd.pid PidFile ${mainCfg.stateDir}/httpd.pid
${optionalString (mainCfg.multiProcessingModule != "prefork") '' ${optionalString (mainCfg.multiProcessingModule != "prefork") ''
@ -321,8 +344,7 @@ let
AddHandler type-map var AddHandler type-map var
<Files ~ "^\.ht"> <Files ~ "^\.ht">
Order allow,deny ${allDenied}
Deny from all
</Files> </Files>
${mimeConf} ${mimeConf}
@ -340,16 +362,14 @@ let
<Directory /> <Directory />
Options FollowSymLinks Options FollowSymLinks
AllowOverride None AllowOverride None
Order deny,allow ${allDenied}
Deny from all
</Directory> </Directory>
# But do allow access to files in the store so that we don't have # But do allow access to files in the store so that we don't have
# to generate <Directory> clauses for every generated file that we # to generate <Directory> clauses for every generated file that we
# want to serve. # want to serve.
<Directory /nix/store> <Directory /nix/store>
Order allow,deny ${allGranted}
Allow from all
</Directory> </Directory>
# Generate directives for the main server. # Generate directives for the main server.
@ -359,7 +379,8 @@ let
${let ${let
ports = map getPort allHosts; ports = map getPort allHosts;
uniquePorts = uniqList {inputList = ports;}; 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 ${let
@ -604,6 +625,10 @@ in
'' ''
mkdir -m 0750 -p ${mainCfg.stateDir} mkdir -m 0750 -p ${mainCfg.stateDir}
chown root.${mainCfg.group} ${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} mkdir -m 0700 -p ${mainCfg.logDir}
${optionalString (mainCfg.documentRoot != null) ${optionalString (mainCfg.documentRoot != null)

View File

@ -343,7 +343,8 @@ in
optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions ++ optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions ++
optional (elem "ati_unfree" driverNames) kernelPackages.ati_drivers_x11; optional (elem "ati_unfree" driverNames) kernelPackages.ati_drivers_x11;
environment.etc = optionals cfg.exportConfiguration environment.etc =
(optionals cfg.exportConfiguration
[ { source = "${configFile}"; [ { source = "${configFile}";
target = "X11/xorg.conf"; target = "X11/xorg.conf";
} }
@ -351,7 +352,15 @@ in
{ source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; { source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
target = "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 = environment.x11Packages =
[ xorg.xorgserver [ xorg.xorgserver
@ -417,6 +426,8 @@ in
"ln -sf ${kernelPackages.nvidia_x11_legacy96} /run/opengl-driver" "ln -sf ${kernelPackages.nvidia_x11_legacy96} /run/opengl-driver"
else if elem "nvidiaLegacy173" driverNames then else if elem "nvidiaLegacy173" driverNames then
"ln -sf ${kernelPackages.nvidia_x11_legacy173} /run/opengl-driver" "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 else if cfg.driSupport then
"ln -sf ${pkgs.mesa} /run/opengl-driver" "ln -sf ${pkgs.mesa} /run/opengl-driver"
else "" else ""

View File

@ -40,10 +40,10 @@ EOF
case $reply in case $reply in
f) f)
exec setsid @shell@ < /dev/$console >/dev/$console 2>/dev/$console ;; exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" ;;
i) i)
echo "Starting interactive shell..." 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...";; echo "Continuing...";;

View File

@ -469,5 +469,12 @@ in
"CGROUPS" "AUTOFS4_FS" "DEVTMPFS" "CGROUPS" "AUTOFS4_FS" "DEVTMPFS"
]; ];
environment.shellAliases =
{ start = "systemctl start";
stop = "systemctl stop";
restart = "systemctl restart";
status = "systemctl status";
};
}; };
} }

View File

@ -5,8 +5,19 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
with pkgs.lib; 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" = boot.systemd.services."fetch-ec2-data" =
{ description = "Fetch EC2 Data"; { description = "Fetch EC2 Data";
@ -56,9 +67,11 @@ with pkgs.lib;
echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub
fi fi
${optionalString (! config.ec2.metadata) ''
# Since the user data is sensitive, prevent it from being # Since the user data is sensitive, prevent it from being
# accessed from now on. # accessed from now on.
ip route add blackhole 169.254.169.254/32 ip route add blackhole 169.254.169.254/32
''}
''; '';
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";