diff options
author | Parnell Springmeyer <parnell@digitalmentat.com> | 2017-02-13 17:16:28 -0600 |
---|---|---|
committer | Parnell Springmeyer <parnell@digitalmentat.com> | 2017-02-13 17:16:28 -0600 |
commit | 9e36a58649199a16a15cba3c78966ab0538a6fd7 (patch) | |
tree | 289d50ecf1068cfac80bdeabdd34d2d42ecbd755 /nixos/modules/services | |
parent | 128bdac94fe8173845e162c61ddb83cb4b8ed8de (diff) | |
parent | 486b9be579fc1f046671ddaf1157f084ba956bdd (diff) | |
download | nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.gz nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.bz2 nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.lz nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.xz nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.zst nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.zip |
Merging against upstream master
Diffstat (limited to 'nixos/modules/services')
50 files changed, 1547 insertions, 993 deletions
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix index 029b11ad98b7..a82802c32662 100644 --- a/nixos/modules/services/cluster/kubernetes.nix +++ b/nixos/modules/services/cluster/kubernetes.nix @@ -775,7 +775,7 @@ in { --bind-address=${cfg.proxy.address} \ ${optionalString cfg.verbose "--v=6"} \ ${optionalString cfg.verbose "--log-flush-frequency=1s"} \ - ${cfg.controllerManager.extraOpts} + ${cfg.proxy.extraOpts} ''; WorkingDirectory = cfg.dataDir; }; diff --git a/nixos/modules/services/continuous-integration/buildbot/master.nix b/nixos/modules/services/continuous-integration/buildbot/master.nix index a40be4f546ea..512e09eb8041 100644 --- a/nixos/modules/services/continuous-integration/buildbot/master.nix +++ b/nixos/modules/services/continuous-integration/buildbot/master.nix @@ -7,7 +7,7 @@ with lib; let cfg = config.services.buildbot-master; escapeStr = s: escape ["'"] s; - masterCfg = pkgs.writeText "master.cfg" '' + masterCfg = if cfg.masterCfg == null then pkgs.writeText "master.cfg" '' from buildbot.plugins import * factory = util.BuildFactory() c = BuildmasterConfig = dict( @@ -27,9 +27,8 @@ let factory.addStep(step) ${cfg.extraConfig} - ''; - - configFile = if cfg.masterCfg == null then masterCfg else cfg.masterCfg; + '' + else pkgs.writeText "master.cfg" cfg.masterCfg; in { options = { @@ -67,15 +66,13 @@ in { }; masterCfg = mkOption { - type = with types; nullOr path; + type = types.str; description = '' - Optionally pass path to raw master.cfg file. + Optionally pass raw master.cfg file as string. Other options in this configuration will be ignored. ''; default = null; - example = literalExample '' - pkgs.writeText "master.cfg" "BuildmasterConfig = c = {}" - ''; + example = "BuildmasterConfig = c = {}"; }; schedulers = mkOption { @@ -99,9 +96,9 @@ in { type = types.listOf types.str; description = "List of Workers."; default = [ - "worker.Worker('default-worker', 'password')" + "worker.Worker('example-worker', 'pass')" ]; - example = [ "worker.LocalWorker('default-worker')" ]; + example = [ "worker.LocalWorker('example-worker')" ]; }; status = mkOption { @@ -209,7 +206,7 @@ in { users.extraUsers = optional (cfg.user == "buildbot") { name = "buildbot"; - description = "buildbot user"; + description = "Buildbot User."; isNormalUser = true; createHome = true; home = cfg.home; @@ -219,7 +216,7 @@ in { }; systemd.services.buildbot-master = { - description = "Buildbot Continuous Integration Server"; + description = "Buildbot Continuous Integration Server."; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; path = cfg.packages; @@ -233,9 +230,8 @@ in { }; preStart = '' - mkdir -vp ${cfg.buildbotDir} - chown -c ${cfg.user}:${cfg.group} ${cfg.buildbotDir} - ln -sf ${configFile} ${cfg.buildbotDir}/master.cfg + ${pkgs.coreutils}/bin/mkdir -vp ${cfg.buildbotDir} + ${pkgs.coreutils}/bin/ln -sfv ${masterCfg} ${cfg.buildbotDir}/master.cfg ${cfg.package}/bin/buildbot create-master ${cfg.buildbotDir} ''; @@ -247,4 +243,6 @@ in { }; }; + meta.maintainers = with lib.maintainers; [ nand0p Mic92 ]; + } diff --git a/nixos/modules/services/continuous-integration/buildbot/worker.nix b/nixos/modules/services/continuous-integration/buildbot/worker.nix new file mode 100644 index 000000000000..430fd4e53f1c --- /dev/null +++ b/nixos/modules/services/continuous-integration/buildbot/worker.nix @@ -0,0 +1,128 @@ +# NixOS module for Buildbot Worker. + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.buildbot-worker; + +in { + options = { + services.buildbot-worker = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable the Buildbot Worker."; + }; + + user = mkOption { + default = "bbworker"; + type = types.str; + description = "User the buildbot Worker should execute under."; + }; + + group = mkOption { + default = "bbworker"; + type = types.str; + description = "Primary group of buildbot Worker user."; + }; + + extraGroups = mkOption { + type = types.listOf types.str; + default = [ "nixbld" ]; + description = "List of extra groups that the Buildbot Worker user should be a part of."; + }; + + home = mkOption { + default = "/home/bbworker"; + type = types.path; + description = "Buildbot home directory."; + }; + + buildbotDir = mkOption { + default = "${cfg.home}/worker"; + type = types.path; + description = "Specifies the Buildbot directory."; + }; + + workerUser = mkOption { + default = "example-worker"; + type = types.str; + description = "Specifies the Buildbot Worker user."; + }; + + workerPass = mkOption { + default = "pass"; + type = types.str; + description = "Specifies the Buildbot Worker password."; + }; + + masterUrl = mkOption { + default = "localhost:9989"; + type = types.str; + description = "Specifies the Buildbot Worker connection string."; + }; + + package = mkOption { + type = types.package; + default = pkgs.buildbot-worker; + description = "Package to use for buildbot worker."; + example = pkgs.buildbot-worker; + }; + + packages = mkOption { + default = [ ]; + example = [ pkgs.git ]; + type = types.listOf types.package; + description = "Packages to add to PATH for the buildbot process."; + }; + + }; + }; + + config = mkIf cfg.enable { + users.extraGroups = optional (cfg.group == "bbworker") { + name = "bbworker"; + }; + + users.extraUsers = optional (cfg.user == "bbworker") { + name = "bbworker"; + description = "Buildbot Worker User."; + isNormalUser = true; + createHome = true; + home = cfg.home; + group = cfg.group; + extraGroups = cfg.extraGroups; + useDefaultShell = true; + }; + + systemd.services.buildbot-worker = { + description = "Buildbot Worker."; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + wants = [ "buildbot-master.service" ]; + path = cfg.packages; + + preStart = '' + # NOTE: ensure master has time to start in case running on localhost + ${pkgs.coreutils}/bin/sleep 4 + ${pkgs.coreutils}/bin/mkdir -vp ${cfg.buildbotDir} + ${cfg.package}/bin/buildbot-worker create-worker ${cfg.buildbotDir} ${cfg.masterUrl} ${cfg.workerUser} ${cfg.workerPass} + ''; + + serviceConfig = { + Type = "forking"; + User = cfg.user; + Group = cfg.group; + WorkingDirectory = cfg.home; + ExecStart = "${cfg.package}/bin/buildbot-worker start ${cfg.buildbotDir}"; + }; + + }; + }; + + meta.maintainers = with lib.maintainers; [ nand0p ]; + +} diff --git a/nixos/modules/services/editors/emacs.xml b/nixos/modules/services/editors/emacs.xml index e03f6046de8e..89f09ed08449 100644 --- a/nixos/modules/services/editors/emacs.xml +++ b/nixos/modules/services/editors/emacs.xml @@ -316,10 +316,10 @@ https://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides <para> If you are not on NixOS or want to install this particular Emacs only for yourself, you can do so by adding it to your - <filename>~/.nixpkgs/config.nix</filename> + <filename>~/.config/nixpkgs/config.nix</filename> (see <link xlink:href="http://nixos.org/nixpkgs/manual/#sec-modify-via-packageOverrides">Nixpkgs manual</link>): <example> - <title>Custom Emacs in <filename>~/.nixpkgs/system.nix</filename></title> + <title>Custom Emacs in <filename>~/.config/nixpkgs/config.nix</filename></title> <programlisting><![CDATA[ { packageOverrides = super: let self = super.pkgs; in { diff --git a/nixos/modules/services/hardware/bluetooth.nix b/nixos/modules/services/hardware/bluetooth.nix index 2c271b328179..de0d48032113 100644 --- a/nixos/modules/services/hardware/bluetooth.nix +++ b/nixos/modules/services/hardware/bluetooth.nix @@ -2,41 +2,7 @@ with lib; let - bluez-bluetooth = if config.services.xserver.desktopManager.kde4.enable then pkgs.bluez else pkgs.bluez5; - - configBluez = { - description = "Bluetooth Service"; - serviceConfig = { - Type = "dbus"; - BusName = "org.bluez"; - ExecStart = "${getBin bluez-bluetooth}/bin/bluetoothd -n"; - }; - wantedBy = [ "bluetooth.target" ]; - }; - - configBluez5 = { - description = "Bluetooth Service"; - serviceConfig = { - Type = "dbus"; - BusName = "org.bluez"; - ExecStart = "${getBin bluez-bluetooth}/bin/bluetoothd -n"; - NotifyAccess="main"; - CapabilityBoundingSet="CAP_NET_ADMIN CAP_NET_BIND_SERVICE"; - LimitNPROC=1; - }; - wantedBy = [ "bluetooth.target" ]; - }; - - obexConfig = { - description = "Bluetooth OBEX service"; - serviceConfig = { - Type = "dbus"; - BusName = "org.bluez.obex"; - ExecStart = "${getBin bluez-bluetooth}/bin/obexd"; - }; - }; - - bluezConfig = if config.services.xserver.desktopManager.kde4.enable then configBluez else configBluez5; + bluez-bluetooth = pkgs.bluez; in { @@ -54,14 +20,25 @@ in }; ###### implementation - + config = mkIf config.hardware.bluetooth.enable { environment.systemPackages = [ bluez-bluetooth pkgs.openobex pkgs.obexftp ]; + services.udev.packages = [ bluez-bluetooth ]; + services.dbus.packages = [ bluez-bluetooth ]; - systemd.services."dbus-org.bluez" = bluezConfig; - systemd.services."dbus-org.bluez.obex" = obexConfig; + + systemd.packages = [ bluez-bluetooth ]; + + systemd.services.bluetooth = { + wantedBy = [ "bluetooth.target" ]; + aliases = [ "dbus-org.bluez.service" ]; + }; + + systemd.user.services.obex = { + aliases = [ "dbus-org.bluez.obex.service" ]; + }; }; diff --git a/nixos/modules/services/hardware/illum.nix b/nixos/modules/services/hardware/illum.nix new file mode 100644 index 000000000000..ff73c99a6537 --- /dev/null +++ b/nixos/modules/services/hardware/illum.nix @@ -0,0 +1,35 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.illum; +in { + + options = { + + services.illum = { + + enable = mkOption { + default = false; + type = types.bool; + description = '' + Enable illum, a daemon for controlling screen brightness with brightness buttons. + ''; + }; + + }; + + }; + + config = mkIf cfg.enable { + + systemd.services.illum = { + description = "Backlight Adjustment Service"; + wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = "${pkgs.illum}/bin/illum-d"; + }; + + }; + +} diff --git a/nixos/modules/services/hardware/sane.nix b/nixos/modules/services/hardware/sane.nix index 8ddb9ef9c53b..d651ccaa5776 100644 --- a/nixos/modules/services/hardware/sane.nix +++ b/nixos/modules/services/hardware/sane.nix @@ -51,7 +51,7 @@ in Enable support for SANE scanners. <note><para> - Users in the "scanner" group will gain access to the scanner. + Users in the "scanner" group will gain access to the scanner, or the "lp" group if it's also a printer. </para></note> ''; }; diff --git a/nixos/modules/services/hardware/trezord.nix b/nixos/modules/services/hardware/trezord.nix new file mode 100644 index 000000000000..38d0a3a1d752 --- /dev/null +++ b/nixos/modules/services/hardware/trezord.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.trezord; +in { + + ### interface + + options = { + services.trezord = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable Trezor bridge daemon, for use with Trezor hardware bitcoin wallets. + ''; + }; + }; + }; + + ### implementation + + config = mkIf cfg.enable { + services.udev.packages = lib.singleton (pkgs.writeTextFile { + name = "trezord-udev-rules"; + destination = "/etc/udev/rules.d/51-trezor.rules"; + text = '' + SUBSYSTEM=="usb", ATTR{idVendor}=="534c", ATTR{idProduct}=="0001", MODE="0666", GROUP="dialout", SYMLINK+="trezor%n" + KERNEL=="hidraw*", ATTRS{idVendor}=="534c", ATTRS{idProduct}=="0001", MODE="0666", GROUP="dialout" + ''; + }); + + systemd.services.trezord = { + description = "TREZOR Bridge"; + after = [ "systemd-udev-settle.service" "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = []; + serviceConfig = { + Type = "simple"; + ExecStart = "${pkgs.trezord}/bin/trezord -f"; + User = "trezord"; + }; + }; + + users.users.trezord = { + group = "trezord"; + description = "Trezor bridge daemon user"; + }; + + users.groups.trezord = {}; + }; +} + diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index cdde41446224..caaa87b94d61 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -79,8 +79,6 @@ let relay_domains = ${concatStringsSep ", " cfg.relayDomains} '' + '' - local_recipient_maps = - relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then cfg.relayHost else diff --git a/nixos/modules/services/misc/geoip-updater.nix b/nixos/modules/services/misc/geoip-updater.nix new file mode 100644 index 000000000000..021ee02782d2 --- /dev/null +++ b/nixos/modules/services/misc/geoip-updater.nix @@ -0,0 +1,300 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.geoip-updater; + + dbBaseUrl = "https://geolite.maxmind.com/download/geoip/database"; + + randomizedTimerDelaySec = "3600"; + + # Use writeScriptBin instead of writeScript, so that argv[0] (logged to the + # journal) doesn't include the long nix store path hash. (Prefixing the + # ExecStart= command with '@' doesn't work because we start a shell (new + # process) that creates a new argv[0].) + geoip-updater = pkgs.writeScriptBin "geoip-updater" '' + #!${pkgs.stdenv.shell} + skipExisting=0 + debug() + { + echo "<7>$@" + } + info() + { + echo "<6>$@" + } + error() + { + echo "<3>$@" + } + die() + { + error "$@" + exit 1 + } + waitNetworkOnline() + { + ret=1 + for i in $(seq 6); do + curl_out=$("${pkgs.curl.bin}/bin/curl" \ + --silent --fail --show-error --max-time 60 "${dbBaseUrl}" 2>&1) + if [ $? -eq 0 ]; then + debug "Server is reachable (try $i)" + ret=0 + break + else + debug "Server is unreachable (try $i): $curl_out" + sleep 10 + fi + done + return $ret + } + dbFnameTmp() + { + dburl=$1 + echo "${cfg.databaseDir}/.$(basename "$dburl")" + } + dbFnameTmpDecompressed() + { + dburl=$1 + echo "${cfg.databaseDir}/.$(basename "$dburl")" | sed 's/\.\(gz\|xz\)$//' + } + dbFname() + { + dburl=$1 + echo "${cfg.databaseDir}/$(basename "$dburl")" | sed 's/\.\(gz\|xz\)$//' + } + downloadDb() + { + dburl=$1 + curl_out=$("${pkgs.curl.bin}/bin/curl" \ + --silent --fail --show-error --max-time 900 -L -o "$(dbFnameTmp "$dburl")" "$dburl" 2>&1) + if [ $? -ne 0 ]; then + error "Failed to download $dburl: $curl_out" + return 1 + fi + } + decompressDb() + { + fn=$(dbFnameTmp "$1") + ret=0 + case "$fn" in + *.gz) + cmd_out=$("${pkgs.gzip}/bin/gzip" --decompress --force "$fn" 2>&1) + ;; + *.xz) + cmd_out=$("${pkgs.xz.bin}/bin/xz" --decompress --force "$fn" 2>&1) + ;; + *) + cmd_out=$(echo "File \"$fn\" is neither a .gz nor .xz file") + false + ;; + esac + if [ $? -ne 0 ]; then + error "$cmd_out" + ret=1 + fi + } + atomicRename() + { + dburl=$1 + mv "$(dbFnameTmpDecompressed "$dburl")" "$(dbFname "$dburl")" + } + removeIfNotInConfig() + { + # Arg 1 is the full path of an installed DB. + # If the corresponding database is not specified in the NixOS config we + # remove it. + db=$1 + for cdb in ${lib.concatStringsSep " " cfg.databases}; do + confDb=$(echo "$cdb" | sed 's/\.\(gz\|xz\)$//') + if [ "$(basename "$db")" = "$(basename "$confDb")" ]; then + return 0 + fi + done + rm "$db" + if [ $? -eq 0 ]; then + debug "Removed $(basename "$db") (not listed in services.geoip-updater.databases)" + else + error "Failed to remove $db" + fi + } + removeUnspecifiedDbs() + { + for f in "${cfg.databaseDir}/"*; do + test -f "$f" || continue + case "$f" in + *.dat|*.mmdb|*.csv) + removeIfNotInConfig "$f" + ;; + *) + debug "Not removing \"$f\" (unknown file extension)" + ;; + esac + done + } + downloadAndInstall() + { + dburl=$1 + if [ "$skipExisting" -eq 1 -a -f "$(dbFname "$dburl")" ]; then + debug "Skipping existing file: $(dbFname "$dburl")" + return 0 + fi + downloadDb "$dburl" || return 1 + decompressDb "$dburl" || return 1 + atomicRename "$dburl" || return 1 + info "Updated $(basename "$(dbFname "$dburl")")" + } + for arg in "$@"; do + case "$arg" in + --skip-existing) + skipExisting=1 + info "Option --skip-existing is set: not updating existing databases" + ;; + *) + error "Unknown argument: $arg";; + esac + done + waitNetworkOnline || die "Network is down (${dbBaseUrl} is unreachable)" + test -d "${cfg.databaseDir}" || die "Database directory (${cfg.databaseDir}) doesn't exist" + debug "Starting update of GeoIP databases in ${cfg.databaseDir}" + all_ret=0 + for db in ${lib.concatStringsSep " \\\n " cfg.databases}; do + downloadAndInstall "${dbBaseUrl}/$db" || all_ret=1 + done + removeUnspecifiedDbs || all_ret=1 + if [ $all_ret -eq 0 ]; then + info "Completed GeoIP database update in ${cfg.databaseDir}" + else + error "Completed GeoIP database update in ${cfg.databaseDir}, with error(s)" + fi + # Hack to work around systemd journal race: + # https://github.com/systemd/systemd/issues/2913 + sleep 2 + exit $all_ret + ''; + +in + +{ + options = { + services.geoip-updater = { + enable = mkOption { + default = false; + type = types.bool; + description = '' + Whether to enable periodic downloading of GeoIP databases from + maxmind.com. You might want to enable this if you, for instance, use + ntopng or Wireshark. + ''; + }; + + interval = mkOption { + type = types.str; + default = "weekly"; + description = '' + Update the GeoIP databases at this time / interval. + The format is described in + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>7</manvolnum></citerefentry>. + To prevent load spikes on maxmind.com, the timer interval is + randomized by an additional delay of ${randomizedTimerDelaySec} + seconds. Setting a shorter interval than this is not recommended. + ''; + }; + + databaseDir = mkOption { + type = types.path; + default = "/var/lib/geoip-databases"; + description = '' + Directory that will contain GeoIP databases. + ''; + }; + + databases = mkOption { + type = types.listOf types.str; + default = [ + "GeoLiteCountry/GeoIP.dat.gz" + "GeoIPv6.dat.gz" + "GeoLiteCity.dat.xz" + "GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz" + "asnum/GeoIPASNum.dat.gz" + "asnum/GeoIPASNumv6.dat.gz" + "GeoLite2-Country.mmdb.gz" + "GeoLite2-City.mmdb.gz" + ]; + description = '' + Which GeoIP databases to update. The full URL is ${dbBaseUrl}/ + + <literal>the_database</literal>. + ''; + }; + + }; + + }; + + config = mkIf cfg.enable { + + assertions = [ + { assertion = (builtins.filter + (x: builtins.match ".*\.(gz|xz)$" x == null) cfg.databases) == []; + message = '' + services.geoip-updater.databases supports only .gz and .xz databases. + + Current value: + ${toString cfg.databases} + + Offending element(s): + ${toString (builtins.filter (x: builtins.match ".*\.(gz|xz)$" x == null) cfg.databases)}; + ''; + } + ]; + + systemd.timers.geoip-updater = + { description = "GeoIP Updater Timer"; + partOf = [ "geoip-updater.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig.OnCalendar = cfg.interval; + timerConfig.Persistent = "true"; + timerConfig.RandomizedDelaySec = randomizedTimerDelaySec; + }; + + systemd.services.geoip-updater = { + description = "GeoIP Updater"; + after = [ "network-online.target" "nss-lookup.target" ]; + wants = [ "network-online.target" ]; + preStart = '' + mkdir -p "${cfg.databaseDir}" + chmod 755 "${cfg.databaseDir}" + chown nobody:root "${cfg.databaseDir}" + ''; + serviceConfig = { + ExecStart = "${geoip-updater}/bin/geoip-updater"; + User = "nobody"; + PermissionsStartOnly = true; + }; + }; + + systemd.services.geoip-updater-setup = { + description = "GeoIP Updater Setup"; + after = [ "network-online.target" "nss-lookup.target" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + conflicts = [ "geoip-updater.service" ]; + preStart = '' + mkdir -p "${cfg.databaseDir}" + chmod 755 "${cfg.databaseDir}" + chown nobody:root "${cfg.databaseDir}" + ''; + serviceConfig = { + ExecStart = "${geoip-updater}/bin/geoip-updater --skip-existing"; + User = "nobody"; + PermissionsStartOnly = true; + # So it won't be (needlessly) restarted: + RemainAfterExit = true; + }; + }; + + }; +} diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index 1fc3a5cc8691..36db4fb96606 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -528,8 +528,8 @@ in { if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then if ! test -e "${cfg.statePath}/db-created"; then - psql postgres -c "CREATE ROLE gitlab WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'" - ${config.services.postgresql.package}/bin/createdb --owner gitlab gitlab || true + psql postgres -c "CREATE ROLE ${cfg.databaseUsername} WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'" + ${config.services.postgresql.package}/bin/createdb --owner ${cfg.databaseUsername} ${cfg.databaseName} || true touch "${cfg.statePath}/db-created" fi fi diff --git a/nixos/modules/services/misc/gogs.nix b/nixos/modules/services/misc/gogs.nix index 09e5c4fe1ff1..ca8fc06e4835 100644 --- a/nixos/modules/services/misc/gogs.nix +++ b/nixos/modules/services/misc/gogs.nix @@ -208,6 +208,7 @@ in group = "gogs"; home = cfg.stateDir; createHome = true; + shell = pkgs.bash; }; extraGroups.gogs.gid = config.ids.gids.gogs; }; diff --git a/nixos/modules/services/misc/ihaskell.nix b/nixos/modules/services/misc/ihaskell.nix index d0e9b839e754..df7b9be0db50 100644 --- a/nixos/modules/services/misc/ihaskell.nix +++ b/nixos/modules/services/misc/ihaskell.nix @@ -20,18 +20,6 @@ in description = "Autostart an IHaskell notebook service."; }; - haskellPackages = mkOption { - default = pkgs.haskellPackages; - defaultText = "pkgs.haskellPackages"; - example = literalExample "pkgs.haskell.packages.ghc784"; - description = '' - haskellPackages used to build IHaskell and other packages. - This can be used to change the GHC version used to build - IHaskell and the packages listed in - <varname>extraPackages</varname>. - ''; - }; - extraPackages = mkOption { default = self: []; example = literalExample '' diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix new file mode 100644 index 000000000000..b04959a9686a --- /dev/null +++ b/nixos/modules/services/misc/ssm-agent.nix @@ -0,0 +1,45 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.services.ssm-agent; + + # The SSM agent doesn't pay attention to our /etc/os-release yet, and the lsb-release tool + # in nixpkgs doesn't seem to work properly on NixOS, so let's just fake the two fields SSM + # looks for. See https://github.com/aws/amazon-ssm-agent/issues/38 for upstream fix. + fake-lsb-release = pkgs.writeScriptBin "lsb_release" '' + #!${pkgs.stdenv.shell} + + case "$1" in + -i) echo "nixos";; + -r) echo "${config.system.nixosVersion}";; + esac + ''; +in { + options.services.ssm-agent = { + enable = mkEnableOption "AWS SSM agent"; + + package = mkOption { + type = types.path; + description = "The SSM agent package to use"; + default = pkgs.ssm-agent; + }; + }; + + config = mkIf cfg.enable { + systemd.services.ssm-agent = { + inherit (cfg.package.meta) description; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + path = [ fake-lsb-release ]; + serviceConfig = { + ExecStart = "${cfg.package.bin}/bin/agent"; + KillMode = "process"; + Restart = "on-failure"; + RestartSec = "15min"; + }; + }; + }; +} + diff --git a/nixos/modules/services/misc/taskserver/default.nix b/nixos/modules/services/misc/taskserver/default.nix index ca82a733f6fc..d28c5dc7af85 100644 --- a/nixos/modules/services/misc/taskserver/default.nix +++ b/nixos/modules/services/misc/taskserver/default.nix @@ -125,10 +125,10 @@ let server.key = ${cfg.dataDir}/keys/server.key server.crl = ${cfg.dataDir}/keys/server.crl '' else '' - ca.cert = ${cfg.pki.ca.cert} - server.cert = ${cfg.pki.server.cert} - server.key = ${cfg.pki.server.key} - server.crl = ${cfg.pki.server.crl} + ca.cert = ${cfg.pki.manual.ca.cert} + server.cert = ${cfg.pki.manual.server.cert} + server.key = ${cfg.pki.manual.server.key} + server.crl = ${cfg.pki.manual.server.crl} ''} '' + cfg.extraConfig); diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix index b9e4015c2380..97806d5d83eb 100644 --- a/nixos/modules/services/monitoring/grafana.nix +++ b/nixos/modules/services/monitoring/grafana.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ options, config, lib, pkgs, ... }: with lib; @@ -232,9 +232,10 @@ in { }; config = mkIf cfg.enable { - warnings = [ - "Grafana passwords will be stored as plaintext in the Nix store!" - ]; + warnings = optional ( + cfg.database.password != options.services.grafana.database.password.default || + cfg.security.adminPassword != options.services.grafana.security.adminPassword.default + ) "Grafana passwords will be stored as plaintext in the Nix store!"; environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/services/network-filesystems/glusterfs.nix b/nixos/modules/services/network-filesystems/glusterfs.nix new file mode 100644 index 000000000000..a2f2c0339515 --- /dev/null +++ b/nixos/modules/services/network-filesystems/glusterfs.nix @@ -0,0 +1,84 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + inherit (pkgs) glusterfs; + + cfg = config.services.glusterfs; + +in + +{ + + ###### interface + + options = { + + services.glusterfs = { + + enable = mkEnableOption "GlusterFS Daemon"; + + logLevel = mkOption { + type = types.enum ["DEBUG" "INFO" "WARNING" "ERROR" "CRITICAL" "TRACE" "NONE"]; + description = "Log level used by the GlusterFS daemon"; + default = "INFO"; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + description = "Extra flags passed to the GlusterFS daemon"; + default = []; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.glusterfs ]; + + services.rpcbind.enable = true; + + systemd.services.glusterd = { + + description = "GlusterFS, a clustered file-system server"; + + wantedBy = [ "multi-user.target" ]; + + requires = [ "rpcbind.service" ]; + after = [ "rpcbind.service" "network.target" "local-fs.target" ]; + before = [ "network-online.target" ]; + + preStart = '' + install -m 0755 -d /var/log/glusterfs + ''; + + serviceConfig = { + Type="forking"; + PIDFile="/run/glusterd.pid"; + LimitNOFILE=65536; + ExecStart="${glusterfs}/sbin/glusterd -p /run/glusterd.pid --log-level=${cfg.logLevel} ${toString cfg.extraFlags}"; + KillMode="process"; + }; + }; + + systemd.services.glustereventsd = { + + description = "Gluster Events Notifier"; + + wantedBy = [ "multi-user.target" ]; + + after = [ "syslog.target" "network.target" ]; + + serviceConfig = { + Type="simple"; + Environment="PYTHONPATH=${glusterfs}/usr/lib/python2.7/site-packages"; + PIDFile="/run/glustereventsd.pid"; + ExecStart="${glusterfs}/sbin/glustereventsd --pid-file /run/glustereventsd.pid"; + ExecReload="/bin/kill -SIGUSR2 $MAINPID"; + KillMode="control-group"; + }; + }; + }; +} diff --git a/nixos/modules/services/network-filesystems/ipfs.nix b/nixos/modules/services/network-filesystems/ipfs.nix index d43147a16f31..e6e04248854e 100644 --- a/nixos/modules/services/network-filesystems/ipfs.nix +++ b/nixos/modules/services/network-filesystems/ipfs.nix @@ -104,31 +104,73 @@ in }; }; - systemd.services.ipfs = { - description = "IPFS Daemon"; + systemd.services.ipfs-init = { + description = "IPFS Initializer"; + + after = [ "local-fs.target" ]; + before = [ "ipfs.service" "ipfs-offline.service" ]; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" "local-fs.target" ]; path = [ pkgs.ipfs pkgs.su pkgs.bash ]; preStart = '' install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir} + ''; + + script = '' if [[ ! -d ${cfg.dataDir}/.ipfs ]]; then cd ${cfg.dataDir} - ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c \ - "${ipfs}/bin/ipfs init ${if cfg.emptyRepo then "-e" else ""}" + ${ipfs}/bin/ipfs init ${optionalString cfg.emptyRepo "-e"} fi - ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c \ - "${ipfs}/bin/ipfs --local config Addresses.API ${cfg.apiAddress} && \ - ${ipfs}/bin/ipfs --local config Addresses.Gateway ${cfg.gatewayAddress}" + ${ipfs}/bin/ipfs --local config Addresses.API ${cfg.apiAddress} + ${ipfs}/bin/ipfs --local config Addresses.Gateway ${cfg.gatewayAddress} ''; serviceConfig = { - ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags}"; User = cfg.user; Group = cfg.group; + Type = "oneshot"; + RemainAfterExit = true; PermissionsStartOnly = true; }; }; + + systemd.services.ipfs = { + description = "IPFS Daemon"; + + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" "local-fs.target" "ipfs-init.service" ]; + + conflicts = [ "ipfs-offline.service" ]; + wants = [ "ipfs-init.service" ]; + + path = [ pkgs.ipfs ]; + + serviceConfig = { + ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags}"; + User = cfg.user; + Group = cfg.group; + Restart = "on-failure"; + RestartSec = 1; + }; + }; + + systemd.services.ipfs-offline = { + description = "IPFS Daemon (offline mode)"; + + after = [ "local-fs.target" "ipfs-init.service" ]; + + conflicts = [ "ipfs.service" ]; + wants = [ "ipfs-init.service" ]; + + path = [ pkgs.ipfs ]; + + serviceConfig = { + ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags} --offline"; + User = cfg.user; + Group = cfg.group; + Restart = "on-failure"; + RestartSec = 1; + }; + }; }; } diff --git a/nixos/modules/services/network-filesystems/nfsd.nix b/nixos/modules/services/network-filesystems/nfsd.nix index ddc7258ce0b4..7d127145101b 100644 --- a/nixos/modules/services/network-filesystems/nfsd.nix +++ b/nixos/modules/services/network-filesystems/nfsd.nix @@ -20,6 +20,7 @@ in server = { enable = mkOption { + type = types.bool; default = false; description = '' Whether to enable the kernel's NFS server. @@ -27,6 +28,7 @@ in }; exports = mkOption { + type = types.lines; default = ""; description = '' Contents of the /etc/exports file. See @@ -36,6 +38,7 @@ in }; hostName = mkOption { + type = types.nullOr types.str; default = null; description = '' Hostname or address on which NFS requests will be accepted. @@ -46,6 +49,7 @@ in }; nproc = mkOption { + type = types.int; default = 8; description = '' Number of NFS server threads. Defaults to the recommended value of 8. @@ -53,11 +57,13 @@ in }; createMountPoints = mkOption { + type = types.bool; default = false; description = "Whether to create the mount points in the exports file at startup time."; }; mountdPort = mkOption { + type = types.nullOr types.int; default = null; example = 4002; description = '' @@ -66,11 +72,26 @@ in }; lockdPort = mkOption { - default = 0; + type = types.nullOr types.int; + default = null; + example = 4001; + description = '' + Use a fixed port for the NFS lock manager kernel module + (<literal>lockd/nlockmgr</literal>). This is useful if the + NFS server is behind a firewall. + ''; + }; + + statdPort = mkOption { + type = types.nullOr types.int; + default = null; + example = 4000; description = '' - Fix the lockd port number. This can help setting firewall rules for NFS. + Use a fixed port for <command>rpc.statd</command>. This is + useful if the NFS server is behind a firewall. ''; }; + }; }; @@ -82,60 +103,47 @@ in config = mkIf cfg.enable { - services.rpcbind.enable = true; + services.nfs.extraConfig = '' + [nfsd] + threads=${toString cfg.nproc} + ${optionalString (cfg.hostName != null) "host=${cfg.hostName}"} - boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd - - environment.systemPackages = [ pkgs.nfs-utils ]; + [mountd] + ${optionalString (cfg.mountdPort != null) "port=${toString cfg.mountdPort}"} - environment.etc.exports.source = exports; + [statd] + ${optionalString (cfg.statdPort != null) "port=${toString cfg.statdPort}"} - boot.kernelModules = [ "nfsd" ]; + [lockd] + ${optionalString (cfg.lockdPort != null) '' + port=${toString cfg.lockdPort} + udp-port=${toString cfg.lockdPort} + ''} + ''; - systemd.services.nfsd = - { description = "NFS Server"; + services.rpcbind.enable = true; - wantedBy = [ "multi-user.target" ]; + boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd - requires = [ "rpcbind.service" "mountd.service" ]; - after = [ "rpcbind.service" "mountd.service" "idmapd.service" ]; - before = [ "statd.service" ]; + environment.etc.exports.source = exports; - path = [ pkgs.nfs-utils ]; + systemd.services.nfs-server = + { enable = true; + wantedBy = [ "multi-user.target" ]; - script = + preStart = '' - # Create a state directory required by NFSv4. mkdir -p /var/lib/nfs/v4recovery - - ${pkgs.procps}/sbin/sysctl -w fs.nfs.nlm_tcpport=${builtins.toString cfg.lockdPort} - ${pkgs.procps}/sbin/sysctl -w fs.nfs.nlm_udpport=${builtins.toString cfg.lockdPort} - - rpc.nfsd \ - ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} \ - ${builtins.toString cfg.nproc} ''; - - postStop = "rpc.nfsd 0"; - - serviceConfig.Type = "oneshot"; - serviceConfig.RemainAfterExit = true; }; - systemd.services.mountd = - { description = "NFSv3 Mount Daemon"; - - requires = [ "rpcbind.service" ]; - after = [ "rpcbind.service" "local-fs.target" ]; - - path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ]; + systemd.services.nfs-mountd = + { enable = true; + restartTriggers = [ exports ]; preStart = '' mkdir -p /var/lib/nfs - touch /var/lib/nfs/rmtab - - mountpoint -q /proc/fs/nfsd || mount -t nfsd none /proc/fs/nfsd ${optionalString cfg.createMountPoints '' @@ -146,18 +154,7 @@ in | xargs -d '\n' mkdir -p '' } - - exportfs -rav ''; - - restartTriggers = [ exports ]; - - serviceConfig.Type = "forking"; - serviceConfig.ExecStart = '' - @${pkgs.nfs-utils}/sbin/rpc.mountd rpc.mountd \ - ${if cfg.mountdPort != null then "-p ${toString cfg.mountdPort}" else ""} - ''; - serviceConfig.Restart = "always"; }; }; diff --git a/nixos/modules/services/networking/asterisk.nix b/nixos/modules/services/networking/asterisk.nix index 5c71a1d8ddae..514204db33fa 100644 --- a/nixos/modules/services/networking/asterisk.nix +++ b/nixos/modules/services/networking/asterisk.nix @@ -17,7 +17,7 @@ let allConfFiles = cfg.confFiles // builtins.listToAttrs (map (x: { name = x; - value = builtins.readFile (pkgs.asterisk + "/etc/asterisk/" + x); }) + value = builtins.readFile (cfg.package + "/etc/asterisk/" + x); }) defaultConfFiles); asteriskEtc = pkgs.stdenv.mkDerivation @@ -38,7 +38,7 @@ let asteriskConf = '' [directories] astetcdir => /etc/asterisk - astmoddir => ${pkgs.asterisk}/lib/asterisk/modules + astmoddir => ${cfg.package}/lib/asterisk/modules astvarlibdir => /var/lib/asterisk astdbdir => /var/lib/asterisk astkeydir => /var/lib/asterisk @@ -47,7 +47,7 @@ let astspooldir => /var/spool/asterisk astrundir => /var/run/asterisk astlogdir => /var/log/asterisk - astsbindir => ${pkgs.asterisk}/sbin + astsbindir => ${cfg.package}/sbin ''; extraConf = cfg.extraConfig; @@ -197,11 +197,17 @@ in Additional command line arguments to pass to Asterisk. ''; }; + package = mkOption { + type = types.package; + default = pkgs.asterisk; + defaultText = "pkgs.asterisk"; + description = "The Asterisk package to use."; + }; }; }; config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.asterisk ]; + environment.systemPackages = [ cfg.package ]; environment.etc.asterisk.source = asteriskEtc; @@ -234,7 +240,7 @@ in # TODO: Make exceptions for /var directories that likely should be updated if [ ! -e "$d" ]; then mkdir -p "$d" - cp --recursive ${pkgs.asterisk}/"$d"/* "$d"/ + cp --recursive ${cfg.package}/"$d"/* "$d"/ chown --recursive ${asteriskUser}:${asteriskGroup} "$d" find "$d" -type d | xargs chmod 0755 fi @@ -247,8 +253,8 @@ in # FIXME: This doesn't account for arguments with spaces argString = concatStringsSep " " cfg.extraArguments; in - "${pkgs.asterisk}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F"; - ExecReload = ''${pkgs.asterisk}/bin/asterisk -x "core reload" + "${cfg.package}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F"; + ExecReload = ''${cfg.package}/bin/asterisk -x "core reload" ''; Type = "forking"; PIDFile = "/var/run/asterisk/asterisk.pid"; diff --git a/nixos/modules/services/networking/chrony.nix b/nixos/modules/services/networking/chrony.nix index f2ff11633b1b..9bf266b38054 100644 --- a/nixos/modules/services/networking/chrony.nix +++ b/nixos/modules/services/networking/chrony.nix @@ -12,6 +12,25 @@ let cfg = config.services.chrony; + configFile = pkgs.writeText "chrony.conf" '' + ${concatMapStringsSep "\n" (server: "server " + server) cfg.servers} + + ${optionalString + cfg.initstepslew.enabled + "initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}" + } + + driftfile ${stateDir}/chrony.drift + + keyfile ${keyFile} + + ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"} + + ${cfg.extraConfig} + ''; + + chronyFlags = "-n -m -u chrony -f ${configFile} ${toString cfg.extraFlags}"; + in { @@ -58,6 +77,13 @@ in <literal>chrony.conf</literal> ''; }; + + extraFlags = mkOption { + default = []; + example = [ "-s" ]; + type = types.listOf types.str; + description = "Extra flags passed to the chronyd command."; + }; }; }; @@ -70,25 +96,6 @@ in # Make chronyc available in the system path environment.systemPackages = [ pkgs.chrony ]; - environment.etc."chrony.conf".text = - '' - ${concatMapStringsSep "\n" (server: "server " + server) cfg.servers} - - ${optionalString - cfg.initstepslew.enabled - "initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}" - } - - driftfile ${stateDir}/chrony.drift - - keyfile ${keyFile} - generatecommandkey - - ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"} - - ${cfg.extraConfig} - ''; - users.extraGroups = singleton { name = "chrony"; gid = config.ids.gids.chrony; @@ -124,7 +131,7 @@ in ''; serviceConfig = - { ExecStart = "${pkgs.chrony}/bin/chronyd -n -m -u chrony"; + { ExecStart = "${pkgs.chrony}/bin/chronyd ${chronyFlags}"; }; }; diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix index a10851c16523..12c2677c3368 100644 --- a/nixos/modules/services/networking/cjdns.nix +++ b/nixos/modules/services/networking/cjdns.nix @@ -258,9 +258,8 @@ in Restart = "always"; StartLimitInterval = 0; RestartSec = 1; - CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW"; - AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_RAW"; - ProtectSystem = "full"; + CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW CAP_SETUID"; + ProtectSystem = true; MemoryDenyWriteExecute = true; ProtectHome = true; PrivateTmp = true; diff --git a/nixos/modules/services/networking/dnschain.nix b/nixos/modules/services/networking/dnschain.nix index f17f8c832ee4..b64929960576 100644 --- a/nixos/modules/services/networking/dnschain.nix +++ b/nixos/modules/services/networking/dnschain.nix @@ -3,23 +3,28 @@ with lib; let - cfg = config.services; + cfgs = config.services; + cfg = cfgs.dnschain; - dnschainConf = pkgs.writeText "dnschain.conf" '' + dataDir = "/var/lib/dnschain"; + username = "dnschain"; + + configFile = pkgs.writeText "dnschain.conf" '' [log] - level=info + level = info [dns] - host = 127.0.0.1 - port = 5333 + host = ${cfg.dns.address} + port = ${toString cfg.dns.port} oldDNSMethod = NO_OLD_DNS - # TODO: check what that address is acutally used for - externalIP = 127.0.0.1 + externalIP = ${cfg.dns.address} [http] - host = 127.0.0.1 - port=8088 - tlsPort=4443 + host = ${cfg.api.hostname} + port = ${toString cfg.api.port} + tlsPort = ${toString cfg.api.tlsPort} + + ${cfg.extraConfig} ''; in @@ -32,28 +37,81 @@ in services.dnschain = { - enable = mkOption { - type = types.bool; - default = false; + enable = mkEnableOption '' + DNSChain, a blockchain based DNS + HTTP server. + To resolve .bit domains set <literal>services.namecoind.enable = true;</literal> + and an RPC username/password. + ''; + + dns.address = mkOption { + type = types.str; + default = "127.0.0.1"; description = '' - Whether to run dnschain. That implies running - namecoind as well, so make sure to configure - it appropriately. + The IP address that will be used to reach this machine. + Leave this unchanged if you do not wish to directly expose the DNSChain resolver. ''; }; - }; + dns.port = mkOption { + type = types.int; + default = 5333; + description = '' + The port the DNSChain resolver will bind to. + ''; + }; + + api.hostname = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + The hostname (or IP address) the DNSChain API server will bind to. + ''; + }; + + api.port = mkOption { + type = types.int; + default = 8080; + description = '' + The port the DNSChain API server (HTTP) will bind to. + ''; + }; - services.dnsmasq = { - resolveDnschainQueries = mkOption { - type = types.bool; - default = false; + api.tlsPort = mkOption { + type = types.int; + default = 4433; description = '' - Resolve <literal>.bit</literal> top-level domains - with dnschain and namecoind. + The port the DNSChain API server (HTTPS) will bind to. ''; }; + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + [log] + level = debug + ''; + description = '' + Additional options that will be appended to the configuration file. + ''; + }; + + }; + + services.dnsmasq.resolveDNSChainQueries = mkOption { + type = types.bool; + default = false; + description = '' + Resolve <literal>.bit</literal> top-level domains using DNSChain and namecoin. + ''; + }; + + services.pdns-recursor.resolveDNSChainQueries = mkOption { + type = types.bool; + default = false; + description = '' + Resolve <literal>.bit</literal> top-level domains using DNSChain and namecoin. + ''; }; }; @@ -61,48 +119,47 @@ in ###### implementation - config = mkIf cfg.dnschain.enable { - - services.namecoind.enable = true; + config = mkIf cfg.enable { - services.dnsmasq.servers = optionals cfg.dnsmasq.resolveDnschainQueries [ "/.bit/127.0.0.1#5333" ]; + services.dnsmasq.servers = optionals cfgs.dnsmasq.resolveDNSChainQueries + [ "/.bit/127.0.0.1#${toString cfg.dns.port}" + "/.dns/127.0.0.1#${toString cfg.dns.port}" + ]; - users.extraUsers = singleton - { name = "dnschain"; - uid = config.ids.uids.dnschain; - extraGroups = [ "namecoin" ]; - description = "Dnschain daemon user"; - home = "/var/lib/dnschain"; - createHome = true; + services.pdns-recursor.forwardZones = mkIf cfgs.pdns-recursor.resolveDNSChainQueries + { bit = "127.0.0.1:${toString cfg.dns.port}"; + dns = "127.0.0.1:${toString cfg.dns.port}"; }; + users.extraUsers = singleton { + name = username; + description = "DNSChain daemon user"; + home = dataDir; + createHome = true; + uid = config.ids.uids.dnschain; + extraGroups = optional cfgs.namecoind.enable "namecoin"; + }; + systemd.services.dnschain = { - description = "Dnschain Daemon"; - after = [ "namecoind.target" ]; - wantedBy = [ "multi-user.target" ]; - path = [ pkgs.openssl ]; - preStart = '' - # Link configuration file into dnschain HOME directory - if [ "$(${pkgs.coreutils}/bin/realpath /var/lib/dnschain/.dnschain.conf)" != "${dnschainConf}" ]; then - rm -rf /var/lib/dnschain/.dnschain.conf - ln -s ${dnschainConf} /var/lib/dnschain/.dnschain.conf - fi - - # Create empty namecoin.conf so that dnschain is not - # searching for /etc/namecoin/namecoin.conf - if [ ! -e /var/lib/dnschain/.namecoin/namecoin.conf ]; then - mkdir -p /var/lib/dnschain/.namecoin - touch /var/lib/dnschain/.namecoin/namecoin.conf - fi - ''; - serviceConfig = { - Type = "simple"; - User = "dnschain"; - EnvironmentFile = config.services.namecoind.userFile; - ExecStart = "${pkgs.dnschain}/bin/dnschain --rpcuser=\${USER} --rpcpassword=\${PASSWORD} --rpcport=8336"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - ExecStop = "${pkgs.coreutils}/bin/kill -KILL $MAINPID"; - }; + description = "DNSChain daemon"; + after = optional cfgs.namecoind.enable "namecoind.target"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + User = "dnschain"; + Restart = "on-failure"; + ExecStart = "${pkgs.dnschain}/bin/dnschain"; + }; + + preStart = '' + # Link configuration file into dnschain home directory + configPath=${dataDir}/.dnschain/dnschain.conf + mkdir -p ${dataDir}/.dnschain + if [ "$(realpath $configPath)" != "${configFile}" ]; then + rm -f $configPath + ln -s ${configFile} $configPath + fi + ''; }; }; diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 34b731ad35c9..243cd04c96c2 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -38,9 +38,9 @@ let cfg = config.networking.firewall; - kernelPackages = config.boot.kernelPackages; + inherit (config.boot.kernelPackages) kernel; - kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false; + kernelHasRPFilter = ((kernel.config.isEnabled or (x: false)) "IP_NF_MATCH_RPFILTER") || (kernel.features.netfilterRPFilter or false); helpers = '' diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix index abb7a4e9137c..c5b27350b3c2 100644 --- a/nixos/modules/services/networking/i2pd.nix +++ b/nixos/modules/services/networking/i2pd.nix @@ -8,7 +8,7 @@ let homeDir = "/var/lib/i2pd"; - extip = "EXTIP=\$(${pkgs.curl.bin}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')"; + extip = "EXTIP=\$(${pkgs.curl.bin}/bin/curl -sLf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')"; toYesNo = b: if b then "true" else "false"; diff --git a/nixos/modules/services/networking/libreswan.nix b/nixos/modules/services/networking/libreswan.nix index 3866b216f8ef..c87e738d2a23 100644 --- a/nixos/modules/services/networking/libreswan.nix +++ b/nixos/modules/services/networking/libreswan.nix @@ -102,7 +102,7 @@ in serviceConfig = { Type = "simple"; Restart = "always"; - EnvironmentFile = "${pkgs.libreswan}/etc/sysconfig/pluto"; + EnvironmentFile = "-${pkgs.libreswan}/etc/sysconfig/pluto"; ExecStartPre = [ "${libexec}/addconn --config ${configFile} --checkconfig" "${libexec}/_stackmanager start" diff --git a/nixos/modules/services/networking/namecoind.nix b/nixos/modules/services/networking/namecoind.nix index 83fc1ec66679..9df9f67cde83 100644 --- a/nixos/modules/services/networking/namecoind.nix +++ b/nixos/modules/services/networking/namecoind.nix @@ -3,25 +3,35 @@ with lib; let - cfg = config.services.namecoind; + cfg = config.services.namecoind; + dataDir = "/var/lib/namecoind"; + useSSL = (cfg.rpc.certificate != null) && (cfg.rpc.key != null); + useRPC = (cfg.rpc.user != null) && (cfg.rpc.password != null); - namecoinConf = - let - useSSL = (cfg.rpcCertificate != null) && (cfg.rpcKey != null); - in - pkgs.writeText "namecoin.conf" '' + listToConf = option: list: + concatMapStrings (value :"${option}=${value}\n") list; + + configFile = pkgs.writeText "namecoin.conf" ('' server=1 daemon=0 - rpcallowip=127.0.0.1 - walletpath=${cfg.wallet} - gen=${if cfg.generate then "1" else "0"} - rpcssl=${if useSSL then "1" else "0"} - ${optionalString useSSL "rpcsslcertificatechainfile=${cfg.rpcCertificate}"} - ${optionalString useSSL "rpcsslprivatekeyfile=${cfg.rpcKey}"} - ${optionalString useSSL "rpcsslciphers=TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"} txindex=1 txprevcache=1 - ''; + walletpath=${cfg.wallet} + gen=${if cfg.generate then "1" else "0"} + ${listToConf "addnode" cfg.extraNodes} + ${listToConf "connect" cfg.trustedNodes} + '' + optionalString useRPC '' + rpcbind=${cfg.rpc.address} + rpcport=${toString cfg.rpc.port} + rpcuser=${cfg.rpc.user} + rpcpassword=${cfg.rpc.password} + ${listToConf "rpcallowip" cfg.rpc.allowFrom} + '' + optionalString useSSL '' + rpcssl=1 + rpcsslcertificatechainfile=${cfg.rpc.certificate} + rpcsslprivatekeyfile=${cfg.rpc.key} + rpcsslciphers=TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH + ''); in @@ -33,66 +43,102 @@ in services.namecoind = { - enable = mkOption { + enable = mkEnableOption "namecoind, Namecoin client."; + + wallet = mkOption { + type = types.path; + default = "${dataDir}/wallet.dat"; + description = '' + Wallet file. The ownership of the file has to be + namecoin:namecoin, and the permissions must be 0640. + ''; + }; + + generate = mkOption { type = types.bool; default = false; description = '' - Whether to run namecoind. + Whether to generate (mine) Namecoins. ''; }; - wallet = mkOption { - type = types.path; - example = "/etc/namecoin/wallet.dat"; + extraNodes = mkOption { + type = types.listOf types.str; + default = [ ]; description = '' - Wallet file. The ownership of the file has to be - namecoin:namecoin, and the permissions must be 0640. + List of additional peer IP addresses to connect to. ''; }; - userFile = mkOption { - type = types.nullOr types.path; + trustedNodes = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + List of the only peer IP addresses to connect to. If specified + no other connection will be made. + ''; + }; + + rpc.user = mkOption { + type = types.nullOr types.str; default = null; - example = "/etc/namecoin/user"; description = '' - File containing the user name and user password to - authenticate RPC connections to namecoind. - The content of the file is of the form: - <literal> - USER=namecoin - PASSWORD=secret - </literal> - The ownership of the file has to be namecoin:namecoin, - and the permissions must be 0640. + User name for RPC connections. ''; }; - generate = mkOption { - type = types.bool; - default = false; + rpc.password = mkOption { + type = types.str; + default = null; description = '' - Whether to generate (mine) Namecoins. + Password for RPC connections. ''; }; - rpcCertificate = mkOption { + rpc.address = mkOption { + type = types.str; + default = "0.0.0.0"; + description = '' + IP address the RPC server will bind to. + ''; + }; + + rpc.port = mkOption { + type = types.int; + default = 8332; + description = '' + Port the RPC server will bind to. + ''; + }; + + rpc.certificate = mkOption { type = types.nullOr types.path; default = null; - example = "/etc/namecoin/server.cert"; + example = "/var/lib/namecoind/server.cert"; description = '' Certificate file for securing RPC connections. ''; }; - rpcKey = mkOption { + rpc.key = mkOption { type = types.nullOr types.path; default = null; - example = "/etc/namecoin/server.pem"; + example = "/var/lib/namecoind/server.pem"; description = '' Key file for securing RPC connections. ''; }; + + rpc.allowFrom = mkOption { + type = types.listOf types.str; + default = [ "127.0.0.1" ]; + description = '' + List of IP address ranges allowed to use the RPC API. + Wiledcards (*) can be user to specify a range. + ''; + }; + }; }; @@ -102,47 +148,54 @@ in config = mkIf cfg.enable { - users.extraUsers = singleton - { name = "namecoin"; - uid = config.ids.uids.namecoin; - description = "Namecoin daemon user"; - home = "/var/lib/namecoin"; - createHome = true; - }; + services.dnschain.extraConfig = '' + [namecoin] + config = ${configFile} + ''; + + users.extraUsers = singleton { + name = "namecoin"; + uid = config.ids.uids.namecoin; + description = "Namecoin daemon user"; + home = dataDir; + createHome = true; + }; - users.extraGroups = singleton - { name = "namecoin"; - gid = config.ids.gids.namecoin; - }; + users.extraGroups = singleton { + name = "namecoin"; + gid = config.ids.gids.namecoin; + }; systemd.services.namecoind = { - description = "Namecoind Daemon"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - preStart = '' - if [ "$(stat --printf '%u' ${cfg.userFile})" != "${toString config.ids.uids.namecoin}" \ - -o "$(stat --printf '%g' ${cfg.userFile})" != "${toString config.ids.gids.namecoin}" \ - -o "$(stat --printf '%a' ${cfg.userFile})" != "640" ]; then - echo "ERROR: bad ownership or rights on ${cfg.userFile}" >&2 - exit 1 - fi - if [ "$(stat --printf '%u' ${cfg.wallet})" != "${toString config.ids.uids.namecoin}" \ - -o "$(stat --printf '%g' ${cfg.wallet})" != "${toString config.ids.gids.namecoin}" \ - -o "$(stat --printf '%a' ${cfg.wallet})" != "640" ]; then - echo "ERROR: bad ownership or rights on ${cfg.wallet}" >&2 - exit 1 - fi - ''; - serviceConfig = { - Type = "simple"; - User = "namecoin"; - EnvironmentFile = cfg.userFile; - ExecStart = "${pkgs.altcoins.namecoind}/bin/namecoind -conf=${namecoinConf} -rpcuser=\${USER} -rpcpassword=\${PASSWORD} -printtoconsole"; - ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; - ExecStop = "${pkgs.coreutils}/bin/kill -KILL $MAINPID"; - StandardOutput = "null"; - Nice = "10"; - }; + description = "Namecoind daemon"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + User = "namecoin"; + Griup = "namecoin"; + ExecStart = "${pkgs.altcoins.namecoind}/bin/namecoind -conf=${configFile} -datadir=${dataDir} -printtoconsole"; + ExecStop = "${pkgs.coreutils}/bin/kill -KILL $MAINPID"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + Nice = "10"; + PrivateTmp = true; + TimeoutStopSec = "60s"; + TimeoutStartSec = "2s"; + Restart = "always"; + StartLimitInterval = "120s"; + StartLimitBurst = "5"; + }; + + preStart = optionalString (cfg.wallet != "${dataDir}/wallet.dat") '' + # check wallet file permissions + if [ "$(stat --printf '%u' ${cfg.wallet})" != "${toString config.ids.uids.namecoin}" \ + -o "$(stat --printf '%g' ${cfg.wallet})" != "${toString config.ids.gids.namecoin}" \ + -o "$(stat --printf '%a' ${cfg.wallet})" != "640" ]; then + echo "ERROR: bad ownership or rights on ${cfg.wallet}" >&2 + exit 1 + fi + ''; + }; }; diff --git a/nixos/modules/services/networking/nylon.nix b/nixos/modules/services/networking/nylon.nix index da6487dbd499..4864ecf3f92f 100644 --- a/nixos/modules/services/networking/nylon.nix +++ b/nixos/modules/services/networking/nylon.nix @@ -8,7 +8,7 @@ let homeDir = "/var/lib/nylon"; - configFile = pkgs.writeText "nylon.conf" '' + configFile = cfg: pkgs.writeText "nylon-${cfg.name}.conf" '' [General] No-Simultaneous-Conn=${toString cfg.nrConnections} Log=${if cfg.logging then "1" else "0"} @@ -22,15 +22,9 @@ let Deny-IP=${concatStringsSep " " cfg.deniedIPRanges} ''; -in - -{ - - ###### interface - - options = { + nylonOpts = { name, config, ... }: { - services.nylon = { + options = { enable = mkOption { type = types.bool; @@ -40,6 +34,12 @@ in ''; }; + name = mkOption { + type = types.str; + default = ""; + description = "The name of this nylon instance."; + }; + nrConnections = mkOption { type = types.int; default = 10; @@ -107,13 +107,51 @@ in ''; }; }; + config = { name = mkDefault name; }; + }; + + mkNamedNylon = cfg: { + "nylon-${cfg.name}" = { + description = "Nylon, a lightweight SOCKS proxy server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + { + User = "nylon"; + Group = "nylon"; + WorkingDirectory = homeDir; + ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile cfg}"; + }; + }; + }; + + anyNylons = collect (p: p ? enable) cfg; + enabledNylons = filter (p: p.enable == true) anyNylons; + nylonUnits = map (nylon: mkNamedNylon nylon) enabledNylons; + +in + +{ + + ###### interface + + options = { + + services.nylon = mkOption { + default = {}; + description = "Collection of named nylon instances"; + type = with types; loaOf (submodule nylonOpts); + internal = true; + options = [ nylonOpts ]; + }; + }; ###### implementation - config = mkIf cfg.enable { + config = mkIf (length(enabledNylons) > 0) { - users.extraUsers.nylon= { + users.extraUsers.nylon = { group = "nylon"; description = "Nylon SOCKS Proxy"; home = homeDir; @@ -123,17 +161,7 @@ in users.extraGroups.nylon.gid = config.ids.gids.nylon; - systemd.services.nylon = { - description = "Nylon, a lightweight SOCKS proxy server"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = - { - User = "nylon"; - Group = "nylon"; - WorkingDirectory = homeDir; - ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile}"; - }; - }; + systemd.services = fold (a: b: a // b) {} nylonUnits; + }; } diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix index edcc12170b20..9b06cccca79e 100644 --- a/nixos/modules/services/networking/quassel.nix +++ b/nixos/modules/services/networking/quassel.nix @@ -25,12 +25,12 @@ in package = mkOption { type = types.package; - default = pkgs.kde4.quasselDaemon; - defaultText = "pkgs.kde4.quasselDaemon"; + default = pkgs.quasselDaemon_qt5; + defaultText = "pkgs.quasselDaemon_qt5"; description = '' The package of the quassel daemon. ''; - example = literalExample "pkgs.quasselDaemon"; + example = literalExample "pkgs.quasselDaemon_qt5"; }; interfaces = mkOption { diff --git a/nixos/modules/services/networking/redsocks.nix b/nixos/modules/services/networking/redsocks.nix new file mode 100644 index 000000000000..a47a78f1005e --- /dev/null +++ b/nixos/modules/services/networking/redsocks.nix @@ -0,0 +1,270 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.redsocks; +in +{ + ##### interface + options = { + services.redsocks = { + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable redsocks."; + }; + + log_debug = mkOption { + type = types.bool; + default = false; + description = "Log connection progress."; + }; + + log_info = mkOption { + type = types.bool; + default = false; + description = "Log start and end of client sessions."; + }; + + log = mkOption { + type = types.str; + default = "stderr"; + description = + '' + Where to send logs. + + Possible values are: + - stderr + - file:/path/to/file + - syslog:FACILITY where FACILITY is any of "daemon", "local0", + etc. + ''; + }; + + chroot = mkOption { + type = with types; nullOr str; + default = null; + description = + '' + Chroot under which to run redsocks. Log file is opened before + chroot, but if logging to syslog /etc/localtime may be required. + ''; + }; + + redsocks = mkOption { + description = + '' + Local port to proxy associations to be performed. + + The example shows how to configure a proxy to handle port 80 as HTTP + relay, and all other ports as HTTP connect. + ''; + example = [ + { port = 23456; proxy = "1.2.3.4:8080"; type = "http-relay"; + redirectCondition = "--dport 80"; + doNotRedirect = [ "-d 1.2.0.0/16" ]; + } + { port = 23457; proxy = "1.2.3.4:8080"; type = "http-connect"; + redirectCondition = true; + doNotRedirect = [ "-d 1.2.0.0/16" ]; + } + ]; + type = types.listOf (types.submodule { options = { + ip = mkOption { + type = types.str; + default = "127.0.0.1"; + description = + '' + IP on which redsocks should listen. Defaults to 127.0.0.1 for + security reasons. + ''; + }; + + port = mkOption { + type = types.int; + default = 12345; + description = "Port on which redsocks should listen."; + }; + + proxy = mkOption { + type = types.str; + description = + '' + Proxy through which redsocks should forward incoming traffic. + Example: "example.org:8080" + ''; + }; + + type = mkOption { + type = types.enum [ "socks4" "socks5" "http-connect" "http-relay" ]; + description = "Type of proxy."; + }; + + login = mkOption { + type = with types; nullOr str; + default = null; + description = "Login to send to proxy."; + }; + + password = mkOption { + type = with types; nullOr str; + default = null; + description = + '' + Password to send to proxy. WARNING, this will end up + world-readable in the store! Awaiting + https://github.com/NixOS/nix/issues/8 to be able to fix. + ''; + }; + + disclose_src = mkOption { + type = types.enum [ "false" "X-Forwarded-For" "Forwarded_ip" + "Forwarded_ipport" ]; + default = "false"; + description = + '' + Way to disclose client IP to the proxy. + - "false": do not disclose + http-connect supports the following ways: + - "X-Forwarded-For": add header "X-Forwarded-For: IP" + - "Forwarded_ip": add header "Forwarded: for=IP" (see RFC7239) + - "Forwarded_ipport": add header 'Forwarded: for="IP:port"' + ''; + }; + + redirectInternetOnly = mkOption { + type = types.bool; + default = true; + description = "Exclude all non-globally-routable IPs from redsocks"; + }; + + doNotRedirect = mkOption { + type = with types; listOf str; + default = []; + description = + '' + Iptables filters that if matched will get the packet off of + redsocks. + ''; + example = [ "-d 1.2.3.4" ]; + }; + + redirectCondition = mkOption { + type = with types; either bool str; + default = false; + description = + '' + Conditions to make outbound packets go through this redsocks + instance. + + If set to false, no packet will be forwarded. If set to true, + all packets will be forwarded (except packets excluded by + redirectInternetOnly). + + If set to a string, this is an iptables filter that will be + matched against packets before getting them into redsocks. For + example, setting it to "--dport 80" will only send + packets to port 80 to redsocks. Note "-p tcp" is always + implicitly added, as udp can only be proxied through redudp or + the like. + ''; + }; + };}); + }; + + # TODO: Add support for redudp and dnstc + }; + }; + + ##### implementation + config = let + redsocks_blocks = concatMapStrings (block: + let proxy = splitString ":" block.proxy; in + '' + redsocks { + local_ip = ${block.ip}; + local_port = ${toString block.port}; + + ip = ${elemAt proxy 0}; + port = ${elemAt proxy 1}; + type = ${block.type}; + + ${optionalString (block.login != null) "login = \"${block.login}\";"} + ${optionalString (block.password != null) "password = \"${block.password}\";"} + + disclose_src = ${block.disclose_src}; + } + '') cfg.redsocks; + configfile = pkgs.writeText "redsocks.conf" + '' + base { + log_debug = ${if cfg.log_debug then "on" else "off" }; + log_info = ${if cfg.log_info then "on" else "off" }; + log = ${cfg.log}; + + daemon = off; + redirector = iptables; + + user = redsocks; + group = redsocks; + ${optionalString (cfg.chroot != null) "chroot = ${cfg.chroot};"} + } + + ${redsocks_blocks} + ''; + internetOnly = [ # TODO: add ipv6-equivalent + "-d 0.0.0.0/8" + "-d 10.0.0.0/8" + "-d 127.0.0.0/8" + "-d 169.254.0.0/16" + "-d 172.16.0.0/12" + "-d 192.168.0.0/16" + "-d 224.168.0.0/4" + "-d 240.168.0.0/4" + ]; + redCond = block: + optionalString (isString block.redirectCondition) block.redirectCondition; + iptables = concatImapStrings (idx: block: + let chain = "REDSOCKS${toString idx}"; doNotRedirect = + concatMapStringsSep "\n" + (f: "ip46tables -t nat -A ${chain} ${f} -j RETURN 2>/dev/null || true") + (block.doNotRedirect ++ (optionals block.redirectInternetOnly internetOnly)); + in + optionalString (block.redirectCondition != false) + '' + ip46tables -t nat -F ${chain} 2>/dev/null || true + ip46tables -t nat -N ${chain} 2>/dev/null || true + ${doNotRedirect} + ip46tables -t nat -A ${chain} -p tcp -j REDIRECT --to-ports ${toString block.port} + + # TODO: show errors, when it will be easily possible by a switch to + # iptables-restore + ip46tables -t nat -A OUTPUT -p tcp ${redCond block} -j ${chain} 2>/dev/null || true + '' + ) cfg.redsocks; + in + mkIf cfg.enable { + users.groups.redsocks = {}; + users.users.redsocks = { + description = "Redsocks daemon"; + group = "redsocks"; + isSystemUser = true; + }; + + systemd.services.redsocks = { + description = "Redsocks"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = "${pkgs.redsocks}/bin/redsocks -c ${configfile}"; + }; + + networking.firewall.extraCommands = iptables; + + networking.firewall.extraStopCommands = + concatImapStringsSep "\n" (idx: block: + let chain = "REDSOCKS${toString idx}"; in + optionalString (block.redirectCondition != false) + "ip46tables -t nat -D OUTPUT -p tcp ${redCond block} -j ${chain} 2>/dev/null || true" + ) cfg.redsocks; + }; +} diff --git a/nixos/modules/services/networking/rpcbind.nix b/nixos/modules/services/networking/rpcbind.nix index eef1e8e8cd88..cddcb09054e0 100644 --- a/nixos/modules/services/networking/rpcbind.nix +++ b/nixos/modules/services/networking/rpcbind.nix @@ -2,35 +2,6 @@ with lib; -let - - netconfigFile = { - target = "netconfig"; - source = pkgs.writeText "netconfig" '' - # - # The network configuration file. This file is currently only used in - # conjunction with the TI-RPC code in the libtirpc library. - # - # Entries consist of: - # - # <network_id> <semantics> <flags> <protofamily> <protoname> \ - # <device> <nametoaddr_libs> - # - # The <device> and <nametoaddr_libs> fields are always empty in this - # implementation. - # - udp tpi_clts v inet udp - - - tcp tpi_cots_ord v inet tcp - - - udp6 tpi_clts v inet6 udp - - - tcp6 tpi_cots_ord v inet6 tcp - - - rawip tpi_raw - inet - - - - local tpi_cots_ord - loopback - - - - unix tpi_cots_ord - loopback - - - - ''; - }; - -in - { ###### interface @@ -58,25 +29,18 @@ in ###### implementation config = mkIf config.services.rpcbind.enable { - environment.systemPackages = [ pkgs.rpcbind ]; - environment.etc = [ netconfigFile ]; - - systemd.services.rpcbind = - { description = "ONC RPC Directory Service"; + systemd.packages = [ pkgs.rpcbind ]; - wantedBy = [ "multi-user.target" ]; - - requires = [ "basic.target" ]; - after = [ "basic.target" ]; - - unitConfig.DefaultDependencies = false; # don't stop during shutdown - - serviceConfig.Type = "forking"; - serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind"; - }; + systemd.services.rpcbind = { + wantedBy = [ "multi-user.target" ]; + }; + users.extraUsers.rpc = { + group = "nogroup"; + uid = config.ids.uids.rpc; + }; }; } diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix index b29db58af99b..b852e4e6dc86 100644 --- a/nixos/modules/services/networking/searx.nix +++ b/nixos/modules/services/networking/searx.nix @@ -34,6 +34,11 @@ in "; }; + package = mkOption { + default = pkgs.pythonPackages.searx; + description = "searx package to use."; + }; + }; }; @@ -61,14 +66,13 @@ in wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "searx"; - ExecStart = "${pkgs.pythonPackages.searx}/bin/searx-run"; + ExecStart = "${cfg.package}/bin/searx-run"; }; } // (optionalAttrs (configFile != "") { environment.SEARX_SETTINGS_PATH = configFile; }); - - environment.systemPackages = [ pkgs.pythonPackages.searx ]; + environment.systemPackages = [ cfg.package ]; }; diff --git a/nixos/modules/services/networking/supplicant.nix b/nixos/modules/services/networking/supplicant.nix index 0c459fb1dd0c..31d11548f195 100644 --- a/nixos/modules/services/networking/supplicant.nix +++ b/nixos/modules/services/networking/supplicant.nix @@ -82,7 +82,8 @@ in configFile = { path = mkOption { - type = types.path; + type = types.nullOr types.path; + default = null; example = literalExample "/etc/wpa_supplicant.conf"; description = '' External <literal>wpa_supplicant.conf</literal> configuration file. diff --git a/nixos/modules/services/security/hologram-agent.nix b/nixos/modules/services/security/hologram-agent.nix new file mode 100644 index 000000000000..49b5c935267b --- /dev/null +++ b/nixos/modules/services/security/hologram-agent.nix @@ -0,0 +1,57 @@ +{pkgs, config, lib, ...}: + +with lib; + +let + cfg = config.services.hologram-agent; + + cfgFile = pkgs.writeText "hologram-agent.json" (builtins.toJSON { + host = cfg.dialAddress; + }); +in { + options = { + services.hologram-agent = { + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable the Hologram agent for AWS instance credentials"; + }; + + dialAddress = mkOption { + type = types.str; + default = "localhost:3100"; + description = "Hologram server and port."; + }; + + httpPort = mkOption { + type = types.str; + default = "80"; + description = "Port for metadata service to listen on."; + }; + + }; + }; + + config = mkIf cfg.enable { + networking.interfaces.dummy0 = { + ipAddress = "169.254.169.254"; + prefixLength = 32; + }; + + systemd.services.hologram-agent = { + description = "Provide EC2 instance credentials to machines outside of EC2"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + requires = [ "network-link-dummy0.service" "network-addresses-dummy0.service" ]; + preStart = '' + /run/current-system/sw/bin/rm -fv /var/run/hologram.sock + ''; + serviceConfig = { + ExecStart = "${pkgs.hologram.bin}/bin/hologram-agent -debug -conf ${cfgFile} -port ${cfg.httpPort}"; + }; + }; + + }; + + meta.maintainers = with lib.maintainers; [ nand0p ]; +} diff --git a/nixos/modules/services/security/hologram.nix b/nixos/modules/services/security/hologram-server.nix index e267fed27955..e267fed27955 100644 --- a/nixos/modules/services/security/hologram.nix +++ b/nixos/modules/services/security/hologram-server.nix diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index fae5a55c5cef..33bc890a78c8 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -20,8 +20,6 @@ let "<includedir>${d}/etc/dbus-1/session.d</includedir>" ])); - daemonArgs = "--address=systemd: --nofork --nopidfile --systemd-activation"; - configDir = pkgs.runCommand "dbus-conf" { preferLocalBuild = true; allowSubstitutes = false; @@ -29,11 +27,6 @@ let '' mkdir -p $out - cp ${pkgs.dbus.out}/share/dbus-1/{system,session}.conf $out - - # include by full path - sed -ri "s@/etc/dbus-1/(system|session)-@$out/\1-@" $out/{system,session}.conf - sed '${./dbus-system-local.conf.in}' \ -e 's,@servicehelper@,${config.security.wrapperDir}/dbus-daemon-launch-helper,g' \ -e 's,@extra@,${systemExtraxml},' \ @@ -95,6 +88,11 @@ in environment.systemPackages = [ pkgs.dbus.daemon pkgs.dbus ]; + environment.etc = singleton + { source = configDir; + target = "dbus-1"; + }; + users.extraUsers.messagebus = { uid = config.ids.uids.messagebus; description = "D-Bus system message bus daemon user"; @@ -124,10 +122,6 @@ in # Don't restart dbus-daemon. Bad things tend to happen if we do. reloadIfChanged = true; restartTriggers = [ configDir ]; - serviceConfig.ExecStart = [ - "" # Default dbus.service has two entries, we need to override both. - "${lib.getBin pkgs.dbus}/bin/dbus-daemon --config-file=/run/current-system/dbus/system.conf ${daemonArgs}" - ]; }; systemd.user = { @@ -135,18 +129,10 @@ in # Don't restart dbus-daemon. Bad things tend to happen if we do. reloadIfChanged = true; restartTriggers = [ configDir ]; - serviceConfig.ExecStart = [ - "" # Default dbus.service has two entries, we need to override both. - "${lib.getBin pkgs.dbus}/bin/dbus-daemon --config-file=/run/current-system/dbus/session.conf ${daemonArgs}" - ]; }; sockets.dbus.wantedBy = mkIf cfg.socketActivated [ "sockets.target" ]; }; environment.pathsToLink = [ "/etc/dbus-1" "/share/dbus-1" ]; - - system.extraSystemBuilderCmds = '' - ln -s ${configDir} $out/dbus - ''; }; } diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix index dc0ca501a484..ed77e0844769 100644 --- a/nixos/modules/services/web-servers/apache-httpd/default.nix +++ b/nixos/modules/services/web-servers/apache-httpd/default.nix @@ -63,6 +63,8 @@ let let svcFunction = if svc ? function then svc.function + # instead of using serviceType="mediawiki"; you can copy mediawiki.nix to any location outside nixpkgs, modify it at will, and use serviceExpression=./mediawiki.nix; + else if svc ? serviceExpression then import (toString svc.serviceExpression) else import (toString "${toString ./.}/${if svc ? serviceType then svc.serviceType else svc.serviceName}.nix"); config = (evalModules { modules = [ { options = res.options; config = svc.config or svc; } ]; diff --git a/nixos/modules/services/web-servers/apache-httpd/moodle.nix b/nixos/modules/services/web-servers/apache-httpd/moodle.nix deleted file mode 100644 index d525348d5c7e..000000000000 --- a/nixos/modules/services/web-servers/apache-httpd/moodle.nix +++ /dev/null @@ -1,198 +0,0 @@ -{ config, lib, pkgs, serverInfo, php, ... }: - -with lib; - -let - - httpd = serverInfo.serverConfig.package; - - version24 = !versionOlder httpd.version "2.4"; - - allGranted = if version24 then '' - Require all granted - '' else '' - Order allow,deny - Allow from all - ''; - - moodleConfig = pkgs.writeText "config.php" - '' - <?php - unset($CFG); - global $CFG; - $CFG = new stdClass(); - $CFG->dbtype = '${config.dbType}'; - $CFG->dblibrary = 'native'; - $CFG->dbhost = '${config.dbHost}'; - $CFG->dbname = '${config.dbName}'; - $CFG->dbuser = '${config.dbUser}'; - $CFG->dbpass = '${config.dbPassword}'; - $CFG->prefix = '${config.dbPrefix}'; - $CFG->dboptions = array( - 'dbpersist' => false, - 'dbsocket' => false, - 'dbport' => "${config.dbPort}", - ); - $CFG->wwwroot = '${config.wwwRoot}'; - $CFG->dataroot = '${config.dataRoot}'; - $CFG->directorypermissions = 02777; - $CFG->admin = 'admin'; - ${optionalString (config.debug.noEmailEver == true) '' - $CFG->noemailever = true; - ''} - - ${config.extraConfig} - require_once(dirname(__FILE__) . '/lib/setup.php'); // Do not edit - ''; - # Unpack Moodle and put the config file in its root directory. - moodleRoot = pkgs.stdenv.mkDerivation rec { - name= "moodle-2.8.10"; - - src = pkgs.fetchurl { - url = "https://download.moodle.org/stable28/${name}.tgz"; - sha256 = "0c3r5081ipcwc9s6shakllnrkd589y2ln5z5m1q09l4h6a7cy4z2"; - }; - - buildPhase = - '' - ''; - - installPhase = - '' - mkdir -p $out - cp -r * $out - cp ${moodleConfig} $out/config.php - ''; - # Marked as broken due to needing an update for security issues. - # See: https://github.com/NixOS/nixpkgs/issues/18856 - meta.broken = true; - - }; - -in - -{ - - extraConfig = - '' - # this should be config.urlPrefix instead of / - Alias / ${moodleRoot}/ - <Directory ${moodleRoot}> - DirectoryIndex index.php - </Directory> - ''; - - documentRoot = moodleRoot; # TODO: fix this, should be config.urlPrefix - - enablePHP = true; - - options = { - - id = mkOption { - default = "main"; - description = '' - A unique identifier necessary to keep multiple Moodle server - instances on the same machine apart. - ''; - }; - - dbType = mkOption { - default = "postgres"; - example = "mysql"; - description = "Database type."; - }; - - dbName = mkOption { - default = "moodle"; - description = "Name of the database that holds the Moodle data."; - }; - - dbHost = mkOption { - default = "localhost"; - example = "10.0.2.2"; - description = '' - The location of the database server. - ''; - }; - - dbPort = mkOption { - default = ""; # use the default port - example = "12345"; - description = '' - The port that is used to connect to the database server. - ''; - }; - - dbUser = mkOption { - default = "moodle"; - description = "The user name for accessing the database."; - }; - - dbPassword = mkOption { - default = ""; - example = "password"; - description = '' - The password of the database user. Warning: this is stored in - cleartext in the Nix store! - ''; - }; - - dbPrefix = mkOption { - default = "mdl_"; - example = "my_other_mdl_"; - description = '' - A prefix for each table, if multiple moodles should run in a single database. - ''; - }; - - wwwRoot = mkOption { - type = types.string; - example = "http://my.machine.com/my-moodle"; - description = '' - The full web address where moodle has been installed. - ''; - }; - - dataRoot = mkOption { - default = "/var/lib/moodledata"; - example = "/var/lib/moodledata"; - description = '' - The data directory for moodle. Needs to be writable! - ''; - type = types.path; - }; - - - extraConfig = mkOption { - type = types.lines; - default = ""; - example = - '' - ''; - description = '' - Any additional text to be appended to Moodle's - configuration file. This is a PHP script. - ''; - }; - - debug = { - noEmailEver = mkOption { - default = false; - example = "true"; - description = '' - Set this to true to prevent Moodle from ever sending any email. - ''; - }; - }; - }; - - startupScript = pkgs.writeScript "moodle_startup.sh" '' - echo "Checking for existence of ${config.dataRoot}" - if [ ! -e "${config.dataRoot}" ] - then - mkdir -p "${config.dataRoot}" - chown ${serverInfo.serverConfig.user}.${serverInfo.serverConfig.group} "${config.dataRoot}" - fi - ''; - -} diff --git a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix index 26f0bdec6559..a5b6548d3c53 100644 --- a/nixos/modules/services/web-servers/apache-httpd/wordpress.nix +++ b/nixos/modules/services/web-servers/apache-httpd/wordpress.nix @@ -6,7 +6,7 @@ with lib; let # Upgrading? We have a test! nix-build ./nixos/tests/wordpress.nix - version = "4.7.1"; + version = "4.7.2"; fullversion = "${version}"; # Our bare-bones wp-config.php file using the above settings @@ -75,7 +75,7 @@ let owner = "WordPress"; repo = "WordPress"; rev = "${fullversion}"; - sha256 = "1wb4f4zn55d23qi0whsfpbpcd4sjvzswgmni6f5rzrmlawq9ssgr"; + sha256 = "0vph12708drf8ww0xd05hpdvbyy7n5gj9ca598lhdhy2i1j6wy32"; }; installPhase = '' mkdir -p $out diff --git a/nixos/modules/services/web-servers/caddy.nix b/nixos/modules/services/web-servers/caddy.nix index 619e0f90b124..a49838c876f9 100644 --- a/nixos/modules/services/web-servers/caddy.nix +++ b/nixos/modules/services/web-servers/caddy.nix @@ -61,6 +61,7 @@ in User = "caddy"; Group = "caddy"; AmbientCapabilities = "cap_net_bind_service"; + LimitNOFILE = 8192; }; }; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index c9eacdd85dcd..aa11a5d5e80a 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -16,7 +16,20 @@ let ) cfg.virtualHosts; enableIPv6 = config.networking.enableIPv6; - configFile = pkgs.writeText "nginx.conf" '' + configFile = pkgs.runCommand "nginx.conf" { + inherit configFileUnformatted; + passAsFile = [ "configFileUnformatted" ]; + # configFileUnformatted is created locally, therefore so should this be. + preferLocalBuild = true; + allowSubstitutes = false; + } '' + cp ${configFileUnformatted} nginx.conf + chmod u+w nginx.conf + ${pkgs.nginx-config-formatter}/bin/nginxfmt nginx.conf + cp nginx.conf $out + ''; + + configFileUnformatted = pkgs.writeText "nginx.unformatted.conf" '' user ${cfg.user} ${cfg.group}; error_log stderr; daemon off; @@ -403,7 +416,7 @@ in acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME) vhostsConfigs; acmePairs = map (vhostConfig: { name = vhostConfig.serverName; value = { user = cfg.user; - group = cfg.group; + group = lib.mkDefault cfg.group; webroot = vhostConfig.acmeRoot; extraDomains = genAttrs vhostConfig.serverAliases (alias: null); postRun = '' diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index 144e4aada277..1f7a925ed054 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -18,9 +18,8 @@ in # determines the default: later modules (if enabled) are preferred. # E.g., if KDE is enabled, it supersedes xterm. imports = [ - ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix - ./lumina.nix ./lxqt.nix ./enlightenment.nix ./gnome3.nix - ./kodi.nix + ./none.nix ./xterm.nix ./xfce.nix ./kde5.nix ./lumina.nix + ./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ]; options = { diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index 9b4caafe3b39..d908553ccdf8 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -64,7 +64,10 @@ in security.wrappers.e_freqset.source = "${e.enlightenment.out}/bin/e_freqset"; - services.xserver.exportConfiguration = true; + environment.etc = singleton + { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + target = "X11/xkb"; + }; fonts.fonts = [ pkgs.dejavu_fonts pkgs.ubuntu_font_family ]; diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 17e84b1d9a16..21453d1917e8 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -78,7 +78,7 @@ in { }; debug = mkEnableOption "gnome-session debug messages"; - }; + }; environment.gnome3.packageSet = mkOption { default = null; @@ -86,7 +86,7 @@ in { description = "Which GNOME 3 package set to use."; apply = p: if p == null then pkgs.gnome3 else p; }; - + environment.gnome3.excludePackages = mkOption { default = []; example = literalExample "[ pkgs.gnome3.totem ]"; @@ -125,6 +125,9 @@ in { services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center services.udev.packages = [ pkgs.gnome3.gnome_settings_daemon ]; + # If gnome3 is installed, build vim for gtk3 too. + nixpkgs.config.vim.gui = "gtk3"; + fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ]; services.xserver.desktopManager.session = singleton diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix deleted file mode 100644 index f810ffdfbb34..000000000000 --- a/nixos/modules/services/x11/desktop-managers/kde4.nix +++ /dev/null @@ -1,190 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - - xcfg = config.services.xserver; - cfg = xcfg.desktopManager.kde4; - xorg = pkgs.xorg; - kde_workspace = config.services.xserver.desktopManager.kde4.kdeWorkspacePackage; - - # Disable Nepomuk and Strigi by default. As of KDE 4.7, they don't - # really work very well (e.g. searching files often fails to find - # files), segfault sometimes and consume significant resources. - # They can be re-enabled in the KDE System Settings under "Desktop - # Search". - disableNepomuk = pkgs.writeTextFile - { name = "nepomuk-config"; - destination = "/share/config/nepomukserverrc"; - text = - '' - [Basic Settings] - Start Nepomuk=false - - [Service-nepomukstrigiservice] - autostart=false - ''; - }; - - phononBackends = { - gstreamer = [ - pkgs.phonon-backend-gstreamer - pkgs.gst_all.gstPluginsBase - pkgs.gst_all.gstPluginsGood - pkgs.gst_all.gstPluginsUgly - pkgs.gst_all.gstPluginsBad - pkgs.gst_all.gstFfmpeg # for mp3 playback - pkgs.gst_all.gstreamer # needed? - ]; - - vlc = [pkgs.phonon-backend-vlc]; - }; - - phononBackendPackages = flip concatMap cfg.phononBackends - (name: attrByPath [name] (throw "unknown phonon backend `${name}'") phononBackends); - -in - -{ - options = { - - services.xserver.desktopManager.kde4 = { - enable = mkOption { - type = types.bool; - default = false; - description = "Enable the KDE 4 desktop environment."; - }; - - phononBackends = mkOption { - type = types.listOf types.str; - default = ["gstreamer"]; - example = ["gstreamer" "vlc"]; - description = "Which phonon multimedia backend kde should use"; - }; - - kdeWorkspacePackage = mkOption { - internal = true; - default = pkgs.kde4.kde_workspace; - defaultText = "pkgs.kde4.kde_workspace"; - type = types.package; - description = "Custom kde-workspace, used for NixOS rebranding."; - }; - - enablePIM = mkOption { - type = types.bool; - default = true; - description = "Whether to enable PIM support. Note that enabling this pulls in Akonadi and MariaDB as dependencies."; - }; - - enableNepomuk = mkOption { - type = types.bool; - default = false; - description = "Whether to enable Nepomuk (deprecated)."; - }; - }; - }; - - - config = mkIf (xcfg.enable && cfg.enable) { - - # If KDE 4 is enabled, make it the default desktop manager (unless - # overridden by the user's configuration). - # !!! doesn't work yet ("Multiple definitions. Only one is allowed - # for this option.") - # services.xserver.desktopManager.default = mkOverride 900 "kde4"; - - services.xserver.desktopManager.session = singleton - { name = "kde4"; - bgSupport = true; - start = - '' - # The KDE icon cache is supposed to update itself - # automatically, but it uses the timestamp on the icon - # theme directory as a trigger. Since in Nix the - # timestamp is always the same, this doesn't work. So as - # a workaround, nuke the icon cache on login. This isn't - # perfect, since it may require logging out after - # installing new applications to update the cache. - # See http://lists-archives.org/kde-devel/26175-what-when-will-icon-cache-refresh.html - rm -fv $HOME/.kde/cache-*/icon-cache.kcache - - # Qt writes a weird ‘libraryPath’ line to - # ~/.config/Trolltech.conf that causes the KDE plugin - # paths of previous KDE invocations to be searched. - # Obviously using mismatching KDE libraries is potentially - # disastrous, so here we nuke references to the Nix store - # in Trolltech.conf. A better solution would be to stop - # Qt from doing this wackiness in the first place. - if [ -e $HOME/.config/Trolltech.conf ]; then - sed -e '/nix\\store\|nix\/store/ d' -i $HOME/.config/Trolltech.conf - fi - - # Load PulseAudio module for routing support. - # See http://colin.guthr.ie/2009/10/so-how-does-the-kde-pulseaudio-support-work-anyway/ - ${optionalString config.hardware.pulseaudio.enable '' - ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1" - ''} - - # Start KDE. - exec ${kde_workspace}/bin/startkde - ''; - }; - - security.wrappers.kcheckpass.source = "${kde_workspace}/lib/kde4/libexec/kcheckpass"; - - environment.systemPackages = - [ pkgs.kde4.kdelibs - - pkgs.kde4.kde_baseapps # Splitted kdebase - kde_workspace - pkgs.kde4.kde_runtime - pkgs.kde4.konsole - pkgs.kde4.kate - - pkgs.kde4.kde_wallpapers # contains kdm's default background - pkgs.kde4.oxygen_icons - - # Starts KDE's Polkit authentication agent. - pkgs.kde4.polkit_kde_agent - - # Miscellaneous runtime dependencies. - pkgs.kde4.qt4 # needed for qdbus - pkgs.shared_mime_info - xorg.xmessage # so that startkde can show error messages - xorg.xset # used by startkde, non-essential - xorg.xauth # used by kdesu - ] - ++ optionals cfg.enablePIM - [ pkgs.kde4.kdepim_runtime - pkgs.kde4.akonadi - pkgs.mysql # used by akonadi - ] - ++ (if cfg.enableNepomuk then - [ pkgs.shared_desktop_ontologies # used by nepomuk - pkgs.strigi # used by nepomuk - pkgs.virtuoso # to enable Nepomuk to find Virtuoso - ] else - [ disableNepomuk ]) - ++ optional config.hardware.pulseaudio.enable pkgs.kde4.kmix # Perhaps this should always be enabled - ++ optional config.hardware.bluetooth.enable pkgs.kde4.bluedevil - ++ optional config.networking.networkmanager.enable pkgs.kde4.plasma-nm - ++ phononBackendPackages; - - environment.pathsToLink = [ "/share" ]; - - environment.profileRelativeEnvVars = mkIf (elem "gstreamer" cfg.phononBackends) { - GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ]; - }; - - services.xserver.exportConfiguration = true; - - # Enable helpful DBus services. - services.udisks2.enable = true; - services.upower.enable = config.powerManagement.enable; - - security.pam.services.kde = { allowNullPassword = true; }; - - }; - -} diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix index 5874e080fd83..06f9f0a62ef8 100644 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ b/nixos/modules/services/x11/desktop-managers/kde5.nix @@ -50,10 +50,6 @@ in }) (mkIf (xcfg.enable && cfg.enable) { - - warnings = optional config.services.xserver.desktopManager.kde4.enable - "KDE 4 should not be enabled at the same time as KDE 5"; - services.xserver.desktopManager.session = singleton { name = "kde5"; bgSupport = true; @@ -188,7 +184,10 @@ in environment.pathsToLink = [ "/share" ]; - services.xserver.exportConfiguration = true; + environment.etc = singleton { + source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + target = "X11/xkb"; + }; environment.variables = { diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index c0daf30d04eb..e8b897fb6050 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -1,5 +1,5 @@ # This module declares the options to define a *display manager*, the -# program responsible for handling X logins (such as xdm, kdm, gdb, or +# program responsible for handling X logins (such as xdm, gdb, or # SLiM). The display manager allows the user to select a *session # type*. When the user logs in, the display manager starts the # *session script* ("xsession" below) to launch the selected session @@ -32,6 +32,9 @@ let '' #! ${pkgs.bash}/bin/bash + # Handle being called by SDDM. + if test "''${1:0:1}" = / ; then eval exec $1 $2 ; fi + ${optionalString cfg.displayManager.logToJournal '' if [ -z "$_DID_SYSTEMD_CAT" ]; then _DID_SYSTEMD_CAT=1 exec ${config.systemd.package}/bin/systemd-cat -t xsession -- "$0" "$@" @@ -55,9 +58,6 @@ let fi ''} - # Handle being called by kdm. - if test "''${1:0:1}" = /; then eval exec "$1"; fi - # Start PulseAudio if enabled. ${optionalString (config.hardware.pulseaudio.enable) '' ${optionalString (!config.hardware.pulseaudio.systemWide) diff --git a/nixos/modules/services/x11/display-managers/kdm.nix b/nixos/modules/services/x11/display-managers/kdm.nix deleted file mode 100644 index 04701a1640cc..000000000000 --- a/nixos/modules/services/x11/display-managers/kdm.nix +++ /dev/null @@ -1,158 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - - dmcfg = config.services.xserver.displayManager; - cfg = dmcfg.kdm; - - inherit (pkgs.kde4) kdebase_workspace; - - defaultConfig = - '' - [Shutdown] - HaltCmd=${config.systemd.package}/sbin/shutdown -h now - RebootCmd=${config.systemd.package}/sbin/shutdown -r now - ${optionalString (config.system.boot.loader.id == "grub") '' - BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"} - ''} - - [X-*-Core] - Xrdb=${pkgs.xorg.xrdb}/bin/xrdb - SessionsDirs=${dmcfg.session.desktops} - Session=${dmcfg.session.script} - FailsafeClient=${pkgs.xterm}/bin/xterm - - [X-:*-Core] - ServerCmd=${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} - # KDM calls `rm' somewhere to clean up some temporary directory. - SystemPath=${pkgs.coreutils}/bin - # The default timeout (15) is too short in a heavily loaded boot process. - ServerTimeout=60 - # Needed to prevent the X server from dying on logout and not coming back: - TerminateServer=true - ${optionalString (cfg.setupScript != "") - '' - Setup=${cfg.setupScript} - ''} - - [X-*-Greeter] - HiddenUsers=root,${concatStringsSep "," dmcfg.hiddenUsers} - PluginsLogin=${kdebase_workspace}/lib/kde4/kgreet_classic.so - ${optionalString (cfg.themeDirectory != null) - '' - UseTheme=true - Theme=${cfg.themeDirectory} - '' - } - - ${optionalString (cfg.enableXDMCP) - '' - [Xdmcp] - Enable=true - ''} - ''; - - kdmrc = pkgs.runCommand "kdmrc" - { config = defaultConfig + cfg.extraConfig; - preferLocalBuild = true; - } - '' - echo "$config" > $out - - # The default kdmrc would add "-nolisten tcp", and we already - # have that managed by nixos. Hence the grep. - cat ${kdebase_workspace}/share/config/kdm/kdmrc | grep -v nolisten >> $out - ''; - -in - -{ - - ###### interface - - options = { - - services.xserver.displayManager.kdm = { - - enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable the KDE display manager. - ''; - }; - - enableXDMCP = mkOption { - type = types.bool; - default = false; - description = '' - Whether to enable XDMCP, which allows remote logins. - ''; - }; - - themeDirectory = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - The path to a KDM theme directory. This theme - will be used by the KDM greeter. - ''; - }; - - setupScript = mkOption { - type = types.lines; - default = ""; - description = '' - The path to a KDM setup script. This script is run as root just - before KDM starts. Can be used for setting up - monitors with xrandr, for example. - ''; - }; - - extraConfig = mkOption { - type = types.lines; - default = ""; - description = '' - Options appended to <filename>kdmrc</filename>, the - configuration file of KDM. - ''; - }; - - }; - - }; - - - ###### implementation - - config = mkIf cfg.enable { - - services.xserver.displayManager.slim.enable = false; - - services.xserver.displayManager.job = - { execCmd = - '' - mkdir -m 0755 -p /var/lib/kdm - chown kdm /var/lib/kdm - ${(optionalString (config.system.boot.loader.id == "grub" && config.system.build.grub != null) "PATH=${config.system.build.grub}/sbin:$PATH ") + - "KDEDIRS=/run/current-system/sw exec ${kdebase_workspace}/bin/kdm -config ${kdmrc} -nodaemon -logfile /dev/stderr"} - ''; - logsXsession = true; - }; - - security.pam.services.kde = { allowNullPassword = true; startSession = true; }; - - users.extraUsers = singleton - { name = "kdm"; - uid = config.ids.uids.kdm; - description = "KDM user"; - }; - - environment.systemPackages = - [ pkgs.kde4.kde_wallpapers ]; # contains kdm's default background - - }; - -} diff --git a/nixos/modules/services/x11/terminal-server.nix b/nixos/modules/services/x11/terminal-server.nix index 785394d9648c..09a7f386876f 100644 --- a/nixos/modules/services/x11/terminal-server.nix +++ b/nixos/modules/services/x11/terminal-server.nix @@ -16,18 +16,8 @@ with lib; services.xserver.enable = true; services.xserver.videoDrivers = []; - # Enable KDM. Any display manager will do as long as it supports XDMCP. - services.xserver.displayManager.kdm.enable = true; - services.xserver.displayManager.kdm.enableXDMCP = true; - services.xserver.displayManager.kdm.extraConfig = - '' - [General] - # We're headless, so don't bother starting an X server. - StaticServers= - - [Xdmcp] - Xaccess=${pkgs.writeText "Xaccess" "localhost"} - ''; + # Enable GDM. Any display manager will do as long as it supports XDMCP. + services.xserver.displayManager.gdm.enable = true; systemd.sockets.terminal-server = { description = "Terminal Server Socket"; diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix index 8617a5fab03f..7ac776571a01 100644 --- a/nixos/modules/services/x11/xserver.nix +++ b/nixos/modules/services/x11/xserver.nix @@ -459,21 +459,31 @@ in knownVideoDrivers; in optional (driver != null) ({ inherit name; modules = []; driverName = name; } // driver)); + nixpkgs.config.xorg = optionalAttrs (elem "vboxvideo" cfg.videoDrivers) { abiCompat = "1.18"; }; + assertions = [ { assertion = config.security.polkit.enable; message = "X11 requires Polkit to be enabled (‘security.polkit.enable = true’)."; } ]; - environment.etc = mkMerge [ - (mkIf cfg.exportConfiguration { - "X11/xorg.conf".source = configFile; - "X11/xkb".source = cfg.xkbDir; - }) + environment.etc = + (optionals cfg.exportConfiguration + [ { source = "${configFile}"; + target = "X11/xorg.conf"; + } + # -xkbdir command line option does not seems to be passed to xkbcomp. + { source = "${cfg.xkbDir}"; + target = "X11/xkb"; + } + ]) # Needed since 1.18; see https://bugs.freedesktop.org/show_bug.cgi?id=89023#c5 - (let cfgPath = "X11/xorg.conf.d/10-evdev.conf"; in - { "${cfgPath}".source = xorg.xf86inputevdev.out + "/share" + cfgPath; }) - ]; + ++ (let cfgPath = "/X11/xorg.conf.d/10-evdev.conf"; in + [{ + source = xorg.xf86inputevdev.out + "/share" + cfgPath; + target = cfgPath; + }] + ); environment.systemPackages = [ xorg.xorgserver.out |