Skip to content

Instantly share code, notes, and snippets.

@TwP
Last active February 24, 2024 19:31
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TwP/a8286f85dfb606a0403b71a6516f4132 to your computer and use it in GitHub Desktop.
Save TwP/a8286f85dfb606a0403b71a6516f4132 to your computer and use it in GitHub Desktop.

UniFi Sonos Configuration

Our goal today is to configure a VLAN for "Internet of Things" devices that is sequestered from our default private network. Devices on the private network are free to initiate connections into our IoT VLAN, but devices in the IoT VLAN should not be able to initiate connections to one another or to the private network.

The focus of this document is the configuration of UniFi system to allow Sonos speakers to operate across VLANs. Creating the VLAN itself is left to the user (there are many other guides out there that cover this topic). For our discussion, here are the networks we'll be working with:

  • 10.1.1.0/24 - this is our Private network where our trusted devices live.
  • 10.1.20.0/24 - this is our IoT network configured as VLAN 20; Sonos devices live here.

Sonos Speakers

Each Sonos speaker is assigned a static IP address via a DHCP reservation. These static IP addresses enable us to write some targeted firewall to allow the Sonos software to work across our VLANs. The IP addresses are all in the network block 10.1.20.16/28 giving us a starting IP address range of 10.1.20.17 to 10.1.20.30. Regular DHCP assignments start after this range.

This network block allows us to add / remove Sonos speakers in the future without requiring updates to our firewall "Port and IP Groups".

You can choose whatever network block works for your own setup. My network block is shoe-horned into the larger VLAN 20 address space; there are a few other static DHCP reservations that come before the Sonos speakers. Like all technology, this configuration has evolved over the years - don't judge me.

UniFi Network Config

Our two networks need a few settings to ensure that AirPlay and SSDP can traverse the VLANs. AirPlay is for playing music from your phone over to the Sonos speakers, and SSDP is the multicast protocol used by Sonos speakers to discover one another and the controller applications.

In the UniFi controller, navigate to the Settings > Networks page and for the Private (Default) network and the IoT network enable the following two settings:

  • Multicast DNS
  • IGMP Snooping

The Multicast DNS is used for the AirPlay protocol, and the IGMP Snooping helps the UniFi switches better manage all of the multicast traffic generated by the Sonos speakers. If you are using a UDM / UDM Pro, please make sure you are running at least UniFi OS 1.12.22; this release of UniFi OS added support for IGMP Snooping on the built-in switch ports on these devices.

IGMP Proxy

Wait! Didn't we just enable IGMP Snooping? Yes, but we also need the igmp-proxy to route multicast packets between our VLANS. Here is a brief article detailing IGMP Snooping vs IGMP Proxy if you're interested in diving a little deeper.

Enabling the igmp-proxy is a little different depending on which UniFi routing appliance you have installed in your network. We'll address each in the following sections.

USG

In order to configure this service we need to log into the USG and issue some configuration commands:

configure
edit protocols igmp-proxy
set interface eth1.20 role downstream
set interface eth1.20 threshold 1
set interface eth1.20 alt-subnet 0.0.0.0/0
set interface eth1 role upstream
set interface eth1 threshold 1
set interface eth1 alt-subnet 0.0.0.0/0
exit
commit
save

Here eth1.20 is the IoT VLAN interface for the Sonos equipment. You will need to restart the igmp-proxy for these changes to be picked up:

restart igmp-proxy

These changes will not be persisted across re-provisioning of the USG, so we'll need to add these settings to the config.gateway.json file. We use the mca-ctrl -t dump-cfg to dump the config and then extract our igmp-proxy configuration from the dump and add it to the gateway config. Here is the config.gateway.json entry:

{
  "protocols": {
    "igmp-proxy": {
      "interface": {
        "eth1": {
          "alt-subnet": ["0.0.0.0/0"],
          "role": "upstream",
          "threshold": "1"
        },
        "eth1.20": {
          "alt-subnet": ["0.0.0.0/0"],
          "role": "downstream",
          "threshold": "1"
        }
      }
    }
  }
}

UDM / UDM Pro

Ubiquiti has created a new operating system for the UDM family of devices. It is a Linux based system (which is nice) but it is lacking many of the features and configurability of the USG. What this means for us is that igmp-proxy is not present on UDM devices ... but it can be. You will need to manually install the igmpproxy package and then configure the upstream/downstream routes. I do not have a UDM device, so I'll defer to some helpful community forum posts and a GitHub repository.

Instructions for installing igmpproxy can be found in this community forum post. That forum thread details the changes that Ubiquiti made to the UniFi OS kernel to support multicast/multipath routing. Those changes make the installation process much easier.

The fabianishere/udm-iptv GitHub repository has a bunch of helpful scripts for installing and configuring the igmp-proxy service. The downside is that firmware updates wipe out the igmpproxy install and configuration. So the repository has tooling to reinstall and reconfigure after a firmware update.

It would be nice if Ubiquiti would build this into the controller software. Alas, it is not a priority for them.

Firewall

Now to isolate this VLAN and allow some Sonos communication.

Port and IP Groups

We need to configure a few Port groups and IP groups to use with the firewall rules that we are going to define. The IP groups are used to target the Sonos speakers, and the IP groups will enable a restricted set of traffic across VLANs.

