diff options
Diffstat (limited to 'nixos/modules/services/networking')
18 files changed, 757 insertions, 34 deletions
diff --git a/nixos/modules/services/networking/3proxy.nix b/nixos/modules/services/networking/3proxy.nix new file mode 100644 index 000000000000..26aa16679467 --- /dev/null +++ b/nixos/modules/services/networking/3proxy.nix @@ -0,0 +1,424 @@ +{ config, lib, pkgs, ... }: +with lib; +let + pkg = pkgs._3proxy; + cfg = config.services._3proxy; + optionalList = list: if list == [ ] then "*" else concatMapStringsSep "," toString list; +in { + options.services._3proxy = { + enable = mkEnableOption "3proxy"; + confFile = mkOption { + type = types.path; + example = "/var/lib/3proxy/3proxy.conf"; + description = '' + Ignore all other 3proxy options and load configuration from this file. + ''; + }; + usersFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/var/lib/3proxy/3proxy.passwd"; + description = '' + Load users and passwords from this file. + + Example users file with plain-text passwords: + + <literal> + test1:CL:password1 + test2:CL:password2 + </literal> + + Example users file with md5-crypted passwords: + + <literal> + test1:CR:$1$tFkisVd2$1GA8JXkRmTXdLDytM/i3a1 + test2:CR:$1$rkpibm5J$Aq1.9VtYAn0JrqZ8M.1ME. + </literal> + + You can generate md5-crypted passwords via https://unix4lyfe.org/crypt/ + Note that htpasswd tool generates incompatible md5-crypted passwords. + Consult <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/How-To-(incomplete)#USERS">documentation</link> for more information. + ''; + }; + services = mkOption { + type = types.listOf (types.submodule { + options = { + type = mkOption { + type = types.enum [ + "proxy" + "socks" + "pop3p" + "ftppr" + "admin" + "dnspr" + "tcppm" + "udppm" + ]; + example = "proxy"; + description = '' + Service type. The following values are valid: + + <itemizedlist> + <listitem><para> + <literal>"proxy"</literal>: HTTP/HTTPS proxy (default port 3128). + </para></listitem> + <listitem><para> + <literal>"socks"</literal>: SOCKS 4/4.5/5 proxy (default port 1080). + </para></listitem> + <listitem><para> + <literal>"pop3p"</literal>: POP3 proxy (default port 110). + </para></listitem> + <listitem><para> + <literal>"ftppr"</literal>: FTP proxy (default port 21). + </para></listitem> + <listitem><para> + <literal>"admin"</literal>: Web interface (default port 80). + </para></listitem> + <listitem><para> + <literal>"dnspr"</literal>: Caching DNS proxy (default port 53). + </para></listitem> + <listitem><para> + <literal>"tcppm"</literal>: TCP portmapper. + </para></listitem> + <listitem><para> + <literal>"udppm"</literal>: UDP portmapper. + </para></listitem> + </itemizedlist> + ''; + }; + bindAddress = mkOption { + type = types.str; + default = "[::]"; + example = "127.0.0.1"; + description = '' + Address used for service. + ''; + }; + bindPort = mkOption { + type = types.nullOr types.int; + default = null; + example = 3128; + description = '' + Override default port used for service. + ''; + }; + maxConnections = mkOption { + type = types.int; + default = 100; + example = 1000; + description = '' + Maximum number of simulationeous connections to this service. + ''; + }; + auth = mkOption { + type = types.listOf (types.enum [ "none" "iponly" "strong" ]); + example = [ "iponly" "strong" ]; + description = '' + Authentication type. The following values are valid: + + <itemizedlist> + <listitem><para> + <literal>"none"</literal>: disables both authentication and authorization. You can not use ACLs. + </para></listitem> + <listitem><para> + <literal>"iponly"</literal>: specifies no authentication. ACLs authorization is used. + </para></listitem> + <listitem><para> + <literal>"strong"</literal>: authentication by username/password. If user is not registered his access is denied regardless of ACLs. + </para></listitem> + </itemizedlist> + + Double authentication is possible, e.g. + + <literal> + { + auth = [ "iponly" "strong" ]; + acl = [ + { + rule = "allow"; + targets = [ "192.168.0.0/16" ]; + } + { + rule = "allow" + users = [ "user1" "user2" ]; + } + ]; + } + </literal> + In this example strong username authentication is not required to access 192.168.0.0/16. + ''; + }; + acl = mkOption { + type = types.listOf (types.submodule { + options = { + rule = mkOption { + type = types.enum [ "allow" "deny" ]; + example = "allow"; + description = '' + ACL rule. The following values are valid: + + <itemizedlist> + <listitem><para> + <literal>"allow"</literal>: connections allowed. + </para></listitem> + <listitem><para> + <literal>"deny"</literal>: connections not allowed. + </para></listitem> + </itemizedlist> + ''; + }; + users = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "user1" "user2" "user3" ]; + description = '' + List of users, use empty list for any. + ''; + }; + sources = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "127.0.0.1" "192.168.1.0/24" ]; + description = '' + List of source IP range, use empty list for any. + ''; + }; + targets = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "127.0.0.1" "192.168.1.0/24" ]; + description = '' + List of target IP ranges, use empty list for any. + May also contain host names instead of addresses. + It's possible to use wildmask in the begginning and in the the end of hostname, e.g. *badsite.com or *badcontent*. + Hostname is only checked if hostname presents in request. + ''; + }; + targetPorts = mkOption { + type = types.listOf types.int; + default = [ ]; + example = [ 80 443 ]; + description = '' + List of target ports, use empty list for any. + ''; + }; + }; + }); + default = [ ]; + example = literalExample '' + [ + { + rule = "allow"; + users = [ "user1" ]; + } + { + rule = "allow"; + sources = [ "192.168.1.0/24" ]; + } + { + rule = "deny"; + } + ] + ''; + description = '' + Use this option to limit user access to resources. + ''; + }; + extraArguments = mkOption { + type = types.nullOr types.str; + default = null; + example = "-46"; + description = '' + Extra arguments for service. + Consult "Options" section in <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg">documentation</link> for available arguments. + ''; + }; + extraConfig = mkOption { + type = types.nullOr types.lines; + default = null; + description = '' + Extra configuration for service. Use this to configure things like bandwidth limiter or ACL-based redirection. + Consult <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg">documentation</link> for available options. + ''; + }; + }; + }); + default = [ ]; + example = literalExample '' + [ + { + type = "proxy"; + bindAddress = "192.168.1.24"; + bindPort = 3128; + auth = [ "none" ]; + } + { + type = "proxy"; + bindAddress = "10.10.1.20"; + bindPort = 3128; + auth = [ "iponly" ]; + } + { + type = "socks"; + bindAddress = "172.17.0.1"; + bindPort = 1080; + auth = [ "strong" ]; + } + ] + ''; + description = '' + Use this option to define 3proxy services. + ''; + }; + denyPrivate = mkOption { + type = types.bool; + default = true; + description = '' + Whether to deny access to private IP ranges including loopback. + ''; + }; + privateRanges = mkOption { + type = types.listOf types.str; + default = [ + "0.0.0.0/8" + "127.0.0.0/8" + "10.0.0.0/8" + "100.64.0.0/10" + "172.16.0.0/12" + "192.168.0.0/16" + "::" + "::1" + "fc00::/7" + ]; + example = [ + "0.0.0.0/8" + "127.0.0.0/8" + "10.0.0.0/8" + "100.64.0.0/10" + "172.16.0.0/12" + "192.168.0.0/16" + "::" + "::1" + "fc00::/7" + ]; + description = '' + What IP ranges to deny access when denyPrivate is set tu true. + ''; + }; + resolution = mkOption { + type = types.submodule { + options = { + nserver = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "127.0.0.53" "192.168.1.3:5353/tcp" ]; + description = '' + List of nameservers to use. + + Up to 5 nservers may be specified. If no nserver is configured, + default system name resolution functions are used. + ''; + }; + nscache = mkOption { + type = types.int; + default = 65535; + example = 65535; + description = "Set name cache size for IPv4."; + }; + nscache6 = mkOption { + type = types.int; + default = 65535; + example = 65535; + description = "Set name cache size for IPv6."; + }; + nsrecord = mkOption { + type = types.attrsOf types.str; + default = { }; + example = { + "files.local" = "192.168.1.12"; + "site.local" = "192.168.1.43"; + }; + description = "Adds static nsrecords."; + }; + }; + }; + default = { }; + description = '' + Use this option to configure name resolution and DNS caching. + ''; + }; + extraConfig = mkOption { + type = types.nullOr types.lines; + default = null; + description = '' + Extra configuration, appended to the 3proxy configuration file. + Consult <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg">documentation</link> for available options. + ''; + }; + }; + + config = mkIf cfg.enable { + services._3proxy.confFile = mkDefault (pkgs.writeText "3proxy.conf" '' + # log to stdout + log + + ${concatMapStringsSep "\n" (x: "nserver " + x) cfg.resolution.nserver} + + nscache ${toString cfg.resolution.nscache} + nscache6 ${toString cfg.resolution.nscache6} + + ${concatMapStringsSep "\n" (x: "nsrecord " + x) + (mapAttrsToList (name: value: "${name} ${value}") + cfg.resolution.nsrecord)} + + ${optionalString (cfg.usersFile != null) + ''users $"${cfg.usersFile}"'' + } + + ${concatMapStringsSep "\n" (service: '' + auth ${concatStringsSep " " service.auth} + + ${optionalString (cfg.denyPrivate) + "deny * * ${optionalList cfg.privateRanges}"} + + ${concatMapStringsSep "\n" (acl: + "${acl.rule} ${ + concatMapStringsSep " " optionalList [ + acl.users + acl.sources + acl.targets + acl.targetPorts + ] + }") service.acl} + + maxconn ${toString service.maxConnections} + + ${optionalString (service.extraConfig != null) service.extraConfig} + + ${service.type} -i${toString service.bindAddress} ${ + optionalString (service.bindPort != null) + "-p${toString service.bindPort}" + } ${ + optionalString (service.extraArguments != null) service.extraArguments + } + + flush + '') cfg.services} + ${optionalString (cfg.extraConfig != null) cfg.extraConfig} + ''); + systemd.services."3proxy" = { + description = "Tiny free proxy server"; + documentation = [ "https://github.com/z3APA3A/3proxy/wiki" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + DynamicUser = true; + StateDirectory = "3proxy"; + ExecStart = "${pkg}/bin/3proxy ${cfg.confFile}"; + Restart = "on-failure"; + }; + }; + }; + + meta.maintainers = with maintainers; [ misuzu ]; +} diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix index cac517f410e5..8402be939fe5 100644 --- a/nixos/modules/services/networking/connman.nix +++ b/nixos/modules/services/networking/connman.nix @@ -13,6 +13,10 @@ let ''; in { + imports = [ + (mkRenamedOptionModule [ "networking" "connman" ] [ "services" "connman" ]) + ]; + ###### interface options = { diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index 04ce5ca3a874..053efe712709 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -30,6 +30,14 @@ with lib; { + imports = [ + (mkChangedOptionModule [ "services" "ddclient" "domain" ] [ "services" "ddclient" "domains" ] + (config: + let value = getAttrFromPath [ "services" "ddclient" "domain" ] config; + in if value != "" then [ value ] else [])) + (mkRemovedOptionModule [ "services" "ddclient" "homeDir" ] "") + ]; + ###### interface options = { diff --git a/nixos/modules/services/networking/dhcpd.nix b/nixos/modules/services/networking/dhcpd.nix index 0b2063bc4246..67f7d8118870 100644 --- a/nixos/modules/services/networking/dhcpd.nix +++ b/nixos/modules/services/networking/dhcpd.nix @@ -182,6 +182,10 @@ in { + imports = [ + (mkRenamedOptionModule [ "services" "dhcpd" ] [ "services" "dhcpd4" ]) + ]; + ###### interface options = { diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 5919962837a2..15aaf7410674 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -42,16 +42,7 @@ let kernelHasRPFilter = ((kernel.config.isEnabled or (x: false)) "IP_NF_MATCH_RPFILTER") || (kernel.features.netfilterRPFilter or false); - helpers = - '' - # Helper command to manipulate both the IPv4 and IPv6 tables. - ip46tables() { - iptables -w "$@" - ${optionalString config.networking.enableIPv6 '' - ip6tables -w "$@" - ''} - } - ''; + helpers = import ./helpers.nix { inherit config lib; }; writeShScript = name: text: let dir = pkgs.writeScriptBin name '' #! ${pkgs.runtimeShell} -e @@ -271,7 +262,7 @@ let apply = canonicalizePortList; example = [ 22 80 ]; description = - '' + '' List of TCP ports on which incoming connections are accepted. ''; @@ -282,7 +273,7 @@ let default = [ ]; example = [ { from = 8999; to = 9003; } ]; description = - '' + '' A range of TCP ports on which incoming connections are accepted. ''; diff --git a/nixos/modules/services/networking/helpers.nix b/nixos/modules/services/networking/helpers.nix new file mode 100644 index 000000000000..d7d42de0e3a8 --- /dev/null +++ b/nixos/modules/services/networking/helpers.nix @@ -0,0 +1,11 @@ +{ config, lib, ... }: '' + # Helper command to manipulate both the IPv4 and IPv6 tables. + ip46tables() { + iptables -w "$@" + ${ + lib.optionalString config.networking.enableIPv6 '' + ip6tables -w "$@" + '' + } + } +'' diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix index f2be417738ee..e2c2275b5512 100644 --- a/nixos/modules/services/networking/i2pd.nix +++ b/nixos/modules/services/networking/i2pd.nix @@ -235,6 +235,10 @@ in { + imports = [ + (mkRenamedOptionModule [ "services" "i2pd" "extIp" ] [ "services" "i2pd" "address" ]) + ]; + ###### interface options = { diff --git a/nixos/modules/services/networking/iodine.nix b/nixos/modules/services/networking/iodine.nix index 344f84374bbd..97b5843bbcf1 100644 --- a/nixos/modules/services/networking/iodine.nix +++ b/nixos/modules/services/networking/iodine.nix @@ -11,6 +11,13 @@ let in { + imports = [ + (mkRenamedOptionModule [ "services" "iodined" "enable" ] [ "services" "iodine" "server" "enable" ]) + (mkRenamedOptionModule [ "services" "iodined" "domain" ] [ "services" "iodine" "server" "domain" ]) + (mkRenamedOptionModule [ "services" "iodined" "ip" ] [ "services" "iodine" "server" "ip" ]) + (mkRenamedOptionModule [ "services" "iodined" "extraConfig" ] [ "services" "iodine" "server" "extraConfig" ]) + (mkRemovedOptionModule [ "services" "iodined" "client" ] "") + ]; ### configuration diff --git a/nixos/modules/services/networking/kresd.nix b/nixos/modules/services/networking/kresd.nix index fc516c01230a..574074944d5e 100644 --- a/nixos/modules/services/networking/kresd.nix +++ b/nixos/modules/services/networking/kresd.nix @@ -13,6 +13,17 @@ in { meta.maintainers = [ maintainers.vcunat /* upstream developer */ ]; + imports = [ + (mkChangedOptionModule [ "services" "kresd" "interfaces" ] [ "services" "kresd" "listenPlain" ] + (config: + let value = getAttrFromPath [ "services" "kresd" "interfaces" ] config; + in map + (iface: if elem ":" (stringToCharacters iface) then "[${iface}]:53" else "${iface}:53") # Syntax depends on being IPv6 or IPv4. + value + ) + ) + ]; + ###### interface options.services.kresd = { enable = mkOption { @@ -39,11 +50,12 @@ in Directory for caches. They are intended to survive reboots. ''; }; - interfaces = mkOption { + listenPlain = mkOption { type = with types; listOf str; - default = [ "::1" "127.0.0.1" ]; + default = [ "[::1]:53" "127.0.0.1:53" ]; description = '' - What addresses the server should listen on. (UDP+TCP 53) + What addresses and ports the server should listen on. + For detailed syntax see ListenStream in man systemd.socket. ''; }; listenTLS = mkOption { @@ -51,7 +63,7 @@ in default = []; example = [ "198.51.100.1:853" "[2001:db8::1]:853" "853" ]; description = '' - Addresses on which kresd should provide DNS over TLS (see RFC 7858). + Addresses and ports on which kresd should provide DNS over TLS (see RFC 7858). For detailed syntax see ListenStream in man systemd.socket. ''; }; @@ -76,10 +88,7 @@ in systemd.sockets.kresd = rec { wantedBy = [ "sockets.target" ]; before = wantedBy; - listenStreams = map - # Syntax depends on being IPv6 or IPv4. - (iface: if elem ":" (stringToCharacters iface) then "[${iface}]:53" else "${iface}:53") - cfg.interfaces; + listenStreams = cfg.listenPlain; socketConfig = { ListenDatagram = listenStreams; FreeBind = true; diff --git a/nixos/modules/services/networking/murmur.nix b/nixos/modules/services/networking/murmur.nix index 082953d2f6ab..3054ae1b201f 100644 --- a/nixos/modules/services/networking/murmur.nix +++ b/nixos/modules/services/networking/murmur.nix @@ -46,6 +46,11 @@ let ''; in { + imports = [ + (mkRenamedOptionModule [ "services" "murmur" "welcome" ] [ "services" "murmur" "welcometext" ]) + (mkRemovedOptionModule [ "services" "murmur" "pidfile" ] "Hardcoded to /run/murmur/murmurd.pid now") + ]; + options = { services.murmur = { enable = mkOption { diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index 5681bda51cb4..f1238bc6b168 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -7,26 +7,33 @@ with lib; let - cfg = config.networking.nat; dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"; + helpers = import ./helpers.nix { inherit config lib; }; + flushNat = '' - iptables -w -t nat -D PREROUTING -j nixos-nat-pre 2>/dev/null|| true - iptables -w -t nat -F nixos-nat-pre 2>/dev/null || true - iptables -w -t nat -X nixos-nat-pre 2>/dev/null || true - iptables -w -t nat -D POSTROUTING -j nixos-nat-post 2>/dev/null || true - iptables -w -t nat -F nixos-nat-post 2>/dev/null || true - iptables -w -t nat -X nixos-nat-post 2>/dev/null || true + ${helpers} + ip46tables -w -t nat -D PREROUTING -j nixos-nat-pre 2>/dev/null|| true + ip46tables -w -t nat -F nixos-nat-pre 2>/dev/null || true + ip46tables -w -t nat -X nixos-nat-pre 2>/dev/null || true + ip46tables -w -t nat -D POSTROUTING -j nixos-nat-post 2>/dev/null || true + ip46tables -w -t nat -F nixos-nat-post 2>/dev/null || true + ip46tables -w -t nat -X nixos-nat-post 2>/dev/null || true + ip46tables -w -t nat -D OUTPUT -j nixos-nat-out 2>/dev/null || true + ip46tables -w -t nat -F nixos-nat-out 2>/dev/null || true + ip46tables -w -t nat -X nixos-nat-out 2>/dev/null || true ${cfg.extraStopCommands} ''; setupNat = '' + ${helpers} # Create subchain where we store rules - iptables -w -t nat -N nixos-nat-pre - iptables -w -t nat -N nixos-nat-post + ip46tables -w -t nat -N nixos-nat-pre + ip46tables -w -t nat -N nixos-nat-post + ip46tables -w -t nat -N nixos-nat-out # We can't match on incoming interface in POSTROUTING, so # mark packets coming from the internal interfaces. @@ -88,8 +95,9 @@ let ${cfg.extraCommands} # Append our chains to the nat tables - iptables -w -t nat -A PREROUTING -j nixos-nat-pre - iptables -w -t nat -A POSTROUTING -j nixos-nat-post + ip46tables -w -t nat -A PREROUTING -j nixos-nat-pre + ip46tables -w -t nat -A POSTROUTING -j nixos-nat-post + ip46tables -w -t nat -A OUTPUT -j nixos-nat-out ''; in diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index 90d1032c41b4..53029b590677 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -336,6 +336,7 @@ in { }; imports = [ + (mkRenamedOptionModule [ "networking" "networkmanager" "useDnsmasq" ] [ "networking" "networkmanager" "dns" ]) (mkRemovedOptionModule ["networking" "networkmanager" "dynamicHosts"] '' This option was removed because allowing (multiple) regular users to override host entries affecting the whole system opens up a huge attack diff --git a/nixos/modules/services/networking/openvpn.nix b/nixos/modules/services/networking/openvpn.nix index 05be97e66a3d..dcd7e9e5fa4c 100644 --- a/nixos/modules/services/networking/openvpn.nix +++ b/nixos/modules/services/networking/openvpn.nix @@ -73,6 +73,9 @@ let in { + imports = [ + (mkRemovedOptionModule [ "services" "openvpn" "enable" ] "") + ]; ###### interface diff --git a/nixos/modules/services/networking/shorewall.nix b/nixos/modules/services/networking/shorewall.nix new file mode 100644 index 000000000000..0f94d414fcf7 --- /dev/null +++ b/nixos/modules/services/networking/shorewall.nix @@ -0,0 +1,75 @@ +{ config, lib, pkgs, ... }: +let + types = lib.types; + cfg = config.services.shorewall; +in { + options = { + services.shorewall = { + enable = lib.mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable Shorewall IPv4 Firewall. + <warning> + <para> + Enabling this service WILL disable the existing NixOS + firewall! Default firewall rules provided by packages are not + considered at the moment. + </para> + </warning> + ''; + }; + package = lib.mkOption { + type = types.package; + default = pkgs.shorewall; + defaultText = "pkgs.shorewall"; + description = "The shorewall package to use."; + }; + configs = lib.mkOption { + type = types.attrsOf types.str; + default = {}; + description = '' + This option defines the Shorewall configs. + The attribute name defines the name of the config, + and the attribute value defines the content of the config. + ''; + apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text); + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.firewall.enable = false; + systemd.services.shorewall = { + description = "Shorewall IPv4 Firewall"; + after = [ "ipset.target" ]; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + reloadIfChanged = true; + restartTriggers = lib.attrValues cfg.configs; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = "${cfg.package}/bin/shorewall start"; + ExecReload = "${cfg.package}/bin/shorewall reload"; + ExecStop = "${cfg.package}/bin/shorewall stop"; + }; + preStart = '' + install -D -d -m 750 /var/lib/shorewall + install -D -d -m 755 /var/lock/subsys + touch /var/log/shorewall.log + chown 750 /var/log/shorewall.log + ''; + }; + environment = { + etc = lib.mapAttrsToList + (name: file: + { source = file; + target = "shorewall/${name}"; + }) + cfg.configs; + systemPackages = [ cfg.package ]; + }; + }; +} diff --git a/nixos/modules/services/networking/shorewall6.nix b/nixos/modules/services/networking/shorewall6.nix new file mode 100644 index 000000000000..9c22a037c0b4 --- /dev/null +++ b/nixos/modules/services/networking/shorewall6.nix @@ -0,0 +1,75 @@ +{ config, lib, pkgs, ... }: +let + types = lib.types; + cfg = config.services.shorewall6; +in { + options = { + services.shorewall6 = { + enable = lib.mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable Shorewall IPv6 Firewall. + <warning> + <para> + Enabling this service WILL disable the existing NixOS + firewall! Default firewall rules provided by packages are not + considered at the moment. + </para> + </warning> + ''; + }; + package = lib.mkOption { + type = types.package; + default = pkgs.shorewall; + defaultText = "pkgs.shorewall"; + description = "The shorewall package to use."; + }; + configs = lib.mkOption { + type = types.attrsOf types.str; + default = {}; + description = '' + This option defines the Shorewall configs. + The attribute name defines the name of the config, + and the attribute value defines the content of the config. + ''; + apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text); + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.firewall.enable = false; + systemd.services.shorewall6 = { + description = "Shorewall IPv6 Firewall"; + after = [ "ipset.target" ]; + before = [ "network-pre.target" ]; + wants = [ "network-pre.target" ]; + wantedBy = [ "multi-user.target" ]; + reloadIfChanged = true; + restartTriggers = lib.attrValues cfg.configs; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = "yes"; + ExecStart = "${cfg.package}/bin/shorewall6 start"; + ExecReload = "${cfg.package}/bin/shorewall6 reload"; + ExecStop = "${cfg.package}/bin/shorewall6 stop"; + }; + preStart = '' + install -D -d -m 750 /var/lib/shorewall6 + install -D -d -m 755 /var/lock/subsys + touch /var/log/shorewall6.log + chown 750 /var/log/shorewall6.log + ''; + }; + environment = { + etc = lib.mapAttrsToList + (name: file: + { source = file; + target = "shorewall6/${name}"; + }) + cfg.configs; + systemPackages = [ cfg.package ]; + }; + }; +} diff --git a/nixos/modules/services/networking/spacecookie.nix b/nixos/modules/services/networking/spacecookie.nix new file mode 100644 index 000000000000..c4d06df6ad4a --- /dev/null +++ b/nixos/modules/services/networking/spacecookie.nix @@ -0,0 +1,83 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.spacecookie; + configFile = pkgs.writeText "spacecookie.json" (lib.generators.toJSON {} { + inherit (cfg) hostname port root; + }); +in { + + options = { + + services.spacecookie = { + + enable = mkEnableOption "spacecookie"; + + hostname = mkOption { + type = types.str; + default = "localhost"; + description = "The hostname the service is reachable via. Clients will use this hostname for further requests after loading the initial gopher menu."; + }; + + port = mkOption { + type = types.port; + default = 70; + description = "Port the gopher service should be exposed on."; + }; + + root = mkOption { + type = types.path; + default = "/srv/gopher"; + description = "The root directory spacecookie serves via gopher."; + }; + }; + }; + + config = mkIf cfg.enable { + + systemd.sockets.spacecookie = { + description = "Socket for the Spacecookie Gopher Server"; + wantedBy = [ "sockets.target" ]; + listenStreams = [ "[::]:${toString cfg.port}" ]; + socketConfig = { + BindIPv6Only = "both"; + }; + }; + + systemd.services.spacecookie = { + description = "Spacecookie Gopher Server"; + wantedBy = [ "multi-user.target" ]; + requires = [ "spacecookie.socket" ]; + + serviceConfig = { + Type = "notify"; + ExecStart = "${pkgs.haskellPackages.spacecookie}/bin/spacecookie ${configFile}"; + FileDescriptorStoreMax = 1; + + DynamicUser = true; + + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateUsers = true; + + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + + CapabilityBoundingSet = ""; + NoNewPrivileges = true; + LockPersonality = true; + RestrictRealtime = true; + + # AF_UNIX for communication with systemd + # AF_INET replaced by BindIPv6Only=both + RestrictAddressFamilies = "AF_UNIX AF_INET6"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 91fc7d72bc6d..b0e2e303cbc0 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -74,6 +74,10 @@ let in { + imports = [ + (mkAliasOptionModule [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ]) + (mkAliasOptionModule [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ]) + ]; ###### interface diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix index 3cf82e8839bb..baed83591e1e 100644 --- a/nixos/modules/services/networking/unbound.nix +++ b/nixos/modules/services/networking/unbound.nix @@ -53,6 +53,13 @@ in enable = mkEnableOption "Unbound domain name server"; + package = mkOption { + type = types.package; + default = pkgs.unbound; + defaultText = "pkgs.unbound"; + description = "The unbound package to use"; + }; + allowedAccess = mkOption { default = [ "127.0.0.0/24" ]; type = types.listOf types.str; @@ -94,7 +101,7 @@ in config = mkIf cfg.enable { - environment.systemPackages = [ pkgs.unbound ]; + environment.systemPackages = [ cfg.package ]; users.users.unbound = { description = "unbound daemon user"; @@ -114,7 +121,7 @@ in mkdir -m 0755 -p ${stateDir}/dev/ cp ${confFile} ${stateDir}/unbound.conf ${optionalString cfg.enableRootTrustAnchor '' - ${pkgs.unbound}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!" + ${cfg.package}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!" chown unbound ${stateDir} ${rootTrustAnchorFile} ''} touch ${stateDir}/dev/random @@ -122,7 +129,7 @@ in ''; serviceConfig = { - ExecStart = "${pkgs.unbound}/bin/unbound -d -c ${stateDir}/unbound.conf"; + ExecStart = "${cfg.package}/bin/unbound -d -c ${stateDir}/unbound.conf"; ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random"; ProtectSystem = true; |