From f93ca99fab906b6d2b83dc3b4c9410da7c29bdde Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 5 Mar 2015 13:01:05 +0100 Subject: [PATCH] initial commit --- certs/zalora-ca.crt | 24 +++ lib/default.nix | 44 +++++ modules/base.nix | 17 ++ modules/exim.nix | 122 ++++++++++++ modules/hosts.nix | 25 +++ modules/iptables.nix | 69 +++++++ modules/nginx.nix | 30 +++ modules/retiolum.nix | 224 +++++++++++++++++++++ modules/tools.nix | 101 ++++++++++ modules/urxvt.nix | 24 +++ modules/users.nix | 226 +++++++++++++++++++++ modules/xserver.nix | 51 +++++ wu.nix | 457 +++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1414 insertions(+) create mode 100644 certs/zalora-ca.crt create mode 100644 lib/default.nix create mode 100644 modules/base.nix create mode 100644 modules/exim.nix create mode 100644 modules/hosts.nix create mode 100644 modules/iptables.nix create mode 100644 modules/nginx.nix create mode 100644 modules/retiolum.nix create mode 100644 modules/tools.nix create mode 100644 modules/urxvt.nix create mode 100644 modules/users.nix create mode 100644 modules/xserver.nix create mode 100644 wu.nix diff --git a/certs/zalora-ca.crt b/certs/zalora-ca.crt new file mode 100644 index 000000000..12cdf8fc6 --- /dev/null +++ b/certs/zalora-ca.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIJAPImpJwMgGmhMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYD +VQQGEwJTRzESMBAGA1UECAwJU2luZ2Fwb3JlMQ8wDQYDVQQKDAZaYWxvcmExCzAJ +BgNVBAsMAklUMSUwIwYDVQQDDBxaYWxvcmEgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MSUwIwYJKoZIhvcNAQkBFhZpdC1zZXJ2aWNlc0B6YWxvcmEuY29tMB4XDTE0MDkx +ODIxNDY0N1oXDTI0MDkxNTIxNDY0N1owgY0xCzAJBgNVBAYTAlNHMRIwEAYDVQQI +DAlTaW5nYXBvcmUxDzANBgNVBAoMBlphbG9yYTELMAkGA1UECwwCSVQxJTAjBgNV +BAMMHFphbG9yYSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxJTAjBgkqhkiG9w0BCQEW +Fml0LXNlcnZpY2VzQHphbG9yYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDi48Tkh6XuS2gdE1+gsPPQjTI8Q2wbXqZGTHnyAZx75btOIUZHeHJm +Fvu8erAD+vtx1nD1GOG30uvHFk9Of2mFY1fxw0R1LthJHSLFJU1/GjFSggHWkaI3 +HBSmeALjss/XHG3EtShLo8SHBc/+B8ehqj1JqcXF8q50JtfTQ+zlf+k26ke2S5Xo +OdHLxjlNaPwj+TgJI1DHqs/bTapaPHPKk5+jFQzAcMmq0bygzpQTHCvvKqcoXaJk +UgDBQnVsJUtwfObrM1TKu2TOXUhqgfnnflYf2sz5Sr30QlkrHP+PM3BRLB+6FXhr +UlKKVcAcIwrBo0aJ5Sd0fv39GwV1XCWVAgMBAAGjUDBOMB0GA1UdDgQWBBQFftMH +5/dc0pUNDqLbVQ8gm7+I5TAfBgNVHSMEGDAWgBQFftMH5/dc0pUNDqLbVQ8gm7+I +5TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQC2aSKJ15v5OI7Zj/HQ +lW+iY9STBPJi9lgOjaGrNaPX0IuhJLkeKDntmzjvpGwvcylHMp6Im02svTymteNN +38s8A0aStnmW4ysGT853H7L7Jxzf7J2vrUF0Dj4QkZ07Gp3vAgKnWVcqz36Xr0Se +DEqrKMl/6fq3Ygl35fZXP1kb6t/wP6qx69bnENH6ksHFpZapWYssKNZO9yiB8+Eq +ngB22X/ycMmAqOnNQDzw1JBw7LzdXypCG75UKEK6kbnUy2yPADdHpH8v9qcRa1U9 +vEmUTJs6i1CpPO+2frPJ8A8QIp61nNxe7xJ1SnNVtwk9d6SRet6YGySvgG748Wjw +GwWx +-----END CERTIFICATE----- diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 000000000..c1663a7b8 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,44 @@ +{ pkgs, ... }: + +with builtins; + +let + inherit (pkgs.lib) stringAsChars; +in + +{ + + + # "7.4.335" -> "74" + majmin = with pkgs.lib; x : concatStrings (take 2 (splitString "." x)); + + + concat = xs : + if xs == [] + then "" + else head xs + concat (tail xs) + ; + + flip = f : x : y : f y x; + + # isSuffixOf :: String -> String -> Bool + isSuffixOf = + s : xs : + let + sn = stringLength s; + xsn = stringLength xs; + in + xsn >= sn && substring (xsn - sn) sn xs == s ; + + removeSuffix = + s : xs : substring 0 (stringLength xs - stringLength s) xs; + + # setMap :: (String -> a -> b) -> Set String a -> [b] + #setMap = f: xs: map (k : f k (getAttr k xs)) (attrNames xs); + + # setToList :: Set k a -> [a] + #setToList = setMap (_: v: v); + + shell-escape = + stringAsChars (c: if c == "\n" then ''"${c}"'' else "\\${c}"); +} diff --git a/modules/base.nix b/modules/base.nix new file mode 100644 index 000000000..76c8b8970 --- /dev/null +++ b/modules/base.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + time.timeZone = "Europe/Berlin"; + + nix.maxJobs = 8; + nix.useChroot = true; + # TODO check if both are required: + nix.chrootDirs = [ "/etc/protocols" pkgs.iana_etc.outPath ]; + + nix.trustedBinaryCaches = [ + "https://cache.nixos.org" + "http://cache.nixos.org" + "http://hydra.nixos.org" + ]; + +} diff --git a/modules/exim.nix b/modules/exim.nix new file mode 100644 index 000000000..4a0232c8c --- /dev/null +++ b/modules/exim.nix @@ -0,0 +1,122 @@ +{ config, pkgs, ... }: + +{ + services.exim = + let + retiolumHostname = "wu.retiolum"; # TODO "${networking.hostName}.retiolum"; + in + { enable = true; + config = '' + primary_hostname = ${retiolumHostname} + domainlist local_domains = @ : localhost + domainlist relay_to_domains = *.retiolum + hostlist relay_from_hosts = <; 127.0.0.1 ; ::1 + + acl_smtp_rcpt = acl_check_rcpt + acl_smtp_data = acl_check_data + + host_lookup = * + rfc1413_hosts = * + rfc1413_query_timeout = 5s + + log_file_path = syslog + syslog_timestamp = false + syslog_duplication = false + + begin acl + + acl_check_rcpt: + accept hosts = : + control = dkim_disable_verify + + deny message = Restricted characters in address + domains = +local_domains + local_parts = ^[.] : ^.*[@%!/|] + + deny message = Restricted characters in address + domains = !+local_domains + local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ + + accept local_parts = postmaster + domains = +local_domains + + #accept + # hosts = *.retiolum + # domains = *.retiolum + # control = dkim_disable_verify + + #require verify = sender + + accept hosts = +relay_from_hosts + control = submission + control = dkim_disable_verify + + accept authenticated = * + control = submission + control = dkim_disable_verify + + require message = relay not permitted + domains = +local_domains : +relay_to_domains + + require verify = recipient + + accept + + + acl_check_data: + accept + + + begin routers + + retiolum: + driver = manualroute + domains = ! ${retiolumHostname} : *.retiolum + transport = remote_smtp + route_list = ^.* $0 byname + no_more + + nonlocal: + debug_print = "R: nonlocal for $local_part@$domain" + driver = redirect + domains = ! +local_domains + allow_fail + data = :fail: Mailing to remote domains not supported + no_more + + local_user: + # debug_print = "R: local_user for $local_part@$domain" + driver = accept + check_local_user + # local_part_suffix = +* : -* + # local_part_suffix_optional + transport = home_maildir + cannot_route_message = Unknown user + + + begin transports + + remote_smtp: + driver = smtp + + home_maildir: + driver = appendfile + maildir_format + directory = $home/Maildir + directory_mode = 0700 + delivery_date_add + envelope_to_add + return_path_add + # group = mail + # mode = 0660 + + begin retry + *.retiolum * F,42d,1m + * * F,2h,15m; G,16h,1h,1.5; F,4d,6h + + begin rewrite + + begin authenticators + ''; + }; +} diff --git a/modules/hosts.nix b/modules/hosts.nix new file mode 100644 index 000000000..f59f87cc0 --- /dev/null +++ b/modules/hosts.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +{ + networking.extraHosts = + '' + 192.168.1.1 wrt.gg23 wrt + 192.168.1.11 mors.gg23 + 192.168.1.12 uriel.gg23 + 192.168.1.23 raspi.gg23 raspi + 192.168.1.37 wu.gg23 + 192.168.1.110 nomic.gg23 + 192.168.1.124 schnabeldrucker.gg23 schnabeldrucker + + 127.0.0.1 dev.zalora.sg www.dev.zalora.sg bob.dev.zalora.sg static.dev.zalora.sg + 127.0.0.1 dev.zalora.com.my www.dev.zalora.com.my bob.dev.zalora.com.my static.dev.zalora.com.my + 127.0.0.1 dev.zalora.com.ph www.dev.zalora.com.ph bob.dev.zalora.com.ph static.dev.zalora.com.ph + 127.0.0.1 dev.zalora.vn www.dev.zalora.vn bob.dev.zalora.vn static.dev.zalora.vn + 127.0.0.1 dev.zalora.co.id www.dev.zalora.co.id bob.dev.zalora.co.id static.dev.zalora.co.id + 127.0.0.1 dev.zalora.co.th www.dev.zalora.co.th bob.dev.zalora.co.th static.dev.zalora.co.th + 127.0.0.1 dev.zalora.com.hk www.dev.zalora.com.hk bob.dev.zalora.com.hk static.dev.zalora.com.hk + + 54.93.104.95 eu-dev.hk.zalora.net www.eu-dev.hk.zalora.net bob.eu-dev.hk.zalora.net static.eu-dev.hk.zalora.net + 54.93.104.95 eu-dev.sg.zalora.net www.eu-dev.sg.zalora.net bob.eu-dev.sg.zalora.net static.eu-dev.sg.zalora.net + ''; +} diff --git a/modules/iptables.nix b/modules/iptables.nix new file mode 100644 index 000000000..ee4034321 --- /dev/null +++ b/modules/iptables.nix @@ -0,0 +1,69 @@ +{ config, pkgs, ... }: + +{ + # + # iptables + # + networking.firewall.enable = false; + system.activationScripts.iptables = + let + log = false; + when = c: f: if c then f else ""; + in + '' + ip4tables() { ${pkgs.iptables}/sbin/iptables "$@"; } + ip6tables() { ${pkgs.iptables}/sbin/ip6tables "$@"; } + ipXtables() { ip4tables "$@"; ip6tables "$@"; } + + # + # nat + # + + # reset tables + ipXtables -t nat -F + ipXtables -t nat -X + + # + ipXtables -t nat -A PREROUTING -j REDIRECT ! -i retiolum -p tcp --dport ssh --to-ports 0 + ipXtables -t nat -A PREROUTING -j REDIRECT -p tcp --dport 11423 --to-ports ssh + + # + # filter + # + + # reset tables + ipXtables -P INPUT DROP + ipXtables -P FORWARD DROP + ipXtables -F + ipXtables -X + + # create custom chains + ipXtables -N Retiolum + + # INPUT + ipXtables -A INPUT -j ACCEPT -m conntrack --ctstate RELATED,ESTABLISHED + ipXtables -A INPUT -j ACCEPT -i lo + ipXtables -A INPUT -j ACCEPT -p tcp --dport ssh -m conntrack --ctstate NEW + ipXtables -A INPUT -j ACCEPT -p tcp --dport http -m conntrack --ctstate NEW + ipXtables -A INPUT -j ACCEPT -p tcp --dport tinc -m conntrack --ctstate NEW + ipXtables -A INPUT -j ACCEPT -p tcp --dport smtp -m conntrack --ctstate NEW + ipXtables -A INPUT -j Retiolum -i retiolum + ${when log "ipXtables -A INPUT -j LOG --log-level info --log-prefix 'INPUT DROP '"} + + # FORWARD + ${when log "ipXtables -A FORWARD -j LOG --log-level info --log-prefix 'FORWARD DROP '"} + + # Retiolum + ip4tables -A Retiolum -j ACCEPT -p icmp --icmp-type echo-request + ip6tables -A Retiolum -j ACCEPT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request + + + ${when log "ipXtables -A Retiolum -j LOG --log-level info --log-prefix 'REJECT '"} + ipXtables -A Retiolum -j REJECT -p tcp --reject-with tcp-reset + ip4tables -A Retiolum -j REJECT -p udp --reject-with icmp-port-unreachable + ip4tables -A Retiolum -j REJECT --reject-with icmp-proto-unreachable + ip6tables -A Retiolum -j REJECT -p udp --reject-with icmp6-port-unreachable + ip6tables -A Retiolum -j REJECT + + ''; +} diff --git a/modules/nginx.nix b/modules/nginx.nix new file mode 100644 index 000000000..8b420613b --- /dev/null +++ b/modules/nginx.nix @@ -0,0 +1,30 @@ +{ config, pkgs, ... }: + +{ + services.nginx = + let + name = config.networking.hostName; + qname = "${name}.retiolum"; + in + { + enable = true; + httpConfig = '' + sendfile on; + server { + listen 80; + server_name ${name} ${qname} localhost; + root /srv/http/${name}; + location ~ ^/~(.+?)(/.*)?$ { + alias /home/$1/public_html$2; + } + } + types { + text/css css; + text/html html; + image/svg+xml svg; + } + default_type text/html; + charset utf-8; + ''; + }; +} diff --git a/modules/retiolum.nix b/modules/retiolum.nix new file mode 100644 index 000000000..40112165b --- /dev/null +++ b/modules/retiolum.nix @@ -0,0 +1,224 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + + ###### interface + + options = { + services.retiolum = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Enable tinc daemon for Retiolum."; + }; + + name = mkOption { + type = types.string; + default = config.networking.hostName; + # Description stolen from tinc.conf(5). + description = '' + This is the name which identifies this tinc daemon. It must + be unique for the virtual private network this daemon will + connect to. The Name may only consist of alphanumeric and + underscore characters. If Name starts with a $, then the + contents of the environment variable that follows will be + used. In that case, invalid characters will be converted to + underscores. If Name is $HOST, but no such environment + variable exist, the hostname will be read using the + gethostnname() system call This is the name which identifies + the this tinc daemon. + ''; + }; + + generateEtcHosts = mkOption { + type = types.string; + default = "both"; + description = '' + If set to short, long, or both, + then generate entries in /etc/hosts from subnets. + ''; + }; + + network = mkOption { + type = types.string; + default = "retiolum"; + description = '' + The tinc network name. + It is used to generate long host entries, + derive the name of the user account under which tincd runs, + and name the TUN device. + ''; + }; + + tincPackage = mkOption { + type = types.package; + default = pkgs.tinc; + description = "Tincd package to use."; + }; + + hosts = mkOption { + default = null; + description = '' + Hosts package or path to use. + If a path is given, then it will be used to generate an ad-hoc package. + ''; + }; + + iproutePackage = mkOption { + type = types.package; + default = pkgs.iproute; + description = "Iproute2 package to use."; + }; + + + privateKeyFile = mkOption { + # TODO if it's types.path then it gets copied to /nix/store with + # bad unsafe permissions... + type = types.string; + default = "/etc/tinc/retiolum/rsa_key.priv"; + description = "Generate file with tincd -K."; + }; + + connectTo = mkOption { + type = types.listOf types.string; + default = [ "fastpoke" "pigstarter" "kheurop" ]; + description = "TODO describe me"; + }; + + }; + }; + + + ###### implementation + + config = + let + cfg = config.services.retiolum; + tinc = cfg.tincPackage; + hostsType = builtins.typeOf cfg.hosts; + hosts = + if hostsType == "package" then + # use package as is + cfg.hosts + else if hostsType == "path" then + # use path to generate a package + pkgs.stdenv.mkDerivation { + name = "custom-retiolum-hosts"; + src = cfg.hosts; + installPhase = '' + mkdir $out + find . -name .git -prune -o -type f -print0 | xargs -0 cp --target-directory $out + ''; + } + else + abort "The option `services.retiolum.hosts' must be set to a package or a path" + ; + iproute = cfg.iproutePackage; + + retiolumExtraHosts = import (pkgs.runCommand "retiolum-etc-hosts" + { } + '' + generate() { + (cd ${hosts} + printf \'\' + for i in `ls`; do + sed -En ' + s|^ *Subnet *= *([^ /]*)(/[0-9]*)? *$|\1 '"$(hostnames $i)"'|p + ' $i + done | sort + printf \'\' + ) + } + + case ${cfg.generateEtcHosts} in + short) + hostnames() { echo "$1"; } + generate + ;; + long) + hostnames() { echo "$1.${cfg.network}"; } + generate + ;; + both) + hostnames() { echo "$1.${cfg.network} $1"; } + generate + ;; + *) + echo '""' + ;; + esac > $out + ''); + + + confDir = pkgs.runCommand "retiolum" { + # TODO text + executable = true; + preferLocalBuild = true; + } '' + set -euf + + mkdir -p $out + + ln -s ${hosts} $out/hosts + + cat > $out/tinc.conf < $out/tinc-up <&2 + exit 23 + ''; + + rebuild = + '' + nixpkgs=''${nixpkgs-/home/tv/src/nixpkgs} + nixos-rebuild \ + --show-trace \ + -I nixpkgs="$nixpkgs" \ + switch \ + 2>&1 \ + | sed ${shell-escape '' + s|"\(/home/tv/src/config/[^":]*\)"|\1| + s|^trace:\s*\(.*\)|\1| + ''} + ''; + + }; + + wrap = script: + '' + #! /bin/sh + set -euf + ${script} + ''; + #lib=$lib + #export PATH=$bin:${makeSearchPath "bin" buildInputs} + + buildScript = name: script: + builtins.trace "building ${name}" + '' + echo ${shell-escape script} > $bin/${shell-escape name} + chmod +x $bin/${shell-escape name} + ''; + + + + tools = pkgs.stdenv.mkDerivation rec { + name = "tools"; + src = /var/empty; + + buildInputs = []; + + + buildPhase = + '' + mkdir $out + + bin=$out/bin + mkdir $bin + + ${concatStringsSep "\n" (attrValues (mapAttrs buildScript scripts))} + + ''; + #'' + #mkdir $out + + #lib=$out/lib + #cp -r lib $lib + + #bin=$out/bin + #mkdir $bin + #${concatStringsSep "\n" (attrValues (mapAttrs (name: script: + # '' + # { + # echo '#! /bin/sh' + # echo 'set -euf' + # echo "lib=$lib" + # echo "export PATH=$bin:${makeSearchPath "bin" buildInputs}" + # echo ${shell-escape script} + # } > $bin/${name} + # chmod +x $bin/${name} + # '') scripts))} + #''; + installPhase = ":"; + }; + +in + +{ + environment.systemPackages = [ tools ]; +} diff --git a/modules/urxvt.nix b/modules/urxvt.nix new file mode 100644 index 000000000..a97581248 --- /dev/null +++ b/modules/urxvt.nix @@ -0,0 +1,24 @@ +{ pkgs, ... }: + + with builtins; + +let + users = [ "tv" ]; + urxvt = pkgs.rxvt_unicode; + mkService = user: { + description = "urxvt terminal daemon"; + wantedBy = [ "multi-user.target" ]; + restartIfChanged = false; + serviceConfig = { + Restart = "always"; + User = user; + ExecStart = "${urxvt}/bin/urxvtd"; + }; + }; + +in + +{ + environment.systemPackages = [ urxvt ]; + systemd.services = listToAttrs (map (u: { name = "${u}-urxvtd"; value = mkService u; }) users); +} diff --git a/modules/users.nix b/modules/users.nix new file mode 100644 index 000000000..eec1defa5 --- /dev/null +++ b/modules/users.nix @@ -0,0 +1,226 @@ +{ config, pkgs, ... }: + +let + inherit (builtins) attrValues; + inherit (pkgs.lib) concatMap filterAttrs mapAttrs concatStringsSep; + + + users = { + tv = { + uid = 1337; + group = "users"; + extraGroups = [ + "audio" + "video" + "wheel" + ]; + }; + + ff = { + uid = 13378001; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + ]; + }; + + cr = { + uid = 13378002; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + vimb = { + uid = 13378003; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + fa = { + uid = 2300001; + group = "tv-sub"; + }; + + rl = { + uid = 2300002; + group = "tv-sub"; + }; + + btc-bitcoind = { + uid = 2301001; + group = "tv-sub"; + }; + + btc-electrum = { + uid = 2301002; + group = "tv-sub"; + }; + + ltc-litecoind = { + uid = 2301101; + group = "tv-sub"; + }; + + eth = { + uid = 2302001; + group = "tv-sub"; + }; + + emse-hsdb = { + uid = 4200101; + group = "tv-sub"; + }; + + wine = { + uid = 13370400; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + # dwarffortress + df = { + uid = 13370401; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + # XXX visudo: Warning: Runas_Alias `FTL' referenced but not defined + FTL = { + uid = 13370402; + #group = "tv-sub"; + extraGroups = [ + "audio" + "video" + "bumblebee" + ]; + }; + + freeciv = { + uid = 13370403; + group = "tv-sub"; + }; + + xr = { + uid = 13370061; + group = "tv-sub"; + extraGroups = [ + "audio" + "video" + ]; + }; + + "23" = { + uid = 13370023; + group = "tv-sub"; + }; + + electrum = { + uid = 13370102; + group = "tv-sub"; + }; + + Reaktor = { + uid = 4230010; + group = "tv-sub"; + }; + + gitolite = { + uid = 7700; + }; + + skype = { + uid = 6660001; + group = "tv-sub"; + extraGroups = [ + "audio" + ]; + }; + + onion = { + uid = 6660010; + group = "tv-sub"; + }; + + zalora = { + uid = 1000301; + group = "tv-sub"; + extraGroups = [ + "audio" + # TODO remove vboxusers when hardening is active + "vboxusers" + "video" + ]; + }; + + }; + + + extraUsers = + mapAttrs (name: user: user // { + inherit name; + home = "/home/${name}"; + createHome = true; + useDefaultShell = true; + }) users; + + + extraGroups = { + tv-sub.gid = 1337; + }; + + + sudoers = + let + inherit (builtins) filter hasAttr; + inherit (import ../lib { inherit pkgs; }) concat isSuffixOf removeSuffix setToList; + + hasMaster = { group ? "", ... }: + isSuffixOf "-sub" group; + + masterOf = user : removeSuffix "-sub" user.group; + in + concatStringsSep "\n" + (map (u: "${masterOf u} ALL=(${u.name}) NOPASSWD: ALL") + (filter hasMaster (attrValues extraUsers))); + +in + + +{ + imports = [ + + ]; + + users.defaultUserShell = "/run/current-system/sw/bin/bash"; + users.extraGroups = extraGroups; + users.extraUsers = extraUsers; + users.mutableUsers = false; + + #security.sudo.configFile = sudoers config.users.extraUsers; + security.sudo.configFile = + with builtins; trace + '' + OK + '' + sudoers; + security.sudo.extraConfig = '' + Defaults mailto="tv@wu.retiolum" + ''; +} diff --git a/modules/xserver.nix b/modules/xserver.nix new file mode 100644 index 000000000..c65201802 --- /dev/null +++ b/modules/xserver.nix @@ -0,0 +1,51 @@ +{ config, pkgs, ... }: + +{ + services.xserver.enable = true; + + + #fonts.enableFontConfig = true; + #fonts.enableFontDir = true; + fonts.fonts = [ + pkgs.xlibs.fontschumachermisc + ]; + #services.xfs.enable = true; + #services.xserver.useXFS = "unix/:7100"; + + services.xserver.displayManager.desktopManagerHandlesLidAndPower = true; + + #services.xserver.display = 11; + #services.xserver.tty = 11; + # services.xserver.layout = "us"; + # services.xserver.xkbOptions = "eurosign:e"; + + # TODO this is host specific + services.xserver.synaptics = { + enable = true; + twoFingerScroll = true; + accelFactor = "0.035"; + additionalOptions = '' + Option "FingerHigh" "60" + Option "FingerLow" "60" + ''; + }; + + #services.xserver.multitouch.enable = true; + + services.xserver.windowManager.xmonad.extraPackages = hspkgs: with hspkgs; [ + X11-xshape + ]; + services.xserver.windowManager.xmonad.enable = true; + services.xserver.windowManager.xmonad.enableContribAndExtras = true; + services.xserver.windowManager.default = "xmonad"; + services.xserver.desktopManager.default = "none"; + services.xserver.desktopManager.xterm.enable = false; + + services.xserver.displayManager.slim.enable = true; + #services.xserver.displayManager.auto.enable = true; + #services.xserver.displayManager.auto.user = "tv"; + #services.xserver.displayManager.job.logsXsession = true; + + + services.xserver.vaapiDrivers = [ pkgs.vaapiIntel ]; +} diff --git a/wu.nix b/wu.nix new file mode 100644 index 000000000..de435fc3a --- /dev/null +++ b/wu.nix @@ -0,0 +1,457 @@ +{ config, pkgs, ... }: + +with (import ./lib { inherit pkgs; }); + +{ + imports = [ + ./modules/base.nix + ./modules/retiolum.nix + ./modules/urxvt.nix + ./modules/iptables.nix + ./modules/users.nix + ./modules/tools.nix + ./modules/hosts.nix + ./modules/xserver.nix + ./modules/exim.nix + ./modules/nginx.nix + ]; + + services.udev.extraRules = '' + SUBSYSTEM=="net", ATTR{address}=="00:90:f5:da:aa:c3", NAME="en0" + SUBSYSTEM=="net", ATTR{address}=="a0:88:b4:1b:ae:6c", NAME="wl0" + + # for jack + KERNEL=="rtc0", GROUP="audio" + KERNEL=="hpet", GROUP="audio" + ''; + + #services.virtualbox.enable = true; + #services.virtualboxGuest.enable = false; + services.virtualboxHost.enable = true; + #services.virtualboxHost.addNetworkInterface = false; + #systemd.services.vboxnet = + # let + # remove_vboxnets = '' + # for i in $(cd /sys/class/net && ls | grep ^vboxnet); do + # VBoxManage hostonlyif remove $i + # done + # ''; + # in { + # wantedBy = [ "multi-user.target" ]; + # requires = [ "dev-vboxnetctl.device" ]; + # after = [ "dev-vboxnetctl.device" ]; + # path = with pkgs; [ + # linuxPackages.virtualbox + # nettools + # ]; + # postStop = remove_vboxnets; + # script = '' + # ${remove_vboxnets} # just in case... + # VBoxManage hostonlyif create # vboxnet0 + # ifconfig vboxnet0 up 169.254.13.37/16 + # ''; + # serviceConfig = { + # Type = "oneshot"; + # PrivateTmp = true; + # RemainAfterExit = "yes"; + # }; + # environment.VBOX_USER_HOME = "/tmp"; + # }; + + + services.bitlbee.enable = true; + + #services.rabbitmq = { + # enable = true; + # cookie = "f00f"; + # plugins = [ + # "rabbitmq_management" + # ]; + #}; + + + #services.elasticsearch.enable = true; + + #services.cgserver = { + # enable = true; + # httpPort = 8003; + # #flushLog = false; + # #cgroupRoot = "/sys/fs/cgroup"; + # #user = "zalora"; + #}; + + + + + #services.tlsdated = { + # enable = true; + # extraOptions = "-p"; + #}; + + services.tor.enable = true; + services.tor.client.enable = true; + + + + # hardware configuration + boot.initrd.luks.devices = [ + { name = "home"; device = "/dev/vg840/enchome"; preLVM = false; } + ]; + boot.initrd.luks.cryptoModules = [ "aes" "sha512" "xts" ]; + boot.initrd.availableKernelModules = [ "ahci" ]; + #boot.kernelParams = [ + # "intel_pstate=enable" + #]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + # 2014-12-17 pkgs.linuxPackages_3_14 is known good + boot.kernelPackages = pkgs.linuxPackages_3_18; + + boot.kernel.sysctl = { + # Enable IPv6 Privacy Extensions + "net.ipv6.conf.all.use_tempaddr" = 2; + "net.ipv6.conf.default.use_tempaddr" = 2; + }; + + boot.extraModprobeConfig = '' + options kvm_intel nested=1 + ''; + + fileSystems = { + "/" = { + device = "/dev/mapper/vg840-wuroot"; + fsType = "btrfs"; + options = "defaults,noatime,ssd,compress=lzo"; + }; + "/home" = { + device = "/dev/mapper/home"; + options = "defaults,noatime,ssd,compress=lzo"; + }; + "/boot" = { + device = "/dev/sda1"; + }; + "/tmp" = { + device = "tmpfs"; + fsType = "tmpfs"; + options = "nosuid,nodev,noatime"; + }; + }; + + swapDevices =[ ]; + + + nixpkgs.config.firefox.enableAdobeFlash = true; + nixpkgs.config.chromium.enablePepperFlash = true; + + nixpkgs.config.allowUnfree = true; + hardware.bumblebee.enable = true; # TODO this is host specific + hardware.bumblebee.group = "video"; + #services.xserver.videoDrivers = [ "nvidia" ]; + hardware.opengl.driSupport32Bit = true; + + hardware.pulseaudio.enable = true; + + hardware.enableAllFirmware = true; + + # Use the gummiboot efi boot loader. + boot.loader.gummiboot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + networking.hostName = "wu"; + networking.wireless.enable = true; + + + # Select internationalisation properties. + # i18n = { + # consoleFont = "lat9w-16"; + # consoleKeyMap = "us"; + # defaultLocale = "en_US.UTF-8"; + # }; + + system.activationScripts.powertopTunables = + '' + echo 1 > /sys/module/snd_hda_intel/parameters/power_save + echo 1500 > /proc/sys/vm/dirty_writeback_centisecs + (cd /sys/bus/pci/devices + for i in *; do + echo auto > $i/power/control # defaults to 'on' + done) + # TODO maybe do this via udev or systemd + # ref https://wiki.archlinux.org/index.php/Wake-on-LAN + # disable wol this cannot find ethtool + # TODO (cd /sys/class/net + # TODO for i in *; do + # TODO if ethtool $i | grep -q Wake-on && + # TODO ! ethtool $i | grep -q 'Wake-on: d'; then + # TODO ethtool -s $i wol d + # TODO fi + # TODO done) + ${pkgs.ethtool}/sbin/ethtool -s en0 wol d + ''; + + environment.systemPackages = with pkgs; [ + xlibs.fontschumachermisc + slock + ethtool + #firefoxWrapper # with plugins + #chromiumDevWrapper + tinc + iptables + vim + #jack2 + ]; + + + environment.etc."vim/vimrc".text = '' + set nocp + ''; + environment.etc."vim/vim${majmin pkgs.vim.version}".source = + "${pkgs.vim}/share/vim/vim${majmin pkgs.vim.version}"; + + # multiple-definition-problem when defining environment.variables.EDITOR + environment.extraInit = '' + EDITOR=vim + ''; + environment.variables.VIM = "/etc/vim"; + + environment.shellAliases = { + # alias cal='cal -m3' + bc = "bc -q"; + gp = "gp -q"; + df = "df -h"; + du = "du -h"; + # alias grep='grep --color=auto' + + # TODO alias cannot contain #\' + # "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep"; + + # alias la='ls -lA' + lAtr = "ls -lAtr"; + # alias ll='ls -l' + ls = "ls -h --color=auto --group-directories-first"; + # alias vim='vim -p' + # alias vi='vim' + # alias view='vim -R' + dmesg = "dmesg -L --reltime"; + }; + + + programs.bash = { + interactiveShellInit = '' + HISTCONTROL='erasedups:ignorespace' + HISTSIZE=65536 + HISTFILESIZE=$HISTSIZE + + shopt -s checkhash + shopt -s histappend histreedit histverify + shopt -s no_empty_cmd_completion + complete -d cd + + # TODO source bridge + ''; + promptInit = '' + case $UID in + 0) + PS1='\[\e[1;31m\]\w\[\e[0m\] ' + ;; + 1337) + PS1='\[\e[1;32m\]\w\[\e[0m\] ' + ;; + *) + PS1='\[\e[1;35m\]\u \[\e[1;32m\]\w\[\e[0m\] ' + ;; + esac + if test -n "$SSH_CLIENT"; then + PS1='\[\e[35m\]\h'" $PS1" + fi + if test -n "$SSH_AGENT_PID"; then + PS1="ssh-agent[$SSH_AGENT_PID] $PS1" + fi + ''; + }; + + + programs.ssh.startAgent = false; + + + security.setuidPrograms = [ + "sendmail" # for cron + "slock" + ]; + + security.pki.certificateFiles = [ + ./certs/zalora-ca.crt + ]; + + #security.pam.loginLimits = [ + # # for jack + # { domain = "@audio"; item = "memlock"; type = "-"; value = "unlimited"; } + # { domain = "@audio"; item = "rtprio"; type = "-"; value = "99"; } + #]; + + #services.haveged.enable = true; + #security.rngd.enable = true; + + #services.privoxy = { + # enable = true; + # extraConfig = '' + # actionsfile /etc/privoxy/easylist.script.action + # actionsfile /etc/privoxy/easylistgermany.script.action + # filterfile /etc/privoxy/easylist.script.filter + # filterfile /etc/privoxy/easylistgermany.script.filter + # ''; + #}; + + services.retiolum = { + enable = true; + hosts = /home/tv/krebs/hosts; + }; + + # TODO + #services.tinc = { + # enable = true; + # network = "retiolum"; + # hosts = /home/tv/krebs/hosts; + # privateKeyFile = /etc/tinc/retiolum/rsa_key.priv; + # connectTo = [ "fastpoke" "pigstarter" "kheurop" ]; + #}; + + + security.rtkit.enable = false; + services.nscd.enable = false; + services.ntp.enable = false; + #services.dbus.enable = true; # rqd4 wpa_supplicant + + # vixiecron sucks + services.cron.enable = false; + services.fcron.enable = true; + + services.logind.extraConfig = '' + HandleHibernateKey=ignore + HandleLidSwitch=ignore + HandlePowerKey=ignore + HandleSuspendKey=ignore + ''; + + # Enable the OpenSSH daemon. + services.openssh = { + enable = true; + hostKeys = [ + # XXX bits here make no science + { bits = 8192; type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + }; + + # services.printing.enable = true; + services.printing = { + enable = true; + #extraConf = '' + # LogLevel debug + #''; + drivers = with pkgs; [ + #cups_filters + #foomatic_filters + #gutenprint + #hplip + ]; + }; + + + + #services.kmscon.enable = true; + + + # TODO virtualisation.libvirtd.enable = true; + # users.extraUsers.tv.extraGroups += [ "libvirtd" ] + + + + + services.journald.extraConfig = '' + SystemMaxUse=1G + RuntimeMaxUse=128M + ''; + + + #systemd.timers.chargeMon = { + # wantedBy = [ "multi-user.target" ]; + # timerConfig.OnCalendar = "*-*-* *:*:00"; + #}; + #systemd.services.chargeMon = { + # path = [ ]; + # environment = { + # ac_online = "/sys/class/power_supply/AC/online"; + # charge_now = "/sys/class/power_supply/BAT/charge_now"; + # charge_full = "/sys/class/power_supply/BAT/charge_full"; + # }; + # serviceConfig = { + # User = "nobody"; + # Type = "oneshot"; + # }; + # script = '' + # if test $(cat $ac_online) == 1; then + # echo "AC is online" + # exit + # fi + # cat $charge_now + # ''; + #}; + + # see tmpfiles.d(5) + systemd.tmpfiles.rules = [ + "d /tmp 1777 root root - -" # does this work with mounted /tmp? + ]; + + # TODO services.smartd + # TODO services.statsd + # TODO services.tor + # TODO write arandr + # TODO what does system.copySystemConfiguration (we need some kind of bku scheme) + # TODO systemd.timers instead of cron(??) + + virtualisation.libvirtd.enable = true; + + + + + #system.replaceRuntimeDependencies = with pkgs; + # let + # bashVulnPatches = [ + # (fetchurl { + # url = "mirror://gnu/bash/bash-4.2-patches/bash42-048"; + # sha256 = "091xk1ms7ycnczsl3fx461gjhj69j6ycnfijlymwj6mj60ims6km"; + # }) + # (fetchurl { + # url = "file:///etc/nixos/bash-20140926.patch"; + # sha256 = "0gdwnimsbi4vh5l46krss4wjrgbch94skn4y2w3rpvb1w4jypha4"; + # }) + # ]; + # in + # [ + # { + # original = bash; + # replacement = pkgs.lib.overrideDerivation bash (oldAttrs: { + # patches = oldAttrs.patches ++ bashVulnPatches; + # }); + # } + # { + # original = bashInteractive; + # replacement = pkgs.lib.overrideDerivation bashInteractive (oldAttrs: { + # patches = oldAttrs.patches ++ bashVulnPatches; + # }); + # } + # { + # original = bitlbee; + # replacement = pkgs.lib.overrideDerivation bitlbee (oldAttrs: { + # configureFlags = [ + # "--gcov=1" + # "--otr=1" + # "--ssl=gnutls" + # ]; + # }); + # } + #]; + + +}