Merge master.

This commit is contained in:
James Cook 2012-11-18 10:49:55 -08:00
commit 63dc873b85
17 changed files with 448 additions and 86 deletions

View File

@ -31,6 +31,7 @@ rec {
inherit pkgs modules baseModules;
modulesPath = ../modules;
pkgs_i686 = import <nixpkgs> { system = "i686-linux"; };
utils = {}; # forward compatibility
};
# Import Nixpkgs, allowing the NixOS option nixpkgs.config to

View File

@ -16,6 +16,18 @@ let
'';
};
networking.dnsSingleRequest = pkgs.lib.mkOption {
default = false;
description = ''
Recent versions of glibc will issue both ipv4 (A) and ipv6 (AAAA)
address queries at the same time, from the same port. Sometimes upstream
routers will systemically drop the ipv4 queries. The symptom of this problem is
that 'getent hosts example.com' only returns ipv6 (or perhaps only ipv4) addresses. The
workaround for this is to specify the option 'single-request' in
/etc/resolve.conf. This option enables that.
'';
};
};
in
@ -60,6 +72,9 @@ in
# Invalidate the nscd cache whenever resolv.conf is
# regenerated.
libc_restart='${pkgs.upstart}/sbin/start invalidate-nscd'
'' + optionalString cfg.dnsSingleRequest ''
# only send one DNS request at a time
resolv_conf_options='single-request'
'' + optionalString config.services.bind.enable ''
# This hosts runs a full-blown DNS resolver.
name_servers='127.0.0.1'

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" ''
Let all the files in the system tarball sit in a directory served by NFS (the NFS root)
like this in exportfs:
/home/pcroot 192.168.1.0/24(rw,no_root_squash,no_all_squash)
Run "exportfs -a" after editing /etc/exportfs, for the nfs server to be aware of the
changes.
Use a tftp server serving the root of boot/ (from the system tarball).
In order to have PXE boot, use the boot/dhcpd.conf-example file for your dhcpd server,
as it will point your PXE clients to pxelinux.0 from the tftp server. Adapt the
configuration to your network.
Adapt the pxelinux configuration (boot/pxelinux.cfg/default) to set the path to your
nfrroot. If you use ip=dhcp in the kernel, the nfs server ip will be taken from
dhcp and so you don't have to specify it.
The linux in bzImage includes network drivers for some usual cards.
QEMU Testing
---------------
You can test qemu pxe boot without having a DHCP server adapted, but having nfsroot,
like this:
qemu-system-x86_64 -tftp /home/pcroot/boot -net nic -net user,bootfile=pxelinux.0 -boot n
I don't know how to use NFS through the qemu '-net user' though.
QEMU Testing with NFS root and bridged network
-------------------------------------------------
This allows testing with qemu as any other host in your LAN.
Testing with the real dhcpd server requires setting up a bridge and having a tap device.
tunctl -t tap0
brctl addbr br0
brctl addif br0 eth0
brctl addif tap0 eth0
ifconfig eth0 0.0.0.0 up
ifconfig tap0 0.0.0.0 up
ifconfig br0 up # With your ip configuration
Then you can run qemu:
qemu-system-x86_64 -boot n -net tap,ifname=tap0,script=no -net nic,model=e1000
'';
readme = builtins.readFile ./system-tarball-pc-readme.txt;
in

View File

@ -129,6 +129,7 @@
./services/networking/gnunet.nix
./services/networking/gogoclient.nix
./services/networking/gvpe.nix
./services/networking/hostapd.nix
./services/networking/ifplugd.nix
./services/networking/ircd-hybrid/default.nix
./services/networking/nat.nix

View File

