aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/services/networking
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-03-24 10:15:32 +0100
committerKatharina Fey <kookie@spacekookie.de>2020-03-24 10:15:32 +0100
commit96f063dd321abc80ecaa156226cfb7cf9540315a (patch)
tree7a53ef61484fc7bfff6419b1fd635c67199f27d2 /nixpkgs/nixos/modules/services/networking
parentaf58f08d3d524e7b008b73a8497ea710915ffaf1 (diff)
parentd96bd3394b734487d1c3bfbac0e8f17465e03afe (diff)
Merge commit 'd96bd3394b734487d1c3bfbac0e8f17465e03afe'
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking')
-rw-r--r--nixpkgs/nixos/modules/services/networking/cjdns.nix52
-rw-r--r--nixpkgs/nixos/modules/services/networking/dhcpcd.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.nix328
-rw-r--r--nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.xml66
-rw-r--r--nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix61
-rw-r--r--nixpkgs/nixos/modules/services/networking/firewall.nix10
-rw-r--r--nixpkgs/nixos/modules/services/networking/freeradius.nix18
-rw-r--r--nixpkgs/nixos/modules/services/networking/git-daemon.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/haproxy.nix26
-rw-r--r--nixpkgs/nixos/modules/services/networking/i2pd.nix22
-rw-r--r--nixpkgs/nixos/modules/services/networking/iodine.nix163
-rw-r--r--nixpkgs/nixos/modules/services/networking/iwd.nix7
-rw-r--r--nixpkgs/nixos/modules/services/networking/knot.nix40
-rw-r--r--nixpkgs/nixos/modules/services/networking/kresd.nix152
-rw-r--r--nixpkgs/nixos/modules/services/networking/minidlna.nix17
-rw-r--r--nixpkgs/nixos/modules/services/networking/nat.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix75
-rw-r--r--nixpkgs/nixos/modules/services/networking/nsd.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/ntp/ntpd.nix13
-rw-r--r--nixpkgs/nixos/modules/services/networking/pppd.nix4
-rw-r--r--nixpkgs/nixos/modules/services/networking/shorewall.nix9
-rw-r--r--nixpkgs/nixos/modules/services/networking/shorewall6.nix9
-rw-r--r--nixpkgs/nixos/modules/services/networking/smartdns.nix61
-rw-r--r--nixpkgs/nixos/modules/services/networking/ssh/sshd.nix26
-rw-r--r--nixpkgs/nixos/modules/services/networking/sslh.nix9
-rw-r--r--nixpkgs/nixos/modules/services/networking/stubby.nix3
-rw-r--r--nixpkgs/nixos/modules/services/networking/supybot.nix111
-rw-r--r--nixpkgs/nixos/modules/services/networking/tailscale.nix46
-rw-r--r--nixpkgs/nixos/modules/services/networking/vsftpd.nix2
-rw-r--r--nixpkgs/nixos/modules/services/networking/wireguard.nix6
-rw-r--r--nixpkgs/nixos/modules/services/networking/zerotierone.nix11
31 files changed, 709 insertions, 652 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/cjdns.nix b/nixpkgs/nixos/modules/services/networking/cjdns.nix
index 3fb85b16cbe..5f8ac96b229 100644
--- a/nixpkgs/nixos/modules/services/networking/cjdns.nix
+++ b/nixpkgs/nixos/modules/services/networking/cjdns.nix
@@ -29,17 +29,13 @@ let
};
# Additional /etc/hosts entries for peers with an associated hostname
- cjdnsExtraHosts = import (pkgs.runCommand "cjdns-hosts" {}
- # Generate a builder that produces an output usable as a Nix string value
- ''
- exec >$out
- echo \'\'
- ${concatStringsSep "\n" (mapAttrsToList (k: v:
- optionalString (v.hostname != "")
- "echo $(${pkgs.cjdns}/bin/publictoip6 ${v.publicKey}) ${v.hostname}")
- (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))}
- echo \'\'
- '');
+ cjdnsExtraHosts = pkgs.runCommandNoCC "cjdns-hosts" {} ''
+ exec >$out
+ ${concatStringsSep "\n" (mapAttrsToList (k: v:
+ optionalString (v.hostname != "")
+ "echo $(${pkgs.cjdns}/bin/publictoip6 ${v.publicKey}) ${v.hostname}")
+ (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo))}
+ '';
parseModules = x:
x // { connectTo = mapAttrs (name: value: { inherit (value) password publicKey; }) x.connectTo; };
@@ -144,13 +140,15 @@ in
connectTo = mkOption {
type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
default = { };
- example = {
- "192.168.1.1:27313" = {
- hostname = "homer.hype";
- password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
- publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
- };
- };
+ example = literalExample ''
+ {
+ "192.168.1.1:27313" = {
+ hostname = "homer.hype";
+ password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
+ publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
+ };
+ }
+ '';
description = ''
Credentials for making UDP tunnels.
'';
@@ -189,13 +187,15 @@ in
connectTo = mkOption {
type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
default = { };
- example = {
- "01:02:03:04:05:06" = {
- hostname = "homer.hype";
- password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
- publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
- };
- };
+ example = literalExample ''
+ {
+ "01:02:03:04:05:06" = {
+ hostname = "homer.hype";
+ password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
+ publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
+ };
+ }
+ '';
description = ''
Credentials for connecting look similar to UDP credientials
except they begin with the mac address.
@@ -278,7 +278,7 @@ in
};
};
- networking.extraHosts = mkIf cfg.addExtraHosts cjdnsExtraHosts;
+ networking.hostFiles = mkIf cfg.addExtraHosts [ cjdnsExtraHosts ];
assertions = [
{ assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != null );
diff --git a/nixpkgs/nixos/modules/services/networking/dhcpcd.nix b/nixpkgs/nixos/modules/services/networking/dhcpcd.nix
index 6972c833cc5..c0619211c2f 100644
--- a/nixpkgs/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixpkgs/nixos/modules/services/networking/dhcpcd.nix
@@ -19,7 +19,7 @@ let
map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ipv4.addresses != [ ]) interfaces)
++ mapAttrsToList (i: _: i) config.networking.sits
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
- ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.vswitches))
+ ++ flatten (concatMap (i: attrNames (filterAttrs (_: config: config.type != "internal") i.interfaces)) (attrValues config.networking.vswitches))
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bonds))
++ config.networking.dhcpcd.denyInterfaces;
@@ -190,6 +190,8 @@ in
before = [ "network-online.target" ];
after = [ "systemd-udev-settle.service" ];
+ restartTriggers = [ exitHook ];
+
# Stopping dhcpcd during a reconfiguration is undesirable
# because it brings down the network interfaces configured by
# dhcpcd. So do a "systemctl restart" instead.
diff --git a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.nix
deleted file mode 100644
index 8edcf925dbf..00000000000
--- a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.nix
+++ /dev/null
@@ -1,328 +0,0 @@
-{ config, lib, pkgs, ... }:
-with lib;
-
-let
- cfg = config.services.dnscrypt-proxy;
-
- stateDirectory = "/var/lib/dnscrypt-proxy";
-
- # The minisign public key used to sign the upstream resolver list.
- # This is somewhat more flexible than preloading the key as an
- # embedded string.
- upstreamResolverListPubKey = pkgs.fetchurl {
- url = https://raw.githubusercontent.com/dyne/dnscrypt-proxy/master/minisign.pub;
- sha256 = "18lnp8qr6ghfc2sd46nn1rhcpr324fqlvgsp4zaigw396cd7vnnh";
- };
-
- # Internal flag indicating whether the upstream resolver list is used.
- useUpstreamResolverList = cfg.customResolver == null;
-
- # The final local address.
- localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
-
- # The final resolvers list path.
- resolverList = "${stateDirectory}/dnscrypt-resolvers.csv";
-
- # Build daemon command line
-
- resolverArgs =
- if (cfg.customResolver == null)
- then
- [ "-L ${resolverList}"
- "-R ${cfg.resolverName}"
- ]
- else with cfg.customResolver;
- [ "-N ${name}"
- "-k ${key}"
- "-r ${address}:${toString port}"
- ];
-
- daemonArgs =
- [ "-a ${localAddress}" ]
- ++ resolverArgs
- ++ cfg.extraArgs;
-in
-
-{
- meta = {
- maintainers = with maintainers; [ joachifm ];
- doc = ./dnscrypt-proxy.xml;
- };
-
- options = {
- # Before adding another option, consider whether it could
- # equally well be passed via extraArgs.
-
- services.dnscrypt-proxy = {
- enable = mkOption {
- default = false;
- type = types.bool;
- description = "Whether to enable the DNSCrypt client proxy";
- };
-
- localAddress = mkOption {
- default = "127.0.0.1";
- type = types.str;
- description = ''
- Listen for DNS queries to relay on this address. The only reason to
- change this from its default value is to proxy queries on behalf
- of other machines (typically on the local network).
- '';
- };
-
- localPort = mkOption {
- default = 53;
- type = types.int;
- description = ''
- Listen for DNS queries to relay on this port. The default value
- assumes that the DNSCrypt proxy should relay DNS queries directly.
- When running as a forwarder for another DNS client, set this option
- to a different value; otherwise leave the default.
- '';
- };
-
- resolverName = mkOption {
- default = "random";
- example = "dnscrypt.eu-nl";
- type = types.nullOr types.str;
- description = ''
- The name of the DNSCrypt resolver to use, taken from
- <filename>${resolverList}</filename>. The default is to
- pick a random non-logging resolver that supports DNSSEC.
- '';
- };
-
- customResolver = mkOption {
- default = null;
- description = ''
- Use an unlisted resolver (e.g., a private DNSCrypt provider). For
- advanced users only. If specified, this option takes precedence.
- '';
- type = types.nullOr (types.submodule ({ ... }: { options = {
- address = mkOption {
- type = types.str;
- description = "IP address";
- example = "208.67.220.220";
- };
-
- port = mkOption {
- type = types.int;
- description = "Port";
- default = 443;
- };
-
- name = mkOption {
- type = types.str;
- description = "Fully qualified domain name";
- example = "2.dnscrypt-cert.example.com";
- };
-
- key = mkOption {
- type = types.str;
- description = "Public key";
- example = "B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79";
- };
- }; }));
- };
-
- extraArgs = mkOption {
- default = [];
- type = types.listOf types.str;
- description = ''
- Additional command-line arguments passed verbatim to the daemon.
- See <citerefentry><refentrytitle>dnscrypt-proxy</refentrytitle>
- <manvolnum>8</manvolnum></citerefentry> for details.
- '';
- example = [ "-X libdcplugin_example_cache.so,--min-ttl=60" ];
- };
- };
- };
-
- config = mkIf cfg.enable (mkMerge [{
- assertions = [
- { assertion = (cfg.customResolver != null) || (cfg.resolverName != null);
- message = "please configure upstream DNSCrypt resolver";
- }
- ];
-
- # make man 8 dnscrypt-proxy work
- environment.systemPackages = [ pkgs.dnscrypt-proxy ];
-
- users.users.dnscrypt-proxy = {
- description = "dnscrypt-proxy daemon user";
- isSystemUser = true;
- group = "dnscrypt-proxy";
- };
- users.groups.dnscrypt-proxy = {};
-
- systemd.sockets.dnscrypt-proxy = {
- description = "dnscrypt-proxy listening socket";
- documentation = [ "man:dnscrypt-proxy(8)" ];
-
- wantedBy = [ "sockets.target" ];
-
- socketConfig = {
- ListenStream = localAddress;
- ListenDatagram = localAddress;
- };
- };
-
- systemd.services.dnscrypt-proxy = {
- description = "dnscrypt-proxy daemon";
- documentation = [ "man:dnscrypt-proxy(8)" ];
-
- before = [ "nss-lookup.target" ];
- after = [ "network.target" ];
- requires = [ "dnscrypt-proxy.socket "];
-
- serviceConfig = {
- NonBlocking = "true";
- ExecStart = "${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
- ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-
- User = "dnscrypt-proxy";
-
- PrivateTmp = true;
- PrivateDevices = true;
- ProtectHome = true;
- };
- };
- }
-
- (mkIf config.security.apparmor.enable {
- systemd.services.dnscrypt-proxy.after = [ "apparmor.service" ];
-
- security.apparmor.profiles = singleton (pkgs.writeText "apparmor-dnscrypt-proxy" ''
- ${pkgs.dnscrypt-proxy}/bin/dnscrypt-proxy {
- /dev/null rw,
- /dev/random r,
- /dev/urandom r,
-
- /etc/passwd r,
- /etc/group r,
- ${config.environment.etc."nsswitch.conf".source} r,
-
- ${getLib pkgs.glibc}/lib/*.so mr,
- ${pkgs.tzdata}/share/zoneinfo/** r,
-
- network inet stream,
- network inet6 stream,
- network inet dgram,
- network inet6 dgram,
-
- ${getLib pkgs.dnscrypt-proxy}/lib/dnscrypt-proxy/libdcplugin*.so mr,
-
- ${getLib pkgs.gcc.cc}/lib/libssp.so.* mr,
- ${getLib pkgs.libsodium}/lib/libsodium.so.* mr,
- ${getLib pkgs.systemd}/lib/libsystemd.so.* mr,
- ${getLib pkgs.utillinuxMinimal.out}/lib/libmount.so.* mr,
- ${getLib pkgs.utillinuxMinimal.out}/lib/libblkid.so.* mr,
- ${getLib pkgs.utillinuxMinimal.out}/lib/libuuid.so.* mr,
- ${getLib pkgs.xz}/lib/liblzma.so.* mr,
- ${getLib pkgs.libgcrypt}/lib/libgcrypt.so.* mr,
- ${getLib pkgs.libgpgerror}/lib/libgpg-error.so.* mr,
- ${getLib pkgs.libcap}/lib/libcap.so.* mr,
- ${getLib pkgs.lz4}/lib/liblz4.so.* mr,
- ${getLib pkgs.attr}/lib/libattr.so.* mr, # */
-
- ${resolverList} r,
-
- /run/systemd/notify rw,
- }
- '');
- })
-
- (mkIf useUpstreamResolverList {
- systemd.services.init-dnscrypt-proxy-statedir = {
- description = "Initialize dnscrypt-proxy state directory";
-
- wantedBy = [ "dnscrypt-proxy.service" ];
- before = [ "dnscrypt-proxy.service" ];
-
- script = ''
- mkdir -pv ${stateDirectory}
- chown -c dnscrypt-proxy:dnscrypt-proxy ${stateDirectory}
- cp -uv \
- ${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv \
- ${stateDirectory}
- '';
-
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = true;
- };
- };
-
- systemd.services.update-dnscrypt-resolvers = {
- description = "Update list of DNSCrypt resolvers";
-
- requires = [ "init-dnscrypt-proxy-statedir.service" ];
- after = [ "init-dnscrypt-proxy-statedir.service" ];
-
- path = with pkgs; [ curl diffutils dnscrypt-proxy minisign ];
- script = ''
- cd ${stateDirectory}
- domain=raw.githubusercontent.com
- get="curl -fSs --resolve $domain:443:$(hostip -r 8.8.8.8 $domain | head -1)"
- $get -o dnscrypt-resolvers.csv.tmp \
- https://$domain/dyne/dnscrypt-proxy/master/dnscrypt-resolvers.csv
- $get -o dnscrypt-resolvers.csv.minisig.tmp \
- https://$domain/dyne/dnscrypt-proxy/master/dnscrypt-resolvers.csv.minisig
- mv dnscrypt-resolvers.csv.minisig{.tmp,}
- if ! minisign -q -V -p ${upstreamResolverListPubKey} \
- -m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig ; then
- echo "failed to verify resolver list!" >&2
- exit 1
- fi
- [[ -f dnscrypt-resolvers.csv ]] && mv dnscrypt-resolvers.csv{,.old}
- mv dnscrypt-resolvers.csv{.tmp,}
- if cmp dnscrypt-resolvers.csv{,.old} ; then
- echo "no change"
- else
- echo "resolver list updated"
- fi
- '';
-
- serviceConfig = {
- PrivateTmp = true;
- PrivateDevices = true;
- ProtectHome = true;
- ProtectSystem = "strict";
- ReadWritePaths = "${dirOf stateDirectory} ${stateDirectory}";
- SystemCallFilter = "~@mount";
- };
- };
-
- systemd.timers.update-dnscrypt-resolvers = {
- wantedBy = [ "timers.target" ];
- timerConfig = {
- OnBootSec = "5min";
- OnUnitActiveSec = "6h";
- };
- };
- })
- ]);
-
- imports = [
- (mkRenamedOptionModule [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ])
-
- (mkChangedOptionModule
- [ "services" "dnscrypt-proxy" "tcpOnly" ]
- [ "services" "dnscrypt-proxy" "extraArgs" ]
- (config:
- let val = getAttrFromPath [ "services" "dnscrypt-proxy" "tcpOnly" ] config; in
- optional val "-T"))
-
- (mkChangedOptionModule
- [ "services" "dnscrypt-proxy" "ephemeralKeys" ]
- [ "services" "dnscrypt-proxy" "extraArgs" ]
- (config:
- let val = getAttrFromPath [ "services" "dnscrypt-proxy" "ephemeralKeys" ] config; in
- optional val "-E"))
-
- (mkRemovedOptionModule [ "services" "dnscrypt-proxy" "resolverList" ] ''
- The current resolver listing from upstream is always used
- unless a custom resolver is specified.
- '')
- ];
-}
diff --git a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.xml b/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.xml
deleted file mode 100644
index afc7880392a..00000000000
--- a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<chapter xmlns="http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- version="5.0"
- xml:id="sec-dnscrypt-proxy">
- <title>DNSCrypt client proxy</title>
- <para>
- The DNSCrypt client proxy relays DNS queries to a DNSCrypt enabled upstream
- resolver. The traffic between the client and the upstream resolver is
- encrypted and authenticated, mitigating the risk of MITM attacks, DNS
- poisoning attacks, and third-party snooping (assuming the upstream is
- trustworthy).
- </para>
- <sect1 xml:id="sec-dnscrypt-proxy-configuration">
- <title>Basic configuration</title>
-
- <para>
- To enable the client proxy, set
-<programlisting>
-<xref linkend="opt-services.dnscrypt-proxy.enable"/> = true;
-</programlisting>
- </para>
-
- <para>
- Enabling the client proxy does not alter the system nameserver; to relay
- local queries, prepend <literal>127.0.0.1</literal> to
- <option>networking.nameservers</option>.
- </para>
- </sect1>
- <sect1 xml:id="sec-dnscrypt-proxy-forwarder">
- <title>As a forwarder for another DNS client</title>
-
- <para>
- To run the DNSCrypt proxy client as a forwarder for another DNS client,
- change the default proxy listening port to a non-standard value and point
- the other client to it:
-<programlisting>
-<xref linkend="opt-services.dnscrypt-proxy.localPort"/> = 43;
-</programlisting>
- </para>
-
- <sect2 xml:id="sec-dnscrypt-proxy-forwarder-dsnmasq">
- <title>dnsmasq</title>
- <para>
-<programlisting>
-{
- <xref linkend="opt-services.dnsmasq.enable"/> = true;
- <xref linkend="opt-services.dnsmasq.servers"/> = [ "127.0.0.1#43" ];
-}
-</programlisting>
- </para>
- </sect2>
-
- <sect2 xml:id="sec-dnscrypt-proxy-forwarder-unbound">
- <title>unbound</title>
- <para>
-<programlisting>
-{
- <xref linkend="opt-services.unbound.enable"/> = true;
- <xref linkend="opt-services.unbound.forwardAddresses"/> = [ "127.0.0.1@43" ];
-}
-</programlisting>
- </para>
- </sect2>
- </sect1>
-</chapter>
diff --git a/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix b/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix
new file mode 100644
index 00000000000..e48eb729103
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/dnscrypt-proxy2.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ... }: with lib;
+
+let
+ cfg = config.services.dnscrypt-proxy2;
+in
+
+{
+ options.services.dnscrypt-proxy2 = {
+ enable = mkEnableOption "dnscrypt-proxy2";
+
+ settings = mkOption {
+ description = ''
+ Attrset that is converted and passed as TOML config file.
+ For available params, see: <link xlink:href="https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml"/>
+ '';
+ example = literalExample ''
+ {
+ sources.public-resolvers = {
+ urls = [ "https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md" ];
+ cache_file = "public-resolvers.md";
+ minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
+ refresh_delay = 72;
+ };
+ }
+ '';
+ type = types.attrs;
+ default = {};
+ };
+
+ configFile = mkOption {
+ description = ''
+ Path to TOML config file. See: <link xlink:href="https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml"/>
+ If this option is set, it will override any configuration done in options.services.dnscrypt-proxy2.settings.
+ '';
+ example = "/etc/dnscrypt-proxy/dnscrypt-proxy.toml";
+ type = types.path;
+ default = pkgs.runCommand "dnscrypt-proxy.toml" {
+ json = builtins.toJSON cfg.settings;
+ passAsFile = [ "json" ];
+ } ''
+ ${pkgs.remarshal}/bin/json2toml < $jsonPath > $out
+ '';
+ defaultText = literalExample "TOML file generated from services.dnscrypt-proxy2.settings";
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ networking.nameservers = lib.mkDefault [ "127.0.0.1" ];
+
+ systemd.services.dnscrypt-proxy2 = {
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ AmbientCapabilities = "CAP_NET_BIND_SERVICE";
+ DynamicUser = true;
+ ExecStart = "${pkgs.dnscrypt-proxy2}/bin/dnscrypt-proxy -config ${cfg.configFile}";
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/networking/firewall.nix b/nixpkgs/nixos/modules/services/networking/firewall.nix
index 15aaf741067..cdc3a172ea7 100644
--- a/nixpkgs/nixos/modules/services/networking/firewall.nix
+++ b/nixpkgs/nixos/modules/services/networking/firewall.nix
@@ -546,9 +546,13 @@ in
options nf_conntrack nf_conntrack_helper=1
'';
- assertions = [ { assertion = (cfg.checkReversePath != false) || kernelHasRPFilter;
- message = "This kernel does not support rpfilter"; }
- ];
+ assertions = [
+ # This is approximately "checkReversePath -> kernelHasRPFilter",
+ # but the checkReversePath option can include non-boolean
+ # values.
+ { assertion = cfg.checkReversePath == false || kernelHasRPFilter;
+ message = "This kernel does not support rpfilter"; }
+ ];
systemd.services.firewall = {
description = "Firewall";
diff --git a/nixpkgs/nixos/modules/services/networking/freeradius.nix b/nixpkgs/nixos/modules/services/networking/freeradius.nix
index e192b70c129..f3fdd576b65 100644
--- a/nixpkgs/nixos/modules/services/networking/freeradius.nix
+++ b/nixpkgs/nixos/modules/services/networking/freeradius.nix
@@ -10,14 +10,15 @@ let
{
description = "FreeRadius server";
wantedBy = ["multi-user.target"];
- after = ["network-online.target"];
- wants = ["network-online.target"];
+ after = ["network.target"];
+ wants = ["network.target"];
preStart = ''
${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout
'';
serviceConfig = {
- ExecStart = "${pkgs.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout -xx";
+ ExecStart = "${pkgs.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout" +
+ optionalString cfg.debug " -xx";
ExecReload = [
"${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout"
"${pkgs.coreutils}/bin/kill -HUP $MAINPID"
@@ -41,6 +42,16 @@ let
'';
};
+ debug = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable debug logging for freeradius (-xx
+ option). This should not be left on, since it includes
+ sensitive data such as passwords in the logs.
+ '';
+ };
+
};
in
@@ -66,6 +77,7 @@ in
};
systemd.services.freeradius = freeradiusService cfg;
+ warnings = optional cfg.debug "Freeradius debug logging is enabled. This will log passwords in plaintext to the journal!";
};
diff --git a/nixpkgs/nixos/modules/services/networking/git-daemon.nix b/nixpkgs/nixos/modules/services/networking/git-daemon.nix
index 6f2e149433f..52c895215fb 100644
--- a/nixpkgs/nixos/modules/services/networking/git-daemon.nix
+++ b/nixpkgs/nixos/modules/services/networking/git-daemon.nix
@@ -104,14 +104,14 @@ in
config = mkIf cfg.enable {
- users.users = optionalAttrs (cfg.user != "git") {
+ users.users = optionalAttrs (cfg.user == "git") {
git = {
uid = config.ids.uids.git;
description = "Git daemon user";
};
};
- users.groups = optionalAttrs (cfg.group != "git") {
+ users.groups = optionalAttrs (cfg.group == "git") {
git.gid = config.ids.gids.git;
};
diff --git a/nixpkgs/nixos/modules/services/networking/haproxy.nix b/nixpkgs/nixos/modules/services/networking/haproxy.nix
index aff71e5e97d..4678829986c 100644
--- a/nixpkgs/nixos/modules/services/networking/haproxy.nix
+++ b/nixpkgs/nixos/modules/services/networking/haproxy.nix
@@ -26,6 +26,18 @@ with lib;
'';
};
+ user = mkOption {
+ type = types.str;
+ default = "haproxy";
+ description = "User account under which haproxy runs.";
+ };
+
+ group = mkOption {
+ type = types.str;
+ default = "haproxy";
+ description = "Group account under which haproxy runs.";
+ };
+
config = mkOption {
type = types.nullOr types.lines;
default = null;
@@ -49,7 +61,8 @@ with lib;
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
- DynamicUser = true;
+ User = cfg.user;
+ Group = cfg.group;
Type = "notify";
# when running the config test, don't be quiet so we can see what goes wrong
ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -f ${haproxyCfg}";
@@ -60,5 +73,16 @@ with lib;
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
};
};
+
+ users.users = optionalAttrs (cfg.user == "haproxy") {
+ haproxy = {
+ group = cfg.group;
+ isSystemUser = true;
+ };
+ };
+
+ users.groups = optionalAttrs (cfg.group == "haproxy") {
+ haproxy = {};
+ };
};
}
diff --git a/nixpkgs/nixos/modules/services/networking/i2pd.nix b/nixpkgs/nixos/modules/services/networking/i2pd.nix
index 326d34f6ca9..93a21fd4c97 100644
--- a/nixpkgs/nixos/modules/services/networking/i2pd.nix
+++ b/nixpkgs/nixos/modules/services/networking/i2pd.nix
@@ -158,10 +158,10 @@ let
(sec "addressbook")
(strOpt "defaulturl" cfg.addressbook.defaulturl)
] ++ (optionalEmptyList "subscriptions" cfg.addressbook.subscriptions)
- ++ (flip mapAttrs
- (collect (name: proto: proto ? port && proto ? address && proto ? name) cfg.proto)
+ ++ (flip map
+ (collect (proto: proto ? port && proto ? address) cfg.proto)
(proto: let protoOpts = [
- (sec name)
+ (sec proto.name)
(boolOpt "enabled" proto.enable)
(strOpt "address" proto.address)
(intOpt "port" proto.port)
@@ -181,10 +181,10 @@ let
tunnelConf = let opts = [
notice
- (flip mapAttrs
- (collect (name: tun: tun ? port && tun ? destination) cfg.outTunnels)
+ (flip map
+ (collect (tun: tun ? port && tun ? destination) cfg.outTunnels)
(tun: let outTunOpts = [
- (sec name)
+ (sec tun.name)
"type = client"
(intOpt "port" tun.port)
(strOpt "destination" tun.destination)
@@ -204,10 +204,10 @@ let
++ (if tun ? crypto.tagsToSend then
optionalNullInt "crypto.tagstosend" tun.crypto.tagsToSend else []);
in concatStringsSep "\n" outTunOpts))
- (flip mapAttrs
- (collect (name: tun: tun ? port && tun ? address) cfg.inTunnels)
+ (flip map
+ (collect (tun: tun ? port && tun ? address) cfg.inTunnels)
(tun: let inTunOpts = [
- (sec name)
+ (sec tun.name)
"type = server"
(intOpt "port" tun.port)
(strOpt "host" tun.address)
@@ -606,7 +606,7 @@ in
outTunnels = mkOption {
default = {};
- type = with types; loaOf (submodule (
+ type = with types; attrsOf (submodule (
{ name, ... }: {
options = {
destinationPort = mkOption {
@@ -627,7 +627,7 @@ in
inTunnels = mkOption {
default = {};
- type = with types; loaOf (submodule (
+ type = with types; attrsOf (submodule (
{ name, ... }: {
options = {
inPort = mkOption {
diff --git a/nixpkgs/nixos/modules/services/networking/iodine.nix b/nixpkgs/nixos/modules/services/networking/iodine.nix
index f9ca26c2796..46051d7044b 100644
--- a/nixpkgs/nixos/modules/services/networking/iodine.nix
+++ b/nixpkgs/nixos/modules/services/networking/iodine.nix
@@ -9,6 +9,8 @@ let
iodinedUser = "iodined";
+ /* is this path made unreadable by ProtectHome = true ? */
+ isProtected = x: hasPrefix "/root" x || hasPrefix "/home" x;
in
{
imports = [
@@ -35,45 +37,48 @@ in
corresponding attribute name.
'';
example = literalExample ''
- {
- foo = {
- server = "tunnel.mdomain.com";
- relay = "8.8.8.8";
- extraConfig = "-v";
+ {
+ foo = {
+ server = "tunnel.mdomain.com";
+ relay = "8.8.8.8";
+ extraConfig = "-v";
+ }
}
- }
'';
- type = types.attrsOf (types.submodule (
- {
- options = {
- server = mkOption {
- type = types.str;
- default = "";
- description = "Domain or Subdomain of server running iodined";
- example = "tunnel.mydomain.com";
- };
-
- relay = mkOption {
- type = types.str;
- default = "";
- description = "DNS server to use as a intermediate relay to the iodined server";
- example = "8.8.8.8";
- };
-
- extraConfig = mkOption {
- type = types.str;
- default = "";
- description = "Additional command line parameters";
- example = "-l 192.168.1.10 -p 23";
- };
-
- passwordFile = mkOption {
- type = types.str;
- default = "";
- description = "File that contains password";
- };
- };
- }));
+ type = types.attrsOf (
+ types.submodule (
+ {
+ options = {
+ server = mkOption {
+ type = types.str;
+ default = "";
+ description = "Hostname of server running iodined";
+ example = "tunnel.mydomain.com";
+ };
+
+ relay = mkOption {
+ type = types.str;
+ default = "";
+ description = "DNS server to use as an intermediate relay to the iodined server";
+ example = "8.8.8.8";
+ };
+
+ extraConfig = mkOption {
+ type = types.str;
+ default = "";
+ description = "Additional command line parameters";
+ example = "-l 192.168.1.10 -p 23";
+ };
+
+ passwordFile = mkOption {
+ type = types.str;
+ default = "";
+ description = "Path to a file containing the password.";
+ };
+ };
+ }
+ )
+ );
};
server = {
@@ -121,31 +126,67 @@ in
boot.kernelModules = [ "tun" ];
systemd.services =
- let
- createIodineClientService = name: cfg:
- {
- description = "iodine client - ${name}";
- after = [ "network.target" ];
- wantedBy = [ "multi-user.target" ];
- script = "exec ${pkgs.iodine}/bin/iodine -f -u ${iodinedUser} ${cfg.extraConfig} ${optionalString (cfg.passwordFile != "") "< \"${cfg.passwordFile}\""} ${cfg.relay} ${cfg.server}";
- serviceConfig = {
- RestartSec = "30s";
- Restart = "always";
+ let
+ createIodineClientService = name: cfg:
+ {
+ description = "iodine client - ${name}";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ script = "exec ${pkgs.iodine}/bin/iodine -f -u ${iodinedUser} ${cfg.extraConfig} ${optionalString (cfg.passwordFile != "") "< \"${builtins.toString cfg.passwordFile}\""} ${cfg.relay} ${cfg.server}";
+ serviceConfig = {
+ RestartSec = "30s";
+ Restart = "always";
+
+ # hardening :
+ # Filesystem access
+ ProtectSystem = "strict";
+ ProtectHome = if isProtected cfg.passwordFile then "read-only" else "true" ;
+ PrivateTmp = true;
+ ReadWritePaths = "/dev/net/tun";
+ PrivateDevices = false;
+ ProtectKernelTunables = true;
+ ProtectKernelModules = true;
+ ProtectControlGroups = true;
+ # Caps
+ NoNewPrivileges = true;
+ # Misc.
+ LockPersonality = true;
+ RestrictRealtime = true;
+ PrivateMounts = true;
+ MemoryDenyWriteExecute = true;
+ };
+ };
+ in
+ listToAttrs (
+ mapAttrsToList
+ (name: value: nameValuePair "iodine-${name}" (createIodineClientService name value))
+ cfg.clients
+ ) // {
+ iodined = mkIf (cfg.server.enable) {
+ description = "iodine, ip over dns server daemon";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ script = "exec ${pkgs.iodine}/bin/iodined -f -u ${iodinedUser} ${cfg.server.extraConfig} ${optionalString (cfg.server.passwordFile != "") "< \"${builtins.toString cfg.server.passwordFile}\""} ${cfg.server.ip} ${cfg.server.domain}";
+ serviceConfig = {
+ # Filesystem access
+ ProtectSystem = "strict";
+ ProtectHome = if isProtected cfg.server.passwordFile then "read-only" else "true" ;
+ PrivateTmp = true;
+ ReadWritePaths = "/dev/net/tun";
+ PrivateDevices = false;
+ ProtectKernelTunables = true;
+ ProtectKernelModules = true;
+ ProtectControlGroups = true;
+ # Caps
+ NoNewPrivileges = true;
+ # Misc.
+ LockPersonality = true;
+ RestrictRealtime = true;
+ PrivateMounts = true;
+ MemoryDenyWriteExecute = true;
+ };
+ };
};
- };
- in
- listToAttrs (
- mapAttrsToList
- (name: value: nameValuePair "iodine-${name}" (createIodineClientService name value))
- cfg.clients
- ) // {
- iodined = mkIf (cfg.server.enable) {
- description = "iodine, ip over dns server daemon";
- after = [ "network.target" ];
- wantedBy = [ "multi-user.target" ];
- script = "exec ${pkgs.iodine}/bin/iodined -f -u ${iodinedUser} ${cfg.server.extraConfig} ${optionalString (cfg.server.passwordFile != "") "< \"${cfg.server.passwordFile}\""} ${cfg.server.ip} ${cfg.server.domain}";
- };
- };
users.users.${iodinedUser} = {
uid = config.ids.uids.iodined;
diff --git a/nixpkgs/nixos/modules/services/networking/iwd.nix b/nixpkgs/nixos/modules/services/networking/iwd.nix
index 839fa48d9a4..6be67a8b96f 100644
--- a/nixpkgs/nixos/modules/services/networking/iwd.nix
+++ b/nixpkgs/nixos/modules/services/networking/iwd.nix
@@ -23,12 +23,7 @@ in {
systemd.packages = [ pkgs.iwd ];
systemd.services.iwd.wantedBy = [ "multi-user.target" ];
-
- systemd.tmpfiles.rules = [
- "d /var/lib/iwd 0700 root root -"
- "d /var/lib/ead 0700 root root -"
- ];
};
- meta.maintainers = with lib.maintainers; [ mic92 ];
+ meta.maintainers = with lib.maintainers; [ mic92 dtzWill ];
}
diff --git a/nixpkgs/nixos/modules/services/networking/knot.nix b/nixpkgs/nixos/modules/services/networking/knot.nix
index 47364ecb846..12ff89fe849 100644
--- a/nixpkgs/nixos/modules/services/networking/knot.nix
+++ b/nixpkgs/nixos/modules/services/networking/knot.nix
@@ -5,14 +5,16 @@ with lib;
let
cfg = config.services.knot;
- configFile = pkgs.writeText "knot.conf" cfg.extraConfig;
- socketFile = "/run/knot/knot.sock";
+ configFile = pkgs.writeTextFile {
+ name = "knot.conf";
+ text = (concatMapStringsSep "\n" (file: "include: ${file}") cfg.keyFiles) + "\n" +
+ cfg.extraConfig;
+ checkPhase = lib.optionalString (cfg.keyFiles == []) ''
+ ${cfg.package}/bin/knotc --config=$out conf-check
+ '';
+ };
- knotConfCheck = file: pkgs.runCommand "knot-config-checked"
- { buildInputs = [ cfg.package ]; } ''
- ln -s ${configFile} $out
- knotc --config=${configFile} conf-check
- '';
+ socketFile = "/run/knot/knot.sock";
knot-cli-wrappers = pkgs.stdenv.mkDerivation {
name = "knot-cli-wrappers";
@@ -45,6 +47,19 @@ in {
'';
};
+ keyFiles = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = ''
+ A list of files containing additional configuration
+ to be included using the include directive. This option
+ allows to include configuration like TSIG keys without
+ exposing them to the nix store readable to any process.
+ Note that using this option will also disable configuration
+ checks at build time.
+ '';
+ };
+
extraConfig = mkOption {
type = types.lines;
default = "";
@@ -65,6 +80,13 @@ in {
};
config = mkIf config.services.knot.enable {
+ users.users.knot = {
+ isSystemUser = true;
+ group = "knot";
+ description = "Knot daemon user";
+ };
+
+ users.groups.knot.gid = null;
systemd.services.knot = {
unitConfig.Documentation = "man:knotd(8) man:knot.conf(5) man:knotc(8) https://www.knot-dns.cz/docs/${cfg.package.version}/html/";
description = cfg.package.meta.description;
@@ -74,12 +96,12 @@ in {
serviceConfig = {
Type = "notify";
- ExecStart = "${cfg.package}/bin/knotd --config=${knotConfCheck configFile} --socket=${socketFile} ${concatStringsSep " " cfg.extraArgs}";
+ ExecStart = "${cfg.package}/bin/knotd --config=${configFile} --socket=${socketFile} ${concatStringsSep " " cfg.extraArgs}";
ExecReload = "${knot-cli-wrappers}/bin/knotc reload";
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE CAP_SETPCAP";
AmbientCapabilities = "CAP_NET_BIND_SERVICE CAP_SETPCAP";
NoNewPrivileges = true;
- DynamicUser = "yes";
+ User = "knot";
RuntimeDirectory = "knot";
StateDirectory = "knot";
StateDirectoryMode = "0700";
diff --git a/nixpkgs/nixos/modules/services/networking/kresd.nix b/nixpkgs/nixos/modules/services/networking/kresd.nix
index bb941e93e15..c5a84eebd46 100644
--- a/nixpkgs/nixos/modules/services/networking/kresd.nix
+++ b/nixpkgs/nixos/modules/services/networking/kresd.nix
@@ -3,16 +3,38 @@
with lib;
let
-
cfg = config.services.kresd;
- configFile = pkgs.writeText "kresd.conf" ''
- ${optionalString (cfg.listenDoH != []) "modules.load('http')"}
- ${cfg.extraConfig};
- '';
- package = pkgs.knot-resolver.override {
- extraFeatures = cfg.listenDoH != [];
- };
+ # Convert systemd-style address specification to kresd config line(s).
+ # On Nix level we don't attempt to precisely validate the address specifications.
+ mkListen = kind: addr: let
+ al_v4 = builtins.match "([0-9.]\+):([0-9]\+)" addr;
+ al_v6 = builtins.match "\\[(.\+)]:([0-9]\+)" addr;
+ al_portOnly = builtins.match "()([0-9]\+)" addr;
+ al = findFirst (a: a != null)
+ (throw "services.kresd.*: incorrect address specification '${addr}'")
+ [ al_v4 al_v6 al_portOnly ];
+ port = last al;
+ addrSpec = if al_portOnly == null then "'${head al}'" else "{'::', '127.0.0.1'}";
+ in # freebind is set for compatibility with earlier kresd services;
+ # it could be configurable, for example.
+ ''
+ net.listen(${addrSpec}, ${port}, { kind = '${kind}', freebind = true })
+ '';
+
+ configFile = pkgs.writeText "kresd.conf" (
+ optionalString (cfg.listenDoH != []) ''
+ modules.load('http')
+ ''
+ + concatMapStrings (mkListen "dns") cfg.listenPlain
+ + concatMapStrings (mkListen "tls") cfg.listenTLS
+ + concatMapStrings (mkListen "doh") cfg.listenDoH
+ + cfg.extraConfig
+ );
+
+ package = if cfg.listenDoH == []
+ then pkgs.knot-resolver # never force `extraFeatures = false`
+ else pkgs.knot-resolver.override { extraFeatures = true; };
in {
meta.maintainers = [ maintainers.vcunat /* upstream developer */ ];
@@ -25,6 +47,7 @@ in {
value
)
)
+ (mkRemovedOptionModule [ "services" "kresd" "cacheDir" ] "Please use (bind-)mounting instead.")
];
###### interface
@@ -35,8 +58,8 @@ in {
description = ''
Whether to enable knot-resolver domain name server.
DNSSEC validation is turned on by default.
- You can run <literal>sudo nc -U /run/kresd/control</literal>
- and give commands interactively to kresd.
+ You can run <literal>sudo nc -U /run/knot-resolver/control/1</literal>
+ and give commands interactively to kresd@1.service.
'';
};
extraConfig = mkOption {
@@ -46,16 +69,10 @@ in {
Extra lines to be added verbatim to the generated configuration file.
'';
};
- cacheDir = mkOption {
- type = types.path;
- default = "/var/cache/kresd";
- description = ''
- Directory for caches. They are intended to survive reboots.
- '';
- };
listenPlain = mkOption {
type = with types; listOf str;
default = [ "[::1]:53" "127.0.0.1:53" ];
+ example = [ "53" ];
description = ''
What addresses and ports the server should listen on.
For detailed syntax see ListenStream in man systemd.socket.
@@ -75,91 +92,54 @@ in {
default = [];
example = [ "198.51.100.1:443" "[2001:db8::1]:443" "443" ];
description = ''
- Addresses and ports on which kresd should provide DNS over HTTPS (see RFC 7858).
+ Addresses and ports on which kresd should provide DNS over HTTPS (see RFC 8484).
For detailed syntax see ListenStream in man systemd.socket.
'';
};
+ instances = mkOption {
+ type = types.ints.unsigned;
+ default = 1;
+ description = ''
+ The number of instances to start. They will be called kresd@{1,2,...}.service.
+ Knot Resolver uses no threads, so this is the way to scale.
+ You can dynamically start/stop them at will, so this is just system default.
+ '';
+ };
# TODO: perhaps options for more common stuff like cache size or forwarding
};
###### implementation
config = mkIf cfg.enable {
- environment.etc."kresd.conf".source = configFile; # not required
+ environment.etc."knot-resolver/kresd.conf".source = configFile; # not required
- users.users.kresd =
- { uid = config.ids.uids.kresd;
- group = "kresd";
+ users.users.knot-resolver =
+ { isSystemUser = true;
+ group = "knot-resolver";
description = "Knot-resolver daemon user";
};
- users.groups.kresd.gid = config.ids.gids.kresd;
-
- systemd.sockets.kresd = rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- listenStreams = cfg.listenPlain;
- socketConfig = {
- ListenDatagram = listenStreams;
- FreeBind = true;
- FileDescriptorName = "dns";
- };
- };
+ users.groups.knot-resolver.gid = null;
- systemd.sockets.kresd-tls = mkIf (cfg.listenTLS != []) rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- partOf = [ "kresd.socket" ];
- listenStreams = cfg.listenTLS;
- socketConfig = {
- FileDescriptorName = "tls";
- FreeBind = true;
- Service = "kresd.service";
- };
- };
+ systemd.packages = [ package ]; # the units are patched inside the package a bit
- systemd.sockets.kresd-doh = mkIf (cfg.listenDoH != []) rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- partOf = [ "kresd.socket" ];
- listenStreams = cfg.listenDoH;
- socketConfig = {
- FileDescriptorName = "doh";
- FreeBind = true;
- Service = "kresd.service";
- };
+ systemd.targets.kresd = { # configure units started by default
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "kres-cache-gc.service" ]
+ ++ map (i: "kresd@${toString i}.service") (range 1 cfg.instances);
};
-
- systemd.sockets.kresd-control = rec {
- wantedBy = [ "sockets.target" ];
- before = wantedBy;
- partOf = [ "kresd.socket" ];
- listenStreams = [ "/run/kresd/control" ];
- socketConfig = {
- FileDescriptorName = "control";
- Service = "kresd.service";
- SocketMode = "0660"; # only root user/group may connect and control kresd
- };
+ systemd.services."kresd@".serviceConfig = {
+ ExecStart = "${package}/bin/kresd --noninteractive "
+ + "-c ${package}/lib/knot-resolver/distro-preconfig.lua -c ${configFile}";
+ # Ensure correct ownership in case UID or GID changes.
+ CacheDirectory = "knot-resolver";
+ CacheDirectoryMode = "0750";
};
- systemd.tmpfiles.rules = [ "d '${cfg.cacheDir}' 0770 kresd kresd - -" ];
+ environment.etc."tmpfiles.d/knot-resolver.conf".source =
+ "${package}/lib/tmpfiles.d/knot-resolver.conf";
- systemd.services.kresd = {
- description = "Knot-resolver daemon";
-
- serviceConfig = {
- User = "kresd";
- Type = "notify";
- WorkingDirectory = cfg.cacheDir;
- Restart = "on-failure";
- Sockets = [ "kresd.socket" "kresd-control.socket" ]
- ++ optional (cfg.listenTLS != []) "kresd-tls.socket";
- };
-
- # Trust anchor goes from dns-root-data by default.
- script = ''
- exec '${package}/bin/kresd' --config '${configFile}' --forks=1
- '';
-
- requires = [ "kresd.socket" ];
- };
+ # Try cleaning up the previously default location of cache file.
+ # Note that /var/cache/* should always be safe to remove.
+ # TODO: remove later, probably between 20.09 and 21.03
+ systemd.tmpfiles.rules = [ "R /var/cache/kresd" ];
};
}
diff --git a/nixpkgs/nixos/modules/services/networking/minidlna.nix b/nixpkgs/nixos/modules/services/networking/minidlna.nix
index 3ddea3c9757..c580ba47dad 100644
--- a/nixpkgs/nixos/modules/services/networking/minidlna.nix
+++ b/nixpkgs/nixos/modules/services/networking/minidlna.nix
@@ -95,6 +95,22 @@ in
'';
};
+ services.minidlna.announceInterval = mkOption {
+ type = types.int;
+ default = 895;
+ description =
+ ''
+ The interval between announces (in seconds).
+
+ By default miniDLNA will announce its presence on the network
+ approximately every 15 minutes.
+
+ Many people prefer shorter announce intervals (e.g. 60 seconds)
+ on their home networks, especially when DLNA clients are
+ started on demand.
+ '';
+ };
+
services.minidlna.config = mkOption {
type = types.lines;
description =
@@ -144,6 +160,7 @@ in
${concatMapStrings (dir: ''
media_dir=${dir}
'') cfg.mediaDirs}
+ notify_interval=${toString cfg.announceInterval}
${cfg.extraConfig}
'';
diff --git a/nixpkgs/nixos/modules/services/networking/nat.nix b/nixpkgs/nixos/modules/services/networking/nat.nix
index 9c658af30f7..21ae9eb8b6d 100644
--- a/nixpkgs/nixos/modules/services/networking/nat.nix
+++ b/nixpkgs/nixos/modules/services/networking/nat.nix
@@ -65,7 +65,7 @@ let
let
m = builtins.match "([0-9.]+):([0-9-]+)" fwd.destination;
destinationIP = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else elemAt m 0;
- destinationPorts = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else elemAt m 1;
+ destinationPorts = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else builtins.replaceStrings ["-"] [":"] (elemAt m 1);
in ''
# Allow connections to ${loopbackip}:${toString fwd.sourcePort} from the host itself
iptables -w -t nat -A nixos-nat-out \
diff --git a/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix b/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix
new file mode 100644
index 00000000000..3f2ce5bca4d
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix
@@ -0,0 +1,75 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ opts = { name, config, ... }: {
+ options = {
+ enable = mkOption {
+ default = true;
+ type = types.bool;
+ example = true;
+ description = "Whether to enable proxy for this bucket";
+ };
+ bucketName = mkOption {
+ type = types.str;
+ default = name;
+ example = "my-bucket-name";
+ description = "Name of Google storage bucket";
+ };
+ address = mkOption {
+ type = types.str;
+ example = "localhost:3000";
+ description = "The address of the proxy.";
+ };
+ };
+ };
+ enabledProxies = lib.filterAttrs (n: v: v.enable) config.services.nix-store-gcs-proxy;
+ mapProxies = function: lib.mkMerge (lib.mapAttrsToList function enabledProxies);
+in
+{
+ options.services.nix-store-gcs-proxy = mkOption {
+ type = types.attrsOf (types.submodule opts);
+ default = {};
+ description = ''
+ An attribute set describing an HTTP to GCS proxy that allows us to use GCS
+ bucket via HTTP protocol.
+ '';
+ };
+
+ config.systemd.services = mapProxies (name: cfg: {
+ "nix-store-gcs-proxy-${name}" = {
+ description = "A HTTP nix store that proxies requests to Google Storage";
+ wantedBy = ["multi-user.target"];
+
+ serviceConfig = {
+ RestartSec = 5;
+ StartLimitInterval = 10;
+ ExecStart = ''
+ ${pkgs.nix-store-gcs-proxy}/bin/nix-store-gcs-proxy \
+ --bucket-name ${cfg.bucketName} \
+ --addr ${cfg.address}
+ '';
+
+ DynamicUser = true;
+
+ ProtectSystem = "strict";
+ ProtectHome = true;
+ PrivateTmp = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateUsers = true;
+
+ ProtectKernelTunables = true;
+ ProtectKernelModules = true;
+ ProtectControlGroups = true;
+
+ NoNewPrivileges = true;
+ LockPersonality = true;
+ RestrictRealtime = true;
+ };
+ };
+ });
+
+ meta.maintainers = [ maintainers.mrkkrp ];
+}
diff --git a/nixpkgs/nixos/modules/services/networking/nsd.nix b/nixpkgs/nixos/modules/services/networking/nsd.nix
index 344396638a6..429580e5c6c 100644
--- a/nixpkgs/nixos/modules/services/networking/nsd.nix
+++ b/nixpkgs/nixos/modules/services/networking/nsd.nix
@@ -244,7 +244,7 @@ let
};
data = mkOption {
- type = types.str;
+ type = types.lines;
default = "";
example = "";
description = ''
@@ -484,7 +484,7 @@ in
};
extraConfig = mkOption {
- type = types.str;
+ type = types.lines;
default = "";
description = ''
Extra nsd config.
diff --git a/nixpkgs/nixos/modules/services/networking/ntp/ntpd.nix b/nixpkgs/nixos/modules/services/networking/ntp/ntpd.nix
index b5403cb747d..54ff054d84c 100644
--- a/nixpkgs/nixos/modules/services/networking/ntp/ntpd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ntp/ntpd.nix
@@ -23,6 +23,8 @@ let
restrict -6 ::1
${toString (map (server: "server " + server + " iburst\n") cfg.servers)}
+
+ ${cfg.extraConfig}
'';
ntpFlags = "-c ${configFile} -u ${ntpUser}:nogroup ${toString cfg.extraFlags}";
@@ -81,6 +83,17 @@ in
'';
};
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ example = ''
+ fudge 127.127.1.0 stratum 10
+ '';
+ description = ''
+ Additional text appended to <filename>ntp.conf</filename>.
+ '';
+ };
+
extraFlags = mkOption {
type = types.listOf types.str;
description = "Extra flags passed to the ntpd command.";
diff --git a/nixpkgs/nixos/modules/services/networking/pppd.nix b/nixpkgs/nixos/modules/services/networking/pppd.nix
index b31bfa64235..c1cbdb46176 100644
--- a/nixpkgs/nixos/modules/services/networking/pppd.nix
+++ b/nixpkgs/nixos/modules/services/networking/pppd.nix
@@ -130,7 +130,7 @@ in
systemdConfigs = listToAttrs (map mkSystemd enabledConfigs);
in mkIf cfg.enable {
- environment.etc = mkMerge etcFiles;
- systemd.services = mkMerge systemdConfigs;
+ environment.etc = etcFiles;
+ systemd.services = systemdConfigs;
};
}
diff --git a/nixpkgs/nixos/modules/services/networking/shorewall.nix b/nixpkgs/nixos/modules/services/networking/shorewall.nix
index 0f94d414fcf..16383be2530 100644
--- a/nixpkgs/nixos/modules/services/networking/shorewall.nix
+++ b/nixpkgs/nixos/modules/services/networking/shorewall.nix
@@ -26,7 +26,7 @@ in {
description = "The shorewall package to use.";
};
configs = lib.mkOption {
- type = types.attrsOf types.str;
+ type = types.attrsOf types.lines;
default = {};
description = ''
This option defines the Shorewall configs.
@@ -63,12 +63,7 @@ in {
'';
};
environment = {
- etc = lib.mapAttrsToList
- (name: file:
- { source = file;
- target = "shorewall/${name}";
- })
- cfg.configs;
+ etc = lib.mapAttrs' (name: conf: lib.nameValuePair "shorewall/${name}" {source=conf;}) cfg.configs;
systemPackages = [ cfg.package ];
};
};
diff --git a/nixpkgs/nixos/modules/services/networking/shorewall6.nix b/nixpkgs/nixos/modules/services/networking/shorewall6.nix
index 9c22a037c0b..e081aedc6c3 100644
--- a/nixpkgs/nixos/modules/services/networking/shorewall6.nix
+++ b/nixpkgs/nixos/modules/services/networking/shorewall6.nix
@@ -26,7 +26,7 @@ in {
description = "The shorewall package to use.";
};
configs = lib.mkOption {
- type = types.attrsOf types.str;
+ type = types.attrsOf types.lines;
default = {};
description = ''
This option defines the Shorewall configs.
@@ -63,12 +63,7 @@ in {
'';
};
environment = {
- etc = lib.mapAttrsToList
- (name: file:
- { source = file;
- target = "shorewall6/${name}";
- })
- cfg.configs;
+ etc = lib.mapAttrs' (name: conf: lib.nameValuePair "shorewall6/${name}" {source=conf;}) cfg.configs;
systemPackages = [ cfg.package ];
};
};
diff --git a/nixpkgs/nixos/modules/services/networking/smartdns.nix b/nixpkgs/nixos/modules/services/networking/smartdns.nix
new file mode 100644
index 00000000000..f1888af7041
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/smartdns.nix
@@ -0,0 +1,61 @@
+{ lib, pkgs, config, ... }:
+
+with lib;
+
+let
+ inherit (lib.types) attrsOf coercedTo listOf oneOf str int bool;
+ cfg = config.services.smartdns;
+
+ confFile = pkgs.writeText "smartdns.conf" (with generators;
+ toKeyValue {
+ mkKeyValue = mkKeyValueDefault {
+ mkValueString = v:
+ if isBool v then
+ if v then "yes" else "no"
+ else
+ mkValueStringDefault { } v;
+ } " ";
+ listsAsDuplicateKeys =
+ true; # Allowing duplications because we need to deal with multiple entries with the same key.
+ } cfg.settings);
+in {
+ options.services.smartdns = {
+ enable = mkEnableOption "SmartDNS DNS server";
+
+ bindPort = mkOption {
+ type = types.port;
+ default = 53;
+ description = "DNS listening port number.";
+ };
+
+ settings = mkOption {
+ type =
+ let atom = oneOf [ str int bool ];
+ in attrsOf (coercedTo atom toList (listOf atom));
+ example = literalExample ''
+ {
+ bind = ":5353 -no-rule -group example";
+ cache-size = 4096;
+ server-tls = [ "8.8.8.8:853" "1.1.1.1:853" ];
+ server-https = "https://cloudflare-dns.com/dns-query -exclude-default-group";
+ prefetch-domain = true;
+ speed-check-mode = "ping,tcp:80";
+ };
+ '';
+ description = ''
+ A set that will be generated into configuration file, see the <link xlink:href="https://github.com/pymumu/smartdns/blob/master/ReadMe_en.md#configuration-parameter">SmartDNS README</link> for details of configuration parameters.
+ You could override the options here like <option>services.smartdns.bindPort</option> by writing <literal>settings.bind = ":5353 -no-rule -group example";</literal>.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.smartdns.settings.bind = mkDefault ":${toString cfg.bindPort}";
+
+ systemd.packages = [ pkgs.smartdns ];
+ systemd.services.smartdns.wantedBy = [ "multi-user.target" ];
+ environment.etc."smartdns/smartdns.conf".source = confFile;
+ environment.etc."default/smartdns".source =
+ "${pkgs.smartdns}/etc/default/smartdns";
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
index b0e2e303cbc..464e9ed38c4 100644
--- a/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix
@@ -17,7 +17,7 @@ let
${cfg.extraConfig}
EOL
- ssh-keygen -f mock-hostkey -N ""
+ ssh-keygen -q -f mock-hostkey -N ""
sshd -t -f $out -h mock-hostkey
'';
@@ -238,6 +238,26 @@ in
description = "Files from which authorized keys are read.";
};
+ authorizedKeysCommand = mkOption {
+ type = types.str;
+ default = "none";
+ description = ''
+ Specifies a program to be used to look up the user's public
+ keys. The program must be owned by root, not writable by group
+ or others and specified by an absolute path.
+ '';
+ };
+
+ authorizedKeysCommandUser = mkOption {
+ type = types.str;
+ default = "nobody";
+ description = ''
+ Specifies the user under whose account the AuthorizedKeysCommand
+ is run. It is recommended to use a dedicated user that has no
+ other role on the host than running authorized keys commands.
+ '';
+ };
+
kexAlgorithms = mkOption {
type = types.listOf types.str;
default = [
@@ -485,6 +505,10 @@ in
PrintMotd no # handled by pam_motd
AuthorizedKeysFile ${toString cfg.authorizedKeysFiles}
+ ${optionalString (cfg.authorizedKeysCommand != "none") ''
+ AuthorizedKeysCommand ${cfg.authorizedKeysCommand}
+ AuthorizedKeysCommandUser ${cfg.authorizedKeysCommandUser}
+ ''}
${flip concatMapStrings cfg.hostKeys (k: ''
HostKey ${k.path}
diff --git a/nixpkgs/nixos/modules/services/networking/sslh.nix b/nixpkgs/nixos/modules/services/networking/sslh.nix
index 0222e8ce8b5..c4fa370a5fe 100644
--- a/nixpkgs/nixos/modules/services/networking/sslh.nix
+++ b/nixpkgs/nixos/modules/services/networking/sslh.nix
@@ -77,19 +77,14 @@ in
config = mkMerge [
(mkIf cfg.enable {
- users.users.${user} = {
- description = "sslh daemon user";
- isSystemUser = true;
- };
-
systemd.services.sslh = {
description = "Applicative Protocol Multiplexer (e.g. share SSH and HTTPS on the same port)";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
- User = user;
- Group = "nogroup";
+ DynamicUser = true;
+ User = "sslh";
PermissionsStartOnly = true;
Restart = "always";
RestartSec = "1s";
diff --git a/nixpkgs/nixos/modules/services/networking/stubby.nix b/nixpkgs/nixos/modules/services/networking/stubby.nix
index b38bcd4cec0..c5e0f929a12 100644
--- a/nixpkgs/nixos/modules/services/networking/stubby.nix
+++ b/nixpkgs/nixos/modules/services/networking/stubby.nix
@@ -72,6 +72,7 @@ let
resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
${fallbacks}
+ appdata_dir: "/var/cache/stubby"
tls_authentication: ${cfg.authenticationMode}
tls_query_padding_blocksize: ${toString cfg.queryPaddingBlocksize}
edns_client_subnet_private: ${if cfg.subnetPrivate then "1" else "0"}
@@ -204,10 +205,12 @@ in
wantedBy = [ "multi-user.target" ];
serviceConfig = {
+ Type = "notify";
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = "CAP_NET_BIND_SERVICE";
ExecStart = "${pkgs.stubby}/bin/stubby -C ${confFile} ${optionalString cfg.debugLogging "-l"}";
DynamicUser = true;
+ CacheDirectory = "stubby";
};
};
};
diff --git a/nixpkgs/nixos/modules/services/networking/supybot.nix b/nixpkgs/nixos/modules/services/networking/supybot.nix
index 92c84bd0e1e..dc9fb31ffd0 100644
--- a/nixpkgs/nixos/modules/services/networking/supybot.nix
+++ b/nixpkgs/nixos/modules/services/networking/supybot.nix
@@ -3,32 +3,35 @@
with lib;
let
-
cfg = config.services.supybot;
-
+ isStateDirHome = hasPrefix "/home/" cfg.stateDir;
+ isStateDirVar = cfg.stateDir == "/var/lib/supybot";
+ pyEnv = pkgs.python3.withPackages (p: [ p.limnoria ] ++ (cfg.extraPackages p));
in
-
{
-
options = {
services.supybot = {
enable = mkOption {
+ type = types.bool;
default = false;
- description = "Enable Supybot, an IRC bot";
+ description = "Enable Supybot, an IRC bot (also known as Limnoria).";
};
stateDir = mkOption {
- # Setting this to /var/lib/supybot caused useradd to fail
- default = "/home/supybot";
+ type = types.path;
+ default = if versionAtLeast config.system.stateVersion "20.09"
+ then "/var/lib/supybot"
+ else "/home/supybot";
+ defaultText = "/var/lib/supybot";
description = "The root directory, logs and plugins are stored here";
};
configFile = mkOption {
type = types.path;
description = ''
- Path to a supybot config file. This can be generated by
+ Path to initial supybot config file. This can be generated by
running supybot-wizard.
Note: all paths should include the full path to the stateDir
@@ -36,21 +39,54 @@ in
'';
};
+ plugins = mkOption {
+ type = types.attrsOf types.path;
+ default = {};
+ description = ''
+ Attribute set of additional plugins that will be symlinked to the
+ <filename>plugin</filename> subdirectory.
+
+ Please note that you still need to add the plugins to the config
+ file (or with <literal>!load</literal>) using their attribute name.
+ '';
+ example = literalExample ''
+ let
+ plugins = pkgs.fetchzip {
+ url = "https://github.com/ProgVal/Supybot-plugins/archive/57c2450c.zip";
+ sha256 = "077snf84ibnva3sbpzdfpfma6hcdw7dflwnhg6pw7mgnf0nd84qd";
+ };
+ in
+ {
+ Wikipedia = "''${plugins}/Wikipedia";
+ Decide = ./supy-decide;
+ }
+ '';
+ };
+
+ extraPackages = mkOption {
+ default = p: [];
+ description = ''
+ Extra Python packages available to supybot plugins. The
+ value must be a function which receives the attrset defined
+ in <varname>python3Packages</varname> as the sole argument.
+ '';
+ example = literalExample ''p: [ p.lxml p.requests ]'';
+ };
+
};
};
-
config = mkIf cfg.enable {
- environment.systemPackages = [ pkgs.pythonPackages.limnoria ];
+ environment.systemPackages = [ pkgs.python3Packages.limnoria ];
- users.users.supybotrs = {
+ users.users.supybot = {
uid = config.ids.uids.supybot;
group = "supybot";
description = "Supybot IRC bot user";
home = cfg.stateDir;
- createHome = true;
+ isSystemUser = true;
};
users.groups.supybot = {
@@ -59,19 +95,16 @@ in
systemd.services.supybot = {
description = "Supybot, an IRC bot";
+ documentation = [ "https://limnoria.readthedocs.io/" ];
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
- path = [ pkgs.pythonPackages.limnoria ];
preStart = ''
- cd ${cfg.stateDir}
- mkdir -p backup conf data plugins logs/plugins tmp web
- ln -sf ${cfg.configFile} supybot.cfg
# This needs to be created afresh every time
- rm -f supybot.cfg.bak
+ rm -f '${cfg.stateDir}/supybot.cfg.bak'
'';
serviceConfig = {
- ExecStart = "${pkgs.pythonPackages.limnoria}/bin/supybot ${cfg.stateDir}/supybot.cfg";
+ ExecStart = "${pyEnv}/bin/supybot ${cfg.stateDir}/supybot.cfg";
PIDFile = "/run/supybot.pid";
User = "supybot";
Group = "supybot";
@@ -79,8 +112,50 @@ in
Restart = "on-abort";
StartLimitInterval = "5m";
StartLimitBurst = "1";
+
+ NoNewPrivileges = true;
+ PrivateDevices = true;
+ PrivateMounts = true;
+ PrivateTmp = true;
+ ProtectControlGroups = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
+ RestrictSUIDSGID = true;
+ SystemCallArchitectures = "native";
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ RemoveIPC = true;
+ ProtectHostname = true;
+ CapabilityBoundingSet = "";
+ ProtectSystem = "full";
+ }
+ // optionalAttrs isStateDirVar {
+ StateDirectory = "supybot";
+ ProtectSystem = "strict";
+ }
+ // optionalAttrs (!isStateDirHome) {
+ ProtectHome = true;
};
};
+ systemd.tmpfiles.rules = [
+ "d '${cfg.stateDir}' 0700 supybot supybot - -"
+ "d '${cfg.stateDir}/backup' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/conf' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/data' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/plugins' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/logs' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/logs/plugins' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/tmp' 0750 supybot supybot - -"
+ "d '${cfg.stateDir}/web' 0750 supybot supybot - -"
+ "L '${cfg.stateDir}/supybot.cfg' - - - - ${cfg.configFile}"
+ ]
+ ++ (flip mapAttrsToList cfg.plugins (name: dest:
+ "L+ '${cfg.stateDir}/plugins/${name}' - - - - ${dest}"
+ ));
+
};
}
diff --git a/nixpkgs/nixos/modules/services/networking/tailscale.nix b/nixpkgs/nixos/modules/services/networking/tailscale.nix
new file mode 100644
index 00000000000..513c42b4011
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/tailscale.nix
@@ -0,0 +1,46 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.services.tailscale;
+in {
+ meta.maintainers = with maintainers; [ danderson mbaillie ];
+
+ options.services.tailscale = {
+ enable = mkEnableOption "Tailscale client daemon";
+
+ port = mkOption {
+ type = types.port;
+ default = 41641;
+ description = "The port to listen on for tunnel traffic (0=autoselect).";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.tailscale = {
+ description = "Tailscale client daemon";
+
+ after = [ "network-pre.target" ];
+ wants = [ "network-pre.target" ];
+ wantedBy = [ "multi-user.target" ];
+
+ unitConfig = {
+ StartLimitIntervalSec = 0;
+ StartLimitBurst = 0;
+ };
+
+ serviceConfig = {
+ ExecStart =
+ "${pkgs.tailscale}/bin/tailscaled --port ${toString cfg.port}";
+
+ RuntimeDirectory = "tailscale";
+ RuntimeDirectoryMode = 755;
+
+ StateDirectory = "tailscale";
+ StateDirectoryMode = 700;
+
+ Restart = "on-failure";
+ };
+ };
+ };
+}
diff --git a/nixpkgs/nixos/modules/services/networking/vsftpd.nix b/nixpkgs/nixos/modules/services/networking/vsftpd.nix
index 47990dbb377..b3e20184423 100644
--- a/nixpkgs/nixos/modules/services/networking/vsftpd.nix
+++ b/nixpkgs/nixos/modules/services/networking/vsftpd.nix
@@ -133,8 +133,8 @@ let
${optionalString cfg.enableVirtualUsers ''
guest_enable=YES
guest_username=vsftpd
- pam_service_name=vsftpd
''}
+ pam_service_name=vsftpd
${cfg.extraConfig}
'';
diff --git a/nixpkgs/nixos/modules/services/networking/wireguard.nix b/nixpkgs/nixos/modules/services/networking/wireguard.nix
index 980961225c9..e8f83f6dd8b 100644
--- a/nixpkgs/nixos/modules/services/networking/wireguard.nix
+++ b/nixpkgs/nixos/modules/services/networking/wireguard.nix
@@ -151,7 +151,7 @@ let
publicKey = mkOption {
example = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=";
type = types.str;
- description = "The base64 public key the peer.";
+ description = "The base64 public key of the peer.";
};
presharedKey = mkOption {
@@ -428,14 +428,14 @@ in
++ (attrValues (
mapAttrs (name: value: {
assertion = value.generatePrivateKeyFile -> (value.privateKey == null);
- message = "networking.wireguard.interfaces.${name}.generatePrivateKey must not be set if networking.wireguard.interfaces.${name}.privateKey is set.";
+ message = "networking.wireguard.interfaces.${name}.generatePrivateKeyFile must not be set if networking.wireguard.interfaces.${name}.privateKey is set.";
}) cfg.interfaces))
++ map ({ interfaceName, peer, ... }: {
assertion = (peer.presharedKey == null) || (peer.presharedKeyFile == null);
message = "networking.wireguard.interfaces.${interfaceName} peer ยซ${peer.publicKey}ยป has both presharedKey and presharedKeyFile set, but only one can be used.";
}) all_peers;
- boot.extraModulePackages = [ kernel.wireguard ];
+ boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
environment.systemPackages = [ pkgs.wireguard-tools ];
systemd.services =
diff --git a/nixpkgs/nixos/modules/services/networking/zerotierone.nix b/nixpkgs/nixos/modules/services/networking/zerotierone.nix
index 069e15a909b..cf39ed065a7 100644
--- a/nixpkgs/nixos/modules/services/networking/zerotierone.nix
+++ b/nixpkgs/nixos/modules/services/networking/zerotierone.nix
@@ -67,5 +67,16 @@ in
networking.firewall.allowedUDPPorts = [ cfg.port ];
environment.systemPackages = [ cfg.package ];
+
+ # Prevent systemd from potentially changing the MAC address
+ systemd.network.links."50-zerotier" = {
+ matchConfig = {
+ OriginalName = "zt*";
+ };
+ linkConfig = {
+ AutoNegotiation = false;
+ MACAddressPolicy = "none";
+ };
+ };
};
}