diff options
Diffstat (limited to 'nixos/modules/services/networking')
31 files changed, 453 insertions, 88 deletions
diff --git a/nixos/modules/services/networking/bind.nix b/nixos/modules/services/networking/bind.nix index 06af4dbcca4e..d09c6735e123 100644 --- a/nixos/modules/services/networking/bind.nix +++ b/nixos/modules/services/networking/bind.nix @@ -78,7 +78,11 @@ in cacheNetworks = mkOption { default = ["127.0.0.0/24"]; description = " - What networks are allowed to use us as a resolver. + What networks are allowed to use us as a resolver. Note + that this is for recursive queries -- all networks are + allowed to query zones configured with the `zones` option. + It is recommended that you limit cacheNetworks to avoid your + server being used for DNS amplification attacks. "; }; diff --git a/nixos/modules/services/networking/bitcoind.nix b/nixos/modules/services/networking/bitcoind.nix index 90f1291c0198..4e00a8865474 100644 --- a/nixos/modules/services/networking/bitcoind.nix +++ b/nixos/modules/services/networking/bitcoind.nix @@ -177,9 +177,6 @@ in { NoNewPrivileges = "true"; PrivateDevices = "true"; MemoryDenyWriteExecute = "true"; - - # Permission for preStart - PermissionsStartOnly = "true"; }; }; users.users.${cfg.user} = { diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix index 31127f790499..8402be939fe5 100644 --- a/nixos/modules/services/networking/connman.nix +++ b/nixos/modules/services/networking/connman.nix @@ -4,7 +4,7 @@ with pkgs; with lib; let - cfg = config.networking.connman; + cfg = config.services.connman; configFile = pkgs.writeText "connman.conf" '' [General] NetworkInterfaceBlacklist=${concatStringsSep "," cfg.networkInterfaceBlacklist} @@ -13,11 +13,15 @@ let ''; in { + imports = [ + (mkRenamedOptionModule [ "networking" "connman" ] [ "services" "connman" ]) + ]; + ###### interface options = { - networking.connman = { + services.connman = { enable = mkOption { type = types.bool; @@ -71,13 +75,13 @@ in { assertions = [{ assertion = !config.networking.useDHCP; - message = "You can not use services.networking.connman with services.networking.useDHCP"; + message = "You can not use services.connman with networking.useDHCP"; }{ assertion = config.networking.wireless.enable; - message = "You must use services.networking.connman with services.networking.wireless"; + message = "You must use services.connman with networking.wireless"; }{ assertion = !config.networking.networkmanager.enable; - message = "You can not use services.networking.connman with services.networking.networkmanager"; + message = "You can not use services.connman with networking.networkmanager"; }]; environment.systemPackages = [ connman ]; 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/dnschain.nix b/nixos/modules/services/networking/dnschain.nix index 5b58ea9b0c91..2586f2d74e9c 100644 --- a/nixos/modules/services/networking/dnschain.nix +++ b/nixos/modules/services/networking/dnschain.nix @@ -137,7 +137,7 @@ in ]; services.pdns-recursor = mkIf cfgs.pdns-recursor.resolveDNSChainQueries { - forwardZones = + forwardZonesRecurse = { bit = "127.0.0.1:${toString cfg.dns.port}"; dns = "127.0.0.1:${toString cfg.dns.port}"; }; @@ -180,4 +180,6 @@ in }; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } diff --git a/nixos/modules/services/networking/dnscrypt-wrapper.nix b/nixos/modules/services/networking/dnscrypt-wrapper.nix index 79f9e1a43083..e53fb7a15782 100644 --- a/nixos/modules/services/networking/dnscrypt-wrapper.nix +++ b/nixos/modules/services/networking/dnscrypt-wrapper.nix @@ -197,4 +197,7 @@ in { }; }; + + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } diff --git a/nixos/modules/services/networking/eternal-terminal.nix b/nixos/modules/services/networking/eternal-terminal.nix index be7337ece7e4..a2e5b30dc0f0 100644 --- a/nixos/modules/services/networking/eternal-terminal.nix +++ b/nixos/modules/services/networking/eternal-terminal.nix @@ -23,6 +23,8 @@ in type = types.int; description = '' The port the server should listen on. Will use the server's default (2022) if not specified. + + Make sure to open this port in the firewall if necessary. ''; }; @@ -86,4 +88,8 @@ in }; }; }; + + meta = { + maintainers = with lib.maintainers; [ pingiun ]; + }; } diff --git a/nixos/modules/services/networking/fakeroute.nix b/nixos/modules/services/networking/fakeroute.nix index 82a9fb729d84..7916ad4098a7 100644 --- a/nixos/modules/services/networking/fakeroute.nix +++ b/nixos/modules/services/networking/fakeroute.nix @@ -60,4 +60,6 @@ in }; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } 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/monero.nix b/nixos/modules/services/networking/monero.nix index 831e4d60d8da..98a3456f6396 100644 --- a/nixos/modules/services/networking/monero.nix +++ b/nixos/modules/services/networking/monero.nix @@ -224,15 +224,17 @@ in }; }; - assertions = singleton { - assertion = cfg.mining.enable -> cfg.mining.address != ""; - message = '' + assertions = singleton { + assertion = cfg.mining.enable -> cfg.mining.address != ""; + message = '' You need a Monero address to receive mining rewards: specify one using option monero.mining.address. - ''; - }; + ''; + }; }; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } 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/namecoind.nix b/nixos/modules/services/networking/namecoind.nix index c8ee0a2f5647..43a9a0b2598b 100644 --- a/nixos/modules/services/networking/namecoind.nix +++ b/nixos/modules/services/networking/namecoind.nix @@ -201,4 +201,6 @@ in }; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } 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/pdns-recursor.nix b/nixos/modules/services/networking/pdns-recursor.nix index ebfdd9f35b72..6ff181377fcc 100644 --- a/nixos/modules/services/networking/pdns-recursor.nix +++ b/nixos/modules/services/networking/pdns-recursor.nix @@ -91,10 +91,18 @@ in { forwardZones = mkOption { type = types.attrs; + default = {}; + description = '' + DNS zones to be forwarded to other authoritative servers. + ''; + }; + + forwardZonesRecurse = mkOption { + type = types.attrs; example = { eth = "127.0.0.1:5353"; }; default = {}; description = '' - DNS zones to be forwarded to other servers. + DNS zones to be forwarded to other recursive servers. ''; }; @@ -158,7 +166,8 @@ in { webserver-port = cfg.api.port; webserver-allow-from = cfg.api.allowFrom; - forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones; + forward-zones = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZones; + forward-zones-recurse = mapAttrsToList (zone: uri: "${zone}.=${uri}") cfg.forwardZonesRecurse; export-etc-hosts = cfg.exportHosts; dnssec = cfg.dnssecValidation; serve-rfc1918 = cfg.serveRFC1918; @@ -210,4 +219,6 @@ in { "To change extra Recursor settings use services.pdns-recursor.settings instead.") ]; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } diff --git a/nixos/modules/services/networking/privoxy.nix b/nixos/modules/services/networking/privoxy.nix index 49ca839a2c37..1f41c720adf5 100644 --- a/nixos/modules/services/networking/privoxy.nix +++ b/nixos/modules/services/networking/privoxy.nix @@ -109,4 +109,6 @@ in }; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix index 9412d0ef8a62..60fb3d5d6d44 100644 --- a/nixos/modules/services/networking/searx.nix +++ b/nixos/modules/services/networking/searx.nix @@ -75,4 +75,6 @@ in }; + meta.maintainers = with lib.maintainers; [ rnhmjoj ]; + } 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/syncthing.nix b/nixos/modules/services/networking/syncthing.nix index 165fd5970cf8..b3f2af5b1794 100644 --- a/nixos/modules/services/networking/syncthing.nix +++ b/nixos/modules/services/networking/syncthing.nix @@ -18,6 +18,7 @@ let fsWatcherEnabled = folder.watch; fsWatcherDelayS = folder.watchDelay; ignorePerms = folder.ignorePerms; + versioning = folder.versioning; }) (filterAttrs ( _: folder: folder.enable @@ -220,6 +221,69 @@ in { ''; }; + versioning = mkOption { + default = null; + description = '' + How to keep changed/deleted files with syncthing. + There are 4 different types of versioning with different parameters. + See https://docs.syncthing.net/users/versioning.html + ''; + example = [ + { + versioning = { + type = "simple"; + params.keep = "10"; + }; + } + { + versioning = { + type = "trashcan"; + params.cleanoutDays = "1000"; + }; + } + { + versioning = { + type = "staggered"; + params = { + cleanInterval = "3600"; + maxAge = "31536000"; + versionsPath = "/syncthing/backup"; + }; + }; + } + { + versioning = { + type = "external"; + params.versionsPath = pkgs.writers.writeBash "backup" '' + folderpath="$1" + filepath="$2" + rm -rf "$folderpath/$filepath" + ''; + }; + } + ]; + type = with types; nullOr (submodule { + options = { + type = mkOption { + type = enum [ "external" "simple" "staggered" "trashcan" ]; + description = '' + Type of versioning. + See https://docs.syncthing.net/users/versioning.html + ''; + }; + params = mkOption { + type = attrsOf (either str path); + description = '' + Parameters for versioning. Structure depends on versioning.type. + See https://docs.syncthing.net/users/versioning.html + ''; + }; + }; + }); + }; + + + rescanInterval = mkOption { type = types.int; default = 3600; 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; diff --git a/nixos/modules/services/networking/v2ray.nix b/nixos/modules/services/networking/v2ray.nix new file mode 100644 index 000000000000..a1774cdffbb9 --- /dev/null +++ b/nixos/modules/services/networking/v2ray.nix @@ -0,0 +1,81 @@ +{ config, lib, pkgs, ... }: + +with lib; + +{ + options = { + + services.v2ray = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to run v2ray server. + + Either <literal>configFile</literal> or <literal>config</literal> must be specified. + ''; + }; + + configFile = mkOption { + type = types.nullOr types.str; + default = null; + example = "/etc/v2ray/config.json"; + description = '' + The absolute path to the configuration file. + + Either <literal>configFile</literal> or <literal>config</literal> must be specified. + + See <link xlink:href="https://v2ray.com/en/configuration/overview.html"/>. + ''; + }; + + config = mkOption { + type = types.nullOr (types.attrsOf types.unspecified); + default = null; + example = { + inbounds = [{ + port = 1080; + listen = "127.0.0.1"; + protocol = "http"; + }]; + outbounds = [{ + protocol = "freedom"; + }]; + }; + description = '' + The configuration object. + + Either `configFile` or `config` must be specified. + + See <link xlink:href="https://v2ray.com/en/configuration/overview.html"/>. + ''; + }; + }; + + }; + + config = let + cfg = config.services.v2ray; + configFile = if cfg.configFile != null + then cfg.configFile + else (pkgs.writeText "v2ray.json" (builtins.toJSON cfg.config)); + + in mkIf cfg.enable { + assertions = [ + { + assertion = (cfg.configFile == null) != (cfg.config == null); + message = "Either but not both `configFile` and `config` should be specified for v2ray."; + } + ]; + + systemd.services.v2ray = { + description = "v2ray Daemon"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.v2ray ]; + script = '' + exec v2ray -config ${configFile} + ''; + }; + }; +} diff --git a/nixos/modules/services/networking/vsftpd.nix b/nixos/modules/services/networking/vsftpd.nix index 67be60da5673..90093d9a78d9 100644 --- a/nixos/modules/services/networking/vsftpd.nix +++ b/nixos/modules/services/networking/vsftpd.nix @@ -34,6 +34,15 @@ let }; optionDescription = [ + (yesNoOption "allowWriteableChroot" "allow_writeable_chroot" false '' + Allow the use of writeable root inside chroot(). + '') + (yesNoOption "virtualUseLocalPrivs" "virtual_use_local_privs" false '' + If enabled, virtual users will use the same privileges as local + users. By default, virtual users will use the same privileges as + anonymous users, which tends to be more restrictive (especially + in terms of write access). + '') (yesNoOption "anonymousUser" "anonymous_enable" false '' Whether to enable the anonymous FTP user. '') @@ -76,9 +85,21 @@ let outgoing data connections can only connect to the client. Only enable if you know what you are doing! '') - (yesNoOption "ssl_tlsv1" "ssl_tlsv1" true '' '') - (yesNoOption "ssl_sslv2" "ssl_sslv2" false '' '') - (yesNoOption "ssl_sslv3" "ssl_sslv3" false '' '') + (yesNoOption "ssl_tlsv1" "ssl_tlsv1" true '' + Only applies if <option>ssl_enable</option> is activated. If + enabled, this option will permit TLS v1 protocol connections. + TLS v1 connections are preferred. + '') + (yesNoOption "ssl_sslv2" "ssl_sslv2" false '' + Only applies if <option>ssl_enable</option> is activated. If + enabled, this option will permit SSL v2 protocol connections. + TLS v1 connections are preferred. + '') + (yesNoOption "ssl_sslv3" "ssl_sslv3" false '' + Only applies if <option>ssl_enable</option> is activated. If + enabled, this option will permit SSL v3 protocol connections. + TLS v1 connections are preferred. + '') ]; configFile = pkgs.writeText "vsftpd.conf" @@ -98,6 +119,9 @@ let listen=YES nopriv_user=vsftpd secure_chroot_dir=/var/empty + ${optionalString (cfg.localRoot != null) '' + local_root=${cfg.localRoot} + ''} syslog_enable=YES ${optionalString (pkgs.stdenv.hostPlatform.system == "x86_64-linux") '' seccomp_sandbox=NO @@ -106,6 +130,11 @@ let ${optionalString cfg.anonymousUser '' anon_root=${cfg.anonymousUserHome} ''} + ${optionalString cfg.enableVirtualUsers '' + guest_enable=YES + guest_username=vsftpd + pam_service_name=vsftpd + ''} ${cfg.extraConfig} ''; @@ -119,10 +148,7 @@ in services.vsftpd = { - enable = mkOption { - default = false; - description = "Whether to enable the vsftpd FTP server."; - }; + enable = mkEnableOption "vsftpd"; userlist = mkOption { default = []; @@ -143,6 +169,61 @@ in ''; }; + enableVirtualUsers = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the <literal>pam_userdb</literal>-based + virtual user system + ''; + }; + + userDbPath = mkOption { + type = types.nullOr types.str; + example = "/etc/vsftpd/userDb"; + default = null; + description = '' + Only applies if <option>enableVirtualUsers</option> is true. + Path pointing to the <literal>pam_userdb</literal> user + database used by vsftpd to authenticate the virtual users. + + This user list should be stored in the Berkeley DB database + format. + + To generate a new user database, create a text file, add + your users using the following format: + <programlisting> + user1 + password1 + user2 + password2 + </programlisting> + + You can then install <literal>pkgs.db</literal> to generate + the Berkeley DB using + <programlisting> + db_load -T -t hash -f logins.txt userDb.db + </programlisting> + + Caution: <literal>pam_userdb</literal> will automatically + append a <literal>.db</literal> suffix to the filename you + provide though this option. This option shouldn't include + this filetype suffix. + ''; + }; + + localRoot = mkOption { + type = types.nullOr types.str; + default = null; + example = "/var/www/$USER"; + description = '' + This option represents a directory which vsftpd will try to + change into after a local (i.e. non- anonymous) login. + + Failure is silently ignored. + ''; + }; + anonymousUserHome = mkOption { type = types.path; default = "/home/ftp/"; @@ -186,18 +267,25 @@ in config = mkIf cfg.enable { - assertions = singleton + assertions = [ { assertion = (cfg.forceLocalLoginsSSL -> cfg.rsaCertFile != null) && (cfg.forceLocalDataSSL -> cfg.rsaCertFile != null); message = "vsftpd: If forceLocalLoginsSSL or forceLocalDataSSL is true then a rsaCertFile must be provided!"; - }; + } + { + assertion = (cfg.enableVirtualUsers -> cfg.userDbPath != null) + && (cfg.enableVirtualUsers -> cfg.localUsers != null); + message = "vsftpd: If enableVirtualUsers is true, you need to setup both the userDbPath and localUsers options."; + }]; users.users = [ { name = "vsftpd"; uid = config.ids.uids.vsftpd; description = "VSFTPD user"; - home = "/homeless-shelter"; + home = if cfg.localRoot != null + then cfg.localRoot # <= Necessary for virtual users. + else "/homeless-shelter"; } ] ++ optional cfg.anonymousUser { name = "ftp"; @@ -213,23 +301,24 @@ in # = false and whitelist root services.vsftpd.userlist = if cfg.userlistDeny then ["root"] else []; - systemd.services.vsftpd = - { description = "Vsftpd Server"; + systemd = { + tmpfiles.rules = optional cfg.anonymousUser + #Type Path Mode User Gr Age Arg + "d '${builtins.toString cfg.anonymousUserHome}' 0555 'ftp' 'ftp' - -"; + services.vsftpd = { + description = "Vsftpd Server"; wantedBy = [ "multi-user.target" ]; - preStart = - optionalString cfg.anonymousUser - '' - mkdir -p -m 555 ${cfg.anonymousUserHome} - chown -R ftp:ftp ${cfg.anonymousUserHome} - ''; - serviceConfig.ExecStart = "@${vsftpd}/sbin/vsftpd vsftpd ${configFile}"; serviceConfig.Restart = "always"; serviceConfig.Type = "forking"; }; + }; + security.pam.services.vsftpd.text = mkIf (cfg.enableVirtualUsers && cfg.userDbPath != null)'' + auth required pam_userdb.so db=${cfg.userDbPath} + account required pam_userdb.so db=${cfg.userDbPath} + ''; }; - } diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix index 4176da2c8cb8..980961225c9e 100644 --- a/nixos/modules/services/networking/wireguard.nix +++ b/nixos/modules/services/networking/wireguard.nix @@ -112,6 +112,32 @@ let Determines whether to add allowed IPs as routes or not. ''; }; + + socketNamespace = mkOption { + default = null; + type = with types; nullOr str; + example = "container"; + description = ''The pre-existing network namespace in which the + WireGuard interface is created, and which retains the socket even if the + interface is moved via <option>interfaceNamespace</option>. When + <literal>null</literal>, the interface is created in the init namespace. + See <link + xlink:href="https://www.wireguard.com/netns/">documentation</link>. + ''; + }; + + interfaceNamespace = mkOption { + default = null; + type = with types; nullOr str; + example = "init"; + description = ''The pre-existing network namespace the WireGuard + interface is moved to. The special value <literal>init</literal> means + the init namespace. When <literal>null</literal>, the interface is not + moved. + See <link + xlink:href="https://www.wireguard.com/netns/">documentation</link>. + ''; + }; }; }; @@ -239,6 +265,10 @@ let if peer.presharedKey != null then pkgs.writeText "wg-psk" peer.presharedKey else peer.presharedKeyFile; + src = interfaceCfg.socketNamespace; + dst = interfaceCfg.interfaceNamespace; + ip = nsWrap "ip" src dst; + wg = nsWrap "wg" src dst; in nameValuePair "wireguard-${interfaceName}-peer-${unitName}" { description = "WireGuard Peer - ${interfaceName} - ${peer.publicKey}"; @@ -255,16 +285,16 @@ let }; script = let - wg_setup = "wg set ${interfaceName} peer ${peer.publicKey}" + + wg_setup = "${wg} set ${interfaceName} peer ${peer.publicKey}" + optionalString (psk != null) " preshared-key ${psk}" + optionalString (peer.endpoint != null) " endpoint ${peer.endpoint}" + optionalString (peer.persistentKeepalive != null) " persistent-keepalive ${toString peer.persistentKeepalive}" + optionalString (peer.allowedIPs != []) " allowed-ips ${concatStringsSep "," peer.allowedIPs}"; route_setup = - optionalString (interfaceCfg.allowedIPsAsRoutes != false) + optionalString interfaceCfg.allowedIPsAsRoutes (concatMapStringsSep "\n" (allowedIP: - "ip route replace ${allowedIP} dev ${interfaceName} table ${interfaceCfg.table}" + "${ip} route replace ${allowedIP} dev ${interfaceName} table ${interfaceCfg.table}" ) peer.allowedIPs); in '' ${wg_setup} @@ -272,13 +302,13 @@ let ''; postStop = let - route_destroy = optionalString (interfaceCfg.allowedIPsAsRoutes != false) + route_destroy = optionalString interfaceCfg.allowedIPsAsRoutes (concatMapStringsSep "\n" (allowedIP: - "ip route delete ${allowedIP} dev ${interfaceName} table ${interfaceCfg.table}" + "${ip} route delete ${allowedIP} dev ${interfaceName} table ${interfaceCfg.table}" ) peer.allowedIPs); in '' - wg set ${interfaceName} peer ${peer.publicKey} remove + ${wg} set ${interfaceName} peer ${peer.publicKey} remove ${route_destroy} ''; }; @@ -287,6 +317,13 @@ let # exactly one way to specify the private key must be set #assert (values.privateKey != null) != (values.privateKeyFile != null); let privKey = if values.privateKeyFile != null then values.privateKeyFile else pkgs.writeText "wg-key" values.privateKey; + src = values.socketNamespace; + dst = values.interfaceNamespace; + ipPreMove = nsWrap "ip" src null; + ipPostMove = nsWrap "ip" src dst; + wg = nsWrap "wg" src dst; + ns = if dst == "init" then "1" else dst; + in nameValuePair "wireguard-${name}" { @@ -307,26 +344,33 @@ let ${values.preSetup} - ip link add dev ${name} type wireguard + ${ipPreMove} link add dev ${name} type wireguard + ${optionalString (values.interfaceNamespace != null && values.interfaceNamespace != values.socketNamespace) "${ipPreMove} link set ${name} netns ${ns}"} ${concatMapStringsSep "\n" (ip: - "ip address add ${ip} dev ${name}" + "${ipPostMove} address add ${ip} dev ${name}" ) values.ips} - wg set ${name} private-key ${privKey} ${ + ${wg} set ${name} private-key ${privKey} ${ optionalString (values.listenPort != null) " listen-port ${toString values.listenPort}"} - ip link set up dev ${name} + ${ipPostMove} link set up dev ${name} ${values.postSetup} ''; postStop = '' - ip link del dev ${name} + ${ipPostMove} link del dev ${name} ${values.postShutdown} ''; }; + nsWrap = cmd: src: dst: + let + nsList = filter (ns: ns != null) [ src dst ]; + ns = last nsList; + in + if (length nsList > 0 && ns != "init") then "ip netns exec ${ns} ${cmd}" else cmd; in { diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 294c0d70edea..8f05c3949fba 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -236,9 +236,12 @@ in { ${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" + UEVENT_PATH=/sys/class/net/$i/uevent + if [ -e "$UEVENT_PATH" ]; then + source "$UEVENT_PATH" + if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then + ifaces="$ifaces''${ifaces:+ -N} -i$i" + fi fi done '' else '' diff --git a/nixos/modules/services/networking/yggdrasil.nix b/nixos/modules/services/networking/yggdrasil.nix index 0da50ccc344b..9e675ecd6f4b 100644 --- a/nixos/modules/services/networking/yggdrasil.nix +++ b/nixos/modules/services/networking/yggdrasil.nix @@ -12,11 +12,11 @@ let configFileProvided = (cfg.configFile != null); generateConfig = ( if configProvided && configFileProvided then - "${pkgs.jq}/bin/jq -s add /run/yggdrasil/configFile.json ${configAsFile}" + "${pkgs.jq}/bin/jq -s add ${configAsFile} ${cfg.configFile}" else if configProvided then "cat ${configAsFile}" else if configFileProvided then - "cat /run/yggdrasil/configFile.json" + "cat ${cfg.configFile}" else "${cfg.package}/bin/yggdrasil -genconf" ); @@ -128,12 +128,6 @@ in { } ]; - environment.etc."yggdrasil.conf" = { - enable = true; - mode = "symlink"; - source = "/run/yggdrasil/yggdrasil.conf"; - }; - systemd.services.yggdrasil = { description = "Yggdrasil Network Service"; path = [ cfg.package ] ++ optional (configProvided && configFileProvided) pkgs.jq; @@ -146,14 +140,14 @@ in { ''; serviceConfig = { - ExecStart = "${cfg.package}/bin/yggdrasil -useconffile /etc/yggdrasil.conf"; + ExecStart = "${cfg.package}/bin/yggdrasil -useconffile /run/yggdrasil/yggdrasil.conf"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; Restart = "always"; RuntimeDirectory = "yggdrasil"; RuntimeDirectoryMode = "0700"; BindReadOnlyPaths = mkIf configFileProvided - [ "${cfg.configFile}:/run/yggdrasil/configFile.json" ]; + [ "${cfg.configFile}" ]; # TODO: as of yggdrasil 0.3.8 and systemd 243, yggdrasil fails # to set up the network adapter when DynamicUser is set. See diff --git a/nixos/modules/services/networking/znc/default.nix b/nixos/modules/services/networking/znc/default.nix index 05f97bfa539f..0a9848a49349 100644 --- a/nixos/modules/services/networking/znc/default.nix +++ b/nixos/modules/services/networking/znc/default.nix @@ -239,7 +239,7 @@ in services.znc = { configFile = mkDefault (pkgs.writeText "znc-generated.conf" semanticString); config = { - Version = (builtins.parseDrvName pkgs.znc.name).version; + Version = lib.getVersion pkgs.znc; Listener.l.Port = mkDefault 5000; Listener.l.SSL = mkDefault true; }; |