Change:
When a "lighthouse" and a regular "roaming" node are on the same network and the default value for () is used, nodes occasionally enter a consistent failure state while trying to connect. I suspect this occurs when Nebula tries to NAT-punch with the local router and always tries to connect to the lighthouse instead of the roaming node. Steps to reproduce the behavior: up a lighthouse node and roaming node -forward port 4242 for the lighthouse node to set a value for in the Nebula config intermittent failures The value of should be required, with a link to Nebula docs: I'm not entirely sure, but logs from the issue indicate the lighthouse-node handshakes are both sending packets to "192.168.1.1:4242", which is port-forwarded to the lighthouse (I'm in a dual-NAT setup unfortunately; this is the IP of the outer NAT). Explicitly setting the port to (to automatically select an ephemeral port) on the roaming nodes immediately fixes the issue. (wrote the initial module with the port default) Please run and paste the result. Add a :+1: [reaction] to [issues you find important]. [reaction]: [issues you find important]:
Based on those docs, I think we can solve this without requiring the user to specify the port. Since we know whether a node is a lighthouse via , we could implement a behavior where defaults to for lighthouses and for non-lighthouses: I'm not sure how to get the for this, though. Maybe if the options were , then we could just refer to ? We'd probably also want to include . Thoughts?
My thought is that a change should meet the following requirements: Per set and to something like:Set the actual value appropriately in the module with an expression like the above if the input is null. If (isLighthouse or isRelay) and the final port evaluates to 0, we should warn, since this config will probably result in connectivity issues. There should be a test for this. I am split on whether to backport this. While this is a bug, people may have relied on the default port to NAT port forward from routers to a Nebula node that is not a lighthouse or a relay. As such the new default may impede connectivity on restrictive NATs, so this is also a breaking change.
Also, good job diagnosing this. I think I've run into this before but didn't know what was causing it.
Per (captured in + ) Given this, it is probably a good idea to both fix and backport this.

Discussion:
format = pkgs.formats.yaml {}; nameToId = netName: "nebula-${netName}"; <ins> resolveFinalPort = netCfg: if netCfg.listen.port == null then if (netCfg.isLighthouse || netCfg.isRelay) then 4242 else 0 else netCfg.listen.port; </ins> in { # Interface

}; listen.port = mkOption { <del> type = types.port; default = 4242; </del> <ins> type = types.nullOr types.port; default = null; defaultText = lib.literalExpression '' if (config.services.nebula.networks.''${name}.isLighthouse || config.services.nebula.networks.''${name}.isRelay) then 4242 else 0; ''; </ins> description = lib.mdDoc "Port number to listen on."; };

}; listen = { host = netCfg.listen.host; <del> port = netCfg.listen.port; </del> <ins> port = resolveFinalPort netCfg; </ins> }; tun = { disabled = netCfg.tun.disable;

outbound = netCfg.firewall.outbound; }; } netCfg.settings; <del> configFile = format.generate "nebula-config-${netName}.yml" settings; </del> <ins> configFile = format.generate "nebula-config-${netName}.yml" ( warnIf ((settings.lighthouse.am_lighthouse || settings.relay.am_relay) && settings.listen.port == 0) '' Nebula network '${netName}' is configured as a lighthouse or relay, and its port is ${builtins.toString settings.listen.port}. You will likely experience connectivity issues: https://nebula.defined.net/docs/config/listen/#listenport '' settings ); </ins> in { # Create the systemd service for Nebula.

# Open the chosen ports for UDP. networking.firewall.allowedUDPPorts = <del> unique (mapAttrsToList (netName: netCfg: netCfg.listen.port) enabledNetworks); </del> <ins> unique (filter (port: port > 0) (mapAttrsToList (netName: netCfg: resolveFinalPort netCfg) enabledNetworks)); </ins> # Create the service users and groups. users.users = mkMerge (mapAttrsToList (netName: netCfg:

environment.systemPackages = [ pkgs.nebula ]; users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; services.openssh.enable = true; <ins> networking.firewall.enable = true; # Implicitly true, but let's make sure. </ins> networking.interfaces.eth1.useDHCP = false; services.nebula.networks.smoke = {

ca = "/etc/nebula/ca.crt"; cert = "/etc/nebula/${name}.crt"; key = "/etc/nebula/${name}.key"; <del> listen = { host = "0.0.0.0"; port = 4242; }; </del> <ins> listen = { host = "0.0.0.0"; port = if (config.services.nebula.networks.smoke.isLighthouse || config.services.nebula.networks.smoke.isRelay) then 4242 else 0; }; </ins> }; } extraConfig