You can create a new profile group by going to the Settings > Profiles > Port and IP Groups in the new UniFi controller (I'm using 7.1.66 for this write up).

This first group allows us to tailor firewall rules for our Private network of trusted devices.

Profile Name - Private  
        Type - IPv4 Atdress/Subnet  
        Port - 10.1.1.0/24

This second group is for our "Internet of Things" on VLAN 20.

Profile Name - IoT  
        Type - IPv4 Atdress/Subnet  
        Port - 10.1.20.0/24

This IP group allows us to target the Sonos speakers in our firewall rules.

Profile Name - Sonos  
        Type - IPv4 Atdress/Subnet  
        Port - 10.1.20.16/28  

The Sonos speakers need to communicate back to controller applications in the Private VLAN. The following TCP ports will be allowed from the Sonos segment of the IoT network back to the Private network.

Profile Name - Sonos App Control TCP  
        Type - Port Group  
        Port - 3400
               3401
               3500  

And there are a bunch of UDP ports used by the Sonos speakers to broadcast information about the currently playing track and playlist. Sonos tends to pick a random UDP port above 2^15, so that is the port range at the end of the list.

Profile Name - Sonos App Control UDP  
        Type - Port Group  
        Port - 319
               1900
               1901
               1902
               6969
               32768-65535  

I have no idea what Sonos uses all of those TCP and UDP ports for. During my initial setup of the Sonos system, I logged all of the denied traffic from the Sonos speakers and then opened up ports as needed to make things work. This is where I've landed. Things have been working fine even after the upgrade to the Sonos S2 system.

The Rules

Firewall rules are created by going to the Settings > Firewall & Security > Firewall Rules in the UniFi controller. All of the rules we will be creating are on the LAN-In portion of the firewall. The firewall rules are presented in the order that they should appear in your UniFi configuration. The order of the rules are important; they are applied sequentially and processing stops when a matching firewall rule is found. So if your first rule is to "drop all traffic", then any later rules that allow traffic will never be reached. Allow first then deny.

First we are going to allow established / related traffic through the firewall. This rule only applies to already established connections so that later deny rules don't drop this traffic.

              Type - LAN In  
       Description - Allow established/related Sessions
      Rule Applied - Before Predefined Rules  
            Action - Accept  
     IPv4 Protocol - All

       Source Type - Port/IP Group
IPv4 Address Group - Any
        Port Group - Any

  Destination Type - Port/IP Group
IPv4 Address Group - Any
        Port Group - Any

          Advanced - Manual
            States - [ ] Match State New
                     [x] Match State Established
                     [ ] Match State Invalid
                     [x] Match State Related

Now we are going to allow traffic from the Sonos speakers back to our Private network. We will only allow traffic on the TCP ports we defined earlier.

              Type - LAN In  
       Description - Allow Sonos to LAN TCP  
      Rule Applied - Before Predefined Rules  
            Action - Accept  
     IPv4 Protocol - TCP

       Source Type - Port/IP Group  
IPv4 Address Group - Sonos  
        Port Group - Any  

  Destination Type - Port/IP Group  
IPv4 Address Group - Private  
        Port Group - Sonos App Control TCP  

Next we allow Sonos --> Private traffic for the UDP ports.

              Type - LAN In  
       Description - Allow Sonos to LAN UDP
      Rule Applied - Before Predefined Rules  
            Action - Accept  
     IPv4 Protocol - UDP  

       Source Type - Port/IP Group
IPv4 Address Group - Sonos
        Port Group - Any

  Destination Type - Port/IP Group
IPv4 Address Group - Private
        Port Group - Sonos App Control UDP

And we allow the Sonos speakers to all talk to each other.

              Type - LAN In  
       Description - Allow Sonos to Sonos
      Rule Applied - Before Predefined Rules  
            Action - Accept  
     IPv4 Protocol - All

       Source Type - Port/IP Group
IPv4 Address Group - Sonos
        Port Group - Any

  Destination Type - Port/IP Group
IPv4 Address Group - Sonos
        Port Group - Any

Now we block all traffic between devices on our IoT VLAN. We only block "New" packets but allow "Established" / "Related" / "Invalid".

              Type - LAN In  
       Description - Drop IoT to IoT
      Rule Applied - Before Predefined Rules  
            Action - Drop  
     IPv4 Protocol - All

       Source Type - Port/IP Group
IPv4 Address Group - IoT
        Port Group - Any

  Destination Type - Port/IP Group
IPv4 Address Group - IoT
        Port Group - Any

          Advanced - Manual
            States - [x] Match State New
                     [ ] Match State Established
                     [ ] Match State Invalid
                     [ ] Match State Related

And we block all traffic from the IoT VLAN back to the Private network. Again, we only need to block "New" packets while allowing the rest. We still want devices in our Private network to be able to establish communications with devices on the IoT network.

              Type - LAN In  
       Description - Drop IoT to Private
      Rule Applied - Before Predefined Rules  
            Action - Drop  
     IPv4 Protocol - All

       Source Type - Port/IP Group
IPv4 Address Group - IoT
        Port Group - Any

  Destination Type - Port/IP Group
IPv4 Address Group - Private
        Port Group - Any

          Advanced - Manual
            States - [x] Match State New
                     [ ] Match State Established
                     [ ] Match State Invalid
                     [ ] Match State Related

Other references that I've used:

@HouseIndoril
Copy link

Just dropping in here to say this was the solution for my issue on a USG-PRO-4. Not with Sonos, but an LG webOS TV that I have VLAN'd off that behaves similarly.

I had to rejigger the firewall rules and interfaces in my config to match my environment (eth1.2 for my user devices and eth1.15 for the IoT subnet). I need to do some additional digging and figure out what other ports the TV uses for local control and the like but to confirm this worked I took my rule to drop all inter-VLAN traffic and set it to allow for a moment to test.

I suspect this is also going to fix a couple other things that haven't really been an issue, but would be nice to have. So in a few words, thank you for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment