Unifi USG – Sonos Betrieb in verschiedenen Subnetzen / VLANs

Das Sonos® System ist von Haus aus auf den Verbrauchermarkt ausgelegt.
In einem einfachen Heimnetzwerk kann quasi von Zero-Config gesprochen werden. Ist die Netzwerkkonfiguration etwas anspruchsvoller wird diese Erleichterung aufgrund fehlender Eingriffsmöglichkeiten schnell zur Qual.
Möchte man nun die Sonos® Komponenten von seinen Endgeräten und dem Heimautomatisierungsnetzwerk betreiben stolpert man der Reihe nach über verschiedene Probleme:

  • Der Sonos® Controller (z.B. die Android App) sucht beim Starten die Lautsprecher per UDP Multicast 239.255.255.250 auf Port 1900.
  • Wird ein Lautsprecher angelernt, so antwortet er per Broadcast 255.255.255.255 auf UDP 6969
  • IP Adressen können nicht fest vergeben werden
  • Alle Lautsprecher haben den gleichen Hostname „SonosZP“.
    Aufgrund eines Bugs? im Unifi Controller lassen sich somit keine DHCP-Reservierungen anlegen, da der Controller immer nur ein Gerät anzeigt.
    Für gut ausformulierte Firewallregeln wäre dies allerdings von Nutzen.

1. DHCP-Reservierungen
Da das Reservieren über die UI im aktuellen Unifi Controller 5.9.32 nicht gelingen wollte, werden die Adressen durch eine Anpassung der
config.gateway.json reserviert.
Die MAC-Adressen lassen sich (zumindest in der aktuellen Betafirmware) aus der Webui des USG entnehmen.

{
   "dhcp-server":{
      "shared-network-name":{
         "net_LAN21_Media_eth1_10.11.21.0-24":{
            "subnet":{
               "10.11.21.0/24":{
                  "static-mapping":{
                     "SonosBeam":{
                        "ip-address":"10.11.21.201",
                        "mac-address":"94:9F:xx:xx:xx:xx"
                     },
                     "SonosP1L":{
                        "ip-address":"10.11.21.203",
                        "mac-address":"78:28:xx:xx:xx:xx"
                     },
                     "SonosP1R":{
                        "ip-address":"10.11.21.204",
                        "mac-address":"78:28:xx:xx:xx:xx"
                     },
                     "SonosSUB":{
                        "ip-address":"10.11.21.202",
                        "mac-address":"94:9F:xx:xx:xx:xx"
                     },
                     "SonosP2": {
                         "ip-address": "10.11.21.205",
                         "mac-address": "78:28:CA:xx:xx:xx"
                     }
                  }
               }
            }
         }
      }
   }
}


Broadcast Relay
Das eigentliche Hauptproblem: Die Multicasts (und Broadcasts) müssen durch die USG zwischen den Subnetzen ausgetauscht werden.
Hierzu bieten sich verschiedene Lösungen an.

Der USG bringt z.B. von Haus aus einen igmp-Proxy mit, der auch über die config.gateway.json konfiguriert werden kann.
Leider unterstützt dieser dieser nur ein Upstreamnetzwerk, so dass er nicht geeignet ist, wenn Hausautomatisierung und Mobiltelefone in unterschiedlichen Subnetzen beheimatet sind.

Man findet im Netz auch eine ältere Version des pimd (PIM-SM/SSM multicast routing daemon), die auf der USG lauffähig ist. Mit diesem konnten die Multicasts gut weitergeleitet werden, allerdings konnte ich ihm nicht beibringen die Broadcasts beim Einrichten weiterzuleiten.
Man konnte das umgehen, wenn man zum Einrichten temporär mit dem Controller (Android App) in das Subnetz der Sonos gewechselt hat.

Heute bin ich dann in der EdgeRouter Community über einen udp bcast relay gestolpert, der Broadcasts an einem definierten UDP Port an definierte Interfaces weiterleitet.
Glücklicherweise ist das Binary auch unter dem USG lauffähig.
Um zumindest die Installationsdateien auch nach einem Firmwareupdate vorzuhalten habe ich sie mal im /config Verzeichnis abgelegt

