diff options
Diffstat (limited to 'nixos/modules/services/networking')
-rw-r--r-- | nixos/modules/services/networking/cjdns.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/networking/dnscrypt-proxy.nix | 48 | ||||
-rw-r--r-- | nixos/modules/services/networking/dnscrypt-proxy.xml | 76 | ||||
-rw-r--r-- | nixos/modules/services/networking/ferm.nix | 63 | ||||
-rw-r--r-- | nixos/modules/services/networking/mjpg-streamer.nix | 8 | ||||
-rw-r--r-- | nixos/modules/services/networking/quagga.nix | 187 | ||||
-rw-r--r-- | nixos/modules/services/networking/teamspeak3.nix | 75 | ||||
-rw-r--r-- | nixos/modules/services/networking/unbound.nix | 10 | ||||
-rw-r--r-- | nixos/modules/services/networking/wpa_supplicant.nix | 99 | ||||
-rw-r--r-- | nixos/modules/services/networking/zerotierone.nix | 16 |
10 files changed, 452 insertions, 132 deletions
diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix index f4063a3406f1..0495b32c6fa8 100644 --- a/nixos/modules/services/networking/cjdns.nix +++ b/nixos/modules/services/networking/cjdns.nix @@ -253,7 +253,7 @@ in networking.extraHosts = "${cjdnsHosts}"; assertions = [ - { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile == "" ); + { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile != "" ); message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined."; } { assertion = config.networking.enableIPv6; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix index cf36ccf05725..2714e8d75993 100644 --- a/nixos/modules/services/networking/dnscrypt-proxy.nix +++ b/nixos/modules/services/networking/dnscrypt-proxy.nix @@ -28,31 +28,15 @@ let in { + meta = { + maintainers = with maintainers; [ joachifm ]; + doc = ./dnscrypt-proxy.xml; + }; + options = { services.dnscrypt-proxy = { - enable = mkEnableOption "dnscrypt-proxy" // { description = '' - Whether to enable the DNSCrypt client proxy. The 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 and third-party - snooping (assuming the upstream is trustworthy). - - Enabling this option does not alter the system nameserver; to relay - local queries, prepend <literal>127.0.0.1</literal> to - <option>networking.nameservers</option>. - - The recommended configuration is to run DNSCrypt proxy as a forwarder - for a caching DNS client, as in - <programlisting> - { - services.dnscrypt-proxy.enable = true; - services.dnscrypt-proxy.localPort = 43; - services.dnsmasq.enable = true; - services.dnsmasq.servers = [ "127.0.0.1#43" ]; - services.dnsmasq.resolveLocalQueries = true; # this is the default - } - </programlisting> - ''; }; + enable = mkEnableOption "DNSCrypt client proxy"; + localAddress = mkOption { default = "127.0.0.1"; type = types.str; @@ -62,6 +46,7 @@ in of other machines (typically on the local network). ''; }; + localPort = mkOption { default = 53; type = types.int; @@ -72,6 +57,7 @@ in to a different value; otherwise leave the default. ''; }; + resolverName = mkOption { default = "dnscrypt.eu-nl"; type = types.nullOr types.str; @@ -82,6 +68,7 @@ in extensions, and claims to not keep logs. ''; }; + resolverList = mkOption { description = '' The list of upstream DNSCrypt resolvers. By default, we use the most @@ -94,6 +81,7 @@ in }; defaultText = "pkgs.fetchurl { url = ...; sha256 = ...; }"; }; + customResolver = mkOption { default = null; description = '' @@ -103,26 +91,30 @@ in type = types.nullOr (types.submodule ({ ... }: { options = { address = mkOption { type = types.str; - description = "Resolver IP address"; + description = "IP address"; example = "208.67.220.220"; }; + port = mkOption { type = types.int; - description = "Resolver port"; + description = "Port"; default = 443; }; + name = mkOption { type = types.str; - description = "Provider fully qualified domain name"; + description = "Fully qualified domain name"; example = "2.dnscrypt-cert.opendns.com"; }; + key = mkOption { type = types.str; - description = "Provider public key"; + description = "Public key"; example = "B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79"; }; }; })); }; + tcpOnly = mkOption { default = false; type = types.bool; @@ -131,6 +123,7 @@ in TCP instead of UDP (on port 443). Use only if the UDP port is blocked. ''; }; + ephemeralKeys = mkOption { default = false; type = types.bool; @@ -212,7 +205,6 @@ in ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}"; User = "dnscrypt-proxy"; - Group = "dnscrypt-proxy"; PrivateTmp = true; PrivateDevices = true; diff --git a/nixos/modules/services/networking/dnscrypt-proxy.xml b/nixos/modules/services/networking/dnscrypt-proxy.xml new file mode 100644 index 000000000000..e212a8d3e2c3 --- /dev/null +++ b/nixos/modules/services/networking/dnscrypt-proxy.xml @@ -0,0 +1,76 @@ +<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><title>Basic configuration</title> + + <para> + To enable the client proxy, set + <programlisting> + 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><title>As a forwarder for a caching DNS client</title> + + <para> + By default, DNSCrypt proxy acts as a transparent proxy for the + system stub resolver. Because the client does not cache lookups, this + setup can significantly slow down e.g., web browsing. The recommended + configuration is to run DNSCrypt proxy as a forwarder for a caching DNS + client. To achieve this, change the default proxy listening port to + a non-standard value and point the caching client to it: + <programlisting> + services.dnscrypt-proxy.localPort = 43; + </programlisting> + </para> + + <sect2><title>dnsmasq</title> + <para> + <programlisting> + { + services.dnsmasq.enable = true; + services.dnsmasq.servers = [ "127.0.0.1#43" ]; + } + </programlisting> + </para> + </sect2> + + <sect2><title>unbound</title> + <para> + <programlisting> + { + networking.nameservers = [ "127.0.0.1" ]; + services.unbound.enable = true; + services.unbound.forwardAddresses = [ "127.0.0.1@43" ]; + services.unbound.extraConfig = '' + do-not-query-localhost: no + ''; + } + </programlisting> + </para> + </sect2> + + </sect1> + +</chapter> diff --git a/nixos/modules/services/networking/ferm.nix b/nixos/modules/services/networking/ferm.nix new file mode 100644 index 000000000000..6271e82541f4 --- /dev/null +++ b/nixos/modules/services/networking/ferm.nix @@ -0,0 +1,63 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.ferm; + + configFile = pkgs.stdenv.mkDerivation { + name = "ferm.conf"; + text = cfg.config; + preferLocalBuild = true; + buildCommand = '' + echo -n "$text" > $out + ${cfg.package}/bin/ferm --noexec $out + ''; + }; +in { + options = { + services.ferm = { + enable = mkOption { + default = false; + example = true; + type = types.bool; + description = '' + Whether to enable Ferm Firewall. + *Warning*: Enabling this service WILL disable the existing NixOS + firewall! Default firewall rules provided by packages are not + considered at the moment. + ''; + }; + config = mkOption { + description = "Verbatim ferm.conf configuration."; + default = ""; + defaultText = "empty firewall, allows any traffic"; + type = types.lines; + }; + package = mkOption { + description = "The ferm package."; + type = types.package; + default = pkgs.ferm; + defaultText = "pkgs.ferm"; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.firewall.enable = false; + systemd.services.ferm = { + description = "Ferm Firewall"; + after = [ "ipset.target" ]; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type="oneshot"; + RemainAfterExit = "yes"; + ExecStart = "${cfg.package}/bin/ferm ${configFile}"; + ExecReload = "${cfg.package}/bin/ferm ${configFile}"; + ExecStop = "${cfg.package}/bin/ferm -F ${configFile}"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/mjpg-streamer.nix b/nixos/modules/services/networking/mjpg-streamer.nix index 9986f549aecf..1286b0c7ef6c 100644 --- a/nixos/modules/services/networking/mjpg-streamer.nix +++ b/nixos/modules/services/networking/mjpg-streamer.nix @@ -59,8 +59,12 @@ in { description = "mjpg-streamer webcam streamer"; wantedBy = [ "multi-user.target" ]; - serviceConfig.User = cfg.user; - serviceConfig.Group = cfg.group; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + Restart = "on-failure"; + RestartSec = 1; + }; script = '' IPLUGIN="${cfg.inputPlugin}" diff --git a/nixos/modules/services/networking/quagga.nix b/nixos/modules/services/networking/quagga.nix new file mode 100644 index 000000000000..ac83da920638 --- /dev/null +++ b/nixos/modules/services/networking/quagga.nix @@ -0,0 +1,187 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.quagga; + + services = [ "babel" "bgp" "isis" "ospf6" "ospf" "pim" "rip" "ripng" ]; + allServices = services ++ [ "zebra" ]; + + isEnabled = service: cfg.${service}.enable; + + daemonName = service: if service == "zebra" then service else "${service}d"; + + configFile = service: + let + scfg = cfg.${service}; + in + if scfg.configFile != null then scfg.configFile + else pkgs.writeText "${daemonName service}.conf" + '' + ! Quagga ${daemonName service} configuration + ! + hostname ${config.networking.hostName} + log syslog + service password-encryption + ! + ${scfg.config} + ! + end + ''; + + serviceOptions = service: + { + enable = mkEnableOption "the Quagga ${toUpper service} routing protocol"; + + configFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/etc/quagga/${daemonName service}.conf"; + description = '' + Configuration file to use for Quagga ${daemonName service}. + By default the NixOS generated files are used. + ''; + }; + + config = mkOption { + type = types.lines; + default = ""; + example = + let + examples = { + rip = '' + router rip + network 10.0.0.0/8 + ''; + + ospf = '' + router ospf + network 10.0.0.0/8 area 0 + ''; + + bgp = '' + router bgp 65001 + neighbor 10.0.0.1 remote-as 65001 + ''; + }; + in + examples.${service} or ""; + description = '' + ${daemonName service} configuration statements. + ''; + }; + + vtyListenAddress = mkOption { + type = types.str; + default = "127.0.0.1"; + description = '' + Address to bind to for the VTY interface. + ''; + }; + + vtyListenPort = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + TCP Port to bind to for the VTY interface. + ''; + }; + }; + +in + +{ + + ###### interface + + options.services.quagga = + { + + zebra = (serviceOptions "zebra") // { + + enable = mkOption { + type = types.bool; + default = any isEnabled services; + example = true; + description = '' + Whether to enable the Zebra routing manager. + + The Zebra routing manager is automatically enabled + if any routing protocols are configured. + ''; + }; + + }; + + } // (genAttrs services serviceOptions); + + ###### implementation + + config = mkIf (any isEnabled allServices) { + + environment.systemPackages = [ + pkgs.quagga # for the vtysh tool + ]; + + users.users.quagga = { + description = "Quagga daemon user"; + isSystemUser = true; + group = "quagga"; + }; + + users.groups = { + quagga = {}; + # Members of the quaggavty group can use vtysh to inspect the Quagga daemons + quaggavty = {}; + }; + + systemd.services = + let + quaggaService = service: + let + scfg = cfg.${service}; + daemon = daemonName service; + in + nameValuePair daemon ({ + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ (configFile service) ]; + + serviceConfig = { + Type = "forking"; + PIDFile = "/run/quagga/${daemon}.pid"; + ExecStart = "@${pkgs.quagga}/libexec/quagga/${daemon} ${daemon} -d -f ${configFile service}" + + optionalString (scfg.vtyListenAddress != "") " -A ${scfg.vtyListenAddress}" + + optionalString (scfg.vtyListenPort != null) " -P ${toString scfg.vtyListenPort}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + Restart = "on-abort"; + }; + } // ( + if service == "zebra" then + { + description = "Quagga Zebra routing manager"; + unitConfig.Documentation = "man:zebra(8)"; + after = [ "network.target" ]; + preStart = '' + install -m 0755 -o quagga -g quagga -d /run/quagga + + ${pkgs.iproute}/bin/ip route flush proto zebra + ''; + } + else + { + description = "Quagga ${toUpper service} routing daemon"; + unitConfig.Documentation = "man:${daemon}(8) man:zebra(8)"; + bindsTo = [ "zebra.service" ]; + after = [ "network.target" "zebra.service" ]; + } + )); + in + listToAttrs (map quaggaService (filter isEnabled allServices)); + + }; + + meta.maintainers = with lib.maintainers; [ tavyc ]; + +} diff --git a/nixos/modules/services/networking/teamspeak3.nix b/nixos/modules/services/networking/teamspeak3.nix index 5f04926eed24..3703921ff703 100644 --- a/nixos/modules/services/networking/teamspeak3.nix +++ b/nixos/modules/services/networking/teamspeak3.nix @@ -95,47 +95,44 @@ in ###### implementation - config = mkMerge [ - (mkIf cfg.enable { - users.users.teamspeak = { - description = "Teamspeak3 voice communication server daemon"; - group = group; - uid = config.ids.uids.teamspeak; - home = cfg.dataDir; - createHome = true; - }; - - users.groups.teamspeak = { - gid = config.ids.gids.teamspeak; - }; + config = mkIf cfg.enable { + users.users.teamspeak = { + description = "Teamspeak3 voice communication server daemon"; + group = group; + uid = config.ids.uids.teamspeak; + home = cfg.dataDir; + createHome = true; + }; - systemd.services.teamspeak3-server = { - description = "Teamspeak3 voice communication server daemon"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; + users.groups.teamspeak = { + gid = config.ids.gids.teamspeak; + }; - preStart = '' - mkdir -p ${cfg.logPath} - chown ${user}:${group} ${cfg.logPath} + systemd.services.teamspeak3-server = { + description = "Teamspeak3 voice communication server daemon"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + preStart = '' + mkdir -p ${cfg.logPath} + chown ${user}:${group} ${cfg.logPath} + ''; + + serviceConfig = { + ExecStart = '' + ${ts3}/bin/ts3server \ + dbsqlpath=${ts3}/lib/teamspeak/sql/ logpath=${cfg.logPath} \ + voice_ip=${cfg.voiceIP} default_voice_port=${toString cfg.defaultVoicePort} \ + filetransfer_ip=${cfg.fileTransferIP} filetransfer_port=${toString cfg.fileTransferPort} \ + query_ip=${cfg.queryIP} query_port=${toString cfg.queryPort} ''; - - serviceConfig = { - ExecStart = '' - ${ts3}/bin/ts3server \ - dbsqlpath=${ts3}/lib/teamspeak/sql/ logpath=${cfg.logPath} \ - voice_ip=${cfg.voiceIP} default_voice_port=${toString cfg.defaultVoicePort} \ - filetransfer_ip=${cfg.fileTransferIP} filetransfer_port=${toString cfg.fileTransferPort} \ - query_ip=${cfg.queryIP} query_port=${toString cfg.queryPort} - ''; - WorkingDirectory = cfg.dataDir; - User = user; - Group = group; - PermissionsStartOnly = true; - }; + WorkingDirectory = cfg.dataDir; + User = user; + Group = group; + PermissionsStartOnly = true; }; - }) - { - meta.maintainers = with lib.maintainers; [ arobyn ]; - } - ]; + }; + }; + + meta.maintainers = with lib.maintainers; [ arobyn ]; } diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix index 0dd24478f409..ed0744c44ccf 100644 --- a/nixos/modules/services/networking/unbound.nix +++ b/nixos/modules/services/networking/unbound.nix @@ -43,14 +43,10 @@ in options = { services.unbound = { - enable = mkOption { - default = false; - type = types.bool; - description = "Whether to enable the Unbound domain name server."; - }; + enable = mkEnableOption "Unbound domain name server"; allowedAccess = mkOption { - default = ["127.0.0.0/24"]; + default = [ "127.0.0.0/24" ]; type = types.listOf types.str; description = "What networks are allowed to use unbound as a resolver."; }; @@ -97,7 +93,7 @@ in }; systemd.services.unbound = { - description="Unbound recursive Domain Name Server"; + description = "Unbound recursive Domain Name Server"; after = [ "network.target" ]; before = [ "nss-lookup.target" ]; wants = [" nss-lookup.target" ]; diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 8d22c10d3f78..de99ce4f0260 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -111,57 +111,54 @@ in { }; }; - config = mkMerge [ - (mkIf cfg.enable { - assertions = flip mapAttrsToList cfg.networks (name: cfg: { - assertion = cfg.psk == null || cfg.pskRaw == null; - message = ''networking.wireless."${name}".psk and networking.wireless."${name}".pskRaw are mutually exclusive''; - }); - - environment.systemPackages = [ pkgs.wpa_supplicant ]; - - services.dbus.packages = [ pkgs.wpa_supplicant ]; - - # FIXME: start a separate wpa_supplicant instance per interface. - systemd.services.wpa_supplicant = let - ifaces = cfg.interfaces; - deviceUnit = interface: [ "sys-subsystem-net-devices-${interface}.device" ]; - in { - description = "WPA Supplicant"; - - after = [ "network-interfaces.target" ] ++ lib.concatMap deviceUnit ifaces; - requires = lib.concatMap deviceUnit ifaces; - wantedBy = [ "network.target" ]; - - path = [ pkgs.wpa_supplicant ]; - - script = '' - ${if ifaces == [] then '' - for i in $(cd /sys/class/net && echo *); do - DEVTYPE= - source /sys/class/net/$i/uevent - if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then - ifaces="$ifaces''${ifaces:+ -N} -i$i" - fi - done - '' else '' - ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}" - ''} - exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces - ''; - }; - - powerManagement.resumeCommands = '' - ${config.systemd.package}/bin/systemctl try-restart wpa_supplicant + config = mkIf cfg.enable { + assertions = flip mapAttrsToList cfg.networks (name: cfg: { + assertion = cfg.psk == null || cfg.pskRaw == null; + message = ''networking.wireless."${name}".psk and networking.wireless."${name}".pskRaw are mutually exclusive''; + }); + + environment.systemPackages = [ pkgs.wpa_supplicant ]; + + services.dbus.packages = [ pkgs.wpa_supplicant ]; + + # FIXME: start a separate wpa_supplicant instance per interface. + systemd.services.wpa_supplicant = let + ifaces = cfg.interfaces; + deviceUnit = interface: [ "sys-subsystem-net-devices-${interface}.device" ]; + in { + description = "WPA Supplicant"; + + after = [ "network-interfaces.target" ] ++ lib.concatMap deviceUnit ifaces; + requires = lib.concatMap deviceUnit ifaces; + wantedBy = [ "network.target" ]; + + path = [ pkgs.wpa_supplicant ]; + + script = '' + ${if ifaces == [] then '' + for i in $(cd /sys/class/net && echo *); do + DEVTYPE= + source /sys/class/net/$i/uevent + if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then + ifaces="$ifaces''${ifaces:+ -N} -i$i" + fi + done + '' else '' + ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}" + ''} + exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces ''; + }; - # Restart wpa_supplicant when a wlan device appears or disappears. - services.udev.extraRules = '' - ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service" - ''; - }) - { - meta.maintainers = with lib.maintainers; [ globin ]; - } - ]; + powerManagement.resumeCommands = '' + ${config.systemd.package}/bin/systemctl try-restart wpa_supplicant + ''; + + # Restart wpa_supplicant when a wlan device appears or disappears. + services.udev.extraRules = '' + ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service" + ''; + }; + + meta.maintainers = with lib.maintainers; [ globin ]; } diff --git a/nixos/modules/services/networking/zerotierone.nix b/nixos/modules/services/networking/zerotierone.nix index e66648f683f4..86e0204ec2f7 100644 --- a/nixos/modules/services/networking/zerotierone.nix +++ b/nixos/modules/services/networking/zerotierone.nix @@ -7,11 +7,19 @@ let in { options.services.zerotierone.enable = mkEnableOption "ZeroTierOne"; - + options.services.zerotierone.package = mkOption { + default = pkgs.zerotierone; + defaultText = "pkgs.zerotierone"; + type = types.package; + description = '' + ZeroTier One package to use. + ''; + }; + config = mkIf cfg.enable { systemd.services.zerotierone = { description = "ZeroTierOne"; - path = [ pkgs.zerotierone ]; + path = [ cfg.package ]; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = @@ -21,7 +29,7 @@ in chown -R root:root /var/lib/zerotier-one ''; serviceConfig = { - ExecStart = "${pkgs.zerotierone}/bin/zerotier-one"; + ExecStart = "${cfg.package}/bin/zerotier-one"; Restart = "always"; KillMode = "process"; }; @@ -30,6 +38,6 @@ in # ZeroTier does not issue DHCP leases, but some strangers might... networking.dhcpcd.denyInterfaces = [ "zt0" ]; - environment.systemPackages = [ pkgs.zerotierone ]; + environment.systemPackages = [ cfg.package ]; }; } |