yggdrasil: multicast peer discovery by default, per-transport dial protocols #7877

Merged
kenji merged 2 commits from yggdrasil-multicast into main 2026-08-26 14:11:06 +00:00
Owner

Two changes to the yggdrasil service:

yggdrasil: enable multicast peer discovery by default

  • multicastInterfaces now defaults to discovery on all interfaces, with overlay/VPN interfaces (zt|wg|tailscale|mycelium|tinc|tun|tap|ygg) degraded to priority 10 so direct links win.
  • Multicast listener ports are opened in the firewall automatically.
  • Static peers get ?priority=20, worse than any multicast-discovered link, so locally discovered peerings carry the traffic and static routes act as fallback. Priority only tie-breaks between multiple links to the same peer, so nodes reachable only statically are unaffected.

yggdrasil: dial per-transport link protocols, disable quic/ws listeners by default

  • Exports from VPN transports (zerotier, wireguard, ...) are dialed with a single plain tcp:// link: the transport already encrypts and doesn't filter, so extra protocols add connections but no reachability.
  • Exports from the internet service may cross filtered networks, so every enabled protocol is dialed to maximize the chance that one gets through.
  • ports.quic and ports.ws are now nullOr port and default to null (listeners disabled, firewall ports closed, not dialed).
Two changes to the yggdrasil service: **yggdrasil: enable multicast peer discovery by default** - `multicastInterfaces` now defaults to discovery on all interfaces, with overlay/VPN interfaces (`zt|wg|tailscale|mycelium|tinc|tun|tap|ygg`) degraded to priority 10 so direct links win. - Multicast listener ports are opened in the firewall automatically. - Static peers get `?priority=20`, worse than any multicast-discovered link, so locally discovered peerings carry the traffic and static routes act as fallback. Priority only tie-breaks between multiple links to the same peer, so nodes reachable only statically are unaffected. **yggdrasil: dial per-transport link protocols, disable quic/ws listeners by default** - Exports from VPN transports (zerotier, wireguard, ...) are dialed with a single plain `tcp://` link: the transport already encrypts and doesn't filter, so extra protocols add connections but no reachability. - Exports from the internet service may cross filtered networks, so every enabled protocol is dialed to maximize the chance that one gets through. - `ports.quic` and `ports.ws` are now `nullOr port` and default to `null` (listeners disabled, firewall ports closed, not dialed).
CODEOWNERS rules requested review from pinpox 2026-08-11 09:33:40 +00:00
CODEOWNERS rules requested review from kenji 2026-08-11 09:33:40 +00:00
DavHau added 1 commit 2026-08-11 09:43:10 +00:00
The multicastInterfaces default of [] disabled multicast entirely,
contradicting the option docs. Default is now the all-interfaces entry
with Port 5400; the firewall opens configured multicast listener ports
automatically (the link-local listener is TCP; the previous UDP 5400
rule was ineffective).

Link priorities ensure direct local links always carry the traffic when
multiple links to the same peer exist: physical-interface multicast 0,
overlay/VPN-interface multicast 10, static peers from exports 20
(appended as ?priority= to generated peer URIs). Without this, ygg
routing tie-breaks equal-priority sub-millisecond links by age, letting
yggdrasil-over-zerotier win over a direct LAN link.

Adds VM test regression assertions for multicast interfaces and fe80
peering.
DavHau force-pushed yggdrasil-multicast from 02b33a6f1c to ef9f41c580 2026-08-11 09:43:10 +00:00 Compare
Owner

hmm, what are the security implications by having this on by default? can strangers in the same network can connect now to my "private" yggdrasil network?

hmm, what are the security implications by having this on by default? can strangers in the same network can connect now to my "private" yggdrasil network?
DavHau added 1 commit 2026-08-12 07:21:01 +00:00
yggdrasil: dial per-transport link protocols, disable quic/ws listeners by default
PR Size Review Check / pr-size-review-gate (pull_request) Successful in 35s
buildbot/nix-eval evaluation succeeded
buildbot/nix-build 150 attributes built
sizelint on each commit / sizelint (pull_request) Successful in 39s
PR Size Review Check / pr-size-review-gate (pull_request_review) Successful in 25s
gitea-mq/buildbot/nix-eval evaluation succeeded (3 warnings)
gitea-mq/buildbot/nix-build 150 attributes built
gitea-mq Merge queue passed
13b50f388e
DavHau force-pushed yggdrasil-multicast from ef9f41c580 to 13b50f388e 2026-08-12 07:21:01 +00:00 Compare
Owner

hmm, what are the security implications by having this on by default? can strangers in the same network can connect now to my "private" yggdrasil network?

We should be doing access control by allowing only our keys to peer with our hosts. Local discovery should have been enabled all along.

