diff options
Diffstat (limited to 'infra/libkookie/nixpkgs/nixos/modules/services/networking')
33 files changed, 469 insertions, 202 deletions
diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/avahi-daemon.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/avahi-daemon.nix index 2900c37f990f..0b7d5575c11f 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/avahi-daemon.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/avahi-daemon.nix @@ -86,7 +86,8 @@ in ipv6 = mkOption { type = types.bool; - default = false; + default = config.networking.enableIPv6; + defaultText = "config.networking.enableIPv6"; description = "Whether to use IPv6."; }; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/babeld.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/babeld.nix index e62c74d0069d..90395dbd3c54 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/babeld.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/babeld.nix @@ -87,9 +87,37 @@ in description = "Babel routing daemon"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - serviceConfig.ExecStart = "${pkgs.babeld}/bin/babeld -c ${configFile}"; + serviceConfig = { + ExecStart = "${pkgs.babeld}/bin/babeld -c ${configFile} -I /run/babeld/babeld.pid -S /var/lib/babeld/state"; + CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; + IPAddressAllow = [ "fe80::/64" "ff00::/8" "::1/128" "127.0.0.0/8" ]; + IPAddressDeny = "any"; + LockPersonality = true; + NoNewPrivileges = true; + MemoryDenyWriteExecute = true; + ProtectSystem = "strict"; + ProtectClock = true; + ProtectKernelTunables = false; # Couldn't write sysctl: Read-only file system + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_NETLINK" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + ProtectHome = true; + ProtectHostname = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateUsers = false; # kernel_route(ADD): Operation not permitted + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" ]; + UMask = "0177"; + RuntimeDirectory = "babeld"; + StateDirectory = "babeld"; + }; }; - }; - } diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix index dde24522756a..ca323e495ec1 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/blockbook-frontend.nix @@ -158,15 +158,21 @@ let type = types.attrs; default = {}; example = literalExample '' { - alternative_estimate_fee = "whatthefee-disabled"; - alternative_estimate_fee_params = "{\"url\": \"https://whatthefee.io/data.json\", \"periodSeconds\": 60}"; - fiat_rates = "coingecko"; - fiat_rates_params = "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"bitcoin\", \"periodSeconds\": 60}"; - coin_shortcut = "BTC"; - coin_label = "Bitcoin"; - xpub_magic = 76067358; - xpub_magic_segwit_p2sh = 77429938; - xpub_magic_segwit_native = 78792518; + "alternative_estimate_fee" = "whatthefee-disabled"; + "alternative_estimate_fee_params" = "{\"url\": \"https://whatthefee.io/data.json\", \"periodSeconds\": 60}"; + "fiat_rates" = "coingecko"; + "fiat_rates_params" = "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"bitcoin\", \"periodSeconds\": 60}"; + "coin_shortcut" = "BTC"; + "coin_label" = "Bitcoin"; + "parse" = true; + "subversion" = ""; + "address_format" = ""; + "xpub_magic" = 76067358; + "xpub_magic_segwit_p2sh" = 77429938; + "xpub_magic_segwit_native" = 78792518; + "mempool_workers" = 8; + "mempool_sub_workers" = 2; + "block_addresses_to_keep" = 300; }''; description = '' Additional configurations to be appended to <filename>coin.conf</filename>. diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/cjdns.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/cjdns.nix index 5f8ac96b2292..f116d6392ea7 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/cjdns.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/cjdns.nix @@ -264,10 +264,10 @@ in '' ); + startLimitIntervalSec = 0; serviceConfig = { Type = "forking"; Restart = "always"; - StartLimitInterval = 0; RestartSec = 1; CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW CAP_SETUID"; ProtectSystem = true; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/dhcpcd.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/dhcpcd.nix index 0507b739d499..d10bffd91474 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/dhcpcd.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/dhcpcd.nix @@ -69,6 +69,11 @@ let if-carrier-up = ""; }.${cfg.wait}} + ${optionalString (config.networking.enableIPv6 == false) '' + # Don't solicit or accept IPv6 Router Advertisements and DHCPv6 if disabled IPv6 + noipv6 + ''} + ${cfg.extraConfig} ''; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix index b9333cd19a2a..ee7e9b0454de 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnscrypt-wrapper.nix @@ -55,7 +55,10 @@ let rotateKeys = '' # check if keys are not expired keyValid() { - fingerprint=$(dnscrypt-wrapper --show-provider-publickey | awk '{print $(NF)}') + fingerprint=$(dnscrypt-wrapper \ + --show-provider-publickey \ + --provider-publickey-file=${publicKey} \ + | awk '{print $(NF)}') dnscrypt-proxy --test=${toString (cfg.keys.checkInterval + 1)} \ --resolver-address=127.0.0.1:${toString cfg.port} \ --provider-name=${cfg.providerName} \ diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnsdist.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnsdist.nix index c48835e73612..05c2bdef83e7 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnsdist.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/dnsdist.nix @@ -41,6 +41,7 @@ in { systemd.services.dnsdist = { wantedBy = [ "multi-user.target" ]; + startLimitIntervalSec = 0; serviceConfig = { DynamicUser = true; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/kresd.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/kresd.nix index ccb34163d5f3..6f1c4c48b430 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/kresd.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/kresd.nix @@ -23,18 +23,14 @@ let ''; 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 + + concatMapStrings (mkListen "doh2") cfg.listenDoH + cfg.extraConfig ); - package = if cfg.listenDoH == [] - then pkgs.knot-resolver # never force `extraFeatures = false` - else pkgs.knot-resolver.override { extraFeatures = true; }; + package = pkgs.knot-resolver; in { meta.maintainers = [ maintainers.vcunat /* upstream developer */ ]; @@ -92,7 +88,7 @@ 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 8484). + Addresses and ports on which kresd should provide DNS over HTTPS/2 (see RFC 8484). For detailed syntax see ListenStream in man systemd.socket. ''; }; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/morty.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/morty.nix index e3a6444c1163..e110a5c86101 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/morty.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/morty.nix @@ -29,9 +29,11 @@ in key = mkOption { type = types.str; default = ""; - description = "HMAC url validation key (hexadecimal encoded). - Leave blank to disable. Without validation key, anyone can - submit proxy requests. Leave blank to disable."; + description = '' + HMAC url validation key (hexadecimal encoded). + Leave blank to disable. Without validation key, anyone can + submit proxy requests. Leave blank to disable. + ''; defaultText = "No HMAC url validation. Generate with echo -n somevalue | openssl dgst -sha1 -hmac somekey"; }; @@ -85,10 +87,10 @@ in serviceConfig = { User = "morty"; ExecStart = ''${cfg.package}/bin/morty \ - -listen ${cfg.listenAddress}:${toString cfg.port} \ - ${optionalString cfg.ipv6 "-ipv6"} \ - ${optionalString (cfg.key != "") "-key " + cfg.key} \ - ''; + -listen ${cfg.listenAddress}:${toString cfg.port} \ + ${optionalString cfg.ipv6 "-ipv6"} \ + ${optionalString (cfg.key != "") "-key " + cfg.key} \ + ''; }; }; environment.systemPackages = [ cfg.package ]; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/mosquitto.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/mosquitto.nix index d2feb93e2b72..10b49d9b2206 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/mosquitto.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/mosquitto.nix @@ -123,12 +123,33 @@ in ''; }; + passwordFile = mkOption { + type = with types; uniq (nullOr str); + example = "/path/to/file"; + default = null; + description = '' + Specifies the path to a file containing the + clear text password for the MQTT user. + ''; + }; + hashedPassword = mkOption { type = with types; uniq (nullOr str); default = null; description = '' Specifies the hashed password for the MQTT User. - <option>hashedPassword</option> overrides <option>password</option>. + To generate hashed password install <literal>mosquitto</literal> + package and use <literal>mosquitto_passwd</literal>. + ''; + }; + + hashedPasswordFile = mkOption { + type = with types; uniq (nullOr str); + example = "/path/to/file"; + default = null; + description = '' + Specifies the path to a file containing the + hashed password for the MQTT user. To generate hashed password install <literal>mosquitto</literal> package and use <literal>mosquitto_passwd</literal>. ''; @@ -190,6 +211,13 @@ in config = mkIf cfg.enable { + assertions = mapAttrsToList (name: cfg: { + assertion = length (filter (s: s != null) (with cfg; [ + password passwordFile hashedPassword hashedPasswordFile + ])) <= 1; + message = "Cannot set more than one password option"; + }) cfg.users; + systemd.services.mosquitto = { description = "Mosquitto MQTT Broker Daemon"; wantedBy = [ "multi-user.target" ]; @@ -204,13 +232,27 @@ in Restart = "on-failure"; ExecStart = "${pkgs.mosquitto}/bin/mosquitto -c ${mosquittoConf}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + + ProtectSystem = "strict"; + ProtectHome = true; + PrivateDevices = true; + PrivateTmp = true; + ReadWritePaths = "${cfg.dataDir}"; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + NoNewPrivileges = true; }; preStart = '' rm -f ${cfg.dataDir}/passwd touch ${cfg.dataDir}/passwd '' + concatStringsSep "\n" ( mapAttrsToList (n: c: - if c.hashedPassword != null then + if c.hashedPasswordFile != null then + "echo '${n}:'$(cat '${c.hashedPasswordFile}') >> ${cfg.dataDir}/passwd" + else if c.passwordFile != null then + "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} $(cat '${c.passwordFile}')" + else if c.hashedPassword != null then "echo '${n}:${c.hashedPassword}' >> ${cfg.dataDir}/passwd" else optionalString (c.password != null) "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} '${c.password}'" diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/mullvad-vpn.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/mullvad-vpn.nix index cc98414257ca..6f595ca4be2b 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/mullvad-vpn.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/mullvad-vpn.nix @@ -15,6 +15,9 @@ with lib; config = mkIf cfg.enable { boot.kernelModules = [ "tun" ]; + # mullvad-daemon writes to /etc/iproute2/rt_tables + networking.iproute2.enable = true; + systemd.services.mullvad-daemon = { description = "Mullvad VPN daemon"; wantedBy = [ "multi-user.target" ]; @@ -29,9 +32,9 @@ with lib; # Needed for ping "/run/wrappers" ]; + startLimitBurst = 5; + startLimitIntervalSec = 20; serviceConfig = { - StartLimitBurst = 5; - StartLimitIntervalSec = 20; ExecStart = "${pkgs.mullvad-vpn}/bin/mullvad-daemon -v --disable-stdout-timestamps"; Restart = "always"; RestartSec = 1; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/murmur.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/murmur.nix index b384f436861d..c6e5649ec479 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/murmur.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/murmur.nix @@ -278,6 +278,10 @@ in home = "/var/lib/murmur"; createHome = true; uid = config.ids.uids.murmur; + group = "murmur"; + }; + users.groups.murmur = { + gid = config.ids.gids.murmur; }; systemd.services.murmur = { @@ -300,6 +304,7 @@ in RuntimeDirectory = "murmur"; RuntimeDirectoryMode = "0700"; User = "murmur"; + Group = "murmur"; }; }; }; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/namecoind.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/namecoind.nix index 16f85df2e77c..4966ed2cac8d 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/namecoind.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/namecoind.nix @@ -165,6 +165,8 @@ in after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; + startLimitIntervalSec = 120; + startLimitBurst = 5; serviceConfig = { User = "namecoin"; Group = "namecoin"; @@ -176,8 +178,6 @@ in TimeoutStopSec = "60s"; TimeoutStartSec = "2s"; Restart = "always"; - StartLimitInterval = "120s"; - StartLimitBurst = "5"; }; preStart = optionalString (cfg.wallet != "${dataDir}/wallet.dat") '' diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nar-serve.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nar-serve.nix new file mode 100644 index 000000000000..ddd42fa01073 --- /dev/null +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nar-serve.nix @@ -0,0 +1,55 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.services.nar-serve; +in +{ + meta = { + maintainers = [ maintainers.rizary ]; + }; + options = { + services.nar-serve = { + enable = mkEnableOption "Serve NAR file contents via HTTP"; + + port = mkOption { + type = types.int; + default = 8383; + description = '' + Port number where nar-serve will listen on. + ''; + }; + + cacheURL = mkOption { + type = types.str; + default = "https://cache.nixos.org/"; + description = '' + Binary cache URL to connect to. + + The URL format is compatible with the nix remote url style, such as: + - http://, https:// for binary caches via HTTP or HTTPS + - s3:// for binary caches stored in Amazon S3 + - gs:// for binary caches stored in Google Cloud Storage + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.nar-serve = { + description = "NAR server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment.PORT = toString cfg.port; + environment.NAR_CACHE_URL = cfg.cacheURL; + + serviceConfig = { + Restart = "always"; + RestartSec = "5s"; + ExecStart = "${pkgs.nar-serve}/bin/nar-serve"; + DynamicUser = true; + }; + }; + }; +} diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nat.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nat.nix index 21ae9eb8b6d4..45eb500fe8ce 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nat.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nat.nix @@ -9,7 +9,14 @@ with lib; let cfg = config.networking.nat; - dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"; + mkDest = externalIP: if externalIP == null + then "-j MASQUERADE" + else "-j SNAT --to-source ${externalIP}"; + dest = mkDest cfg.externalIP; + destIPv6 = mkDest cfg.externalIPv6; + + # Whether given IP (plus optional port) is an IPv6. + isIPv6 = ip: builtins.length (lib.splitString ":" ip) > 2; helpers = import ./helpers.nix { inherit config lib; }; @@ -28,63 +35,80 @@ let ${cfg.extraStopCommands} ''; - setupNat = '' - ${helpers} - # Create subchain where we store rules - ip46tables -w -t nat -N nixos-nat-pre - ip46tables -w -t nat -N nixos-nat-post - ip46tables -w -t nat -N nixos-nat-out - + mkSetupNat = { iptables, dest, internalIPs, forwardPorts }: '' # We can't match on incoming interface in POSTROUTING, so # mark packets coming from the internal interfaces. ${concatMapStrings (iface: '' - iptables -w -t nat -A nixos-nat-pre \ + ${iptables} -w -t nat -A nixos-nat-pre \ -i '${iface}' -j MARK --set-mark 1 '') cfg.internalInterfaces} # NAT the marked packets. ${optionalString (cfg.internalInterfaces != []) '' - iptables -w -t nat -A nixos-nat-post -m mark --mark 1 \ + ${iptables} -w -t nat -A nixos-nat-post -m mark --mark 1 \ ${optionalString (cfg.externalInterface != null) "-o ${cfg.externalInterface}"} ${dest} ''} # NAT packets coming from the internal IPs. ${concatMapStrings (range: '' - iptables -w -t nat -A nixos-nat-post \ + ${iptables} -w -t nat -A nixos-nat-post \ -s '${range}' ${optionalString (cfg.externalInterface != null) "-o ${cfg.externalInterface}"} ${dest} - '') cfg.internalIPs} + '') internalIPs} # NAT from external ports to internal ports. ${concatMapStrings (fwd: '' - iptables -w -t nat -A nixos-nat-pre \ + ${iptables} -w -t nat -A nixos-nat-pre \ -i ${toString cfg.externalInterface} -p ${fwd.proto} \ --dport ${builtins.toString fwd.sourcePort} \ -j DNAT --to-destination ${fwd.destination} ${concatMapStrings (loopbackip: 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 builtins.replaceStrings ["-"] [":"] (elemAt m 1); + matchIP = if isIPv6 fwd.destination then "[[]([0-9a-fA-F:]+)[]]" else "([0-9.]+)"; + m = builtins.match "${matchIP}:([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 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 \ + ${iptables} -w -t nat -A nixos-nat-out \ -d ${loopbackip} -p ${fwd.proto} \ --dport ${builtins.toString fwd.sourcePort} \ -j DNAT --to-destination ${fwd.destination} # Allow connections to ${loopbackip}:${toString fwd.sourcePort} from other hosts behind NAT - iptables -w -t nat -A nixos-nat-pre \ + ${iptables} -w -t nat -A nixos-nat-pre \ -d ${loopbackip} -p ${fwd.proto} \ --dport ${builtins.toString fwd.sourcePort} \ -j DNAT --to-destination ${fwd.destination} - iptables -w -t nat -A nixos-nat-post \ + ${iptables} -w -t nat -A nixos-nat-post \ -d ${destinationIP} -p ${fwd.proto} \ --dport ${destinationPorts} \ -j SNAT --to-source ${loopbackip} '') fwd.loopbackIPs} - '') cfg.forwardPorts} + '') forwardPorts} + ''; + + setupNat = '' + ${helpers} + # Create subchains where we store rules + ip46tables -w -t nat -N nixos-nat-pre + ip46tables -w -t nat -N nixos-nat-post + ip46tables -w -t nat -N nixos-nat-out + + ${mkSetupNat { + iptables = "iptables"; + inherit dest; + inherit (cfg) internalIPs; + forwardPorts = filter (x: !(isIPv6 x.destination)) cfg.forwardPorts; + }} + + ${optionalString cfg.enableIPv6 (mkSetupNat { + iptables = "ip6tables"; + dest = destIPv6; + internalIPs = cfg.internalIPv6s; + forwardPorts = filter (x: isIPv6 x.destination) cfg.forwardPorts; + })} ${optionalString (cfg.dmzHost != null) '' iptables -w -t nat -A nixos-nat-pre \ @@ -117,6 +141,15 @@ in ''; }; + networking.nat.enableIPv6 = mkOption { + type = types.bool; + default = false; + description = + '' + Whether to enable IPv6 NAT. + ''; + }; + networking.nat.internalInterfaces = mkOption { type = types.listOf types.str; default = []; @@ -141,6 +174,18 @@ in ''; }; + networking.nat.internalIPv6s = mkOption { + type = types.listOf types.str; + default = []; + example = [ "fc00::/64" ]; + description = + '' + The IPv6 address ranges for which to perform NAT. Packets + coming from these addresses (on any interface) and destined + for the external interface will be rewritten. + ''; + }; + networking.nat.externalInterface = mkOption { type = types.nullOr types.str; default = null; @@ -164,6 +209,19 @@ in ''; }; + networking.nat.externalIPv6 = mkOption { + type = types.nullOr types.str; + default = null; + example = "2001:dc0:2001:11::175"; + description = + '' + The public IPv6 address to which packets from the local + network are to be rewritten. If this is left empty, the + IP address associated with the external interface will be + used. + ''; + }; + networking.nat.forwardPorts = mkOption { type = with types; listOf (submodule { options = { @@ -176,7 +234,7 @@ in destination = mkOption { type = types.str; example = "10.0.0.1:80"; - description = "Forward connection to destination ip:port; to specify a port range, use ip:start-end"; + description = "Forward connection to destination ip:port (or [ipv6]:port); to specify a port range, use ip:start-end"; }; proto = mkOption { @@ -195,11 +253,15 @@ in }; }); default = []; - example = [ { sourcePort = 8080; destination = "10.0.0.1:80"; proto = "tcp"; } ]; + example = [ + { sourcePort = 8080; destination = "10.0.0.1:80"; proto = "tcp"; } + { sourcePort = 8080; destination = "[fc00::2]:80"; proto = "tcp"; } + ]; description = '' List of forwarded ports from the external interface to - internal destinations by using DNAT. + internal destinations by using DNAT. Destination can be + IPv6 if IPv6 NAT is enabled. ''; }; @@ -246,6 +308,9 @@ in (mkIf config.networking.nat.enable { assertions = [ + { assertion = cfg.enableIPv6 -> config.networking.enableIPv6; + message = "networking.nat.enableIPv6 requires networking.enableIPv6"; + } { assertion = (cfg.dmzHost != null) -> (cfg.externalInterface != null); message = "networking.nat.dmzHost requires networking.nat.externalInterface"; } @@ -261,6 +326,15 @@ in kernel.sysctl = { "net.ipv4.conf.all.forwarding" = mkOverride 99 true; "net.ipv4.conf.default.forwarding" = mkOverride 99 true; + } // optionalAttrs cfg.enableIPv6 { + # Do not prevent IPv6 autoconfiguration. + # See <http://strugglers.net/~andy/blog/2011/09/04/linux-ipv6-router-advertisements-and-forwarding/>. + "net.ipv6.conf.all.accept_ra" = mkOverride 99 2; + "net.ipv6.conf.default.accept_ra" = mkOverride 99 2; + + # Forward IPv6 packets. + "net.ipv6.conf.all.forwarding" = mkOverride 99 true; + "net.ipv6.conf.default.forwarding" = mkOverride 99 true; }; }; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/networkmanager.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/networkmanager.nix index 17c549d42c32..2e680544ec24 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/networkmanager.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/networkmanager.nix @@ -15,6 +15,7 @@ let networkmanager-openconnect networkmanager-openvpn networkmanager-vpnc + networkmanager-sstp ] ++ optional (!delegateWireless && !enableIwd) wpa_supplicant; delegateWireless = config.networking.wireless.enable == true && cfg.unmanaged != []; @@ -386,6 +387,9 @@ in { "NetworkManager/VPN/nm-iodine-service.name".source = "${networkmanager-iodine}/lib/NetworkManager/VPN/nm-iodine-service.name"; + + "NetworkManager/VPN/nm-sstp-service.name".source = + "${networkmanager-sstp}/lib/NetworkManager/VPN/nm-sstp-service.name"; } // optionalAttrs (cfg.appendNameservers != [] || cfg.insertNameservers != []) { @@ -461,7 +465,7 @@ in { restartTriggers = [ configFile overrideNameserversScript ]; # useful binaries for user-specified hooks - path = [ pkgs.iproute pkgs.utillinux pkgs.coreutils ]; + path = [ pkgs.iproute pkgs.util-linux pkgs.coreutils ]; aliases = [ "dbus-org.freedesktop.nm-dispatcher.service" ]; }; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nextdns.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nextdns.nix index a633bff62ec7..b070eeec894f 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nextdns.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nextdns.nix @@ -28,9 +28,9 @@ in { environment = { SERVICE_RUN_MODE = "1"; }; + startLimitIntervalSec = 5; + startLimitBurst = 10; serviceConfig = { - StartLimitInterval = 5; - StartLimitBurst = 10; ExecStart = "${pkgs.nextdns}/bin/nextdns run ${escapeShellArgs config.services.nextdns.arguments}"; RestartSec = 120; LimitMEMLOCK = "infinity"; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix index 3f2ce5bca4da..0012302db2e3 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nix-store-gcs-proxy.nix @@ -42,9 +42,9 @@ in description = "A HTTP nix store that proxies requests to Google Storage"; wantedBy = ["multi-user.target"]; + startLimitIntervalSec = 10; serviceConfig = { RestartSec = 5; - StartLimitInterval = 10; ExecStart = '' ${pkgs.nix-store-gcs-proxy}/bin/nix-store-gcs-proxy \ --bucket-name ${cfg.bucketName} \ diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nsd.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nsd.nix index 3ecbd06ee416..f33c350a257a 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/nsd.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/nsd.nix @@ -916,14 +916,14 @@ in after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; + startLimitBurst = 4; + startLimitIntervalSec = 5 * 60; # 5 mins serviceConfig = { ExecStart = "${nsdPkg}/sbin/nsd -d -c ${nsdEnv}/nsd.conf"; StandardError = "null"; PIDFile = pidFile; Restart = "always"; RestartSec = "4s"; - StartLimitBurst = 4; - StartLimitInterval = "5min"; }; preStart = '' diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix index 78de50583f34..e6fa48daf46c 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/ntp/chrony.nix @@ -6,6 +6,7 @@ let cfg = config.services.chrony; stateDir = "/var/lib/chrony"; + driftFile = "${stateDir}/chrony.drift"; keyFile = "${stateDir}/chrony.keys"; configFile = pkgs.writeText "chrony.conf" '' @@ -16,7 +17,7 @@ let "initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.servers}" } - driftfile ${stateDir}/chrony.drift + driftfile ${driftFile} keyfile ${keyFile} ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"} @@ -95,6 +96,7 @@ in systemd.tmpfiles.rules = [ "d ${stateDir} 0755 chrony chrony - -" + "f ${driftFile} 0640 chrony chrony -" "f ${keyFile} 0640 chrony chrony -" ]; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/pdns-recursor.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/pdns-recursor.nix index 6ff181377fcc..a326eccfd65d 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/pdns-recursor.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/pdns-recursor.nix @@ -3,9 +3,6 @@ with lib; let - dataDir = "/var/lib/pdns-recursor"; - username = "pdns-recursor"; - cfg = config.services.pdns-recursor; oneOrMore = type: with types; either type (listOf type); @@ -21,7 +18,7 @@ let else if builtins.isList val then (concatMapStringsSep "," serialize val) else ""; - configFile = pkgs.writeText "recursor.conf" + configDir = pkgs.writeTextDir "recursor.conf" (concatStringsSep "\n" (flip mapAttrsToList cfg.settings (name: val: "${name}=${serialize val}"))); @@ -173,45 +170,30 @@ in { serve-rfc1918 = cfg.serveRFC1918; lua-config-file = pkgs.writeText "recursor.lua" cfg.luaConfig; + daemon = false; + write-pid = false; log-timestamp = false; disable-syslog = true; }; - users.users.${username} = { - home = dataDir; - createHome = true; - uid = config.ids.uids.pdns-recursor; - description = "PowerDNS Recursor daemon user"; - }; + systemd.packages = [ pkgs.pdns-recursor ]; systemd.services.pdns-recursor = { - unitConfig.Documentation = "man:pdns_recursor(1) man:rec_control(1)"; - description = "PowerDNS recursive server"; wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; serviceConfig = { - User = username; - Restart ="on-failure"; - RestartSec = "5"; - PrivateTmp = true; - PrivateDevices = true; - AmbientCapabilities = "cap_net_bind_service"; - ExecStart = ''${pkgs.pdns-recursor}/bin/pdns_recursor \ - --config-dir=${dataDir} \ - --socket-dir=${dataDir} - ''; + ExecStart = [ "" "${pkgs.pdns-recursor}/bin/pdns_recursor --config-dir=${configDir}" ]; }; + }; - preStart = '' - # Link configuration file into recursor home directory - configPath=${dataDir}/recursor.conf - if [ "$(realpath $configPath)" != "${configFile}" ]; then - rm -f $configPath - ln -s ${configFile} $configPath - fi - ''; + users.users.pdns-recursor = { + isSystemUser = true; + group = "pdns-recursor"; + description = "PowerDNS Recursor daemon user"; }; + + users.groups.pdns-recursor = {}; + }; imports = [ diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/powerdns.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/powerdns.nix index ba05e15389f6..8cae61b83543 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/powerdns.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/powerdns.nix @@ -8,42 +8,40 @@ let in { options = { services.powerdns = { - enable = mkEnableOption "Powerdns domain name server"; + enable = mkEnableOption "PowerDNS domain name server"; extraConfig = mkOption { type = types.lines; default = "launch=bind"; description = '' - Extra lines to be added verbatim to pdns.conf. - Powerdns will chroot to /var/lib/powerdns. - So any file, powerdns is supposed to be read, - should be in /var/lib/powerdns and needs to specified - relative to the chroot. + PowerDNS configuration. Refer to + <link xlink:href="https://doc.powerdns.com/authoritative/settings.html"/> + for details on supported values. ''; }; }; }; - config = mkIf config.services.powerdns.enable { + config = mkIf cfg.enable { + + systemd.packages = [ pkgs.powerdns ]; + systemd.services.pdns = { - unitConfig.Documentation = "man:pdns_server(1) man:pdns_control(1)"; - description = "Powerdns name server"; wantedBy = [ "multi-user.target" ]; - after = ["network.target" "mysql.service" "postgresql.service" "openldap.service"]; + after = [ "network.target" "mysql.service" "postgresql.service" "openldap.service" ]; serviceConfig = { - Restart="on-failure"; - RestartSec="1"; - StartLimitInterval="0"; - PrivateDevices=true; - CapabilityBoundingSet="CAP_CHOWN CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT"; - NoNewPrivileges=true; - ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /var/lib/powerdns"; - ExecStart = "${pkgs.powerdns}/bin/pdns_server --setuid=nobody --setgid=nogroup --chroot=/var/lib/powerdns --socket-dir=/ --daemon=no --guardian=no --disable-syslog --write-pid=no --config-dir=${configDir}"; - ProtectSystem="full"; - ProtectHome=true; - RestrictAddressFamilies="AF_UNIX AF_INET AF_INET6"; + ExecStart = [ "" "${pkgs.powerdns}/bin/pdns_server --config-dir=${configDir} --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no" ]; }; }; + + users.users.pdns = { + isSystemUser = true; + group = "pdns"; + description = "PowerDNS"; + }; + + users.groups.pdns = {}; + }; } diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/prosody.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/prosody.nix index a6c1cb0f4797..e7a7aa700be6 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/prosody.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/prosody.nix @@ -261,7 +261,7 @@ let toLua = x: if builtins.isString x then ''"${x}"'' - else if builtins.isBool x then (if x == true then "true" else "false") + else if builtins.isBool x then boolToString x else if builtins.isInt x then toString x else if builtins.isList x then ''{ ${lib.concatStringsSep ", " (map (n: toLua n) x) } }'' else throw "Invalid Lua value"; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix index 5365b8b9b107..3cc77e4cb938 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/ssh/sshd.nix @@ -269,6 +269,7 @@ in kexAlgorithms = mkOption { type = types.listOf types.str; default = [ + "curve25519-sha256" "curve25519-sha256@libssh.org" "diffie-hellman-group-exchange-sha256" ]; @@ -279,7 +280,7 @@ in Defaults to recommended settings from both <link xlink:href="https://stribika.github.io/2015/01/04/secure-secure-shell.html" /> and - <link xlink:href="https://wiki.mozilla.org/Security/Guidelines/OpenSSH#Modern_.28OpenSSH_6.7.2B.29" /> + <link xlink:href="https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67" /> ''; }; @@ -300,7 +301,7 @@ in Defaults to recommended settings from both <link xlink:href="https://stribika.github.io/2015/01/04/secure-secure-shell.html" /> and - <link xlink:href="https://wiki.mozilla.org/Security/Guidelines/OpenSSH#Modern_.28OpenSSH_6.7.2B.29" /> + <link xlink:href="https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67" /> ''; }; @@ -321,7 +322,7 @@ in Defaults to recommended settings from both <link xlink:href="https://stribika.github.io/2015/01/04/secure-secure-shell.html" /> and - <link xlink:href="https://wiki.mozilla.org/Security/Guidelines/OpenSSH#Modern_.28OpenSSH_6.7.2B.29" /> + <link xlink:href="https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67" /> ''; }; @@ -476,7 +477,7 @@ in # https://github.com/NixOS/nixpkgs/pull/10155 # https://github.com/NixOS/nixpkgs/pull/41745 services.openssh.authorizedKeysFiles = - [ ".ssh/authorized_keys" ".ssh/authorized_keys2" "/etc/ssh/authorized_keys.d/%u" ]; + [ "%h/.ssh/authorized_keys" "%h/.ssh/authorized_keys2" "/etc/ssh/authorized_keys.d/%u" ]; services.openssh.extraConfig = mkOrder 0 '' diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/sslh.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/sslh.nix index 0921febba668..4c2740d20192 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/sslh.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/sslh.nix @@ -31,7 +31,7 @@ let { name: "openvpn"; host: "localhost"; port: "1194"; probe: "builtin"; }, { name: "xmpp"; host: "localhost"; port: "5222"; probe: "builtin"; }, { name: "http"; host: "localhost"; port: "80"; probe: "builtin"; }, - { name: "ssl"; host: "localhost"; port: "443"; probe: "builtin"; }, + { name: "tls"; host: "localhost"; port: "443"; probe: "builtin"; }, { name: "anyprot"; host: "localhost"; port: "443"; probe: "builtin"; } ); ''; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/module.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/module.nix index 0fec3ef00ad9..f67eedac2961 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/module.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/module.nix @@ -63,7 +63,7 @@ in { description = "strongSwan IPsec IKEv1/IKEv2 daemon using swanctl"; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; - path = with pkgs; [ kmod iproute iptables utillinux ]; + path = with pkgs; [ kmod iproute iptables util-linux ]; environment = { STRONGSWAN_CONF = pkgs.writeTextFile { name = "strongswan.conf"; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix index 808cb863a9cf..1d1e0bd1ca19 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix @@ -1173,20 +1173,20 @@ in { ppk = mkPrefixedAttrsOfParams { secret = mkOptionalStrParam '' - Value of the PPK. It may either be an ASCII string, a hex encoded string - if it has a <literal>0x</literal> prefix or a Base64 encoded string if - it has a <literal>0s</literal> prefix in its value. Should have at least - 256 bits of entropy for 128-bit security. + Value of the PPK. It may either be an ASCII string, a hex encoded string + if it has a <literal>0x</literal> prefix or a Base64 encoded string if + it has a <literal>0s</literal> prefix in its value. Should have at least + 256 bits of entropy for 128-bit security. ''; id = mkPrefixedAttrsOfParam (mkOptionalStrParam "") '' - PPK identity the PPK belongs to. Multiple unique identities may be - specified, each having an <literal>id</literal> prefix, if a secret is - shared between multiple peers. + PPK identity the PPK belongs to. Multiple unique identities may be + specified, each having an <literal>id</literal> prefix, if a secret is + shared between multiple peers. ''; } '' - Postquantum Preshared Key (PPK) section for a specific secret. Each PPK is - defined in a unique section having the <literal>ppk</literal> prefix. + Postquantum Preshared Key (PPK) section for a specific secret. Each PPK is + defined in a unique section having the <literal>ppk</literal> prefix. ''; private = mkPrefixedAttrsOfParams { diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan.nix index 13a1a897c5ed..f6170b813654 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/strongswan.nix @@ -152,7 +152,7 @@ in systemd.services.strongswan = { description = "strongSwan IPSec Service"; wantedBy = [ "multi-user.target" ]; - path = with pkgs; [ kmod iproute iptables utillinux ]; # XXX Linux + path = with pkgs; [ kmod iproute iptables util-linux ]; # XXX Linux after = [ "network-online.target" ]; environment = { STRONGSWAN_CONF = strongswanConf { inherit setup connections ca secretsFile managePlugins enabledPlugins; }; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/stunnel.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/stunnel.nix index ab51bba2f6ac..fe1616f411f0 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/stunnel.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/stunnel.nix @@ -16,8 +16,12 @@ let serverConfig = { options = { accept = mkOption { - type = types.int; - description = "On which port stunnel should listen for incoming TLS connections."; + type = types.either types.str types.int; + description = '' + On which [host:]port stunnel should listen for incoming TLS connections. + Note that unlike other softwares stunnel ipv6 address need no brackets, + so to listen on all IPv6 addresses on port 1234 one would use ':::1234'. + ''; }; connect = mkOption { @@ -129,7 +133,6 @@ in type = with types; attrsOf (submodule serverConfig); example = { fancyWebserver = { - enable = true; accept = 443; connect = 8080; cert = "/path/to/pem/file"; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/supybot.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/supybot.nix index dc9fb31ffd0b..7a62e04ec7c4 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/supybot.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/supybot.nix @@ -103,6 +103,8 @@ in rm -f '${cfg.stateDir}/supybot.cfg.bak' ''; + startLimitIntervalSec = 5 * 60; # 5 min + startLimitBurst = 1; serviceConfig = { ExecStart = "${pyEnv}/bin/supybot ${cfg.stateDir}/supybot.cfg"; PIDFile = "/run/supybot.pid"; @@ -110,8 +112,6 @@ in Group = "supybot"; UMask = "0007"; Restart = "on-abort"; - StartLimitInterval = "5m"; - StartLimitBurst = "1"; NoNewPrivileges = true; PrivateDevices = true; diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/tailscale.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/tailscale.nix index 4d6aeb75ebd1..1a1474595beb 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/tailscale.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/tailscale.nix @@ -14,36 +14,21 @@ in { default = 41641; description = "The port to listen on for tunnel traffic (0=autoselect)."; }; + + package = mkOption { + type = types.package; + default = pkgs.tailscale; + defaultText = "pkgs.tailscale"; + description = "The package to use for tailscale"; + }; }; config = mkIf cfg.enable { - systemd.services.tailscale = { - description = "Tailscale client daemon"; - - after = [ "network-pre.target" ]; - wants = [ "network-pre.target" ]; + environment.systemPackages = [ cfg.package ]; # for the CLI + systemd.packages = [ cfg.package ]; + systemd.services.tailscaled = { 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 = 750; - - CacheDirectory = "tailscale"; - CacheDirectoryMode = 750; - - Restart = "on-failure"; - }; + serviceConfig.Environment = "PORT=${toString cfg.port}"; }; }; } diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/unbound.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/unbound.nix index baed83591e1e..9a46fa3075fa 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/unbound.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/unbound.nix @@ -1,9 +1,7 @@ { config, lib, pkgs, ... }: with lib; - let - cfg = config.services.unbound; stateDir = "/var/lib/unbound"; @@ -17,12 +15,12 @@ let forward = optionalString (any isLocalAddress cfg.forwardAddresses) '' do-not-query-localhost: no - '' + - optionalString (cfg.forwardAddresses != []) '' + '' + + optionalString (cfg.forwardAddresses != []) '' forward-zone: name: . - '' + - concatMapStringsSep "\n" (x: " forward-addr: ${x}") cfg.forwardAddresses; + '' + + concatMapStringsSep "\n" (x: " forward-addr: ${x}") cfg.forwardAddresses; rootTrustAnchorFile = "${stateDir}/root.key"; @@ -31,19 +29,25 @@ let confFile = pkgs.writeText "unbound.conf" '' server: + ip-freebind: yes directory: "${stateDir}" username: unbound - chroot: "${stateDir}" + chroot: "" pidfile: "" + # when running under systemd there is no need to daemonize + do-daemonize: no ${interfaces} ${access} ${trustAnchor} + ${lib.optionalString (cfg.localControlSocketPath != null) '' + remote-control: + control-enable: yes + control-interface: ${cfg.localControlSocketPath} + ''} ${cfg.extraConfig} ${forward} ''; - in - { ###### interface @@ -55,8 +59,8 @@ in package = mkOption { type = types.package; - default = pkgs.unbound; - defaultText = "pkgs.unbound"; + default = pkgs.unbound-with-systemd; + defaultText = "pkgs.unbound-with-systemd"; description = "The unbound package to use"; }; @@ -69,11 +73,14 @@ in interfaces = mkOption { default = [ "127.0.0.1" ] ++ optional config.networking.enableIPv6 "::1"; type = types.listOf types.str; - description = "What addresses the server should listen on."; + description = '' + What addresses the server should listen on. This supports the interface syntax documented in + <citerefentry><refentrytitle>unbound.conf</refentrytitle><manvolnum>8</manvolnum></citerefentry>. + ''; }; forwardAddresses = mkOption { - default = [ ]; + default = []; type = types.listOf types.str; description = "What servers to forward queries to."; }; @@ -84,6 +91,28 @@ in description = "Use and update root trust anchor for DNSSEC validation."; }; + localControlSocketPath = mkOption { + default = null; + # FIXME: What is the proper type here so users can specify strings, + # paths and null? + # My guess would be `types.nullOr (types.either types.str types.path)` + # but I haven't verified yet. + type = types.nullOr types.str; + example = "/run/unbound/unbound.ctl"; + description = '' + When not set to <literal>null</literal> this option defines the path + at which the unbound remote control socket should be created at. The + socket will be owned by the unbound user (<literal>unbound</literal>) + and group will be <literal>nogroup</literal>. + + Users that should be permitted to access the socket must be in the + <literal>unbound</literal> group. + + If this option is <literal>null</literal> remote control will not be + configured at all. Unbounds default values apply. + ''; + }; + extraConfig = mkOption { default = ""; type = types.lines; @@ -106,43 +135,85 @@ in users.users.unbound = { description = "unbound daemon user"; isSystemUser = true; + group = lib.mkIf (cfg.localControlSocketPath != null) (lib.mkDefault "unbound"); + }; + + # We need a group so that we can give users access to the configured + # control socket. Unbound allows access to the socket only to the unbound + # user and the primary group. + users.groups = lib.mkIf (cfg.localControlSocketPath != null) { + unbound = {}; }; networking.resolvconf.useLocalResolver = mkDefault true; + + environment.etc."unbound/unbound.conf".source = confFile; + systemd.services.unbound = { description = "Unbound recursive Domain Name Server"; after = [ "network.target" ]; before = [ "nss-lookup.target" ]; - wants = [ "nss-lookup.target" ]; - wantedBy = [ "multi-user.target" ]; - - preStart = '' - mkdir -m 0755 -p ${stateDir}/dev/ - cp ${confFile} ${stateDir}/unbound.conf - ${optionalString cfg.enableRootTrustAnchor '' - ${cfg.package}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!" - chown unbound ${stateDir} ${rootTrustAnchorFile} - ''} - touch ${stateDir}/dev/random - ${pkgs.utillinux}/bin/mount --bind -n /dev/urandom ${stateDir}/dev/random + wantedBy = [ "multi-user.target" "nss-lookup.target" ]; + + preStart = lib.mkIf cfg.enableRootTrustAnchor '' + ${cfg.package}/bin/unbound-anchor -a ${rootTrustAnchorFile} || echo "Root anchor updated!" ''; - serviceConfig = { - ExecStart = "${cfg.package}/bin/unbound -d -c ${stateDir}/unbound.conf"; - ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random"; + restartTriggers = [ + confFile + ]; - ProtectSystem = true; - ProtectHome = true; + serviceConfig = { + ExecStart = "${cfg.package}/bin/unbound -p -d -c /etc/unbound/unbound.conf"; + ExecReload = "+/run/current-system/sw/bin/kill -HUP $MAINPID"; + + NotifyAccess = "main"; + Type = "notify"; + + # FIXME: Which of these do we actualy need, can we drop the chroot flag? + AmbientCapabilities = [ + "CAP_NET_BIND_SERVICE" + "CAP_NET_RAW" + "CAP_SETGID" + "CAP_SETUID" + "CAP_SYS_CHROOT" + "CAP_SYS_RESOURCE" + ]; + + User = "unbound"; + Group = lib.mkIf (cfg.localControlSocketPath != null) (lib.mkDefault "unbound"); + + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; PrivateDevices = true; - Restart = "always"; - RestartSec = "5s"; + PrivateTmp = true; + ProtectHome = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectSystem = "strict"; + RuntimeDirectory = "unbound"; + ConfigurationDirectory = "unbound"; + StateDirectory = "unbound"; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "~@clock" + "@cpu-emulation" + "@debug" + "@keyring" + "@module" + "mount" + "@obsolete" + "@resources" + ]; + RestrictNamespaces = true; + LockPersonality = true; + RestrictSUIDSGID = true; }; }; - # If networkmanager is enabled, ask it to interface with unbound. networking.networkmanager.dns = "unbound"; - }; - } diff --git a/infra/libkookie/nixpkgs/nixos/modules/services/networking/wasabibackend.nix b/infra/libkookie/nixpkgs/nixos/modules/services/networking/wasabibackend.nix index 6eacffe709b0..8482823e197f 100644 --- a/infra/libkookie/nixpkgs/nixos/modules/services/networking/wasabibackend.nix +++ b/infra/libkookie/nixpkgs/nixos/modules/services/networking/wasabibackend.nix @@ -21,7 +21,7 @@ let RegTestBitcoinCoreRpcEndPoint = "${cfg.rpc.ip}:${toString cfg.rpc.port}"; }; - configFile = pkgs.writeText "wasabibackend.conf" (builtins.toJSON confOptions); + configFile = pkgs.writeText "wasabibackend.conf" (builtins.toJSON confOptions); in { |