From 90581c977ff1dc2442a79fd9d173ae1e307f6e53 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Wed, 28 Dec 2022 19:48:59 -0800 Subject: [PATCH] nixos/nebula: don't run as root; support relays --- .../from_md/release-notes/rl-2305.section.xml | 22 +++++++++ .../manual/release-notes/rl-2305.section.md | 4 ++ nixos/modules/services/networking/nebula.nix | 49 ++++++++++++------- nixos/tests/nebula.nix | 17 ++++--- 4 files changed, 66 insertions(+), 26 deletions(-) diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml index 2fd0d01abefa..4ab4f6aab5d8 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml @@ -412,6 +412,16 @@ attribute name. + + + Nebula now runs as a system user and group created for each + nebula network, using the CAP_NET_ADMIN + ambient capability on launch rather than starting as root. + Ensure that any files each Nebula instance needs to access are + owned by the correct user and group, by default + nebula-${networkName}. + + In mastodon it is now necessary to specify @@ -794,6 +804,18 @@ system.stateVersion. + + + Nebula now supports the + services.nebula.networks.<name>.isRelay + and + services.nebula.networks.<name>.relays + configuration options for setting up or allowing traffic + relaying. See the + announcement + for more details about relays. + + hip has been separated into diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index 01e2ff01f290..e0c1671d5aca 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -99,6 +99,8 @@ In addition to numerous new and upgraded packages, this release has the followin - The [services.wordpress.sites.<name>.plugins](#opt-services.wordpress.sites._name_.plugins) and [services.wordpress.sites.<name>.themes](#opt-services.wordpress.sites._name_.themes) options have been converted from sets to attribute sets to allow for consumers to specify explicit install paths via attribute name. +- Nebula now runs as a system user and group created for each nebula network, using the `CAP_NET_ADMIN` ambient capability on launch rather than starting as root. Ensure that any files each Nebula instance needs to access are owned by the correct user and group, by default `nebula-${networkName}`. + - In `mastodon` it is now necessary to specify location of file with `PostgreSQL` database password. In `services.mastodon.database.passwordFile` parameter default value `/var/lib/mastodon/secrets/db-password` has been changed to `null`. - The `--target-host` and `--build-host` options of `nixos-rebuild` no longer treat the `localhost` value specially – to build on/deploy to local machine, omit the relevant flag. @@ -197,6 +199,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [Garage](https://garagehq.deuxfleurs.fr/) version is based on [system.stateVersion](options.html#opt-system.stateVersion), existing installations will keep using version 0.7. New installations will use version 0.8. In order to upgrade a Garage cluster, please follow [upstream instructions](https://garagehq.deuxfleurs.fr/documentation/cookbook/upgrading/) and force [services.garage.package](options.html#opt-services.garage.package) or upgrade accordingly [system.stateVersion](options.html#opt-system.stateVersion). +- Nebula now supports the `services.nebula.networks..isRelay` and `services.nebula.networks..relays` configuration options for setting up or allowing traffic relaying. See the [announcement](https://www.defined.net/blog/announcing-relay-support-in-nebula/) for more details about relays. + - `hip` has been separated into `hip`, `hip-common` and `hipcc`. - `services.nginx.recommendedProxySettings` now removes the `Connection` header preventing clients from closing backend connections. diff --git a/nixos/modules/services/networking/nebula.nix b/nixos/modules/services/networking/nebula.nix index 2bedafc5d9fe..c5d395b3406e 100644 --- a/nixos/modules/services/networking/nebula.nix +++ b/nixos/modules/services/networking/nebula.nix @@ -68,6 +68,12 @@ in description = lib.mdDoc "Whether this node is a lighthouse."; }; + isRelay = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Whether this node is a relay."; + }; + lighthouses = mkOption { type = types.listOf types.str; default = []; @@ -78,6 +84,15 @@ in example = [ "192.168.100.1" ]; }; + relays = mkOption { + type = types.listOf types.str; + default = []; + description = lib.mdDoc '' + List of IPs of relays that this node should allow traffic from. + ''; + example = [ "192.168.100.1" ]; + }; + listen.host = mkOption { type = types.str; default = "0.0.0.0"; @@ -157,6 +172,10 @@ in am_lighthouse = netCfg.isLighthouse; hosts = netCfg.lighthouses; }; + relay = { + am_relay = netCfg.isRelay; + relays = netCfg.relays; + }; listen = { host = netCfg.listen.host; port = netCfg.listen.port; @@ -173,25 +192,22 @@ in configFile = format.generate "nebula-config-${netName}.yml" settings; in { - # Create systemd service for Nebula. + # Create the systemd service for Nebula. "nebula@${netName}" = { description = "Nebula VPN service for ${netName}"; wants = [ "basic.target" ]; after = [ "basic.target" "network.target" ]; before = [ "sshd.service" ]; wantedBy = [ "multi-user.target" ]; - serviceConfig = mkMerge [ - { - Type = "simple"; - Restart = "always"; - ExecStart = "${netCfg.package}/bin/nebula -config ${configFile}"; - } - # The service needs to launch as root to access the tun device, if it's enabled. - (mkIf netCfg.tun.disable { - User = networkId; - Group = networkId; - }) - ]; + serviceConfig = { + Type = "simple"; + Restart = "always"; + ExecStart = "${netCfg.package}/bin/nebula -config ${configFile}"; + CapabilityBoundingSet = "CAP_NET_ADMIN"; + AmbientCapabilities = "CAP_NET_ADMIN"; + User = networkId; + Group = networkId; + }; unitConfig.StartLimitIntervalSec = 0; # ensure Restart=always is always honoured (networks can go down for arbitrarily long) }; }) enabledNetworks); @@ -202,7 +218,7 @@ in # Create the service users and groups. users.users = mkMerge (mapAttrsToList (netName: netCfg: - mkIf netCfg.tun.disable { + { ${nameToId netName} = { group = nameToId netName; description = "Nebula service user for network ${netName}"; @@ -210,9 +226,6 @@ in }; }) enabledNetworks); - users.groups = mkMerge (mapAttrsToList (netName: netCfg: - mkIf netCfg.tun.disable { - ${nameToId netName} = {}; - }) enabledNetworks); + users.groups = mkMerge (mapAttrsToList (netName: netCfg: { ${nameToId netName} = {}; }) enabledNetworks); }; } diff --git a/nixos/tests/nebula.nix b/nixos/tests/nebula.nix index 372cfebdf801..1617430b3890 100644 --- a/nixos/tests/nebula.nix +++ b/nixos/tests/nebula.nix @@ -123,12 +123,13 @@ in testScript = let setUpPrivateKey = name: '' - ${name}.succeed( - "mkdir -p /root/.ssh", - "chown 700 /root/.ssh", - "cat '${snakeOilPrivateKey}' > /root/.ssh/id_snakeoil", - "chown 600 /root/.ssh/id_snakeoil", - ) + ${name}.start() + ${name}.succeed( + "mkdir -p /root/.ssh", + "chown 700 /root/.ssh", + "cat '${snakeOilPrivateKey}' > /root/.ssh/id_snakeoil", + "chown 600 /root/.ssh/id_snakeoil", + ) ''; # From what I can tell, StrictHostKeyChecking=no is necessary for ssh to work between machines. @@ -154,18 +155,18 @@ in ${name}.succeed( "scp ${sshOpts} 192.168.1.1:/tmp/${name}.crt /etc/nebula/${name}.crt", "scp ${sshOpts} 192.168.1.1:/etc/nebula/ca.crt /etc/nebula/ca.crt", + '(id nebula-smoke >/dev/null && chown -R nebula-smoke:nebula-smoke /etc/nebula) || true' ) ''; in '' - start_all() - # Create the certificate and sign the lighthouse's keys. ${setUpPrivateKey "lighthouse"} lighthouse.succeed( "mkdir -p /etc/nebula", 'nebula-cert ca -name "Smoke Test" -out-crt /etc/nebula/ca.crt -out-key /etc/nebula/ca.key', 'nebula-cert sign -ca-crt /etc/nebula/ca.crt -ca-key /etc/nebula/ca.key -name "lighthouse" -groups "lighthouse" -ip "10.0.100.1/24" -out-crt /etc/nebula/lighthouse.crt -out-key /etc/nebula/lighthouse.key', + 'chown -R nebula-smoke:nebula-smoke /etc/nebula' ) # Reboot the lighthouse and verify that the nebula service comes up on boot.