allowedPublicKeys = lib.filter (key: key != "") (
map (
name:
lib.trim (
clanLib.getPublicValue {
flake = config.clan.core.settings.directory;
machine = name;
generator = "yggdrasil";
file = "publicKey";
default = "";
}
)
) (lib.attrNames roles.default.machines)
);

> hmm, what are the security implications by having this on by default? can strangers in the same network can connect now to my "private" yggdrasil network? We should be doing access control by allowing only our keys to peer with our hosts. Local discovery should have been enabled all along. https://git.clan.lol/clan/clan-core/src/commit/33a9c3dcd95f5f92657f74b0e13122ded1b3a405/clanServices/yggdrasil/default.nix#L217-L230
Author
Owner

good question, went trough the yggdrasil source to check. Answer is: they can peer, but they get nothing useful out of it. AllowedPublicKeys explicitly does NOT apply to link-local multicast peers (multicast listeners go through ListenLocal which skips teh check). So yes, a stranger on the same LAN can establish a peering with your node.

But peering != access: yggdrasil is e2e encrypted and this module already firewalls the ygg interface to only accept traffic from clan member IPs. So the stranger can use your node as transit and sees your pubkey, but cant reach any services or hosts in the clan.

If we want to close even that, multicast supports a Password option (only nodes with the same password discover each other), we could derive one from a clan-wide secret via vars. Would do that in a follow up PR tho.

good question, went trough the yggdrasil source to check. Answer is: they can peer, but they get nothing useful out of it. AllowedPublicKeys explicitly does NOT apply to link-local multicast peers (multicast listeners go through ListenLocal which skips teh check). So yes, a stranger on the same LAN can establish a peering with your node. But peering != access: yggdrasil is e2e encrypted and this module already firewalls the ygg interface to only accept traffic from clan member IPs. So the stranger can use your node as transit and sees your pubkey, but cant reach any services or hosts in the clan. If we want to close even that, multicast supports a Password option (only nodes with the same password discover each other), we could derive one from a clan-wide secret via vars. Would do that in a follow up PR tho.
DavHau changed title from yggdrasil: multicast peer discovery by default, single link protocol per peer to yggdrasil: multicast peer discovery by default, per-transport dial protocols 2026-08-12 07:24:38 +00:00
Author
Owner

The password option doesn't seem to be sound from a security perspective. Enabling it would just prevent connecting with foreigners by accident, but doesn't guarantee it.

The password option doesn't seem to be sound from a security perspective. Enabling it would just prevent connecting with foreigners by accident, but doesn't guarantee it.
Owner

hmm, but they could route via my peers to another peer which maybe is not firewalled off? maybe that's obscure enough that we don't need to think too hard about it?

hmm, but they could route via my peers to another peer which maybe is not firewalled off? maybe that's obscure enough that we don't need to think too hard about it?
Owner

with overlay/VPN interfaces (zt|wg|tailscale|mycelium|tinc|tun|tap|ygg) degraded to priority 10 so direct links win.

wg and most tap/tun devices don't have any multicast support. Is there anything we lose/gain from disabling that for them anyway?

hmm, but they could route via my peers to another peer which maybe is not firewalled off? maybe that's obscure enough that we don't need to think too hard about it?

That is a good point. Other than that I think this looks reasonable.

> with overlay/VPN interfaces (zt|wg|tailscale|mycelium|tinc|tun|tap|ygg) degraded to priority 10 so direct links win. wg and most tap/tun devices don't have any multicast support. Is there anything we lose/gain from disabling that for them anyway? > hmm, but they could route via my peers to another peer which maybe is not firewalled off? maybe that's obscure enough that we don't need to think too hard about it? That is a good point. Other than that I think this looks reasonable.
kenji approved these changes 2026-08-26 13:56:23 +00:00
kenji scheduled this pull request to auto merge when all checks succeed 2026-08-26 13:56:28 +00:00
kenji merged commit 95675a2a70 into main 2026-08-26 14:11:06 +00:00
kenji deleted branch yggdrasil-multicast 2026-08-26 14:11:07 +00:00
Owner

How does this affect data center based deployments? Will Hetzner be mad?

How does this affect data center based deployments? Will Hetzner be mad?
Owner

I looked at it from that side and I doubt it:

AllowedEncryptionPublicKeys = allowedPublicKeys

first we actually would only peer with peers we already have added.
Second I could not find any actual multicast specific wording in the hetzner tos, I assume they just block it and thats it.

Also I'm the canary in the coalmine I cheery picked this and have been running it for 4 days now actually on Hetzner and my homelab.

I looked at it from that side and I doubt it: ``` AllowedEncryptionPublicKeys = allowedPublicKeys ``` first we actually would only peer with peers we already have added. Second I could not find any actual multicast specific wording in the hetzner tos, I assume they just block it and thats it. Also I'm the canary in the coalmine I cheery picked this and have been running it for 4 days now actually on Hetzner and my homelab.
Sign in to join this conversation.
No Reviewers
5 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: clan/clan-core#7877