diff options
Diffstat (limited to 'nixos/modules/services/networking')
-rw-r--r-- | nixos/modules/services/networking/avahi-daemon.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/networking/ddclient.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/networking/dnsmasq.md | 68 | ||||
-rw-r--r-- | nixos/modules/services/networking/dnsmasq.nix | 2 | ||||
-rw-r--r-- | nixos/modules/services/networking/firewall-iptables.nix | 3 | ||||
-rw-r--r-- | nixos/modules/services/networking/gns3-server.md | 31 | ||||
-rw-r--r-- | nixos/modules/services/networking/gns3-server.nix | 263 | ||||
-rw-r--r-- | nixos/modules/services/networking/harmonia.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/networking/kea.nix | 22 | ||||
-rw-r--r-- | nixos/modules/services/networking/ssh/sshd.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/networking/tailscale.nix | 4 | ||||
-rw-r--r-- | nixos/modules/services/networking/yggdrasil.nix | 28 |
12 files changed, 403 insertions, 28 deletions
diff --git a/nixos/modules/services/networking/avahi-daemon.nix b/nixos/modules/services/networking/avahi-daemon.nix index 89b30996e8faa..08fc092e230c0 100644 --- a/nixos/modules/services/networking/avahi-daemon.nix +++ b/nixos/modules/services/networking/avahi-daemon.nix @@ -95,7 +95,6 @@ in ipv6 = mkOption { type = types.bool; default = false; - defaultText = literalExpression "config.networking.enableIPv6"; description = lib.mdDoc "Whether to use IPv6."; }; diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index a67f0c5de9ba3..18f205b8d99ef 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -217,7 +217,7 @@ with lib; inherit RuntimeDirectory; inherit StateDirectory; Type = "oneshot"; - ExecStartPre = "!${pkgs.writeShellScript "ddclient-prestart" preStart}"; + ExecStartPre = [ "!${pkgs.writeShellScript "ddclient-prestart" preStart}" ]; ExecStart = "${lib.getExe cfg.package} -file /run/${RuntimeDirectory}/ddclient.conf"; }; }; diff --git a/nixos/modules/services/networking/dnsmasq.md b/nixos/modules/services/networking/dnsmasq.md new file mode 100644 index 0000000000000..6fc9178b1c0d5 --- /dev/null +++ b/nixos/modules/services/networking/dnsmasq.md @@ -0,0 +1,68 @@ +# Dnsmasq {#module-services-networking-dnsmasq} + +Dnsmasq is an integrated DNS, DHCP and TFTP server for small networks. + +## Configuration {#module-services-networking-dnsmasq-configuration} + +### An authoritative DHCP and DNS server on a home network {#module-services-networking-dnsmasq-configuration-home} + +On a home network, you can use Dnsmasq as a DHCP and DNS server. New devices on +your network will be configured by Dnsmasq, and instructed to use it as the DNS +server by default. This allows you to rely on your own server to perform DNS +queries and caching, with DNSSEC enabled. + +The following example assumes that + +- you have disabled your router's integrated DHCP server, if it has one +- your router's address is set in [](#opt-networking.defaultGateway.address) +- your system's Ethernet interface is `eth0` +- you have configured the address(es) to forward DNS queries in [](#opt-networking.nameservers) + +```nix +{ + services.dnsmasq = { + enable = true; + settings = { + interface = "eth0"; + bind-interfaces = true; # Only bind to the specified interface + dhcp-authoritative = true; # Should be set when dnsmasq is definitely the only DHCP server on a network + + server = config.networking.nameservers; # Upstream dns servers to which requests should be forwarded + + dhcp-host = [ + # Give the current system a fixed address of 192.168.0.254 + "dc:a6:32:0b:ea:b9,192.168.0.254,${config.networking.hostName},infinite" + ]; + + dhcp-option = [ + # Address of the gateway, i.e. your router + "option:router,${config.networking.defaultGateway.address}" + ]; + + dhcp-range = [ + # Range of IPv4 addresses to give out + # <range start>,<range end>,<lease time> + "192.168.0.10,192.168.0.253,24h" + # Enable stateless IPv6 allocation + "::f,::ff,constructor:eth0,ra-stateless" + ]; + + dhcp-rapid-commit = true; # Faster DHCP negotiation for IPv6 + local-service = true; # Accept DNS queries only from hosts whose address is on a local subnet + log-queries = true; # Log results of all DNS queries + bogus-priv = true; # Don't forward requests for the local address ranges (192.168.x.x etc) to upstream nameservers + domain-needed = true; # Don't forward requests without dots or domain parts to upstream nameservers + + dnssec = true; # Enable DNSSEC + # DNSSEC trust anchor. Source: https://data.iana.org/root-anchors/root-anchors.xml + trust-anchor = ".,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"; + }; + }; +} +``` + +## References {#module-services-networking-dnsmasq-references} + +- Upstream website: <https://dnsmasq.org> +- Manpage: <https://dnsmasq.org/docs/dnsmasq-man.html> +- FAQ: <https://dnsmasq.org/docs/FAQ> diff --git a/nixos/modules/services/networking/dnsmasq.nix b/nixos/modules/services/networking/dnsmasq.nix index 8d1ca36c38ed2..d01a1b6707a53 100644 --- a/nixos/modules/services/networking/dnsmasq.nix +++ b/nixos/modules/services/networking/dnsmasq.nix @@ -181,4 +181,6 @@ in restartTriggers = [ config.environment.etc.hosts.source ]; }; }; + + meta.doc = ./dnsmasq.md; } diff --git a/nixos/modules/services/networking/firewall-iptables.nix b/nixos/modules/services/networking/firewall-iptables.nix index e900868387203..2d11517700086 100644 --- a/nixos/modules/services/networking/firewall-iptables.nix +++ b/nixos/modules/services/networking/firewall-iptables.nix @@ -308,8 +308,9 @@ in description = "Firewall"; wantedBy = [ "sysinit.target" ]; wants = [ "network-pre.target" ]; - before = [ "network-pre.target" ]; after = [ "systemd-modules-load.service" ]; + before = [ "network-pre.target" "shutdown.target" ]; + conflicts = [ "shutdown.target" ]; path = [ cfg.package ] ++ cfg.extraPackages; diff --git a/nixos/modules/services/networking/gns3-server.md b/nixos/modules/services/networking/gns3-server.md new file mode 100644 index 0000000000000..9320d914fbd3a --- /dev/null +++ b/nixos/modules/services/networking/gns3-server.md @@ -0,0 +1,31 @@ +# GNS3 Server {#module-services-gns3-server} + +[GNS3](https://www.gns3.com/), a network software emulator. + +## Basic Usage {#module-services-gns3-server-basic-usage} + +A minimal configuration looks like this: + +```nix +{ + services.gns3-server = { + enable = true; + + auth = { + enable = true; + user = "gns3"; + passwordFile = "/var/lib/secrets/gns3_password"; + }; + + ssl = { + enable = true; + certFile = "/var/lib/gns3/ssl/cert.pem"; + keyFile = "/var/lib/gns3/ssl/key.pem"; + }; + + dynamips.enable = true; + ubridge.enable = true; + vpcs.enable = true; + }; +} +``` diff --git a/nixos/modules/services/networking/gns3-server.nix b/nixos/modules/services/networking/gns3-server.nix new file mode 100644 index 0000000000000..25583765de672 --- /dev/null +++ b/nixos/modules/services/networking/gns3-server.nix @@ -0,0 +1,263 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.gns3-server; + + settingsFormat = pkgs.formats.ini { }; + configFile = settingsFormat.generate "gns3-server.conf" cfg.settings; + +in { + meta = { + doc = ./gns3-server.md; + maintainers = [ lib.maintainers.anthonyroussel ]; + }; + + options = { + services.gns3-server = { + enable = lib.mkEnableOption (lib.mdDoc "GNS3 Server daemon"); + + package = lib.mkPackageOptionMD pkgs "gns3-server" { }; + + auth = { + enable = lib.mkEnableOption (lib.mdDoc "password based HTTP authentication to access the GNS3 Server"); + + user = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "gns3"; + description = lib.mdDoc ''Username used to access the GNS3 Server.''; + }; + + passwordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/secrets/gns3-server-password"; + description = lib.mdDoc '' + A file containing the password to access the GNS3 Server. + + ::: {.warning} + This should be a string, not a nix path, since nix paths + are copied into the world-readable nix store. + ::: + ''; + }; + }; + + settings = lib.mkOption { + type = lib.types.submodule { freeformType = settingsFormat.type; }; + default = {}; + example = { host = "127.0.0.1"; port = 3080; }; + description = lib.mdDoc '' + The global options in `config` file in ini format. + + Refer to <https://docs.gns3.com/docs/using-gns3/administration/gns3-server-configuration-file/> + for all available options. + ''; + }; + + log = { + file = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = "/var/log/gns3/server.log"; + description = lib.mdDoc ''Path of the file GNS3 Server should log to.''; + }; + + debug = lib.mkEnableOption (lib.mdDoc "debug logging"); + }; + + ssl = { + enable = lib.mkEnableOption (lib.mdDoc "SSL encryption"); + + certFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/var/lib/gns3/ssl/server.pem"; + description = lib.mdDoc '' + Path to the SSL certificate file. This certificate will + be offered to, and may be verified by, clients. + ''; + }; + + keyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/var/lib/gns3/ssl/server.key"; + description = lib.mdDoc "Private key file for the certificate."; + }; + }; + + dynamips = { + enable = lib.mkEnableOption (lib.mdDoc ''Whether to enable Dynamips support.''); + package = lib.mkPackageOptionMD pkgs "dynamips" { }; + }; + + ubridge = { + enable = lib.mkEnableOption (lib.mdDoc ''Whether to enable uBridge support.''); + package = lib.mkPackageOptionMD pkgs "ubridge" { }; + }; + + vpcs = { + enable = lib.mkEnableOption (lib.mdDoc ''Whether to enable VPCS support.''); + package = lib.mkPackageOptionMD pkgs "vpcs" { }; + }; + }; + }; + + config = let + flags = { + enableDocker = config.virtualisation.docker.enable; + enableLibvirtd = config.virtualisation.libvirtd.enable; + }; + + in lib.mkIf cfg.enable { + assertions = [ + { + assertion = cfg.ssl.enable -> cfg.ssl.certFile != null; + message = "Please provide a certificate to use for SSL encryption."; + } + { + assertion = cfg.ssl.enable -> cfg.ssl.keyFile != null; + message = "Please provide a private key to use for SSL encryption."; + } + { + assertion = cfg.auth.enable -> cfg.auth.user != null; + message = "Please provide a username to use for HTTP authentication."; + } + { + assertion = cfg.auth.enable -> cfg.auth.passwordFile != null; + message = "Please provide a password file to use for HTTP authentication."; + } + ]; + + users.groups.ubridge = lib.mkIf cfg.ubridge.enable { }; + + security.wrappers.ubridge = lib.mkIf cfg.ubridge.enable { + capabilities = "cap_net_raw,cap_net_admin=eip"; + group = "ubridge"; + owner = "root"; + permissions = "u=rwx,g=rx,o=r"; + source = lib.getExe cfg.ubridge.package; + }; + + services.gns3-server.settings = lib.mkMerge [ + { + Server = { + appliances_path = lib.mkDefault "/var/lib/gns3/appliances"; + configs_path = lib.mkDefault "/var/lib/gns3/configs"; + images_path = lib.mkDefault "/var/lib/gns3/images"; + projects_path = lib.mkDefault "/var/lib/gns3/projects"; + symbols_path = lib.mkDefault "/var/lib/gns3/symbols"; + }; + } + (lib.mkIf (cfg.ubridge.enable) { + Server.ubridge_path = lib.mkDefault (lib.getExe cfg.ubridge.package); + }) + (lib.mkIf (cfg.auth.enable) { + Server = { + auth = lib.mkDefault (lib.boolToString cfg.auth.enable); + user = lib.mkDefault cfg.auth.user; + password = lib.mkDefault "@AUTH_PASSWORD@"; + }; + }) + (lib.mkIf (cfg.vpcs.enable) { + VPCS.vpcs_path = lib.mkDefault (lib.getExe cfg.vpcs.package); + }) + (lib.mkIf (cfg.dynamips.enable) { + Dynamips.dynamips_path = lib.mkDefault (lib.getExe cfg.dynamips.package); + }) + ]; + + systemd.services.gns3-server = let + commandArgs = lib.cli.toGNUCommandLineShell { } { + config = "/etc/gns3/gns3_server.conf"; + pid = "/run/gns3/server.pid"; + log = cfg.log.file; + ssl = cfg.ssl.enable; + # These are implicitly not set if `null` + certfile = cfg.ssl.certFile; + certkey = cfg.ssl.keyFile; + }; + in + { + description = "GNS3 Server"; + + after = [ "network.target" "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + + # configFile cannot be stored in RuntimeDirectory, because GNS3 + # uses the `--config` base path to stores supplementary configuration files at runtime. + # + preStart = '' + install -m660 ${configFile} /etc/gns3/gns3_server.conf + + ${lib.optionalString cfg.auth.enable '' + ${pkgs.replace-secret}/bin/replace-secret \ + '@AUTH_PASSWORD@' \ + "''${CREDENTIALS_DIRECTORY}/AUTH_PASSWORD" \ + /etc/gns3/gns3_server.conf + ''} + ''; + + path = lib.optional flags.enableLibvirtd pkgs.qemu; + + reloadTriggers = [ configFile ]; + + serviceConfig = { + ConfigurationDirectory = "gns3"; + ConfigurationDirectoryMode = "0750"; + DynamicUser = true; + Environment = "HOME=%S/gns3"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + ExecStart = "${lib.getExe cfg.package} ${commandArgs}"; + Group = "gns3"; + LimitNOFILE = 16384; + LoadCredential = lib.mkIf cfg.auth.enable [ "AUTH_PASSWORD:${cfg.auth.passwordFile}" ]; + LogsDirectory = "gns3"; + LogsDirectoryMode = "0750"; + PIDFile = "/run/gns3/server.pid"; + Restart = "on-failure"; + RestartSec = 5; + RuntimeDirectory = "gns3"; + StateDirectory = "gns3"; + StateDirectoryMode = "0750"; + SupplementaryGroups = lib.optional flags.enableDocker "docker" + ++ lib.optional flags.enableLibvirtd "libvirtd" + ++ lib.optional cfg.ubridge.enable "ubridge"; + User = "gns3"; + WorkingDirectory = "%S/gns3"; + + # Hardening + DeviceAllow = lib.optional flags.enableLibvirtd "/dev/kvm"; + DevicePolicy = "closed"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateTmp = true; + PrivateUsers = true; + # Don't restrict ProcSubset because python3Packages.psutil requires read access to /proc/stat + # ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_NETLINK" + "AF_UNIX" + "AF_PACKET" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + UMask = "0077"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/harmonia.nix b/nixos/modules/services/networking/harmonia.nix index d0f4a8a6e6333..b384ac9261376 100644 --- a/nixos/modules/services/networking/harmonia.nix +++ b/nixos/modules/services/networking/harmonia.nix @@ -55,6 +55,7 @@ in ExecStart = lib.getExe cfg.package; User = "harmonia"; Group = "harmonia"; + Restart = "on-failure"; PrivateUsers = true; DeviceAllow = [ "" ]; UMask = "0066"; diff --git a/nixos/modules/services/networking/kea.nix b/nixos/modules/services/networking/kea.nix index 2f922a026a3a9..5ca705976c413 100644 --- a/nixos/modules/services/networking/kea.nix +++ b/nixos/modules/services/networking/kea.nix @@ -254,6 +254,8 @@ in DynamicUser = true; User = "kea"; ConfigurationDirectory = "kea"; + RuntimeDirectory = "kea"; + RuntimeDirectoryPreserve = true; StateDirectory = "kea"; UMask = "0077"; }; @@ -288,8 +290,8 @@ in ]; environment = { - KEA_PIDFILE_DIR = "/run/kea-ctrl-agent"; - KEA_LOCKFILE_DIR = "/run/kea-ctrl-agent"; + KEA_PIDFILE_DIR = "/run/kea"; + KEA_LOCKFILE_DIR = "/run/kea"; }; restartTriggers = [ @@ -300,7 +302,6 @@ in ExecStart = "${package}/bin/kea-ctrl-agent -c /etc/kea/ctrl-agent.conf ${lib.escapeShellArgs cfg.ctrl-agent.extraArgs}"; KillMode = "process"; Restart = "on-failure"; - RuntimeDirectory = "kea-ctrl-agent"; } // commonServiceConfig; }; }) @@ -329,8 +330,8 @@ in ]; environment = { - KEA_PIDFILE_DIR = "/run/kea-dhcp4"; - KEA_LOCKFILE_DIR = "/run/kea-dhcp4"; + KEA_PIDFILE_DIR = "/run/kea"; + KEA_LOCKFILE_DIR = "/run/kea"; }; restartTriggers = [ @@ -348,7 +349,6 @@ in "CAP_NET_BIND_SERVICE" "CAP_NET_RAW" ]; - RuntimeDirectory = "kea-dhcp4"; } // commonServiceConfig; }; }) @@ -377,8 +377,8 @@ in ]; environment = { - KEA_PIDFILE_DIR = "/run/kea-dhcp6"; - KEA_LOCKFILE_DIR = "/run/kea-dhcp6"; + KEA_PIDFILE_DIR = "/run/kea"; + KEA_LOCKFILE_DIR = "/run/kea"; }; restartTriggers = [ @@ -394,7 +394,6 @@ in CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; - RuntimeDirectory = "kea-dhcp6"; } // commonServiceConfig; }; }) @@ -423,8 +422,8 @@ in ]; environment = { - KEA_PIDFILE_DIR = "/run/kea-dhcp-ddns"; - KEA_LOCKFILE_DIR = "/run/kea-dhcp-ddns"; + KEA_PIDFILE_DIR = "/run/kea"; + KEA_LOCKFILE_DIR = "/run/kea"; }; restartTriggers = [ @@ -439,7 +438,6 @@ in CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; - RuntimeDirectory = "kea-dhcp-ddns"; } // commonServiceConfig; }; }) diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index f54ce59174387..39793922ab516 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -674,7 +674,11 @@ in (lport: "sshd -G -T -C lport=${toString lport} -f ${sshconf} > /dev/null") cfg.ports} ${concatMapStringsSep "\n" - (la: "sshd -G -T -C ${escapeShellArg "laddr=${la.addr},lport=${toString la.port}"} -f ${sshconf} > /dev/null") + (la: + concatMapStringsSep "\n" + (port: "sshd -G -T -C ${escapeShellArg "laddr=${la.addr},lport=${toString port}"} -f ${sshconf} > /dev/null") + (if la.port != null then [ la.port ] else cfg.ports) + ) cfg.listenAddresses} touch $out '') diff --git a/nixos/modules/services/networking/tailscale.nix b/nixos/modules/services/networking/tailscale.nix index 3822df81063d9..1070e4e252967 100644 --- a/nixos/modules/services/networking/tailscale.nix +++ b/nixos/modules/services/networking/tailscale.nix @@ -100,8 +100,8 @@ in { }; systemd.services.tailscaled-autoconnect = mkIf (cfg.authKeyFile != null) { - after = ["tailscale.service"]; - wants = ["tailscale.service"]; + after = ["tailscaled.service"]; + wants = ["tailscaled.service"]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; diff --git a/nixos/modules/services/networking/yggdrasil.nix b/nixos/modules/services/networking/yggdrasil.nix index 514753687d699..9173e7eb3457b 100644 --- a/nixos/modules/services/networking/yggdrasil.nix +++ b/nixos/modules/services/networking/yggdrasil.nix @@ -137,16 +137,24 @@ in message = "networking.enableIPv6 must be true for yggdrasil to work"; }]; - system.activationScripts.yggdrasil = mkIf cfg.persistentKeys '' - if [ ! -e ${keysPath} ] - then - mkdir --mode=700 -p ${builtins.dirOf keysPath} - ${binYggdrasil} -genconf -json \ - | ${pkgs.jq}/bin/jq \ - 'to_entries|map(select(.key|endswith("Key")))|from_entries' \ - > ${keysPath} - fi - ''; + # This needs to be a separate service. The yggdrasil service fails if + # this is put into its preStart. + systemd.services.yggdrasil-persistent-keys = lib.mkIf cfg.persistentKeys { + wantedBy = [ "multi-user.target" ]; + before = [ "yggdrasil.service" ]; + serviceConfig.Type = "oneshot"; + serviceConfig.RemainAfterExit = true; + script = '' + if [ ! -e ${keysPath} ] + then + mkdir --mode=700 -p ${builtins.dirOf keysPath} + ${binYggdrasil} -genconf -json \ + | ${pkgs.jq}/bin/jq \ + 'to_entries|map(select(.key|endswith("Key")))|from_entries' \ + > ${keysPath} + fi + ''; + }; systemd.services.yggdrasil = { description = "Yggdrasil Network Service"; |