I’m trying to improve my pi’s security by adding a firewall (I’ve chosen UFW, although that shouldn’t matter for this question). I have configured it to allow all outgoing traffic, to block all incoming traffic, and then added some rules to allow specific ports to allow incoming traffic for HASS, Mosquitto, SSH, Pi-Hole etc.
However, ever since I turned the firewall on the Sonos media_player component has stopped working. Adding a rule to allow all incoming traffic from the Sonos’ IP address solves the issue, so the firewall is the reason that it has stopped working.
Things I have tried so far:
Adding rules to allow all incoming traffic on ports used by Sonos as defined on their website:
Looking at the UFW logs to see which ports are blocked when trying to connect to Sonos after a HASS restart and adding rules to allow incoming traffic on these ports
But nothing helps!
For now I have simply added a rule to allow all incoming traffic from the Sonos IP address on all ports, which works, but I want to understand why it isn’t working!
So my big question is: which ports are used to allow a connection between HASS and Sonos?
Necro’ing an old thread, but I thought I’d share an excellent serverfault page for how to enable UPNP service discovery via UFW, without whitelisting the 192.168.0.0/16 IP range. This worked for me running HA via docker, with host networking, on raspbian.
sudo apt-get install ipset
ipset create upnp hash:ip,port timeout 3
#add the following to your /etc/ufw/before.rules, before the commit statement
-A ufw-before-input -p udp -m set --match-set upnp dst,dst -j ACCEPT
-A ufw-before-output -d 239.255.255.250/32 -p udp -m udp --dport 1900 -j SET --add-set upnp src,src --exist
What these rules do, which is explained in serverfault, is insert, temporarily, the source port when sending to the multicast ssdp address. Then, when evaluating the rules for incoming, if the dest port of a packet exists in that set (which has a 3 second timeout), it allows it.
As an example, this was what was happening before this rule was added:
We can see the multicast go out from port 50338, but then the reply got blocked. Firewalls usually allow response to whatever port was just used, but that only works when the DEST for outgoing, matching the SRC for incoming, which isn’t true with broadcast packets.
This work great, except if you reboot your Raspberry Pi will lose the ability to reach the network because the ipset command doesn’t run on startup and ufw chokes on the iptables rules and leaves your firewall in a hosed state. I have been using this guide to persist the ipset rules and it works across reboots now: