As of late 2024, all existing documentation on configuring VLANs for Sonos devices is now outdated due to many new changes to the Sonos network architecture.
Sonos has shifted from a LAN-first to a cloud-first architecture, which introduces updated networking requirements. This shift impacts how VLANs must be configured to support:
- Device discovery & setup
- Media streaming
- Local library sharing
- Compatibility with the Sonos controller application & AirPlay
A fully functional Sonos system working across VLANs with OpenWRT requires the following components:
- π An mDNS System: Avahi is typically installed by default in OpenWRT.
- π‘ IGMP Snooping: To efficiently manage multicast traffic.
- π IGMP Multicast Proxying: To forward multicast traffic between VLANs.
- π₯ ICMP between Sonos devices, router & controller: Facilitates various timing & background communications
- π‘οΈ Various TCP & UDP firewall & proxy rules to:
- Securely direct multicast traffic
- Forward Sonos specific unicast traffic between VLANs
These example config files form the reference system in this guide.
- LAN VLAN:
- The trusted network where the Sonos controller application will operate from.
- This VLAN will be considered the "Upstream" network for IGMP proxying.
- Guest VLAN (optional):
- Trusted network for guests also using a Sonos application.
- Also considered an "Upstream" network for IGMP proxying.
- IOT VLAN:
- The untrusted VLAN for IOT devices.
- Considered the "Downstream" network for IGMP proxying.
- VLANS for LAN, Guest & IOT have been pre-created on a DSA bridge device. (OpenWRT 21.02 and above)
- LAN, Guest & IOT network interfaces have been configured with the their appropriate VLAN & static IP.
- WAN access is available to all VLANs.
- Sonos devices are using static IP addresses (static dhcp reservations are recommended).
The igmpproxy
package must be installed for proxying of multicast traffic between VLANs
For 23.05.5 or lower:
opkg update
opkg install
For 24.10 and above:
apk update
apk add igmpproxy
Warning with muticast proxy:
Sonos device discovery requires SSDP relay across router interfaces, however IGMPproxy (wisely) disables the SSDP multicast address 239.255.255.250 by default as this address is also used by the broader uPnP suite. As such, be advised that proxied multicast should only be allowed explicitly where needed. There are many security risks with unrestricted uPnP traffic, especially if allowed to reach the WAN interface. This guide shows how to remove the default IGMPproxy restriction and limit SSDP relay between just the LAN, GUEST & IOT VLANs.
It is strongly recommended to include all firewall rules provided in this guide as a baseline minimum. You should also remove or disable any Universal Plug & Play packages present. If legacy uPnP is a requirement, you may need to further restrict uPnP very carefully as required. See OpenWRT's uPnP warning here.
To enable IGMP snooping & Spanning Tree Protocol (STP), add the following lines to the LAN, Guest & IOT bridge devices found in /etc/config/network
:
option igmp_snooping '1'
option stp '1'
Example bridge device configuration. Do this for the LAN, Guest & IOT device.
config device
option name 'br-lan'
option type 'bridge'
list ports 'eth0'
option igmp_snooping '1'
option stp '1'
Note: Don't apply changes or restart OpenWRT until all new defaults are added!
To secure all traffic (and to avoid spamming multicast everywhere), all input traffic to the router & forwarding between zones must first be denied. To implement this change without breaking things, the below configuration achieves this whilst still allowing LUCI access, SSH, DNS, DHCP & ICMP to the router. This important step establishes the firewall best practice of deny all by default, and explicitly permit as needed.
Edit /etc/config/firewall
to restrict traffic as follows:
Set the firewall default behavior to implicitly deny all to/through the router interface:
config defaults
option input 'REJECT' # Prevents implied inputs to the router
option output 'ACCEPT' # Allow outgoing traffic from any zone
option forward 'REJECT' # Reject forces explicit firewall rules to be used for forwarding
option synflood_protect '1'
Next, configure each zone to implicitly deny all to/through the router interface:
config zone
option name 'lan'
option family 'ipv4'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'lan'
config zone
option name 'guest'
option family 'ipv4'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'guest'
config zone
option name 'iot'
option family 'ipv4'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'iot'
Check for correct zone forwarding:
config forwarding
option src 'lan'
option dest 'wan'
config forwarding
option src 'guest'
option dest 'wan'
config forwarding
option src 'iot'
option dest 'wan'
Now add explicit allow rules for Luci, SSH, DNS, DHCP & ICMP to the router
config rule
option name 'Allow-DNS-LAN'
option family 'ipv4'
list proto 'udp'
option src 'lan'
option dest_port '53'
option target 'ACCEPT'
config rule
option name 'Allow-DNS-GUEST'
option family 'ipv4'
list proto 'udp'
option src 'guest'
option dest_port '53'
option target 'ACCEPT'
config rule
option name 'Allow-DNS-IOT'
option family 'ipv4'
list proto 'udp'
option src 'iot'
option dest_port '53'
option target 'ACCEPT'
config rule
option name 'Allow-DHCP-WAN'
option family 'ipv4'
option src 'wan'
option proto 'udp'
option dest_port '68'
option target 'ACCEPT'
config rule
option name 'Allow-DHCP-LAN'
option family 'ipv4'
list proto 'udp'
option src 'lan'
option src_port '68'
option dest_port '67'
option target 'ACCEPT'
config rule
option name 'Allow-DHCP-GUEST'
option family 'ipv4'
list proto 'udp'
option src 'guest'
option src_port '68'
option dest_port '67'
option target 'ACCEPT'
config rule
option name 'Allow-DHCP-IOT'
option family 'ipv4'
list proto 'udp'
option src 'iot'
option src_port '68'
option dest_port '67'
option target 'ACCEPT'
config rule
option name 'Allow-Luci-SSH-LAN'
option family 'ipv4'
list proto 'tcp'
option src 'lan'
option dest_port '22 80'
option target 'ACCEPT'
config rule
option name 'Allow-ICMP-Router'
option family 'ipv4'
list proto 'icmp'
option src '*'
option target 'ACCEPT'
config rule
option name 'Allow-ICMP-Everywhere'
option family 'ipv4'
option target 'ACCEPT'
list proto 'icmp'
option src '*'
option dest '*'
Add the following to /etc/config/firewall
:
With the addition of the below multicast restrictions from the internet to the router's WAN interface and to/from the WAN zone from internal zones, simpler catch-all rules to allow the entire RFC1112 multicast block (224.0.0.0/4) to be used internally.
This RFC1112 block strategy minimises complexity while enabling cross-VLAN multicast for any device that relies on protocols like mDNS, SSDP, or multicast for discovery.
To allow new device types, simply add specific unicast firewall rules incrementally. Start by researching the traffic requirements for communication from the trusted VLAN to IOT, and vice versa (TCP dump and Wireshark are very useful for this). Then update the firewall rules accordingly.
config rule
option name 'Deny-ICMP-from-WAN' # Place at top of firewall rules
option family 'ipv4'
option src 'wan'
option proto 'icmp'
option target 'DROP'
list icmp_type 'echo-request'
config rule
option name 'Deny-Multicast-from-WAN' # Deny multicast to the router itself from WAN. Place at top of firewall rules
option family 'ipv4'
list proto 'udp'
option src 'wan'
option target 'DROP'
list dest_ip '224.0.0.0/4'
config rule
option name 'Deny-Multicast-WAN-to-Internal' # Deny multicast through the router. Place at top of firewall rules
option family 'ipv4'
option src 'wan'
option dest '*'
option proto 'udp'
option target 'DROP'
list dest_ip '224.0.0.0/4'
config rule
option name 'Deny-Multicast-All-Zones-to-WAN' # Deny multicast to the WAN. # Place at top of firewall rules
option family 'ipv4'
list proto 'udp'
option target 'DROP'
option src '*'
option dest 'wan'
list dest_ip '224.0.0.0/4'
config rule
option name 'Allow-Multicast-LAN'
option family 'ipv4'
option target 'ACCEPT'
option src 'lan'
list proto 'udp'
list dest_ip '224.0.0.0/4'
config rule
option name 'Allow-Multicast-IOT'
option family 'ipv4'
option target 'ACCEPT'
option src 'iot'
list proto 'udp'
list dest_ip '224.0.0.0/4'
config rule
option name 'Allow-Multicast-GUEST'
option family 'ipv4'
option target 'ACCEPT'
option src 'guest'
list proto 'udp'
list dest_ip '224.0.0.0/4'
config rule
option name 'Allow-Sonos-from-LAN'
option family 'ipv4'
option src 'lan'
option dest 'iot'
option target 'ACCEPT'
list proto 'all'
list dest_ip 'sonos.static.ip.range/29'
config rule
option name 'Allow-Sonos-from-Guest'
option family 'ipv4'
option src 'guest'
option dest 'iot'
option target 'ACCEPT'
list proto 'all'
list dest_ip 'sonos.static.ip.range/29'
config rule
option name 'Allow-Sonos-TCP-to-LAN'
option family 'ipv4'
option src 'iot'
option dest 'lan'
option target 'ACCEPT'
list proto 'tcp'
option src_port '445 3445 1400 1433 3400 3401 3500 4070 4444'
list src_ip 'sonos.static.ip.range/29'
config rule
option name 'Allow-Sonos-TCP-to-GUEST'
option family 'ipv4'
option src 'iot'
option dest 'guest'
option target 'ACCEPT'
list proto 'tcp'
option src_port '445 3445 1400 1433 3400 3401 3500 4070 4444'
list src_ip 'sonos.static.ip.range/29'
config rule
option name 'Allow-Sonos-UDP-to-LAN'
option family 'ipv4'
list proto 'udp'
option src 'iot'
option dest 'lan'
option target 'ACCEPT'
option dest_port '319 320 1900 1901 2869 5353 6969 10280-10284 30000-65535'
list src_ip 'sonos.static.ip.range/29'
config rule
option name 'Allow-Sonos-UDP-to-GUEST'
option family 'ipv4'
list proto 'udp'
option src 'iot'
option dest 'lan'
option target 'ACCEPT'
option dest_port '319 320 1900 1901 2869 5353 6969 10280-10284 30000-65535'
list src_ip 'sonos.static.ip.range/29'
Edit /etc/config/igmpproxy
to configure the upstream & downstream networks that will be allowed to proxy multicast:
Note: list altnet
should be used to restrict igmpproxy to just the desired internal networks. Don't use 0.0.0.0/0!
config igmpproxy
option quickleave 1
config phyint
option network lan
option zone lan
option direction upstream
list altnet 192.168.1.0/24 # Adjust to your LAN network address
config phyint
option network guest
option zone guest
option direction upstream
list altnet 192.168.2.0/24 # Adjust to your Guest network address
config phyint
option network iot
option zone iot
option direction downstream
list altnet 192.168.3.0/24 # a# Adjust to your IOT network address
For security, OpenWRT's default /etc/init.d/igmpproxy
launch script creates background firewall rules that block UDP uPnP multicast traffic on 239.255.255.250. However, Sonos device discovery across VLANs requires the relay of UDP on this same address.
Warning: Step 5 above must be completed first. Removing the launch script default restriction creates potential security risks if uPnP package(s) are present and/or firewall or other settings deviate or are less restrictive than the minimums provided in this guide.
To lift this restriction, replace the /etc/init.d/igmpproxy
script with the patched version linked below:
π Patched IGMPproxy launch script
In future OpenWRT versions it may be possible to toggle this uPnP script restriction on/off in a config file, as is suggested in this recent pull request
Edit /etc/avahi/avahi-daemon.conf
as follows:
Note: The allow-interfaces
directive must be used to restrict mDNS access to just the required internal networks.
[server]
use-ipv4=yes
use-ipv6=yes # Or no as required
check-response-ttl=no
use-iff-running=no
allow-interfaces=br-lan.90,br-lan.100,br-lan.110 # Adapt to your specific VLAN interfaces here
[publish]
publish-addresses=yes
publish-hinfo=yes
publish-workstation=no
publish-domain=yes
[reflector]
enable-reflector=yes
reflect-ipv=no
[rlimits]
rlimit-core=0
rlimit-data=4194304
rlimit-fsize=0
rlimit-nofile=30
rlimit-stack=4194304
rlimit-nproc=3
Because a router is typically always on, music library file sharing from the OpenWRT router itself offeres a very simple & low-power approach to file sharing. To achieve this, additionally install the Samba & WSDD2 packages and see this Youtube tutorial for sharing a usb drive with Samba & OpenWRT.
opkg update
opkg install luci-app-samba4 samba4-server wsdd2
or
apk update
apk add luci-app-samba4 samba4-server wsdd2
Edit the [Global] section of /etc/samba/smb/conf/template
as follows:
disable netbios = yes
min protocol = SMB2
smb ports = 445
mdns name = mdns
Now add a guest (password-free) music file share at the bottom of /etc/samba/smb/conf/template
.
[Music]
path = /mnt/disk/path
create mask = 0666
directory mask = 0777
read only = yes
guest ok = yes
vfs objects = io_uring
hosts allow = 192.168.1.0/24, 192.168.3.0/24 # Adjust to your LAN & IOT ip network addresses
hosts deny = 0.0.0.0/0 # deny everything else
Lastly, add the following firewall rules:
config rule
option name 'Allow-Router-SMB-LAN'
option family 'ipv4'
option dest_port '445 5355 3702'
option target 'ACCEPT'
option src 'lan'
config rule
option name 'Allow-Router-SMB-IOT'
option family 'ipv4'
option dest_port '445 5355 3702'
option target 'ACCEPT'
option src 'iot'
If using a virtual instance of OpenwWRT on x86, a very robust approach for adding a persistent file storage to OpenWRT is to create a separate EXT4 formatted vdisk and auto mount it via /etc/fstab
. For auto mount & vdisk file share persistence across firmware resets or firmware upgrades, create a new firmware image with the updated /etc/fstab
file baked in as a customised default via this useful script: https://github.com/itiligent/Easy-OpenWRT-Builder.
S1 & S2
- The above guide should work fine on Android or Apple IOS as S1 & S2 utilise ICMP, UDP 6969 and UDP 5353 (uPnP, not mDNS). The above firewall rules deliberately account for this. (Not tested).
Desktop Application:
- Apple OS: The above guide should work fine thanks to Bonjour for discovery. (Not tested).
- Windows: Will not work because this version relies on UDP 1900 broadcast to 255.255.255.255 for discovery (in addition to UDP 6969 and UDP 5353 as above). Some form of broadcast relay with a tool like Socat configured as below or similar may work. (Not tested).
config socat 'sonos_bcast_forward'
option enable '1'
option SocatOptions '-d -d udp4-recvfrom:1900,broadcast,fork udp4-sendto:192.168.3.255:1900'
option user 'nobody'
If previous behavior is a good predictor of future things, Sonos will be well on track to break things again.
The above config was tested on both Android and Apple devices on 12th Jan 2025 with the current latest available Sonos S80 application & firmware. All functions at that time were 100% working (Sonos S80 app, Airplay, new device discovery, new device setup, volume control, speaker grouping and Samba music library access all whilst connected to either the LAN VLAN or Guest VLAN).
Please submit an issue if you notice something is not working, or share any helpful suggestions.