RoonBroadcastRelay - Make Roon work on complex network infrastructures (VPN/VLAN)

How is this wall of text slop connected to RoonBroadcastRelay?

Fair point…same problem (SOOD discovery not crossing subnets), different fix (L2 overlay instead of a relay). Off-topic for your thread though, so I’ve moved it to its own. Apologies for the clutter…and thanks for RoonBroadcastRelay, it’s how I narrowed down my debugging.

1 Like

RAAT discovery fails and AirPlay session connects to the wrong subnet across a Site-to-Site WireGuard VPN

Hi Simone,

first of all, thank you very much for creating RoonBroadcastRelay. It is an impressive project and exactly what I was looking for.

Unfortunately, I have run into an issue that I have not been able to solve after several days of systematic troubleshooting.

Network topology

Site A

  • Synology DS723+

  • Latest DSM

  • Roon Server

  • RoonBroadcastRelay v1.0 (official GitHub release)

  • Network: 192.168.178.0/24

Site B

  • Raspberry Pi

  • Raspberry Pi OS

  • RoonBroadcastRelay v1.0 (official GitHub release)

  • Denon Home 250 stereo pair

  • Network: 192.168.188.0/24

Both sites are connected through a Fritz!Box ↔ Fritz!Box Site-to-Site WireGuard VPN.

Routing between both subnets works correctly.


Installed version

Both systems are running the official v1.0 (BETA) release from GitHub.

The SHA256 checksum of the Linux x64 binary matches the published checksum.


Configuration

Both relays use:
{
“Raat”: true,
“AirPlay”: true,
“Ssdp”: true,
“Squeezebox”: false
}

Discovery

Discovery appears to work correctly.

Running

avahi-browse -rt _raop._tcp

returns the remote Denon speaker with the correct IP address in Site B.

So the relay advertises the correct AirPlay endpoint.


AirPlay behaviour

The Denon immediately appears inside Roon.

Playback starts with the correct Site B speaker IP.

Immediately afterwards, the Roon log changes and the AirPlay endpoint suddenly becomes an IP address inside Site A.

The session then fails with:

403 Forbidden

RECORD failed

NetworkError

So Roon initially connects to the correct remote speaker but then switches to an IP address inside the local subnet.


RAAT

This is actually the bigger issue.

RAAT is enabled on both relays.

However:

  • No remote RAAT devices ever appear in Roon.

  • Only AirPlay devices become visible.


Verification already performed

We have verified all of the following:

  • Official GitHub release (v1.0 BETA)

  • Official SHA256 checksum

  • mDNS forwarding works correctly

  • SSDP forwarding works correctly

  • Routing between both subnets works correctly

  • Avahi advertises the correct remote IP address

  • Both relay instances are running correctly

  • Disconnecting another Synology NAS from the network made no difference

  • The relay configuration is identical on both systems


Questions

  1. Should remote RAAT endpoints automatically appear with this configuration?

  2. Is there anything else required for RAAT discovery?

  3. Is the AirPlay behaviour (switching from the correct remote subnet to the local subnet) something you have seen before?

If you need additional logs, packet captures, or if you would like me to test a debug build, I would be happy to help.

Thank you very much for your work and your time.
Hauke

Hi Hauke,

thanks for the detailed report! The first thing I’d like to check is the router configuration, as this is the most commonly missed part of the setup.

Could you please send the WireGuard configuration and the forwarding/routing rules between the WireGuard interface and the LAN on both Fritz!Boxes? In particular, I need to verify that UDP 9004 reaches each relay’s LAN IP in both directions
and that traffic between the Roon Server and Denon subnets is allowed.

Please compare your setup with the Site-to-Site configuration in EXAMPLES.md, including the firewall/forwarding rules ..not only the relay’s protocol settings.

Ofc redact public IPs, hostnames, WireGuard keys and credentials, but please leave private IPs, subnets, ports, routes and AllowedIPs visible.

Once I have that, together with the complete appsettings.json from both relays, I can properly investigate RAAT and AirPlay.

Hi Simone,

thank you for your quick reply.

I have now verified everything you asked me to check.

FRITZ!Box Site-to-Site WireGuard