curl -o /config/install_ubnt_bcast_relay.v1.0.tgz https://community.ubnt.com/ubnt/attachments/ubnt/EdgeMAX/67208/1/ubnt-bcast-relay.v1.0.tgz
sudo mkdir /config/_install
sudo tar zxvf /config/install_ubnt_bcast_relay.v1.0.tgz -C /config/_install

sudo rm /config/install_ubnt_bcast_relay.v1.0.tgz

sudo chmod +x /config/_install/ubnt-bcast-relay/install.sh
sudo chmod +x /config/_install/ubnt-bcast-relay/uninstall.sh

cd config/_install/ubnt-bcast-relay/
sudo ./install.sh

Nach einem Firmwareupgrade sollte es ausreichend sein die install.sh erneut aufzurufen.
Alternativ kann unter /config/scripts/post-config.d ein einfaches Script „installrelay.sh“
abgelegt werden, dass sicherstellt, dass die Erweiterung auch nach einem Firmwareupdate automatisch installiert wird.

#!/bin/vbash

sudo /config/_install/ubnt-bcast-relay/install.sh

Das Script anschließen noch mit chmod +x installrelay.sh
ausführbar machen

Konfiguration:
Wir Konfigurieren zwei Instanzen des Broadcast Relays über die CLI des USGs.
Die drei aufgeführten Interfaces stellen die bei den Broadcasts beteiligten VLANs dar:
eth1.10 – Heimautomatisierung
eth1.11 – Mobiltelefone / Tabletts
eth1.21 – Multimedia Geräte (u.a. die Sonos® Lautsprecher)

configure
set service bcast-relay id 1 description 'Sonos Controller to Player'
set service bcast-relay id 1 interface eth1.10
set service bcast-relay id 1 interface eth1.11
set service bcast-relay id 1 interface eth1.21
set service bcast-relay id 1 port 1900

set service bcast-relay id 2 description 'Sonos Player to Controller'
set service bcast-relay id 2 interface eth1.10
set service bcast-relay id 2 interface eth1.11
set service bcast-relay id 2 interface eth1.21
set service bcast-relay id 2 port 6969
commit

Anschließend dumpen wir die Konfig und ergänzen die relevanten Daten in unserer config.gateway.json
mca-ctrl -t dump-cfg > /tmp/config.txt

Der resultierende Eintrag sollte in etwa so aussehen:

