Move all of NixOS to nixos/ in preparation of the repository merge

This commit is contained in:
Eelco Dolstra
2013-10-10 13:28:20 +02:00
parent 6070bc016b
commit 5c1f8cbc70
481 changed files with 0 additions and 0 deletions
@@ -0,0 +1,80 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
clamavUser = "clamav";
stateDir = "/var/lib/clamav";
clamavGroup = clamavUser;
cfg = config.services.clamav;
in
{
###### interface
options = {
services.clamav = {
updater = {
enable = mkOption {
default = false;
description = ''
Whether to enable automatic ClamAV virus definitions database updates.
'';
};
frequency = mkOption {
default = 12;
description = ''
Number of database checks per day.
'';
};
config = mkOption {
default = "";
description = ''
Extra configuration for freshclam. Contents will be added verbatim to the
configuration file.
'';
};
};
};
};
###### implementation
config = mkIf cfg.updater.enable {
environment.systemPackages = [ pkgs.clamav ];
users.extraUsers = singleton
{ name = clamavUser;
uid = config.ids.uids.clamav;
description = "ClamAV daemon user";
home = stateDir;
};
users.extraGroups = singleton
{ name = clamavGroup;
gid = config.ids.gids.clamav;
};
services.clamav.updater.config = ''
DatabaseDirectory ${stateDir}
Foreground yes
Checks ${toString cfg.updater.frequency}
DatabaseMirror database.clamav.net
'';
jobs = {
clamav_updater = {
name = "clamav-updater";
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
preStart = ''
mkdir -m 0755 -p ${stateDir}
chown ${clamavUser}:${clamavGroup} ${stateDir}
'';
exec = "${pkgs.clamav}/bin/freshclam --config-file=${pkgs.writeText "freshclam.conf" cfg.updater.config}";
};
};
};
}
@@ -0,0 +1,150 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.fail2ban;
fail2banConf = pkgs.writeText "fail2ban.conf" cfg.daemonConfig;
jailConf = pkgs.writeText "jail.conf"
(concatStringsSep "\n" (attrValues (flip mapAttrs cfg.jails (name: def:
optionalString (def != "")
''
[${name}]
${def}
''))));
in
{
###### interface
options = {
services.fail2ban = {
daemonConfig = mkOption {
default =
''
[Definition]
loglevel = 3
logtarget = SYSLOG
socket = /var/run/fail2ban/fail2ban.sock
'';
type = types.string;
description =
''
The contents of Fail2ban's main configuration file. It's
generally not necessary to change it.
'';
};
jails = mkOption {
default = { };
example =
{ "apache-nohome-iptables" =
''
# Block an IP address if it accesses a non-existent
# home directory more than 5 times in 10 minutes,
# since that indicates that it's scanning.
filter = apache-nohome
action = iptables-multiport[name=HTTP, port="http,https"]
logpath = /var/log/httpd/error_log*
findtime = 600
bantime = 600
maxretry = 5
'';
};
type = types.attrsOf types.string;
description =
''
The configuration of each Fail2ban jail. A jail
consists of an action (such as blocking a port using
<command>iptables</command>) that is triggered when a
filter applied to a log file triggers more than a certain
number of times in a certain time period. Actions are
defined in <filename>/etc/fail2ban/action.d</filename>,
while filters are defined in
<filename>/etc/fail2ban/filter.d</filename>.
'';
};
};
};
###### implementation
config = {
environment.systemPackages = [ pkgs.fail2ban ];
environment.etc =
[ { source = fail2banConf;
target = "fail2ban/fail2ban.conf";
}
{ source = jailConf;
target = "fail2ban/jail.conf";
}
{ source = "${pkgs.fail2ban}/etc/fail2ban/action.d/*.conf";
target = "fail2ban/action.d";
}
{ source = "${pkgs.fail2ban}/etc/fail2ban/filter.d/*.conf";
target = "fail2ban/filter.d";
}
];
system.activationScripts.fail2ban =
''
mkdir -p /var/run/fail2ban -m 0755
'';
systemd.services.fail2ban =
{ description = "Fail2ban intrusion prevention system";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
restartTriggers = [ fail2banConf jailConf ];
path = [ pkgs.fail2ban pkgs.iptables ];
serviceConfig =
{ ExecStart = "${pkgs.fail2ban}/bin/fail2ban-server -f";
ReadOnlyDirectories = "/";
ReadWriteDirectories = "/var/run/fail2ban /var/tmp";
CapabilityBoundingSet="CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW";
};
postStart =
''
fail2ban-client reload
'';
};
# Add some reasonable default jails. The special "DEFAULT" jail
# sets default values for all other jails.
services.fail2ban.jails.DEFAULT =
''
ignoreip = 127.0.0.1/8
bantime = 600
findtime = 600
maxretry = 3
backend = auto
'';
# Block SSH if there are too many failing connection attempts.
services.fail2ban.jails."ssh-iptables" =
''
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/warn
maxretry = 5
'';
};
}
+88
View File
@@ -0,0 +1,88 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
fprotUser = "fprot";
stateDir = "/var/lib/fprot";
fprotGroup = fprotUser;
cfg = config.services.fprot;
in {
options = {
services.fprot = {
updater = {
enable = mkOption {
default = false;
description = ''
Whether to enable automatic F-Prot virus definitions database updates.
'';
};
productData = mkOption {
default = "${pkgs.fprot}/opt/f-prot/product.data";
description = ''
product.data file. Defaults to the one supplied with installation package.
'';
};
frequency = mkOption {
default = 30;
description = ''
Update virus definitions every X minutes.
'';
};
licenseKeyfile = mkOption {
default = "${pkgs.fprot}/opt/f-prot/license.key";
description = ''
License keyfile. Defaults to the one supplied with installation package.
'';
};
};
};
};
###### implementation
config = mkIf cfg.updater.enable {
environment.systemPackages = [ pkgs.fprot ];
environment.etc = singleton {
source = "${pkgs.fprot}/opt/f-prot/f-prot.conf";
target = "f-prot.conf";
};
users.extraUsers = singleton
{ name = fprotUser;
uid = config.ids.uids.fprot;
description = "F-Prot daemon user";
home = stateDir;
};
users.extraGroups = singleton
{ name = fprotGroup;
gid = config.ids.gids.fprot;
};
services.cron.systemCronJobs = [ "*/${toString cfg.updater.frequency} * * * * root start fprot-updater" ];
jobs = {
fprot_updater = {
name = "fprot-updater";
task = true;
# have to copy fpupdate executable because it insists on storing the virus database in the same dir
preStart = ''
mkdir -m 0755 -p ${stateDir}
chown ${fprotUser}:${fprotGroup} ${stateDir}
cp ${pkgs.fprot}/opt/f-prot/fpupdate ${stateDir}
ln -sf ${cfg.updater.productData} ${stateDir}/product.data
'';
#setuid = fprotUser;
#setgid = fprotGroup;
exec = "/var/lib/fprot/fpupdate --keyfile ${cfg.updater.licenseKeyfile}";
};
};
};
}
@@ -0,0 +1,31 @@
{pkgs, config, ...}:
let kernel = config.boot.kernelPackages;
in
{
###### interface
options = {
services.frandom.enable = pkgs.lib.mkOption {
default = false;
type = pkgs.lib.types.bool;
description = ''
enable the /dev/frandom device (a very fast random number generator)
'';
};
};
###### implementation
config = pkgs.lib.mkIf config.services.frandom.enable {
boot.kernelModules = [ "frandom" ];
boot.extraModulePackages = [ kernel.frandom ];
services.udev.packages = [ kernel.frandom ];
};
}
+321
View File
@@ -0,0 +1,321 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
inherit (pkgs) tor privoxy;
stateDir = "/var/lib/tor";
privoxyDir = stateDir+"/privoxy";
cfg = config.services.tor;
torUser = "tor";
opt = name: value: if value != "" then "${name} ${value}" else "";
optint = name: value: if value != 0 then "${name} ${toString value}" else "";
in
{
###### interface
options = {
services.tor = {
config = mkOption {
default = "";
description = ''
Extra configuration. Contents will be added verbatim to the
configuration file.
'';
};
client = {
enable = mkOption {
default = false;
description = ''
Whether to enable Tor daemon to route application connections.
You might want to disable this if you plan running a dedicated Tor relay.
'';
};
socksListenAddress = mkOption {
default = "127.0.0.1:9050";
example = "192.168.0.1:9100";
description = ''
Bind to this address to listen for connections from Socks-speaking
applications.
'';
};
socksListenAddressFaster = mkOption {
default = "127.0.0.1:9063";
description = ''
Same as socksListenAddress but uses weaker circuit isolation to provide
performance suitable for a web browser.
'';
};
socksPolicy = mkOption {
default = "";
example = "accept 192.168.0.0/16, reject *";
description = ''
Entry policies to allow/deny SOCKS requests based on IP address.
First entry that matches wins. If no SocksPolicy is set, we accept
all (and only) requests from SocksListenAddress.
'';
};
privoxy = {
enable = mkOption {
default = true;
description = ''
Whether to enable a special instance of privoxy dedicated to Tor.
To have anonymity, protocols need to be scrubbed of identifying
information.
Most people using Tor want to anonymize their web traffic, so by
default we enable an special instance of privoxy specifically for
Tor.
However, if you are only going to use Tor only for other kinds of
traffic then you can disable this option.
'';
};
listenAddress = mkOption {
default = "127.0.0.1:8118";
description = ''
Address that Tor's instance of privoxy is listening to.
*This does not configure the standard NixOS instance of privoxy.*
This is for Tor connections only!
See services.privoxy.listenAddress to configure the standard NixOS
instace of privoxy.
'';
};
config = mkOption {
default = "";
description = ''
Extra configuration for Tor's instance of privoxy. Contents will be
added verbatim to the configuration file.
*This does not configure the standard NixOS instance of privoxy.*
This is for Tor connections only!
See services.privoxy.extraConfig to configure the standard NixOS
instace of privoxy.
'';
};
};
};
relay = {
enable = mkOption {
default = false;
description = ''
Whether to enable relaying TOR traffic for others.
See https://www.torproject.org/docs/tor-doc-relay for details.
'';
};
isBridge = mkOption {
default = false;
description = ''
Bridge relays (or "bridges" ) are Tor relays that aren't listed in the
main directory. Since there is no complete public list of them, even if an
ISP is filtering connections to all the known Tor relays, they probably
won't be able to block all the bridges.
A bridge relay can't be an exit relay.
You need to set relay.enable to true for this option to take effect.
The bridge is set up with an obfuscated transport proxy.
See https://www.torproject.org/bridges.html.en for more info.
'';
};
isExit = mkOption {
default = false;
description = ''
An exit relay allows Tor users to access regular Internet services.
Unlike running a non-exit relay, running an exit relay may expose
you to abuse complaints. See https://www.torproject.org/faq.html.en#ExitPolicies for more info.
You can specify which services Tor users may access via your exit relay using exitPolicy option.
'';
};
nickname = mkOption {
default = "anonymous";
description = ''
A unique handle for your TOR relay.
'';
};
bandwidthRate = mkOption {
default = 0;
example = 100;
description = ''
Specify this to limit the bandwidth usage of relayed (server)
traffic. Your own traffic is still unthrottled. Units: bytes/second.
'';
};
bandwidthBurst = mkOption {
default = cfg.relay.bandwidthRate;
example = 200;
description = ''
Specify this to allow bursts of the bandwidth usage of relayed (server)
traffic. The average usage will still be as specified in relayBandwidthRate.
Your own traffic is still unthrottled. Units: bytes/second.
'';
};
port = mkOption {
default = 9001;
description = ''
What port to advertise for Tor connections.
'';
};
listenAddress = mkOption {
default = "";
example = "0.0.0.0:9090";
description = ''
Set this if you need to listen on a port other than the one advertised
in relayPort (e.g. to advertise 443 but bind to 9090). You'll need to do
ipchains or other port forwsarding yourself to make this work.
'';
};
exitPolicy = mkOption {
default = "";
example = "accept *:6660-6667,reject *:*";
description = ''
A comma-separated list of exit policies. They're considered first
to last, and the first match wins. If you want to _replace_
the default exit policy, end this with either a reject *:* or an
accept *:*. Otherwise, you're _augmenting_ (prepending to) the
default exit policy. Leave commented to just use the default, which is
available in the man page or at https://www.torproject.org/documentation.html
Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
for issues you might encounter if you use the default exit policy.
If certain IPs and ports are blocked externally, e.g. by your firewall,
you should update your exit policy to reflect this -- otherwise Tor
users will be told that those destinations are down.
'';
};
};
};
};
###### implementation
config = mkIf (cfg.client.enable || cfg.relay.enable) (
mkAssert (cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit)) "
Can't be both an exit and a bridge relay at the same time
" {
users.extraUsers = singleton
{ name = torUser;
uid = config.ids.uids.tor;
description = "Tor daemon user";
home = stateDir;
};
jobs = {
tor = { name = "tor";
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
preStart = ''
mkdir -m 0755 -p ${stateDir}
chown ${torUser} ${stateDir}
'';
exec = "${tor}/bin/tor -f ${pkgs.writeText "torrc" cfg.config}";
}; }
// optionalAttrs (cfg.client.privoxy.enable && cfg.client.enable) {
torPrivoxy = { name = "tor-privoxy";
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
preStart = ''
mkdir -m 0755 -p ${privoxyDir}
chown ${torUser} ${privoxyDir}
'';
exec = "${privoxy}/sbin/privoxy --no-daemon --user ${torUser} ${pkgs.writeText "torPrivoxy.conf" cfg.client.privoxy.config}";
}; };
services.tor.config = ''
DataDirectory ${stateDir}
User ${torUser}
''
+ optionalString cfg.client.enable ''
SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr
SOCKSPort ${cfg.client.socksListenAddressFaster}
${opt "SocksPolicy" cfg.client.socksPolicy}
''
+ optionalString cfg.relay.enable ''
ORPort ${toString cfg.relay.port}
${opt "ORListenAddress" cfg.relay.listenAddress }
${opt "Nickname" cfg.relay.nickname}
${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
${if cfg.relay.isExit then opt "ExitPolicy" cfg.relay.exitPolicy else "ExitPolicy reject *:*"}
${if cfg.relay.isBridge then ''
BridgeRelay 1
ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
'' else ""}
'';
services.tor.client.privoxy.config = ''
# Generally, this file goes in /etc/privoxy/config
#
# Tor listens as a SOCKS4a proxy here:
forward-socks4a / ${cfg.client.socksListenAddressFaster} .
confdir ${privoxy}/etc
logdir ${privoxyDir}
# actionsfile standard # Internal purpose, recommended
actionsfile default.action # Main actions file
actionsfile user.action # User customizations
filterfile default.filter
# Don't log interesting things, only startup messages, warnings and errors
logfile logfile
#jarfile jarfile
#debug 0 # show each GET/POST/CONNECT request
debug 4096 # Startup banner and warnings
debug 8192 # Errors - *we highly recommended enabling this*
user-manual ${privoxy}/doc/privoxy/user-manual
listen-address ${cfg.client.privoxy.listenAddress}
toggle 1
enable-remote-toggle 0
enable-edit-actions 0
enable-remote-http-toggle 0
buffer-limit 4096
# Extra config goes here
'';
});
}
@@ -0,0 +1,69 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.tor;
torify = pkgs.writeTextFile {
name = "torify";
text = ''
#!${pkgs.stdenv.shell}
TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.torify.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@"
'';
executable = true;
destination = "/bin/torify";
};
in
{
###### interface
options = {
services.tor.torify = {
enable = mkOption {
default = cfg.client.enable;
description = ''
Whether to build torify scipt to relay application traffic via TOR.
'';
};
server = mkOption {
default = "localhost:9050";
example = "192.168.0.20";
description = ''
IP address of TOR client to use.
'';
};
config = mkOption {
default = "";
description = ''
Extra configuration. Contents will be added verbatim to TSocks
configuration file.
'';
};
};
};
###### implementation
config = mkIf cfg.torify.enable {
environment.systemPackages = [ torify ]; # expose it to the users
services.tor.torify.config = ''
server = ${toString(head (splitString ":" cfg.torify.server))}
server_port = ${toString(tail (splitString ":" cfg.torify.server))}
local = 127.0.0.0/255.128.0.0
local = 127.128.0.0/255.192.0.0
'';
};
}
@@ -0,0 +1,85 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.tor;
makeConfig = server: ''
server = ${toString(head (splitString ":" server))}
server_port = ${toString(tail (splitString ":" server))}
local = 127.0.0.0/255.128.0.0
local = 127.128.0.0/255.192.0.0
local = 169.254.0.0/255.255.0.0
local = 172.16.0.0/255.240.0.0
local = 192.168.0.0/255.255.0.0
${cfg.torsocks.config}
'';
makeTorsocks = name: server: pkgs.writeTextFile {
name = name;
text = ''
#!${pkgs.stdenv.shell}
TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (makeConfig server)} LD_PRELOAD="${pkgs.torsocks}/lib/torsocks/libtorsocks.so $LD_PRELOAD" "$@"
'';
executable = true;
destination = "/bin/${name}";
};
torsocks = makeTorsocks "torsocks" cfg.torsocks.server;
torsocksFaster = makeTorsocks "torsocks-faster" cfg.torsocks.serverFaster;
in
{
###### interface
options = {
services.tor.torsocks = {
enable = mkOption {
default = cfg.client.enable;
description = ''
Whether to build torsocks scipt to relay application traffic via TOR.
'';
};
server = mkOption {
default = cfg.client.socksListenAddress;
example = "192.168.0.20:9050";
description = ''
IP address of TOR client to use.
'';
};
serverFaster = mkOption {
default = cfg.client.socksListenAddressFaster;
example = "192.168.0.20:9063";
description = ''
IP address of TOR client to use for applications like web browsers which
need less circuit isolation to achive satisfactory performance.
'';
};
config = mkOption {
default = "";
description = ''
Extra configuration. Contents will be added verbatim to torsocks
configuration file.
'';
};
};
};
###### implementation
config = mkIf cfg.torsocks.enable {
environment.systemPackages = [ torsocks torsocksFaster ]; # expose it to the users
};
}