@ -7,6 +7,25 @@ with pkgs.lib;
let
initBashCompletion = optionalString config.environment.enableBashCompletion ''
# Check whether we're running a version of Bash that has support for
# programmable completion. If we do, enable all modules installed in
# the system (and user profile).
if shopt -q progcomp &>/dev/null; then
. "${pkgs.bashCompletion}/etc/profile.d/bash_completion.sh"
nullglobStatus=$(shopt -p nullglob)
shopt -s nullglob
for p in $NIX_PROFILES; do
for m in "$p/etc/bash_completion.d/"*; do
. $m
done
done
eval "$nullglobStatus"
unset nullglobStatus p m
fi
'';
options = {
environment.shellInit = mkOption {
@ -18,6 +37,12 @@ let
type = with pkgs.lib.types; string;
};
environment.enableBashCompletion = mkOption {
default = false;
description = "Enable bash-completion for all interactive shells.";
type = with pkgs.lib.types; bool;
};
};
in
@ -38,7 +63,10 @@ in
{ # /etc/bashrc: executed every time a bash starts. Sources
# /etc/profile to ensure that the system environment is
# configured properly.
source = ./bashrc.sh;
source = pkgs.substituteAll {
src = ./bashrc.sh;
inherit initBashCompletion;
};
target = "bashrc";
}
@ -59,4 +87,5 @@ in
mv /bin/.sh.tmp /bin/sh # atomically replace /bin/sh
'';
environment.pathsToLink = optional config.environment.enableBashCompletion "/etc/bash_completion.d";
}

View File

@ -27,15 +27,7 @@ if test "$TERM" = "xterm"; then
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
fi
# Check whether we're running a version of Bash that has support for
# programmable completion. If we do, and if the current user has
# installed the package 'bash-completion' in her $HOME/.nix-profile,
# then completion is enabled automatically.
if [ -f "$HOME/.nix-profile/etc/profile.d/bash_completion.sh" ]; then
if shopt -q progcomp &>/dev/null; then
. "$HOME/.nix-profile/etc/profile.d/bash_completion.sh"
fi
fi
@initBashCompletion@
# Some aliases.
alias ls="ls --color=tty"

View File

@ -235,6 +235,7 @@ in
{ name = "i3lock"; }
{ name = "lshd"; }
{ name = "samba"; }
{ name = "screen"; }
{ name = "sshd"; }
{ name = "vlock"; }
{ name = "xlock"; }

View File

