Sonos S1 Music Library Restoration Guide (Zero-Trust & VLANs)
This guide provides the technical blueprint for connecting a legacy Sonos S1 speaker system to a modern storage backend (e.g., TrueNAS) across segmented network VLANs.
The Challenge
Sonos S1 systems rely on SMBv1 and NetBIOS, both of which are deprecated and insecure. Modern NAS systems (TrueNAS, Synology) often disable these protocols by default. Furthermore, cross-VLAN communication for Sonos is notoriously difficult due to its reliance on discovery and specific "ghost ports" used during the library registration process.
Architecture Overview
To maintain security while supporting legacy hardware, we use a Raspberry Pi SMB Proxy:
- TrueNAS exports the music library via NFSv4 (Secure/Modern).
- Raspberry Pi mounts the NFS share and re-exports it via Samba (SMBv1).
- Sonos Speakers connect only to the Pi on a dedicated "Legacy" VLAN.
1. Raspberry Pi Proxy Configuration
Optimized NFS Mount (/etc/fstab)
To prevent the Pi from hanging during a large library index and to achieve maximum throughput, use NFSv4.1 along with NFS session slot tuning:
text
<NAS_IP>:/path/to/music /mnt/music nfs ro,hard,noatime,nfsvers=4.1,rsize=1048576,wsize=1048576,timeo=600,retrans=5,nolock,_netdev 0 0
nfsvers=4.1: Mandatory. NFSv4.0 requires the NAS to establish callback connections back to the Pi. In a segmented network, the firewall typically blocks these NAS -> Pi connections, leading to read freezes. NFSv4.1 resolves this by routing callbacks through the existing client-initiated TCP session.rsize=1048576,wsize=1048576: 1 MB read/write sizes. This maximizes throughput and keeps the network pipeline full.ro: Read-only (Sonos doesn't need write access).hard: Patiently retries instead of failing during high latency.
IMPORTANT
NFSv4.1 Session Slot Tuning: Over firewalled network paths with latency, NFSv4.1 throughput can collapse to < 1 MB/s because the kernel defaults to 64 session slots, serializing reads. You must increase this by creating /etc/modprobe.d/nfs.conf on the Pi:
text
options nfs max_session_slots=256
And apply it via echo 256 | sudo tee /sys/module/nfs/parameters/max_session_slots. This parallelizes reads and yields full gigabit line rates (110+ MB/s), completely eliminating indexing timeouts.
Automated Cache Warmup (Cron Job)
For very large libraries (10,000+ tracks), schedule a script to pre-load the NAS directory structure into the Pi's RAM before the Sonos nightly index. Because actimeo=3600 caches metadata for 1 hour, the Pi will then serve the entire library structure from memory when Sonos asks for it.
Create /usr/local/bin/warmup_sonos_cache.sh:
bash
#!/bin/bash
# Warm up the NFS cache for Sonos S1 to prevent indexing timeouts
sudo -u sonos find /mnt/music -type d > /dev/null 2>&1
sudo -u sonos find /mnt/music -type f > /dev/null 2>&1
Add to /etc/cron.d/sonos_cache (runs at 1:50 AM, 10 min before Sonos's 2:00 AM auto-update):
text
50 1 * * * root /usr/local/bin/warmup_sonos_cache.sh
Samba Configuration (/etc/samba/smb.conf)
ini
[global]
server min protocol = NT1
ntlm auth = ntlmv1-permitted
lanman auth = yes
server signing = disabled
[music]
path = /mnt/music
read only = yes
guest ok = no
valid users = <sonos_user>
oplocks = no
nt acl support = no
oplocks = no/nt acl support = no: Prevents kernel deadlocks when re-exporting a network mount.
2. Firewall & Network Requirements
Required Ports (Zero-Trust)
If your controllers (Phone/PC) and speakers are on different VLANs, you must allow the following:
| Port | Protocol | Direction | Purpose |
|---|---|---|---|
| 137-139 | UDP/TCP | Both | NetBIOS / SMB Session |
| 445 | TCP | Both | SMB Direct |
| 1400 | TCP | C → S | Standard Sonos Control |
| 1443 | TCP | Both | CRITICAL: Encrypted setup/registration |
| 3400-3500 | TCP | Both | UPnP Eventing / Callbacks |
| 5228 | TCP | C → S | CRITICAL: Google GCM (Android registration) |
Discovery Requirements
A multicast relay (like udpbroadcastrelay or avahi) must bridge these ports across VLANs:
- 1900 (SSDP)
- 1902 (Sonos Discovery)
- 5353 (mDNS)
Firewall Rule: Speaker → Controller Callbacks
CRITICAL: The rule allowing traffic from Sonos speakers back to controllers must have its destination port set to
any(not a restricted alias). Sonos speakers send indexing completion notifications and event callbacks on ephemeral ports (49152-65535). If these are blocked, the Sonos app on your phone will be permanently stuck on "Indexing..." even after the speakers have finished.
3. Troubleshooting "Error 1001/1002"
If the Sonos app fails to add the share:
- Check the Bridge: If you have a Sonos Bridge, it must be included in your firewall "Allow" aliases. The phone often "hands off" the validation to the Bridge.
- Validation Loop: The Android app validates credentials locally before telling the speakers. If the phone cannot reach the Pi on port 445/139, registration will fail with 1001.
- NFS Stalls: If indexing starts but stops with "Music files not available," check your NFS mount options. Use the
hardmount andactimeosettings listed above to ensure stability.
4. Troubleshooting "App Stuck on Indexing..."
If your Sonos app says "Indexing..." indefinitely but shows 0 or very few songs:
- Check the firewall callback rule (see above). If speakers can't push notifications back to your phone, the app will never receive the "done" signal.
- Check Path MTU and Physical Switches. If pings above a certain size (e.g., 1472 bytes payload / 1500 bytes MTU) fail with 100% packet loss across your LAN (e.g.
ping -s 1472 -M do <gateway_ip>), you have an MTU bottleneck. Cheap unmanaged switches can silently drop frames larger than ~558 bytes, stalling NFS reads. Plug devices directly into a managed switch. - Verify NFSv4.1 and Session Slots. Ensure the mount is using
vers=4.1(to bypass firewall-blocked NFSv4.0 callbacks) and thatmax_session_slotsis increased to256(otherwise, throughput drops to ~0.3 MB/s, causing Sonos timeouts).
5. Performance Optimization: Layer 2 Storage Bypass
If you host your storage backend (TrueNAS, Synology) on a separate routed storage VLAN (e.g., <Storage_VLAN>) and your proxy/workstations on a LAN VLAN (e.g., <LAN_VLAN>), all heavy storage traffic (NFS, SMB) must pass through your firewall CPU.
During large indexing runs (10,000+ files) or high-bandwidth data transfers, this firewalled path can lead to:
- High firewall CPU utilization.
- State table timeouts and packet drop.
- Latency spikes resulting in Sonos indexing stalls.
Solution:
Migrate your storage backend's data interface to a direct Layer 2 (L2) connection on the same subnet as the clients (e.g., configuring a second physical NIC on the NAS server directly on the LAN subnet, matching <NAS_LAN_IP>).
- This allows the client/proxy and NAS to talk directly at the switch layer.
- It completely bypasses the firewall CPU, yielding true line-rate performance (~110+ MB/s on Gigabit) and rock-solid indexing stability.
- Admin and Web UI access can remain on the isolated admin segment for security.
6. Remote Access & NAT Traversal (Tailscale)
If you run Tailscale alongside a highly locked-down Zero-Trust network, you might experience issues where Tailscale reports UDP: false and continually falls back to TCP-based DERP relay servers, causing connection flapping and logs like: health(warnable=no-derp-connection): error: Tailscale could not connect to relay server
This is caused by two common firewall behaviors:
- Blocked Outbound UDP: A typical Zero-Trust outbound policy may restrict LAN outbound traffic strictly to TCP
80and443(Allowed_Web_Ports), blocking STUN queries on UDP port3478. - Symmetric (Hard) NAT: By default, firewalls like pfSense rewrite source ports dynamically on outbound NAT, which prevents peer-to-peer connections.
Solution:
- Allow STUN Outbound: Create a firewall rule on your LAN/local interface allowing outbound UDP traffic from your subnet/workstation to Any destination.
- Configure Static Port NAT:
- In pfSense, navigate to Firewall > NAT > Outbound.
- Select Hybrid Outbound NAT and save.
- Add a mapping rule for your local subnet:
- Protocol:
UDP - Source: Your local network (e.g.,
<LAN_Subnet>) - Translation > Port or Range: Check Static Port (prevents pfSense from rewriting source ports on UDP traffic).
- Protocol:
After applying these, running tailscale netcheck should output UDP: true and MappingVariesByDestIP: false, allowing direct peer-to-peer tunnels.
Verified on Sonos S1 (2026)
12:39 PM