This setup uses a native FRITZ!Box ↔ FRITZ!Box Site-to-Site WireGuard connection.

Unlike OPNsense or pfSense, FRITZ!OS does not expose configurable firewall or forwarding rules between the WireGuard interface and the LAN. Routing between both LAN subnets is handled automatically by FRITZ!OS.

UDP 9004 verification

I explicitly tested UDP port 9004 in both directions.

Site B → Site A

Verified using tcpdump on the Synology:
192.168.188.39 → 192.168.178.145:9004

Site A → Site B

Verified using a Python UDP sender on the Synology and a UDP listener on the Raspberry Pi.

The packet was successfully received.

Therefore, UDP port 9004 is reachable in both directions between the two relays.

Current status

At this point I have verified:

  • WireGuard tunnel is working correctly.

  • Routing between both LAN subnets is working.

  • UDP port 9004 works in both directions.

  • mDNS discovery works correctly.

  • SSDP discovery works correctly.

  • Both relays are running the official v1.0 release.

  • Both relay configurations are mirrored and appear correct.

However:

  • Remote RAAT devices never appear in Roon.

  • AirPlay devices do appear, but playback initially connects to the correct remote speaker IP and then switches to an IP address in the local subnet before failing with a 403 Forbidden error.

I have pasted the complete appsettings.json files from both relays below.

If you would still like to inspect the complete WireGuard peer configuration, I can export it from both FRITZ!Boxes and redact the public IPs, hostnames and WireGuard keys while leaving the private subnets, routes and AllowedIPs visible.

Thanks a lot again for your help!
Hauke

Site A (Synology)
{

“SiteName”: “Hamburg”,

“TunnelPort”: 9004,

“RemoteRelayIp”: “192.168.188.39”,

“LocalInterfaces”: [

{

  "LocalIp": "192.168.178.145",

  "BroadcastAddress": "192.168.178.255",

  "SubnetMask": "255.255.255.0"

}

],

“UnicastTargets”: [],

“Protocols”: {

"Raat": true,

"AirPlay": true,

"Ssdp": true,

"Squeezebox": false

}

}

Site B (Raspberry)
{

“SiteName”: “Ferienhaus”,

“TunnelPort”: 9004,

“RemoteRelayIp”: “192.168.178.145”,

“LocalInterfaces”: [

{

  "LocalIp": "192.168.188.39",

  "BroadcastAddress": "192.168.188.255",

  "SubnetMask": "255.255.255.0"

}

],

“UnicastTargets”: [],

“Protocols”: {

"Raat": true,

"AirPlay": true,

"Ssdp": true,

"Squeezebox": false

}

}

One more detail: can you confirm the IP address used by Roon Server? Is it also 192.168.178.145?

Yes, I can confirm that.

The Roon Server is running on the Synology NAS at 192.168.178.145.

The relay is also configured to use 192.168.178.145 as its local interface.

The NAS has no other active LAN IP addresses.

Besides the primary LAN interface, there is only the Docker bridge (172.17.0.1) and an internal DSM tunnel interface (169.254.x.x), but no additional active interface in the 192.168.178.x subnet.

That’s probably the main issue, try it on a minimal vm on the synology (or if you have any SBC or mini-pc available those are fine too).
RonnBroadcastRelay ignores every discovery packet originating from its own configured IP as loop prevention.

Thanks a lot for yoour swift response, that makes sense.

Just to make sure I don’t misunderstand:

It’s a requirement that the relay must run on a different host than the Roon Server

If I move the relay to another Linux VM in the same LAN while keeping the Roon Server on the Synology, both RAAT discovery and AirPlay should work correctly?
Thanks again!!

Hi Simone,

You were absolutely right.

The issue was that Roon Server and RoonBroadcastRelay were running on the same Synology (192.168.178.145). After moving the relay to a second Synology on the same LAN (192.168.178.46), while keeping the Roon Server on the original NAS, everything started working immediately.

The remote Denon Home 250 now appears as a Roon Ready device, can be enabled, and playback starts successfully.

So your loop prevention based on the local IP was indeed the root cause in this setup.

Thank you so much for your help!!!

Perfect, I’'update the README in the repo so it’s clear to everyone