@ -13,7 +13,7 @@ with pkgs.lib;
};
configFile = mkOption {
default = builtins.toPath "${pkgs.pommed}/etc/pommed.conf";
default = "${pkgs.pommed}/etc/pommed.conf";
description = ''
The contents of the pommed.conf file.
'';

View File

@ -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
<literal>dnsmasq.conf</literal>
'';
};
};
};
@ -49,7 +62,7 @@ in
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
{
@ -140,6 +149,53 @@ in
'';
};
networking.firewall.checkReversePath = mkOption {
default = kernelHasRPFilter;
type = types.bool;
description =
''
Performs a reverse path filter test on a packet.
If a reply to the packet would not be sent via the same interface
that the packet arrived on, it is refused.
If using asymmetric routing or other complicated routing,
disable this setting and setup your own counter-measures.
(needs kernel 3.3+)
'';
};
networking.firewall.connectionTrackingModules = mkOption {
default = [ "ftp" ];
example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
type = types.list types.string;
description =
''
List of connection-tracking helpers that are auto-loaded.
The complete list of possible values is given in the example.
As helpers can pose as a security risk, it is adviced to
set this to an empty list and disable the setting
networking.firewall.autoLoadConntrackHelpers
Loading of helpers is recommended to be done through the new
CT target. More info:
https://home.regit.org/netfilter-en/secure-use-of-helpers/
'';
};
networking.firewall.autoLoadConntrackHelpers = mkOption {
default = true;
type = types.bool;
description =
''
Whether to auto-load connection-tracking helpers.
See the description at networking.firewall.connectionTrackingModules
(needs kernel 3.5+)
'';
};
networking.firewall.extraCommands = mkOption {
default = "";
example = "iptables -A INPUT -p icmp -j ACCEPT";
@ -168,7 +224,16 @@ in
environment.systemPackages = [ pkgs.iptables ];
boot.kernelModules = [ "nf_conntrack_ftp" ];
boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
options nf_conntrack nf_conntrack_helper=0
'';
assertions = [ { assertion = ! cfg.checkReversePath || kernelHasRPFilter;
message = "This kernel does not support rpfilter"; }
{ assertion = cfg.autoLoadConntrackHelpers || kernelCanDisableHelpers;
message = "This kernel does not support disabling conntrack helpers"; }
];
jobs.firewall =
{ startOn = "started network-interfaces";
@ -233,6 +298,12 @@ in
# The "nixos-fw" chain does the actual work.
ip46tables -N nixos-fw
# Perform a reverse-path test to refuse spoofers
# For now, we just drop, as the raw table doesn't have a log-refuse yet
${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP
''}
# Accept all traffic on the trusted interfaces.
${flip concatMapStrings cfg.trustedInterfaces (iface: ''
ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept
@ -269,9 +340,11 @@ in
# Accept all ICMPv6 messages except redirects and node
# information queries (type 139). See RFC 4890, section
# 4.4.
ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP
ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP
ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept
${optionalString config.networking.enableIPv6 ''
ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP
ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP
ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept
''}
${cfg.extraCommands}

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

@ -34,6 +34,9 @@ in
coming from these networks and destined for the external
interface will be rewritten.
'';
# Backward compatibility: this used to be a single range instead
# of a list.
apply = x: if isList x then x else [x];
};
networking.nat.externalInterface = mkOption {
@ -78,8 +81,8 @@ in
''
iptables -t nat -F POSTROUTING
iptables -t nat -X
''
+ (concatMapStrings (network:
''
+ (concatMapStrings (network:
''
iptables -t nat -A POSTROUTING \
-s ${network} -o ${cfg.externalInterface} \

View File

@ -356,6 +356,7 @@ in
UsePAM ${if cfg.usePAM then "yes" else "no"}
AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
${concatMapStrings (port: ''
Port ${toString port}
'') cfg.ports}

View File

@ -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
<Directory "${documentRoot}">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
${allGranted}
</Directory>
'';
@ -241,12 +263,10 @@ let
AllowOverride FileInfo AuthConfig Limit Indexes
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
<Limit GET POST OPTIONS>
Order allow,deny
Allow from all
${allGranted}
</Limit>
<LimitExcept GET POST OPTIONS>
Order deny,allow
Deny from all
${allDenied}
</LimitExcept>
</Directory>
@ -268,8 +288,7 @@ let
Alias ${elem.urlPath} ${elem.dir}/
<Directory ${elem.dir}>
Options +Indexes
Order allow,deny
Allow from all
${allGranted}
AllowOverride All
</Directory>
'';
@ -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
<Files ~ "^\.ht">
Order allow,deny
Deny from all
${allDenied}
</Files>
${mimeConf}
@ -340,16 +362,14 @@ let
<Directory />
Options FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
${allDenied}
</Directory>
# 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
# want to serve.
<Directory /nix/store>
Order allow,deny
Allow from all
${allGranted}
</Directory>
# Generate directives for the main server.
@ -359,7 +379,8 @@ let
${let
ports = map getPort allHosts;
uniquePorts = uniqList {inputList = ports;};
in concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts
directives = concatMapStrings (port: "NameVirtualHost *:${toString port}\n") uniquePorts;
in optionalString (!version24) directives
}
${let
@ -620,6 +641,10 @@ in
''
mkdir -m 0750 -p ${mainCfg.stateDir}
chown root.${mainCfg.group} ${mainCfg.stateDir}
${optionalString version24 ''
mkdir -m 0750 -p "${mainCfg.stateDir}/runtime"
chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime"
''}
mkdir -m 0700 -p ${mainCfg.logDir}
${optionalString (mainCfg.documentRoot != null)

View File

@ -343,7 +343,8 @@ in
optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions ++
optional (elem "ati_unfree" driverNames) kernelPackages.ati_drivers_x11;
environment.etc = optionals cfg.exportConfiguration
environment.etc =
(optionals cfg.exportConfiguration
[ { source = "${configFile}";
target = "X11/xorg.conf";
}
@ -351,7 +352,15 @@ in
{ source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
target = "X11/xkb";
}
];
])
++ (optionals (elem "ati_unfree" driverNames) [
# according toiive on #ati you don't need the pcs, it is like registry... keeps old stuff to make your
# life harder ;) Still it seems to be required
{ source = "${kernelPackages.ati_drivers_x11}/etc/ati";
target = "ati";
}
]);
environment.x11Packages =
[ xorg.xorgserver
@ -420,6 +429,8 @@ in
"ln -sf ${kernelPackages.nvidia_x11_legacy96} /run/opengl-driver"
else if elem "nvidiaLegacy173" driverNames then
"ln -sf ${kernelPackages.nvidia_x11_legacy173} /run/opengl-driver"
else if elem "ati_unfree" driverNames then
"ln -sf ${kernelPackages.ati_drivers_x11} /run/opengl-driver"
else if cfg.driSupport then
"ln -sf ${pkgs.mesa} /run/opengl-driver"
else ""

View File

@ -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...";;