{"version":"https://jsonfeed.org/version/1.1","title":"Jaryl Chng's Knowledge Base","home_page_url":"https://kb.jarylchng.com","feed_url":"https://kb.jarylchng.com/json/","description":"<p>Welcome to the index page of my knowledge base, if you haven't done so, do visit my website at <a href=\"https://jarylchng.com\" rel=\"noopener noreferrer\" target=\"_blank\">https://jarylchng.com</a>.</p><p>I will mainly use this site to document stuff, most of which will likely be in the public domain.</p>","icon":"https://kb-static.jarylchng.com/kb-jarylchng-com/production/images/channel-c68f1f55f856ab833b4365991609dbec.png","favicon":"https://kb-static.jarylchng.com/kb-jarylchng-com/production/images/favicon-b94914f57599a477f9f72dab6bc71001.png","authors":[{"name":"Jaryl Chng"}],"language":"en-us","items":[{"id":"72mN-cdfjph","title":"Sonos - Asus Router Merlin Yazfi Guest Network with One Way to Guest","attachments":[{"url":"https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/image-f00ed809361ceabd0d29380d07f2d3d5.png","mime_type":"image/png","size_in_byte":206925}],"url":"https://kb.jarylchng.com/i/sonos-asus-router-merlin-yazfi-guest-network-wit-72mN-cdfjph/","content_html":"<h2>Update 13/01/2025</h2><p>For Sonos products that only support Airplay v2 (ERA100s, ERA300s, Sonos Arc Ultram etc.), there is currently a bug when placing your Sonos devices in a separate VLAN and trying to Airplay to them.</p><p>See this community thread for more information: <a href=\"https://en.community.sonos.com/advanced-setups-229000/unable-to-airplay-to-era-100-in-separate-vlan-ubiquity-6920955\" rel=\"noopener noreferrer\" target=\"_blank\">https://en.community.sonos.com/advanced-setups-229000/unable-to-airplay-to-era-100-in-separate-vlan-ubiquity-6920955</a></p><h2>Update 16/05/2024 notice: version 80.xx.xx.xx</h2><p>After the mobile app update to version 80.xx.xx.xx, the method that the app use to discover speakers has completely changed. It is now required to allow destination UDP port 1900 (UPNP) traffic and source TCP port 1443 to flow to br0 instead:</p><pre class=\"ql-syntax\" spellcheck=\"false\">iptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p udp --dport 1900 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --sport 1443 -j ACCEPT\n</pre><p>Where 172.27.15.3 is the IP address of the Sonos system.</p><p>For Airplay to work it is also required to allow destination TCP ephemeral ports, source TCP 7000 (BBS), along with destination UDP 319:320 (PTP) ports to flow to br0:</p><pre class=\"ql-syntax\" spellcheck=\"false\">iptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --dport 32768:65535 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --sport 7000 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p udp --dport 319:320 -j ACCEPT\n</pre><p>Where 172.27.15.3 is the IP address of the Sonos system.</p><p>I've also noticed that Sonos also need source TCP 4444 (krb524) to br0 while running updates:</p><pre class=\"ql-syntax\" spellcheck=\"false\">iptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --sport 4444 -j ACCEPT\n</pre><p>Where 172.27.15.3 is the IP address of the Sonos system.</p><p>Relevant new tcpdumps:</p><pre class=\"ql-syntax\" spellcheck=\"false\"># SONOS APP TESTING\njarylc@RT-AX88U:/jffs/addons/YazFi.d/userscripts.d# tcpdump -i any src 172.27.15.3 and dst 172.27.14.98\n08:23:59.721602 wl0.1 In&nbsp; IP 172.27.15.3.34242 &gt; 172.27.14.98.upnp: UDP, length 741\n08:23:59.721669 br0&nbsp;&nbsp; Out IP 172.27.15.3.34242 &gt; 172.27.14.98.upnp: UDP, length 741\n08:23:59.721678 eth7&nbsp; Out IP 172.27.15.3.34242 &gt; 172.27.14.98.upnp: UDP, length 741\n08:23:59.870068 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [S.], seq 165454314, ack 134039494, win 28960, options [mss 1460,sackOK,TS val 355714560 ecr 4169303348,nop,wscale 7], length 0\n08:23:59.870090 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [S.], seq 165454314, ack 134039494, win 28960, options [mss 1460,sackOK,TS val 355714560 ecr 4169303348,nop,wscale 7], length 0\n08:23:59.870093 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [S.], seq 165454314, ack 134039494, win 28960, options [mss 1460,sackOK,TS val 355714560 ecr 4169303348,nop,wscale 7], length 0\n08:23:59.926271 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [.], ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 0\n08:23:59.926303 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [.], ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 0\n08:23:59.926307 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [.], ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 0\n08:23:59.926275 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [P.], seq 1:63, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 62\n08:23:59.926330 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [P.], seq 1:63, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 62\n08:23:59.926333 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [P.], seq 1:63, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 62\n08:23:59.926280 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [.], seq 63:1511, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 1448\n08:23:59.926357 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [.], seq 63:1511, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 1448\n08:23:59.926361 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [.], seq 63:1511, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 1448\n08:24:01.100909 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [P.], seq 2093:2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 31\n08:24:01.100937 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [P.], seq 2093:2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 31\n08:24:01.100942 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [P.], seq 2093:2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 31\n08:24:01.100913 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 0\n08:24:01.100960 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 0\n08:24:01.100963 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 0\n08:24:01.190110 wl0.1 In&nbsp; IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714891 ecr 4169304590], length 0\n08:24:01.190127 br0&nbsp;&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714891 ecr 4169304590], length 0\n08:24:01.190130 eth7&nbsp; Out IP 172.27.15.3.1443 &gt; 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714891 ecr 4169304590], length 0\n08:25:01.196936 wl0.1 In&nbsp; IP 172.27.15.3.33005 &gt; 172.27.14.98.57454: UDP, length 741\n08:25:03.196969 br0&nbsp;&nbsp; Out IP 172.27.15.3.33005 &gt; 172.27.14.98.57454: UDP, length 741\n08:25:05.196976 eth7&nbsp; Out IP 172.27.15.3.33005 &gt; 172.27.14.98.57454: UDP, length 741\n\n# AIRPLAY TESTING\njarylc@RT-AX88U-0BC0:/tmp/home/root# tcpdump -i any src 172.27.15.3 and dst 172.27.14.110\ntcpdump: data link type LINUX_SLL2\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes\n08:59:34.272732 wl0.1 In&nbsp; IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [S.], seq 361871852, ack 1905326041, win 28960, options [mss 1460,sackOK,TS val 356248160 ecr 2914930491,nop,wscale 7], length 0\n08:59:34.272761 br0&nbsp;&nbsp; Out IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [S.], seq 361871852, ack 1905326041, win 28960, options [mss 1460,sackOK,TS val 356248160 ecr 2914930491,nop,wscale 7], length 0\n08:59:34.272769 eth7&nbsp; Out IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [S.], seq 361871852, ack 1905326041, win 28960, options [mss 1460,sackOK,TS val 356248160 ecr 2914930491,nop,wscale 7], length 0\n08:59:34.284023 wl0.1 In&nbsp; IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [.], ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 0\n08:59:34.284038 br0&nbsp;&nbsp; Out IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [.], ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 0\n08:59:34.284041 eth7&nbsp; Out IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [.], ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 0\n08:59:34.288263 wl0.1 In&nbsp; IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [P.], seq 1:977, ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 976\n08:59:34.288281 br0&nbsp;&nbsp; Out IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [P.], seq 1:977, ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 976\n08:59:34.288285 eth7&nbsp; Out IP 172.27.15.3.bbs &gt; 172.27.14.110.53646: Flags [P.], seq 1:977, ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 976\n08:59:35.333401 wl0.1 In&nbsp; IP 172.27.15.3 &gt; 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 112\n08:59:35.333430 br0&nbsp;&nbsp; Out IP 172.27.15.3 &gt; 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 112\n08:59:35.333435 eth7&nbsp; Out IP 172.27.15.3 &gt; 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 112\n08:59:35.333405 wl0.1 In&nbsp; IP 172.27.15.3 &gt; 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 142\n08:59:35.333452 br0&nbsp;&nbsp; Out IP 172.27.15.3 &gt; 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 142\n08:59:35.333455 eth7&nbsp; Out IP 172.27.15.3 &gt; 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 142\n08:59:35.333408 wl0.1 In&nbsp; IP 172.27.15.3.46785 &gt; 172.27.14.110.53647: Flags [S.], seq 4199358917, ack 972859376, win 28960, options [mss 1460,sackOK,TS val 356248426 ecr 2879974157,nop,wscale 7], length 0\n08:59:35.333474 br0&nbsp;&nbsp; Out IP 172.27.15.3.46785 &gt; 172.27.14.110.53647: Flags [S.], seq 4199358917, ack 972859376, win 28960, options [mss 1460,sackOK,TS val 356248426 ecr 2879974157,nop,wscale 7], length 0\n08:59:35.333477 eth7&nbsp; Out IP 172.27.15.3.46785 &gt; 172.27.14.110.53647: Flags [S.], seq 4199358917, ack 972859376, win 28960, options [mss 1460,sackOK,TS val 356248426 ecr 2879974157,nop,wscale 7], length 0\n\n# UPDATE TESTING\njarylc@RT-AX88U-0BC0:/tmp/home/root# tcpdump -i any src 172.27.15.3 or src 172.27.15.1 or src 172.27.15.3\n08:22:01.901621 wl0.1 In&nbsp; IP 172.27.15.3.krb524 &gt; 172.27.14.98.35390: Flags [R.], seq 0, ack 3400968069, win 0, length 0\n08:22:01.901646 br0&nbsp;&nbsp; Out IP 172.27.15.3.krb524 &gt; 172.27.14.98.35390: Flags [R.], seq 0, ack 1, win 0, length 0\n08:22:01.901653 eth7&nbsp; Out IP 172.27.15.3.krb524 &gt; 172.27.14.98.35390: Flags [R.], seq 0, ack 1, win 0, length 0\n</pre><p>Overall, my latest script looks like this now:</p><pre class=\"ql-syntax\" spellcheck=\"false\">HOME_ASSISTANT='172.27.14.254'\nMEDIA_RANGE='172.27.15.2-172.27.15.20'\niptables -I YazFiFORWARD -i wl0.1 -o br0 -d ${HOME_ASSISTANT} -p tcp -m multiport --dports 1400,8123 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -m iprange --src-range \"${MEDIA_RANGE}\" -p tcp --dport 32768:65535 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -m iprange --src-range \"${MEDIA_RANGE}\" -p udp -m multiport --dports 319,320,1900 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -m iprange --src-range \"${MEDIA_RANGE}\" -p tcp -m multiport --sports 1400,1443,4444,7000 -j ACCEPT\n</pre><blockquote>End of update here, original post follows</blockquote><p>Most recently I've discovered that <a href=\"https://www.asuswrt-merlin.net/\" rel=\"noopener noreferrer\" target=\"_blank\">Asuswrt-Merlin (community firmware for Asus routers)</a> has a terminal UI interface `<a href=\"https://github.com/RMerl/asuswrt-merlin.ng/wiki/AMTM\" rel=\"noopener noreferrer\" target=\"_blank\">amtm</a>`.</p><p>Within it there is a project called <a href=\"https://github.com/jackyaz/YazFi\" rel=\"noopener noreferrer\" target=\"_blank\">Yazfi by @jackyaz</a> which provides a \"feature expansion of guest Wi-Fi networks on AsusWRT-Merlin\".</p><p>I've always wanted to move all my smart devices to another VLAN with only pinhole access to my main LAN. Thanks to Yazfi, the effort is reduced tremendously trying to configure these while leveraging on the Guest Network functionality of Asus Routers. With that, I started my project to reformat my Asus Router, rotating my Wi-Fi passwords and start moving everything over.</p><p>I did however encounter some issues with discovering Sonos devices on the mobile app even with `One way to guest` enabled, it was either totally not discovering or very slow, and decided to start digging into it.</p><h2>Investigation</h2><blockquote>This section explains how I investigated how the Sonos works in my network under the hood and you can skip to the Solution section below if you only care about that!</blockquote><h3>Temporarily allowing two-way traffic between LAN and Guest Network</h3><p><img src=\"https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/rich-editor/items/72mN-cdfjph/image-5ac9a50702c7676fa5aa8c61de1a85a3.png\"></p><p>Since we are investigating how Sonos operates, I temporarily allowed two-way communication between the 2 networks in Yazfi configuration.</p><h3>Enabling multicast routing</h3><p><img src=\"https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/rich-editor/items/72mN-cdfjph/image-57274ae829415195afe92f3d8103d890.png\"></p><p>Since various online sources says that Sonos uses <a href=\"https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol\" rel=\"noopener noreferrer\" target=\"_blank\">Simple Service Discovery Protocol (SSDP)</a> and <a href=\"https://en.wikipedia.org/wiki/Multicast_DNS\" rel=\"noopener noreferrer\" target=\"_blank\">multicast DNS (mDNS)</a> to support discoverability, for good measure, I enabled multicast routing under LAN &gt; IPTV &gt; Enable multicast routing</p><p>However I'm not 100% sure there is a need for this.</p><h3>Installing entware and tcpdump on my router</h3><p>You can <a href=\"https://github.com/RMerl/asuswrt-merlin.ng/wiki/Entware\" rel=\"noopener noreferrer\" target=\"_blank\">follow these instructions to install entware on your router</a>.</p><p>After installationof entware is complete, it's as simple as</p><pre class=\"ql-syntax\" spellcheck=\"false\">jarylc@RT-AX88U:/tmp/home/root# opkg install tcpdump\n</pre><h3>Running tcpdump</h3><p>After snooping around the UI and the Sonos App, the private IP addresses of the relevant devices are the following:</p><ul><li>My Android phone: 172.27.14.98 (172.27.14.x is my main LAN)</li><li>One of my Sonos devices: 172.27.15.3 (172.27.15.x is my smart devices Guest network)</li></ul><p>I limited the snooping to UDP packets only as that is what SSDP and mDNS primarily uses</p><pre class=\"ql-syntax\" spellcheck=\"false\">jarylc@RT-AX88U:/jffs/addons/YazFi.d/userscripts.d# tcpdump -i any 'udp and (src 172.27.15.3 or src 172.27.14.98)'\n09:26:30.044460 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 200\n09:26:30.044469 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 200\n09:26:30.044433 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 200\n09:26:30.044582 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 200\n09:26:30.044589 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 200\n09:26:30.044443 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 200\n09:26:30.045267 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:30.045274 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:30.045259 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:30.045539 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:30.045544 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:30.045530 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:30.048134 wl0.4 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:30.048139 wl0.1 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:30.048125 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:30.227307 wl0.1 M&nbsp;&nbsp; IP 172.27.15.3.5353 &gt; mdns.mcast.net.5353: 0*- [0q] 1/0/6 PTR Sonos-XXXXXXXXXXXX@Media Room._sonos._tcp.local. (676)\n09:26:30.266863 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:30.266871 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:30.266828 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:30.266945 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:30.266950 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:30.266840 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:30.580416 wl0.1 In&nbsp; IP 172.27.15.3.37360 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:30.580456 br0&nbsp;&nbsp; Out IP 172.27.15.3.37360 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:31.072123 wl0.4 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:31.072128 wl0.1 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:31.071869 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:31.072203 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 200\n09:26:31.072208 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 200\n09:26:31.071885 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 200\n09:26:31.072269 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 200\n09:26:31.072274 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 200\n09:26:31.071892 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 200\n09:26:31.309102 wl0.1 In&nbsp; IP 172.27.15.3.38139 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:31.309125 br0&nbsp;&nbsp; Out IP 172.27.15.3.38139 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:31.343765 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:31.343773 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:31.343737 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:31.343853 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:31.343858 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:31.343748 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:31.692594 wl0.1 In&nbsp; IP 172.27.15.3.38570 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:31.692617 br0&nbsp;&nbsp; Out IP 172.27.15.3.38570 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:32.271746 wl0.4 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:32.271753 wl0.1 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:32.271598 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:32.278203 eth7&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:32.278226 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:32.278232 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:32.278203 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:32.278296 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:32.278301 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:32.278214 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:32.465141 wl0.1 M&nbsp;&nbsp; IP 172.27.15.3.5353 &gt; mdns.mcast.net.5353: 0*- [0q] 1/0/6 PTR Sonos-XXXXXXXXXXXX@Media Room._sonos._tcp.local. (676)\n09:26:32.701778 wl0.1 In&nbsp; IP 172.27.15.3.41457 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:32.701801 br0&nbsp;&nbsp; Out IP 172.27.15.3.41457 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:33.215347 wl0.4 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:33.215355 wl0.1 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:33.215331 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:33.905757 wl0.4 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:33.905763 wl0.1 Out IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:33.905736 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 239.255.255.250.upnp: UDP, length 254\n09:26:33.905846 wl0.4 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:33.905851 wl0.1 Out IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:33.905744 br0&nbsp;&nbsp; B&nbsp;&nbsp; IP 172.27.14.98.37972 &gt; 255.255.255.255.upnp: UDP, length 254\n09:26:34.034082 wl0.1 In&nbsp; IP 172.27.15.3.59807 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:34.034122 br0&nbsp;&nbsp; Out IP 172.27.15.3.59807 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:34.220437 wl0.4 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 3 PTR (QM)? _sonos._tcp.local. (35)\n09:26:34.220444 wl0.1 Out IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 3 PTR (QM)? _sonos._tcp.local. (35)\n09:26:34.220422 br0&nbsp;&nbsp; M&nbsp;&nbsp; IP 172.27.14.98.5353 &gt; mdns.mcast.net.5353: 3 PTR (QM)? _sonos._tcp.local. (35)\n09:26:34.387343 wl0.1 M&nbsp;&nbsp; IP 172.27.15.3.5353 &gt; mdns.mcast.net.5353: 0*- [0q] 1/0/6 PTR Sonos-XXXXXXXXXXXX@Media Room._sonos._tcp.local. (676)\n</pre><h3>The problem</h3><pre class=\"ql-syntax\" spellcheck=\"false\">09:26:30.580416 wl0.1 In&nbsp; IP 172.27.15.3.37360 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:30.580456 br0&nbsp;&nbsp; Out IP 172.27.15.3.37360 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:31.309102 wl0.1 In&nbsp; IP 172.27.15.3.38139 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:31.309125 br0&nbsp;&nbsp; Out IP 172.27.15.3.38139 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:32.701778 wl0.1 In&nbsp; IP 172.27.15.3.41457 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:32.701801 br0&nbsp;&nbsp; Out IP 172.27.15.3.41457 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:34.034082 wl0.1 In&nbsp; IP 172.27.15.3.59807 &gt; 172.27.14.98.37972: UDP, length 741\n09:26:34.034122 br0&nbsp;&nbsp; Out IP 172.27.15.3.59807 &gt; 172.27.14.98.37972: UDP, length 741\n</pre><p>Filtering out all the noise, I noticed that the Sonos device was trying to send a UDP packet from the ephemeral UDP ports (range 32768-65535) to my mobile device.</p><p>This is actually not surprising as that is how SSDP works as the device would switch to unicast after being discovered. Prior to this, I was not very familiar with SSDP and did not know that.</p><p>I noticed in a previous tcpdump before enabling two-way communication that this was being blocked:</p><pre class=\"ql-syntax\" spellcheck=\"false\">00:13:65.371058 wl0.1 In&nbsp; IP 172.27.15.3.46814 &gt; 172.27.14.98.49972: UDP, length 737\n00:13:54.373059 wl0.1 Out IP 172.27.15.1 &gt; 172.27.15.3: ICMP 172.27.14.98 udp port 49972 unreachable, length 556\n</pre><h3><img src=\"https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/image-f00ed809361ceabd0d29380d07f2d3d5.png\"></h3><h2>Solution</h2><h3>Adding custom firewall allow rules to Yazfi to allow this UDP traffic from Sonos devices</h3><p><a href=\"https://github.com/jackyaz/YazFi?tab=readme-ov-file#custom-firewall-rules\" rel=\"noopener noreferrer\" target=\"_blank\">Yazfi allows additional iptables rules by adding a shell script with iptables commands to any file in `/jffs/addons/YazFi.d/userscripts.d/`</a></p><p>With that I created a file called `myscript.sh` within the folder and placed this in the file to allow UDP traffic on the ephemeral ports (range 32768-65535) originating from the Sonos device to flow back to the main LAN</p><pre class=\"ql-syntax\" spellcheck=\"false\">#!/bin/sh\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p udp --dport 32768:65535 -j ACCEPT\n</pre><ul><li>`-I YazFiForward` - adds the rule to the FORWARD chain in the YazFi table</li><li>`-i wl0.1` - <strong>make sure to change this to your actual Guest Wi-Fi interface</strong></li><li>`-o br0` - packets moving to the bridge interface</li><li>`-s 172.27.15.3` - <strong>make sure to change this to your actual Sonos device's IP address</strong></li><li>`-p udp` - UDP packets only</li><li>`--dport 32768:65536` - ephemeral UDP port ranges only</li><li>`-j ACCEPT` - allow packets filtered by this rule</li></ul><blockquote>You can duplicate that iptables line for as many Sonos device you have and their respective IPs, or you can also use `-srcrange` (i.e. `-m iprange --src-range 172.27.15.2-172.27.15.9`) if you have configured continuous static DHCP IPs for them.</blockquote><p>Be reminded to `chmod +x` the file afterwards</p><pre class=\"ql-syntax\" spellcheck=\"false\">jarylc@RT-AX88U:/jffs/addons/YazFi.d/userscripts.d# chmod +x myscript.sh\n</pre><h3>Reverting to only allowing one-way (LAN to Guest) communication</h3><p><img src=\"https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/rich-editor/items/72mN-cdfjph/image-f772aec66b26bfe8d57b92437818a68f.png\"></p><p>During investigation, I allowed two-way communication, so I am reverting it to one-way only in the Yazfi configuration.</p><h3>Testing the Sonos app again</h3><p>Sure enough, after allowing the UDP packet to flow back allows the Sonos app to be snappy again.</p><h2>Bonus</h2><h3>HomeAssistant</h3><p>I integrated my Sonos systems with HomeAssistant as well, it is also <a href=\"https://www.home-assistant.io/integrations/sonos/#network-requirements\" rel=\"noopener noreferrer\" target=\"_blank\">recommended by them to enable communication back via port 1400</a></p><pre class=\"ql-syntax\" spellcheck=\"false\">iptables -I YazFiFORWARD -i wl0.1 -o br0 -d 172.27.14.100 -p tcp --dport 1400 -j ACCEPT\n</pre><ul><li>`-I YazFiForward` - adds the rule to the FORWARD chain in the YazFi table</li><li>`-i wl0.1` - <strong>make sure to change this to your actual Guest Wi-Fi interface</strong></li><li>`-o br0` - packets moving to the bridge interface</li><li>`-s 172.27.14.100` - <strong>make sure to change this to your actual HomeAssistant's IP address</strong></li><li>`-p tcp` - TCP packets only</li><li>`-dport 1400` - port 1400 only</li><li>`-j ACCEPT` - allow packets filtered by this rule</li></ul><p>It is also highly recommended to allow the Sonos systems to communicate with HomeAssistant directly (especially to use local media storage if you have any)</p><pre class=\"ql-syntax\" spellcheck=\"false\">iptables -I YazFiFORWARD -i wl0.1 -o br0 -d 172.27.14.100 -p tcp --dport 8123 -j ACCEPT\n</pre><ul><li>`-I YazFiForward` - adds the rule to the FORWARD chain in the YazFi table</li><li>`-i wl0.1` - <strong>make sure to change this to your actual Guest Wi-Fi interface</strong></li><li>`-o br0` - packets moving to the bridge interface</li><li>`-s 172.27.14.100` - <strong>make sure to change this to your actual HomeAssistant's IP address</strong></li><li>`-p tcp` - TCP packets only</li><li>`-dport 8123` - <strong>make sure to change this to your actual HomeAssistant's port</strong></li><li>`-j ACCEPT` - allow packets filtered by this rule</li></ul>","content_text":"UPDATE 13/01/2025\n\nFor Sonos products that only support Airplay v2 (ERA100s, ERA300s, Sonos Arc\nUltram etc.), there is currently a bug when placing your Sonos devices in a\nseparate VLAN and trying to Airplay to them.\n\nSee this community thread for more information:\nhttps://en.community.sonos.com/advanced-setups-229000/unable-to-airplay-to-era-100-in-separate-vlan-ubiquity-6920955\n\n\nUPDATE 16/05/2024 NOTICE: VERSION 80.XX.XX.XX\n\nAfter the mobile app update to version 80.xx.xx.xx, the method that the app use\nto discover speakers has completely changed. It is now required to allow\ndestination UDP port 1900 (UPNP) traffic and source TCP port 1443 to flow to br0\ninstead:\n\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p udp --dport 1900 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --sport 1443 -j ACCEPT\n\n\nWhere 172.27.15.3 is the IP address of the Sonos system.\n\nFor Airplay to work it is also required to allow destination TCP ephemeral\nports, source TCP 7000 (BBS), along with destination UDP 319:320 (PTP) ports to\nflow to br0:\n\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --dport 32768:65535 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --sport 7000 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p udp --dport 319:320 -j ACCEPT\n\n\nWhere 172.27.15.3 is the IP address of the Sonos system.\n\nI've also noticed that Sonos also need source TCP 4444 (krb524) to br0 while\nrunning updates:\n\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p tcp --sport 4444 -j ACCEPT\n\n\nWhere 172.27.15.3 is the IP address of the Sonos system.\n\nRelevant new tcpdumps:\n\n# SONOS APP TESTING\njarylc@RT-AX88U:/jffs/addons/YazFi.d/userscripts.d# tcpdump -i any src 172.27.15.3 and dst 172.27.14.98\n08:23:59.721602 wl0.1 In  IP 172.27.15.3.34242 > 172.27.14.98.upnp: UDP, length 741\n08:23:59.721669 br0   Out IP 172.27.15.3.34242 > 172.27.14.98.upnp: UDP, length 741\n08:23:59.721678 eth7  Out IP 172.27.15.3.34242 > 172.27.14.98.upnp: UDP, length 741\n08:23:59.870068 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [S.], seq 165454314, ack 134039494, win 28960, options [mss 1460,sackOK,TS val 355714560 ecr 4169303348,nop,wscale 7], length 0\n08:23:59.870090 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [S.], seq 165454314, ack 134039494, win 28960, options [mss 1460,sackOK,TS val 355714560 ecr 4169303348,nop,wscale 7], length 0\n08:23:59.870093 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [S.], seq 165454314, ack 134039494, win 28960, options [mss 1460,sackOK,TS val 355714560 ecr 4169303348,nop,wscale 7], length 0\n08:23:59.926271 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [.], ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 0\n08:23:59.926303 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [.], ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 0\n08:23:59.926307 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [.], ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 0\n08:23:59.926275 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [P.], seq 1:63, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 62\n08:23:59.926330 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [P.], seq 1:63, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 62\n08:23:59.926333 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [P.], seq 1:63, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 62\n08:23:59.926280 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [.], seq 63:1511, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 1448\n08:23:59.926357 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [.], seq 63:1511, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 1448\n08:23:59.926361 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [.], seq 63:1511, ack 157, win 235, options [nop,nop,TS val 355714574 ecr 4169303497], length 1448\n08:24:01.100909 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [P.], seq 2093:2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 31\n08:24:01.100937 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [P.], seq 2093:2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 31\n08:24:01.100942 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [P.], seq 2093:2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 31\n08:24:01.100913 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 0\n08:24:01.100960 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 0\n08:24:01.100963 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714868 ecr 4169304590], length 0\n08:24:01.190110 wl0.1 In  IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714891 ecr 4169304590], length 0\n08:24:01.190127 br0   Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714891 ecr 4169304590], length 0\n08:24:01.190130 eth7  Out IP 172.27.15.3.1443 > 172.27.14.98.50146: Flags [F.], seq 2124, ack 476, win 243, options [nop,nop,TS val 355714891 ecr 4169304590], length 0\n08:25:01.196936 wl0.1 In  IP 172.27.15.3.33005 > 172.27.14.98.57454: UDP, length 741\n08:25:03.196969 br0   Out IP 172.27.15.3.33005 > 172.27.14.98.57454: UDP, length 741\n08:25:05.196976 eth7  Out IP 172.27.15.3.33005 > 172.27.14.98.57454: UDP, length 741\n\n# AIRPLAY TESTING\njarylc@RT-AX88U-0BC0:/tmp/home/root# tcpdump -i any src 172.27.15.3 and dst 172.27.14.110\ntcpdump: data link type LINUX_SLL2\ntcpdump: verbose output suppressed, use -v[v]... for full protocol decode\nlistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes\n08:59:34.272732 wl0.1 In  IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [S.], seq 361871852, ack 1905326041, win 28960, options [mss 1460,sackOK,TS val 356248160 ecr 2914930491,nop,wscale 7], length 0\n08:59:34.272761 br0   Out IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [S.], seq 361871852, ack 1905326041, win 28960, options [mss 1460,sackOK,TS val 356248160 ecr 2914930491,nop,wscale 7], length 0\n08:59:34.272769 eth7  Out IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [S.], seq 361871852, ack 1905326041, win 28960, options [mss 1460,sackOK,TS val 356248160 ecr 2914930491,nop,wscale 7], length 0\n08:59:34.284023 wl0.1 In  IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [.], ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 0\n08:59:34.284038 br0   Out IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [.], ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 0\n08:59:34.284041 eth7  Out IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [.], ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 0\n08:59:34.288263 wl0.1 In  IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [P.], seq 1:977, ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 976\n08:59:34.288281 br0   Out IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [P.], seq 1:977, ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 976\n08:59:34.288285 eth7  Out IP 172.27.15.3.bbs > 172.27.14.110.53646: Flags [P.], seq 1:977, ack 281, win 235, options [nop,nop,TS val 356248164 ecr 2914930539], length 976\n08:59:35.333401 wl0.1 In  IP 172.27.15.3 > 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 112\n08:59:35.333430 br0   Out IP 172.27.15.3 > 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 112\n08:59:35.333435 eth7  Out IP 172.27.15.3 > 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 112\n08:59:35.333405 wl0.1 In  IP 172.27.15.3 > 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 142\n08:59:35.333452 br0   Out IP 172.27.15.3 > 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 142\n08:59:35.333455 eth7  Out IP 172.27.15.3 > 172.27.14.110: ICMP 172.27.15.3 udp port 320 unreachable, length 142\n08:59:35.333408 wl0.1 In  IP 172.27.15.3.46785 > 172.27.14.110.53647: Flags [S.], seq 4199358917, ack 972859376, win 28960, options [mss 1460,sackOK,TS val 356248426 ecr 2879974157,nop,wscale 7], length 0\n08:59:35.333474 br0   Out IP 172.27.15.3.46785 > 172.27.14.110.53647: Flags [S.], seq 4199358917, ack 972859376, win 28960, options [mss 1460,sackOK,TS val 356248426 ecr 2879974157,nop,wscale 7], length 0\n08:59:35.333477 eth7  Out IP 172.27.15.3.46785 > 172.27.14.110.53647: Flags [S.], seq 4199358917, ack 972859376, win 28960, options [mss 1460,sackOK,TS val 356248426 ecr 2879974157,nop,wscale 7], length 0\n\n# UPDATE TESTING\njarylc@RT-AX88U-0BC0:/tmp/home/root# tcpdump -i any src 172.27.15.3 or src 172.27.15.1 or src 172.27.15.3\n08:22:01.901621 wl0.1 In  IP 172.27.15.3.krb524 > 172.27.14.98.35390: Flags [R.], seq 0, ack 3400968069, win 0, length 0\n08:22:01.901646 br0   Out IP 172.27.15.3.krb524 > 172.27.14.98.35390: Flags [R.], seq 0, ack 1, win 0, length 0\n08:22:01.901653 eth7  Out IP 172.27.15.3.krb524 > 172.27.14.98.35390: Flags [R.], seq 0, ack 1, win 0, length 0\n\n\nOverall, my latest script looks like this now:\n\nHOME_ASSISTANT='172.27.14.254'\nMEDIA_RANGE='172.27.15.2-172.27.15.20'\niptables -I YazFiFORWARD -i wl0.1 -o br0 -d ${HOME_ASSISTANT} -p tcp -m multiport --dports 1400,8123 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -m iprange --src-range \"${MEDIA_RANGE}\" -p tcp --dport 32768:65535 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -m iprange --src-range \"${MEDIA_RANGE}\" -p udp -m multiport --dports 319,320,1900 -j ACCEPT\niptables -I YazFiFORWARD -i wl0.1 -o br0 -m iprange --src-range \"${MEDIA_RANGE}\" -p tcp -m multiport --sports 1400,1443,4444,7000 -j ACCEPT\n\n\n> End of update here, original post follows\n\nMost recently I've discovered that Asuswrt-Merlin (community firmware for Asus\nrouters) has a terminal UI interface `amtm`.\n\nWithin it there is a project called Yazfi by @jackyaz which provides a \"feature\nexpansion of guest Wi-Fi networks on AsusWRT-Merlin\".\n\nI've always wanted to move all my smart devices to another VLAN with only\npinhole access to my main LAN. Thanks to Yazfi, the effort is reduced\ntremendously trying to configure these while leveraging on the Guest Network\nfunctionality of Asus Routers. With that, I started my project to reformat my\nAsus Router, rotating my Wi-Fi passwords and start moving everything over.\n\nI did however encounter some issues with discovering Sonos devices on the mobile\napp even with `One way to guest` enabled, it was either totally not discovering\nor very slow, and decided to start digging into it.\n\n\nINVESTIGATION\n\n> This section explains how I investigated how the Sonos works in my network\n> under the hood and you can skip to the Solution section below if you only care\n> about that!\n\n\nTEMPORARILY ALLOWING TWO-WAY TRAFFIC BETWEEN LAN AND GUEST NETWORK\n\n[https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/rich-editor/items/72mN-cdfjph/image-5ac9a50702c7676fa5aa8c61de1a85a3.png]\n\nSince we are investigating how Sonos operates, I temporarily allowed two-way\ncommunication between the 2 networks in Yazfi configuration.\n\n\nENABLING MULTICAST ROUTING\n\n[https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/rich-editor/items/72mN-cdfjph/image-57274ae829415195afe92f3d8103d890.png]\n\nSince various online sources says that Sonos uses Simple Service Discovery\nProtocol (SSDP) and multicast DNS (mDNS) to support discoverability, for good\nmeasure, I enabled multicast routing under LAN > IPTV > Enable multicast routing\n\nHowever I'm not 100% sure there is a need for this.\n\n\nINSTALLING ENTWARE AND TCPDUMP ON MY ROUTER\n\nYou can follow these instructions to install entware on your router.\n\nAfter installationof entware is complete, it's as simple as\n\njarylc@RT-AX88U:/tmp/home/root# opkg install tcpdump\n\n\n\nRUNNING TCPDUMP\n\nAfter snooping around the UI and the Sonos App, the private IP addresses of the\nrelevant devices are the following:\n\n * My Android phone: 172.27.14.98 (172.27.14.x is my main LAN)\n * One of my Sonos devices: 172.27.15.3 (172.27.15.x is my smart devices Guest\n   network)\n\nI limited the snooping to UDP packets only as that is what SSDP and mDNS\nprimarily uses\n\njarylc@RT-AX88U:/jffs/addons/YazFi.d/userscripts.d# tcpdump -i any 'udp and (src 172.27.15.3 or src 172.27.14.98)'\n09:26:30.044460 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 200\n09:26:30.044469 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 200\n09:26:30.044433 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 200\n09:26:30.044582 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 200\n09:26:30.044589 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 200\n09:26:30.044443 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 200\n09:26:30.045267 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:30.045274 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:30.045259 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:30.045539 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:30.045544 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:30.045530 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:30.048134 wl0.4 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:30.048139 wl0.1 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:30.048125 br0   M   IP 172.27.14.98.5353 > mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:30.227307 wl0.1 M   IP 172.27.15.3.5353 > mdns.mcast.net.5353: 0*- [0q] 1/0/6 PTR Sonos-XXXXXXXXXXXX@Media Room._sonos._tcp.local. (676)\n09:26:30.266863 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:30.266871 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:30.266828 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:30.266945 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:30.266950 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:30.266840 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:30.580416 wl0.1 In  IP 172.27.15.3.37360 > 172.27.14.98.37972: UDP, length 741\n09:26:30.580456 br0   Out IP 172.27.15.3.37360 > 172.27.14.98.37972: UDP, length 741\n09:26:31.072123 wl0.4 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:31.072128 wl0.1 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:31.071869 br0   M   IP 172.27.14.98.5353 > mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:31.072203 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 200\n09:26:31.072208 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 200\n09:26:31.071885 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 200\n09:26:31.072269 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 200\n09:26:31.072274 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 200\n09:26:31.071892 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 200\n09:26:31.309102 wl0.1 In  IP 172.27.15.3.38139 > 172.27.14.98.37972: UDP, length 741\n09:26:31.309125 br0   Out IP 172.27.15.3.38139 > 172.27.14.98.37972: UDP, length 741\n09:26:31.343765 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:31.343773 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:31.343737 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:31.343853 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:31.343858 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:31.343748 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:31.692594 wl0.1 In  IP 172.27.15.3.38570 > 172.27.14.98.37972: UDP, length 741\n09:26:31.692617 br0   Out IP 172.27.15.3.38570 > 172.27.14.98.37972: UDP, length 741\n09:26:32.271746 wl0.4 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:32.271753 wl0.1 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:32.271598 br0   M   IP 172.27.14.98.5353 > mdns.mcast.net.5353: 1 PTR (QU)? _sonos._tcp.local. (35)\n09:26:32.278203 eth7  M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:32.278226 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:32.278232 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:32.278203 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:32.278296 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:32.278301 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:32.278214 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:32.465141 wl0.1 M   IP 172.27.15.3.5353 > mdns.mcast.net.5353: 0*- [0q] 1/0/6 PTR Sonos-XXXXXXXXXXXX@Media Room._sonos._tcp.local. (676)\n09:26:32.701778 wl0.1 In  IP 172.27.15.3.41457 > 172.27.14.98.37972: UDP, length 741\n09:26:32.701801 br0   Out IP 172.27.15.3.41457 > 172.27.14.98.37972: UDP, length 741\n09:26:33.215347 wl0.4 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:33.215355 wl0.1 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:33.215331 br0   M   IP 172.27.14.98.5353 > mdns.mcast.net.5353: 2 PTR (QM)? _sonos._tcp.local. (35)\n09:26:33.905757 wl0.4 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:33.905763 wl0.1 Out IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:33.905736 br0   M   IP 172.27.14.98.37972 > 239.255.255.250.upnp: UDP, length 254\n09:26:33.905846 wl0.4 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:33.905851 wl0.1 Out IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:33.905744 br0   B   IP 172.27.14.98.37972 > 255.255.255.255.upnp: UDP, length 254\n09:26:34.034082 wl0.1 In  IP 172.27.15.3.59807 > 172.27.14.98.37972: UDP, length 741\n09:26:34.034122 br0   Out IP 172.27.15.3.59807 > 172.27.14.98.37972: UDP, length 741\n09:26:34.220437 wl0.4 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 3 PTR (QM)? _sonos._tcp.local. (35)\n09:26:34.220444 wl0.1 Out IP 172.27.14.98.5353 > mdns.mcast.net.5353: 3 PTR (QM)? _sonos._tcp.local. (35)\n09:26:34.220422 br0   M   IP 172.27.14.98.5353 > mdns.mcast.net.5353: 3 PTR (QM)? _sonos._tcp.local. (35)\n09:26:34.387343 wl0.1 M   IP 172.27.15.3.5353 > mdns.mcast.net.5353: 0*- [0q] 1/0/6 PTR Sonos-XXXXXXXXXXXX@Media Room._sonos._tcp.local. (676)\n\n\n\nTHE PROBLEM\n\n09:26:30.580416 wl0.1 In  IP 172.27.15.3.37360 > 172.27.14.98.37972: UDP, length 741\n09:26:30.580456 br0   Out IP 172.27.15.3.37360 > 172.27.14.98.37972: UDP, length 741\n09:26:31.309102 wl0.1 In  IP 172.27.15.3.38139 > 172.27.14.98.37972: UDP, length 741\n09:26:31.309125 br0   Out IP 172.27.15.3.38139 > 172.27.14.98.37972: UDP, length 741\n09:26:32.701778 wl0.1 In  IP 172.27.15.3.41457 > 172.27.14.98.37972: UDP, length 741\n09:26:32.701801 br0   Out IP 172.27.15.3.41457 > 172.27.14.98.37972: UDP, length 741\n09:26:34.034082 wl0.1 In  IP 172.27.15.3.59807 > 172.27.14.98.37972: UDP, length 741\n09:26:34.034122 br0   Out IP 172.27.15.3.59807 > 172.27.14.98.37972: UDP, length 741\n\n\nFiltering out all the noise, I noticed that the Sonos device was trying to send\na UDP packet from the ephemeral UDP ports (range 32768-65535) to my mobile\ndevice.\n\nThis is actually not surprising as that is how SSDP works as the device would\nswitch to unicast after being discovered. Prior to this, I was not very familiar\nwith SSDP and did not know that.\n\nI noticed in a previous tcpdump before enabling two-way communication that this\nwas being blocked:\n\n00:13:65.371058 wl0.1 In  IP 172.27.15.3.46814 > 172.27.14.98.49972: UDP, length 737\n00:13:54.373059 wl0.1 Out IP 172.27.15.1 > 172.27.15.3: ICMP 172.27.14.98 udp port 49972 unreachable, length 556\n\n\n\n[HTTPS://KB-STATIC.JARYLCHNG.COM/KB-JARYLCHNG-COM/PRODUCTION/MEDIA/IMAGE-F00ED809361CEABD0D29380D07F2D3D5.PNG]\n\n\nSOLUTION\n\n\nADDING CUSTOM FIREWALL ALLOW RULES TO YAZFI TO ALLOW THIS UDP TRAFFIC FROM SONOS\nDEVICES\n\nYazfi allows additional iptables rules by adding a shell script with iptables\ncommands to any file in `/jffs/addons/YazFi.d/userscripts.d/`\n\nWith that I created a file called `myscript.sh` within the folder and placed\nthis in the file to allow UDP traffic on the ephemeral ports (range 32768-65535)\noriginating from the Sonos device to flow back to the main LAN\n\n#!/bin/sh\niptables -I YazFiFORWARD -i wl0.1 -o br0 -s 172.27.15.3 -p udp --dport 32768:65535 -j ACCEPT\n\n\n * `-I YazFiForward` - adds the rule to the FORWARD chain in the YazFi table\n * `-i wl0.1` - make sure to change this to your actual Guest Wi-Fi interface\n * `-o br0` - packets moving to the bridge interface\n * `-s 172.27.15.3` - make sure to change this to your actual Sonos device's IP\n   address\n * `-p udp` - UDP packets only\n * `--dport 32768:65536` - ephemeral UDP port ranges only\n * `-j ACCEPT` - allow packets filtered by this rule\n\n> You can duplicate that iptables line for as many Sonos device you have and\n> their respective IPs, or you can also use `-srcrange` (i.e. `-m iprange\n> --src-range 172.27.15.2-172.27.15.9`) if you have configured continuous static\n> DHCP IPs for them.\n\nBe reminded to `chmod +x` the file afterwards\n\njarylc@RT-AX88U:/jffs/addons/YazFi.d/userscripts.d# chmod +x myscript.sh\n\n\n\nREVERTING TO ONLY ALLOWING ONE-WAY (LAN TO GUEST) COMMUNICATION\n\n[https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/rich-editor/items/72mN-cdfjph/image-f772aec66b26bfe8d57b92437818a68f.png]\n\nDuring investigation, I allowed two-way communication, so I am reverting it to\none-way only in the Yazfi configuration.\n\n\nTESTING THE SONOS APP AGAIN\n\nSure enough, after allowing the UDP packet to flow back allows the Sonos app to\nbe snappy again.\n\n\nBONUS\n\n\nHOMEASSISTANT\n\nI integrated my Sonos systems with HomeAssistant as well, it is also recommended\nby them to enable communication back via port 1400\n\niptables -I YazFiFORWARD -i wl0.1 -o br0 -d 172.27.14.100 -p tcp --dport 1400 -j ACCEPT\n\n\n * `-I YazFiForward` - adds the rule to the FORWARD chain in the YazFi table\n * `-i wl0.1` - make sure to change this to your actual Guest Wi-Fi interface\n * `-o br0` - packets moving to the bridge interface\n * `-s 172.27.14.100` - make sure to change this to your actual HomeAssistant's\n   IP address\n * `-p tcp` - TCP packets only\n * `-dport 1400` - port 1400 only\n * `-j ACCEPT` - allow packets filtered by this rule\n\nIt is also highly recommended to allow the Sonos systems to communicate with\nHomeAssistant directly (especially to use local media storage if you have any)\n\niptables -I YazFiFORWARD -i wl0.1 -o br0 -d 172.27.14.100 -p tcp --dport 8123 -j ACCEPT\n\n\n * `-I YazFiForward` - adds the rule to the FORWARD chain in the YazFi table\n * `-i wl0.1` - make sure to change this to your actual Guest Wi-Fi interface\n * `-o br0` - packets moving to the bridge interface\n * `-s 172.27.14.100` - make sure to change this to your actual HomeAssistant's\n   IP address\n * `-p tcp` - TCP packets only\n * `-dport 8123` - make sure to change this to your actual HomeAssistant's port\n * `-j ACCEPT` - allow packets filtered by this rule","banner_image":"https://kb-static.jarylchng.com/kb-jarylchng-com/production/media/image-f00ed809361ceabd0d29380d07f2d3d5.png","date_published":"2024-04-28T01:40:00.000Z","_microfeed":{"is_audio":false,"is_document":false,"is_external_url":false,"is_video":false,"is_image":true,"web_url":"https://kb.jarylchng.com/i/sonos-asus-router-merlin-yazfi-guest-network-wit-72mN-cdfjph/","json_url":"https://kb.jarylchng.com/i/72mN-cdfjph/json/","rss_url":"https://kb.jarylchng.com/i/72mN-cdfjph/rss/","guid":"72mN-cdfjph","status":"published","itunes:episodeType":"full","date_published_short":"Sat Apr 27 2024","date_published_ms":1714268400000}}],"_microfeed":{"microfeed_version":"0.1.2","base_url":"https://kb.jarylchng.com","categories":[{"name":"Technology"}],"subscribe_methods":[{"name":"RSS","type":"rss","url":"https://kb.jarylchng.com/rss/","image":"https://kb.jarylchng.com/assets/brands/subscribe/rss.png","enabled":true,"editable":false,"id":"sQbXXExV58H"},{"name":"JSON","type":"json","url":"https://kb.jarylchng.com/json/","image":"https://kb.jarylchng.com/assets/brands/subscribe/json.png","enabled":true,"editable":false,"id":"nC8cjLCnOOi"}],"description_text":"Welcome to the index page of my knowledge base, if you haven't done so, do visit\nmy website at https://jarylchng.com.\n\nI will mainly use this site to document stuff, most of which will likely be in\nthe public domain.","copyright":"©2024","itunes:type":"episodic","items_sort_order":"newest_first"}}