From c60c8aa759b7b3b396a709effefb879ceed96fa6 Mon Sep 17 00:00:00 2001 From: gnidorah Date: Tue, 29 May 2018 22:10:25 +0300 Subject: nixos/firewall: per-interface port options --- nixos/modules/services/networking/firewall.nix | 439 +++++++++++++------------ 1 file changed, 230 insertions(+), 209 deletions(-) (limited to 'nixos/modules') diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index c4bd0e7f9eef..36f1dd8d2479 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -148,38 +148,42 @@ let ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept # Accept connections to the allowed TCP ports. - ${concatMapStrings (port: + ${concatStrings (mapAttrsToList (iface: cfg: + concatMapStrings (port: '' - ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept + ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"} '' ) cfg.allowedTCPPorts - } + ) cfg.interfaces)} # Accept connections to the allowed TCP port ranges. - ${concatMapStrings (rangeAttr: + ${concatStrings (mapAttrsToList (iface: cfg: + concatMapStrings (rangeAttr: let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in '' - ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept + ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"} '' ) cfg.allowedTCPPortRanges - } + ) cfg.interfaces)} # Accept packets on the allowed UDP ports. - ${concatMapStrings (port: + ${concatStrings (mapAttrsToList (iface: cfg: + concatMapStrings (port: '' - ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept + ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"} '' ) cfg.allowedUDPPorts - } + ) cfg.interfaces)} # Accept packets on the allowed UDP port ranges. - ${concatMapStrings (rangeAttr: + ${concatStrings (mapAttrsToList (iface: cfg: + concatMapStrings (rangeAttr: let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in '' - ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept + ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"} '' ) cfg.allowedUDPPortRanges - } + ) cfg.interfaces)} # Accept IPv4 multicast. Not a big security risk since # probably nobody is listening anyway. @@ -254,106 +258,30 @@ let fi ''; -in - -{ - - ###### interface - - options = { - - networking.firewall.enable = mkOption { - type = types.bool; - default = true; - description = - '' - Whether to enable the firewall. This is a simple stateful - firewall that blocks connection attempts to unauthorised TCP - or UDP ports on this machine. It does not affect packet - forwarding. - ''; - }; - - networking.firewall.logRefusedConnections = mkOption { - type = types.bool; - default = true; - description = - '' - Whether to log rejected or dropped incoming connections. - ''; - }; - - networking.firewall.logRefusedPackets = mkOption { - type = types.bool; - default = false; - description = - '' - Whether to log all rejected or dropped incoming packets. - This tends to give a lot of log messages, so it's mostly - useful for debugging. - ''; - }; - - networking.firewall.logRefusedUnicastsOnly = mkOption { - type = types.bool; - default = true; - description = - '' - If - and this option are enabled, then only log packets - specifically directed at this machine, i.e., not broadcasts - or multicasts. - ''; - }; - - networking.firewall.rejectPackets = mkOption { - type = types.bool; - default = false; - description = - '' - If set, refused packets are rejected rather than dropped - (ignored). This means that an ICMP "port unreachable" error - message is sent back to the client (or a TCP RST packet in - case of an existing connection). Rejecting packets makes - port scanning somewhat easier. - ''; - }; - - networking.firewall.trustedInterfaces = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "enp0s2" ]; - description = - '' - Traffic coming in from these interfaces will be accepted - unconditionally. Traffic from the loopback (lo) interface - will always be accepted. - ''; - }; - - networking.firewall.allowedTCPPorts = mkOption { + commonOptions = { + allowedTCPPorts = mkOption { type = types.listOf types.int; default = [ ]; example = [ 22 80 ]; description = - '' + '' List of TCP ports on which incoming connections are accepted. ''; }; - networking.firewall.allowedTCPPortRanges = mkOption { + allowedTCPPortRanges = mkOption { type = types.listOf (types.attrsOf types.int); default = [ ]; example = [ { from = 8999; to = 9003; } ]; description = - '' + '' A range of TCP ports on which incoming connections are accepted. ''; }; - networking.firewall.allowedUDPPorts = mkOption { + allowedUDPPorts = mkOption { type = types.listOf types.int; default = [ ]; example = [ 53 ]; @@ -363,7 +291,7 @@ in ''; }; - networking.firewall.allowedUDPPortRanges = mkOption { + allowedUDPPortRanges = mkOption { type = types.listOf (types.attrsOf types.int); default = [ ]; example = [ { from = 60000; to = 61000; } ]; @@ -372,133 +300,226 @@ in Range of open UDP ports. ''; }; + }; - networking.firewall.allowPing = mkOption { - type = types.bool; - default = true; - description = - '' - Whether to respond to incoming ICMPv4 echo requests - ("pings"). ICMPv6 pings are always allowed because the - larger address space of IPv6 makes network scanning much - less effective. - ''; - }; +in - networking.firewall.pingLimit = mkOption { - type = types.nullOr (types.separatedString " "); - default = null; - example = "--limit 1/minute --limit-burst 5"; - description = - '' - If pings are allowed, this allows setting rate limits - on them. If non-null, this option should be in the form of - flags like "--limit 1/minute --limit-burst 5" - ''; - }; +{ - networking.firewall.checkReversePath = mkOption { - type = types.either types.bool (types.enum ["strict" "loose"]); - default = kernelHasRPFilter; - example = "loose"; - description = - '' - Performs a reverse path filter test on a packet. If a reply - to the packet would not be sent via the same interface that - the packet arrived on, it is refused. + ###### interface - If using asymmetric routing or other complicated routing, set - this option to loose mode or disable it and setup your own - counter-measures. + options = { - This option can be either true (or "strict"), "loose" (only - drop the packet if the source address is not reachable via any - interface) or false. Defaults to the value of - kernelHasRPFilter. + networking.firewall = { + enable = mkOption { + type = types.bool; + default = true; + description = + '' + Whether to enable the firewall. This is a simple stateful + firewall that blocks connection attempts to unauthorised TCP + or UDP ports on this machine. It does not affect packet + forwarding. + ''; + }; - (needs kernel 3.3+) - ''; - }; + logRefusedConnections = mkOption { + type = types.bool; + default = true; + description = + '' + Whether to log rejected or dropped incoming connections. + ''; + }; - networking.firewall.logReversePathDrops = mkOption { - type = types.bool; - default = false; - description = - '' - Logs dropped packets failing the reverse path filter test if - the option networking.firewall.checkReversePath is enabled. - ''; - }; + logRefusedPackets = mkOption { + type = types.bool; + default = false; + description = + '' + Whether to log all rejected or dropped incoming packets. + This tends to give a lot of log messages, so it's mostly + useful for debugging. + ''; + }; - networking.firewall.connectionTrackingModules = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ]; - description = - '' - List of connection-tracking helpers that are auto-loaded. - The complete list of possible values is given in the example. - - As helpers can pose as a security risk, it is advised to - set this to an empty list and disable the setting - networking.firewall.autoLoadConntrackHelpers unless you - know what you are doing. Connection tracking is disabled - by default. - - Loading of helpers is recommended to be done through the - CT target. More info: - https://home.regit.org/netfilter-en/secure-use-of-helpers/ - ''; - }; + logRefusedUnicastsOnly = mkOption { + type = types.bool; + default = true; + description = + '' + If + and this option are enabled, then only log packets + specifically directed at this machine, i.e., not broadcasts + or multicasts. + ''; + }; - networking.firewall.autoLoadConntrackHelpers = mkOption { - type = types.bool; - default = false; - description = - '' - Whether to auto-load connection-tracking helpers. - See the description at networking.firewall.connectionTrackingModules + rejectPackets = mkOption { + type = types.bool; + default = false; + description = + '' + If set, refused packets are rejected rather than dropped + (ignored). This means that an ICMP "port unreachable" error + message is sent back to the client (or a TCP RST packet in + case of an existing connection). Rejecting packets makes + port scanning somewhat easier. + ''; + }; - (needs kernel 3.5+) - ''; - }; + trustedInterfaces = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "enp0s2" ]; + description = + '' + Traffic coming in from these interfaces will be accepted + unconditionally. Traffic from the loopback (lo) interface + will always be accepted. + ''; + }; - networking.firewall.extraCommands = mkOption { - type = types.lines; - default = ""; - example = "iptables -A INPUT -p icmp -j ACCEPT"; - description = - '' - Additional shell commands executed as part of the firewall - initialisation script. These are executed just before the - final "reject" firewall rule is added, so they can be used - to allow packets that would otherwise be refused. - ''; - }; + allowPing = mkOption { + type = types.bool; + default = true; + description = + '' + Whether to respond to incoming ICMPv4 echo requests + ("pings"). ICMPv6 pings are always allowed because the + larger address space of IPv6 makes network scanning much + less effective. + ''; + }; - networking.firewall.extraPackages = mkOption { - type = types.listOf types.package; - default = [ ]; - example = literalExample "[ pkgs.ipset ]"; - description = - '' - Additional packages to be included in the environment of the system - as well as the path of networking.firewall.extraCommands. - ''; - }; + pingLimit = mkOption { + type = types.nullOr (types.separatedString " "); + default = null; + example = "--limit 1/minute --limit-burst 5"; + description = + '' + If pings are allowed, this allows setting rate limits + on them. If non-null, this option should be in the form of + flags like "--limit 1/minute --limit-burst 5" + ''; + }; - networking.firewall.extraStopCommands = mkOption { - type = types.lines; - default = ""; - example = "iptables -P INPUT ACCEPT"; - description = - '' - Additional shell commands executed as part of the firewall - shutdown script. These are executed just after the removal - of the NixOS input rule, or if the service enters a failed - state. - ''; - }; + checkReversePath = mkOption { + type = types.either types.bool (types.enum ["strict" "loose"]); + default = kernelHasRPFilter; + example = "loose"; + description = + '' + Performs a reverse path filter test on a packet. If a reply + to the packet would not be sent via the same interface that + the packet arrived on, it is refused. + + If using asymmetric routing or other complicated routing, set + this option to loose mode or disable it and setup your own + counter-measures. + + This option can be either true (or "strict"), "loose" (only + drop the packet if the source address is not reachable via any + interface) or false. Defaults to the value of + kernelHasRPFilter. + + (needs kernel 3.3+) + ''; + }; + + logReversePathDrops = mkOption { + type = types.bool; + default = false; + description = + '' + Logs dropped packets failing the reverse path filter test if + the option networking.firewall.checkReversePath is enabled. + ''; + }; + + connectionTrackingModules = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ]; + description = + '' + List of connection-tracking helpers that are auto-loaded. + The complete list of possible values is given in the example. + + As helpers can pose as a security risk, it is advised to + set this to an empty list and disable the setting + networking.firewall.autoLoadConntrackHelpers unless you + know what you are doing. Connection tracking is disabled + by default. + + Loading of helpers is recommended to be done through the + CT target. More info: + https://home.regit.org/netfilter-en/secure-use-of-helpers/ + ''; + }; + + autoLoadConntrackHelpers = mkOption { + type = types.bool; + default = false; + description = + '' + Whether to auto-load connection-tracking helpers. + See the description at networking.firewall.connectionTrackingModules + + (needs kernel 3.5+) + ''; + }; + + extraCommands = mkOption { + type = types.lines; + default = ""; + example = "iptables -A INPUT -p icmp -j ACCEPT"; + description = + '' + Additional shell commands executed as part of the firewall + initialisation script. These are executed just before the + final "reject" firewall rule is added, so they can be used + to allow packets that would otherwise be refused. + ''; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = [ ]; + example = literalExample "[ pkgs.ipset ]"; + description = + '' + Additional packages to be included in the environment of the system + as well as the path of networking.firewall.extraCommands. + ''; + }; + + extraStopCommands = mkOption { + type = types.lines; + default = ""; + example = "iptables -P INPUT ACCEPT"; + description = + '' + Additional shell commands executed as part of the firewall + shutdown script. These are executed just after the removal + of the NixOS input rule, or if the service enters a failed + state. + ''; + }; + + interfaces = mkOption { + default = { + default = mapAttrs (name: value: cfg."${name}") commonOptions; + }; + type = with types; attrsOf (submodule [ { options = commonOptions; } ]); + description = + '' + Interface-specific open ports. Setting this value will override + all values of the networking.firewall.allowed* + options. + ''; + }; + } // commonOptions; }; -- cgit 1.4.1 From d08967a3a84281270180027b96e5d91924f4bec1 Mon Sep 17 00:00:00 2001 From: ivanbrennan Date: Sun, 1 Jul 2018 15:26:07 -0400 Subject: nixos/security.sudo: describe extraRules order The order of sudoers entries is significant. The man page for sudoers(5) notes: Where there are multiple matches, the last match is used (which is not necessarily the most specific match). This module adds a rule for group "wheel" matching all commands. If you wanted to add a more specific rule allowing members of the "wheel" group to run command `foo` without a password, you'd need to use mkAfter to ensure your rule comes after the more general rule. extraRules = lib.mkAfter [ { groups = [ "wheel" ]; commands = [ { command = "${pkgs.foo}/bin/foo"; options = [ "NOPASSWD" "SETENV" ]; } ] } ]; Otherwise, when configuration options are merged, if the general rule ends up after the specific rule, it will dictate the behavior even when running the `foo` command. --- nixos/modules/security/sudo.nix | 3 +++ 1 file changed, 3 insertions(+) (limited to 'nixos/modules') diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index 24283e1d6165..361a7e869602 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -66,6 +66,9 @@ in security.sudo.extraRules = mkOption { description = '' Define specific rules to be in the sudoers file. + More specific rules should come after more general ones in order to + yield the expected behavior. You can use mkBefore/mkAfter to ensure + this is the case when configuration options are merged. ''; default = []; example = [ -- cgit 1.4.1 From 16a46139d30ec7e6c1ea93db819e52b3d12988d0 Mon Sep 17 00:00:00 2001 From: ldesgoui Date: Mon, 2 Jul 2018 05:30:43 +0200 Subject: murmur: prevent silent launch failure --- nixos/modules/services/networking/murmur.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nixos/modules') diff --git a/nixos/modules/services/networking/murmur.nix b/nixos/modules/services/networking/murmur.nix index 873d62dbf341..266974ac5408 100644 --- a/nixos/modules/services/networking/murmur.nix +++ b/nixos/modules/services/networking/murmur.nix @@ -248,7 +248,7 @@ in systemd.services.murmur = { description = "Murmur Chat Service"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target "]; + after = [ "network-online.target "]; serviceConfig = { Type = "forking"; -- cgit 1.4.1 From cfd8c4ee88fec3a7f989663e09d8e39513b8488e Mon Sep 17 00:00:00 2001 From: Svein Ove Aas Date: Sat, 16 Jun 2018 02:39:07 +0100 Subject: zfs: Improve import handling --- nixos/modules/tasks/filesystems/zfs.nix | 92 +++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 15 deletions(-) (limited to 'nixos/modules') diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix index bfcd81d62159..39f51c363673 100644 --- a/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixos/modules/tasks/filesystems/zfs.nix @@ -58,6 +58,45 @@ let snapshotNames = [ "frequent" "hourly" "daily" "weekly" "monthly" ]; + # When importing ZFS pools, there's one difficulty: These scripts may run + # before the backing devices (physical HDDs, etc.) of the pool have been + # scanned and initialized. + # + # An attempted import with all devices missing will just fail, and can be + # retried, but an import where e.g. two out of three disks in a three-way + # mirror are missing, will succeed. This is a problem: When the missing disks + # are later discovered, they won't be automatically set online, rendering the + # pool redundancy-less (and far slower) until such time as the system reboots. + # + # The solution is the below. poolReady checks the status of an un-imported + # pool, to see if *every* device is available -- in which case the pool will be + # in state ONLINE, as opposed to DEGRADED, FAULTED or MISSING. + # + # The import scripts then loop over this, waiting until the pool is ready or a + # sufficient amount of time has passed that we can assume it won't be. In the + # latter case it makes one last attempt at importing, allowing the system to + # (eventually) boot even with a degraded pool. + importLib = {zpoolCmd, awkCmd, cfgZfs}: '' + poolReady() { + pool="$1" + state="$("${zpoolCmd}" import | "${awkCmd}" "/pool: $pool/ { found = 1 }; /state:/ { if (found == 1) { print \$2; exit } }; END { if (found == 0) { print \"MISSING\" } }")" + if [[ "$state" = "ONLINE" ]]; then + return 0 + else + echo "Pool $pool in state $state, waiting" + return 1 + fi + } + poolImported() { + pool="$1" + "${zpoolCmd}" list "$pool" >/dev/null 2>/dev/null + } + poolImport() { + pool="$1" + "${zpoolCmd}" import -d "${cfgZfs.devNodes}" -N $ZFS_FORCE "$pool" + } + ''; + in { @@ -339,19 +378,26 @@ in ;; esac done - ''] ++ (map (pool: '' + ''] ++ [(importLib { + # See comments at importLib definition. + zpoolCmd = "zpool"; + awkCmd = "awk"; + inherit cfgZfs; + })] ++ (map (pool: '' echo -n "importing root ZFS pool \"${pool}\"..." - trial=0 - until msg="$(zpool import -d ${cfgZfs.devNodes} -N $ZFS_FORCE '${pool}' 2>&1)"; do - sleep 0.25 - echo -n . - trial=$(($trial + 1)) - if [[ $trial -eq 60 ]]; then - break + # Loop across the import until it succeeds, because the devices needed may not be discovered yet. + if ! poolImported "${pool}"; then + for trial in `seq 1 60`; do + poolReady "${pool}" > /dev/null && msg="$(poolImport "${pool}" 2>&1)" && break + sleep 1 + echo -n . + done + echo + if [[ -n "$msg" ]]; then + echo "$msg"; fi - done - echo - if [[ -n "$msg" ]]; then echo "$msg"; fi + poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. + fi ${lib.optionalString cfgZfs.requestEncryptionCredentials '' zfs load-key -a ''} @@ -395,10 +441,26 @@ in Type = "oneshot"; RemainAfterExit = true; }; - script = '' - zpool_cmd="${packages.zfsUser}/sbin/zpool" - ("$zpool_cmd" list "${pool}" >/dev/null) || "$zpool_cmd" import -d ${cfgZfs.devNodes} -N ${optionalString cfgZfs.forceImportAll "-f"} "${pool}" - ${optionalString cfgZfs.requestEncryptionCredentials "\"${packages.zfsUser}/sbin/zfs\" load-key -r \"${pool}\""} + script = (importLib { + # See comments at importLib definition. + zpoolCmd="${packages.zfsUser}/sbin/zpool"; + awkCmd="${pkgs.gawk}/bin/awk"; + inherit cfgZfs; + }) + '' + poolImported "${pool}" && exit + echo -n "importing ZFS pool \"${pool}\"..." + # Loop across the import until it succeeds, because the devices needed may not be discovered yet. + for trial in `seq 1 60`; do + poolReady "${pool}" && poolImport "${pool}" && break + sleep 1 + done + poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. + if poolImported "${pool}"; then + ${optionalString cfgZfs.requestEncryptionCredentials "\"${packages.zfsUser}/sbin/zfs\" load-key -r \"${pool}\""} + echo "Successfully imported ${pool}" + else + exit 1 + fi ''; }; -- cgit 1.4.1 From 57ed52d61f11d01ed1f590ef4d2d9dbc0d740177 Mon Sep 17 00:00:00 2001 From: Richard Marko Date: Tue, 3 Jul 2018 00:40:57 +0200 Subject: nixos/gpsd-service: add services.gpsd.nowait option --- nixos/modules/services/misc/gpsd.nix | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'nixos/modules') diff --git a/nixos/modules/services/misc/gpsd.nix b/nixos/modules/services/misc/gpsd.nix index 71de08609073..80f5501ec1d8 100644 --- a/nixos/modules/services/misc/gpsd.nix +++ b/nixos/modules/services/misc/gpsd.nix @@ -53,6 +53,14 @@ in ''; }; + nowait = mkOption { + type = types.bool; + default = false; + description = '' + don't wait for client connects to poll GPS + ''; + }; + port = mkOption { type = types.int; default = 2947; @@ -100,6 +108,7 @@ in ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \ -S "${toString cfg.port}" \ ${if cfg.readonly then "-b" else ""} \ + ${if cfg.nowait then "-n" else ""} \ "${cfg.device}" ''; }; -- cgit 1.4.1 From da994fb64ec55df5a1cc6cf7c6deabf7f2184978 Mon Sep 17 00:00:00 2001 From: Allan Espinosa Date: Mon, 2 Jul 2018 20:15:11 -0400 Subject: nixos/kerberos: update binary folder pointer ${pkg.tcp_wrappers}/sbin does not exist anymore. --- nixos/modules/services/system/kerberos.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'nixos/modules') diff --git a/nixos/modules/services/system/kerberos.nix b/nixos/modules/services/system/kerberos.nix index 4f2e2fdf662b..d85dee089827 100644 --- a/nixos/modules/services/system/kerberos.nix +++ b/nixos/modules/services/system/kerberos.nix @@ -41,8 +41,8 @@ in flags = "REUSE NAMEINARGS"; protocol = "tcp"; user = "root"; - server = "${pkgs.tcp_wrappers}/sbin/tcpd"; - serverArgs = "${pkgs.heimdalFull}/sbin/kadmind"; + server = "${pkgs.tcp_wrappers}/bin/tcpd"; + serverArgs = "${pkgs.heimdalFull}/bin/kadmind"; }; systemd.services.kdc = { @@ -51,13 +51,13 @@ in preStart = '' mkdir -m 0755 -p ${stateDir} ''; - script = "${heimdalFull}/sbin/kdc"; + script = "${heimdalFull}/bin/kdc"; }; systemd.services.kpasswdd = { description = "Kerberos Password Changing daemon"; wantedBy = [ "multi-user.target" ]; - script = "${heimdalFull}/sbin/kpasswdd"; + script = "${heimdalFull}/bin/kpasswdd"; }; }; -- cgit 1.4.1 From 32e982448d055ad2f2536f687da92a8017a24f8e Mon Sep 17 00:00:00 2001 From: Jörg Thalheim Date: Tue, 3 Jul 2018 13:55:27 +0100 Subject: gpsd: use optionalString --- nixos/modules/services/misc/gpsd.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nixos/modules') diff --git a/nixos/modules/services/misc/gpsd.nix b/nixos/modules/services/misc/gpsd.nix index 80f5501ec1d8..3bfcb636a3c6 100644 --- a/nixos/modules/services/misc/gpsd.nix +++ b/nixos/modules/services/misc/gpsd.nix @@ -107,8 +107,8 @@ in ExecStart = '' ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \ -S "${toString cfg.port}" \ - ${if cfg.readonly then "-b" else ""} \ - ${if cfg.nowait then "-n" else ""} \ + ${optionalString cfg.readonly "-b"} \ + ${optionalString cfg.nowait "-n"} \ "${cfg.device}" ''; }; -- cgit 1.4.1