{
   "service":{
      "bcast-relay":{
         "id":{
            "1":{
               "description":"Sonos Controller to Player",
               "interface":[
                  "eth1.10",
                  "eth1.11",
                  "eth1.21"
               ],
               "port":"1900"
            },
            "2":{
               "description":"Sonos Player to Controller",
               "interface":[
                  "eth1.10",
                  "eth1.11",
                  "eth1.21"
               ],
               "port":"6969"
            }
         }
      }
   }

Firewall

Die hier aufgeführten Regeln basieren darauf, dass
– Eine SPI Regel „Allow all Established/Related Traffic“ existiert
– Das Media-VLAN nicht auf die anderen VLAN’s zugreifen darf
– allen 3 VLANs der Internetzugriff gestattet ist

Bei anderen Ansprüchen, müssen entsprechende zusätzliche Regeln ergänzt werden.
Liste der von Sonos verwendeten Ports

Zunächst benötigen wir ein paar Firewall Regeln.
Dazu ist es sinnvoll vorab ein paar Firewall Gruppen anzulegen:
1. „H_SonosPlayers“ Type „Address IPv4“ enthält alle IP-Adressen der Sonos-Lautsprecher
2. „H_SonosController“ Type „Address IPv4“ enthält alle IP-Adressen/IP-Netze der verwendeten Controller (Mobiltelefone/FHEM Server)
3. „H_SonosMultiCast“ Type „Address IPv4“ mit der Adresse „239.255.255.250“
4. „All_private_IPs_RFC1918“ Type „Address IPv4“ mit den Adressen „192.168.0.0/16“, „172.16.0.0/12“, „10.0.0.0/8“
5. „P_Sonos_ControlTCP“ Type „Port“ mit den Ports 1400, 1443
6. „P_Sonos_TCP“ Type „Port“ mit den Ports 3400, 3401, 3500
7. „P_Sonos_UDP“ Type „Port“ mit den Ports 1900, 1901, 6969
8. „P_1900“ Type „Port“ mit dem Port 1900

und darauf aufbauend dann folgende Regeln:
1. LAN IN Regel „Sonos_TCP“
Protokoll: TCP
SRC: „H_SonosPlayers“ Ports: „ANY“
DST: „H_SonosController“ Ports: „P_Sonos_TCP“

2. LAN IN Regel „Sonos_UDP“
Protokoll: UDP
SRC: „H_SonosPlayers“ Ports: „ANY“
DST: „H_SonosController“ Ports: „P_Sonos_UDP“

3. LAN IN Regel „SonosControl“
Protokoll: TCP
SRC: „H_SonosController“ Ports: „ANY“
DST: „H_SonosPlayers“ Ports: „P_Sonos_ControlTCP“

4. LAN IN Regel „Sonos_FHEM_Access“
Protokoll: TCP
SRC: „H_SonosPlayers“ Ports: „ANY“
DST: „H_FHEMServer“ Ports: „ANY“
Anmerkung: Leider werden die Anfragen von FHEM nicht von den SPI Regeln abgedeckt, so dass die Antworten der Lautsprecher nicht unter etablished/related traffic fallen.
Quell- und Zielport sind leider immer ein zufälliger High-Port, so dass diese Pauschalregel notwendig wird 🙁

5. LAN IN Regel „Sonos_SSDP“
Protokoll: UDP
SRC: „ANY“ Ports: „ANY“
DST: „H_SonosMultiCast“ Ports: „P_1900“
Anmerkung: Die Regel ist noch etwas schwammig formuliert und eventuell auch ganz überflüssig

6. LAN IN Regel „VLAN21_Media_deny all“
Protokoll: ALL
SRC: Network „LAN21_MEDIA“
DST: „All_private_IPs_RFC1918“ Ports: „ANY“

7. WAN LOCAL Regel „DROP udp-bcast-relay from external“
Action: DROP
Protokoll: UDP
DST Ports: „P_Sonos_UDP“
Diese Regel ist besonders wichtig, da das Relay sonst aus dem Internet erreichbar ist.
Ich verstehe das zwar nicht, konnte es aber mit

nmap -sU -p 1900 [ext. IP]

bzw.

nc -u [ext. IP] 1900

Von einem externen Server und einem tcpdump auf meinem lokalen Server reproduzieren!

Weitere Einstellungen im USG Controller
Hier noch ein paar Einstellungen
Settings / Networks / Wireless Networks / * / „Block LAN to WLAN Multicast and Broadcast Data
deaktivieren bzw.
– In der SSID, in der sich die Player befinden müssen die Mac-Adressen der jeweiligen Controller aufgeführt sein, da diese die Lautsprecher per Broad-/Multicast suchen

– In der SSID, in der sich die Controller befinden müssen die Mac-Adressen der jeweiligen Player aufgeführt sein, da die Lautsprecher bei der Grundinitialisierung per Broad-/Multicast antworten

– Settings / Networks / Wireless Networks / * / „Enable multicast enhancement (IGMPv3)“ ist aktiviert

– Settings / Networks / * / „Enable IGMP snooping“ ist in jedem beteiligten Netzwerk aktiviert

– Settings / Services / MDNS / „Enable Multicast DNS“ ist aktiviert

– Settings / Services / UPNP/ „Enable UPnP“ ist deaktiviert

Bei den letzten beiden kann ich leider nicht sagen ob sie relevant sind – ich habe sie nur der Vollständigkeit halber aufgeführt.

Das Spanning Tree Protocoll im root-Switch sollte nach diversen Quellen im Internet wie folgt konfiguriert werden:
– STP statt RSTP (da Sonos kein RSTP unterstützt)
– STP Priority 4096
Werden weitere Switche eingesetzt, so ist dort abhängig von der Ebene die Priority in 4096er Schritten zu erhöhen.

Author: Stefan