Mobile-to-TV casting across subnets
-
This is a tip to help others, not a question (apologies if posted in the wrong forum). After much trial-and-error, I've managed to configure pfsense to allow hosts in one subnet (e.g. mobile devices) to communicate with consumer media players in another subnet, including Google casting (eg YouTube to Smart TV). A quick search shows that many people have had trouble doing this, especially with Google apps; there are some other threads such as https://forum.netgate.com/topic/139218/sonos-speakers-and-applications-on-different-subnets-vlan-s with lots of useful details, but thought a summary may be useful for people.
My setup:
- Two VLANs (of relevance here):
- VLAN2 (main VLAN, both wifi and ethernet), with hosts including Android/iOS mobile devices and a NAS.
- VLAN4 (IoT VLAN, ethernet), with hosts including an LG Smart TV and two Denon HEOS audio players (which are to be controlled by devices in VLAN2 and are to play content from the NAS in VLAN2).
- Standard configuration of one IP subnet per VLAN (no L2 bridging between VLANs).
First problem: TV casting and HEOS audio control use multicast protocols (Multicast DNS and SSDP), which aren't routed across subnets by default.
Solution:
- Install the PIMD package for multicast routing.
- Configure PIMD with default settings:
- General tab: Enable, set Bind to None, leave the rest as default.
- Interfaces: Add the interfaces for the two VLANs, each with Always Bind and other settings as default.
- BSR Candidates: Create one entry with default settings.
- RP Candidates: Create one entry with default settings.
- Enable firewall rules for multicast (on both VLAN interfaces):
- Multicast DNS: IPv4 UDP SourceNet:* -> 224.0.0.251:5353 [advanced: allow IP options]
- SSDP: IPv4 UDP SourceNet:* -> 239.255.255.250:1900 [advanced: allow IP options]
- IGMP: IPv4 IGMP SourceNet:* -> : [advanced: allow IP options]
- Enable firewall rules for unicast TCP/UDP communication between controller hosts (mobile devices) and NAS in VLAN2 and media players/TV in VLAN4 (both directions).
- I just filtered by host, but you could restrict it by port if required. HEOS ports are listed here: https://denon-uk.custhelp.com/app/answers/detail/a_id/4717/~/network-requirements-for-heos
Note: I also tried the Avahi multicast DNS package, but that didn't solve the problem on its own (presumably because of the SSDP requirement as well), and once I'd set up PIMD as above Avahi wasn't required for my setup. But some threads suggested running both, so some other configurations may need it.
With the above setup, I was able to control my HEOS players, and see my TV listed when clicking the cast icon in the YouTube app. However, casting still didn't work, due to...
Second problem: YouTube (and probably other Google apps) set TTL to 1 on their SSDP multicast packets, preventing the router from forwarding them to the other subnet, even with PIMD up and running.
Solution:
- Based on info in this thread: https://forum.netgate.com/topic/4435/modify-ttl-value-for-security-reasons
- This is an unsupported hack, so apply it at your own risk!
- Using Diagnostics->EditFile, take a copy of the pfsense firewall config script, /etc/inc/filter.inc
- Search for the section that adds a "scrub" rule to the pf config for each interface (see https://docstore.mik.ua/manuals/openbsd/faq/pf/scrub.html). In pfsense 2.4.5 this is a "foreach ($FilterIflist as $scrubif => $scrubcfg)" loop in a function called filter_generate_scrubing.
- Just before that section, add the following line to increase the TTL of SSDP packets to 2 (change "VLAN2" to the name of the interface that has the controlling devices, and "10.0.2.0" to the corresponding subnet):
$scrubrules .= "scrub in on $VLAN2 inet proto udp from 10.0.2.0/24 to 239.255.255.250 port 1900 min-ttl 2 {$scrubnodf} {$scrubrnid} {$mssclamp} fragment reassemble\n"; - Add similar rules if you have other VLANs with controlling devices.
- Edit any firewall rule to regenerate the pf config (which you can check at /tmp/rules.debug).
Hope this info is helpful to anyone in a similar situation.
- Two VLANs (of relevance here):
-
Thank you for this guide. I have been struggling to get this to work, and have just found the cause.
I am using PFSense 2.5.1.
note that my rules below were lost when I upgraded from 2.5 to 2.5.1I have two vlans called "IOT" (vlan 30) and "LAN" (vlan 10)
The key is there must be a single backslash \ to escape the $ variable to make the rule parse correctly.
I'm adding two rules, one for each direction. This may not be required.This error in the above post may be caused by the forum post formatter!
$scrubrules .= "scrub in on \$IOT inet proto udp from 192.168.30.0/24 to 239.255.255.250 port 1900 min-ttl 2 {$scrubnodf} {$scrubrnid} {$mssclamp} fragment reassemble\n";
$scrubrules .= "scrub in on \$LAN inet proto udp from 192.168.10.0/24 to 239.255.255.250 port 1900 min-ttl 2 {$scrubnodf} {$scrubrnid} {$mssclamp} fragment reassemble\n";
After correcting this rule I could see SSDP traffic between the two vlans when using wireshark.
"C:\Program Files (x86)\PuTTY\plink.exe" -ssh root@192.168.1.1 tcpdump -n -nn -s 0 -U -w - -i igb1 vlan 10 and port not 22 and ssdp | "C:\Program Files\Wireshark\wireshark.exe" -i - -k
"C:\Program Files (x86)\PuTTY\plink.exe" -ssh root@192.168.1.1 tcpdump -n -nn -s 0 -U -w - -i igb1 vlan 30 and port not 22 and ssdp | "C:\Program Files\Wireshark\wireshark.exe" -i - -k
I am generating SSDP M-Search requests using Device Spy:
https://www.meshcommander.com/upnptools -
@wrightsonm Update: Whilst this has fixed the SSDP broadcast across VLANs, i am still unable to get my Samsung TV to appear in Device Spy on vlan 10
-
Thanks, I didn't notice the PIMD package at all. I set it us as described (I have the same exact setup as you) and I was able to Chromecast across VLANS (I use Avahi previously), but I'm unable to pair my LG TV with my phone. FW log doesn't show any blocked traffic.
-
@pfnow I don't think pimd is required for chromecast. It uses mDns for discovery so only avahi is required.
On the Samsung multicast side of things, i still don't have it working. Changing SSDP to ttl=2 has resulted in the tv receiving the ssdp m-search query.
Device spy is seeing data coming back too. Though something is missing as it fails to add the tv to the list of found devices.
One of the things i have noticed is that many of the urls advertised by the tv throw a 401 unauthorized error when accessed from the wrong vlan.
I don't yet know if the 401 error is due to some form of upnp authorization mechanism that is failing or if it is blanket 401 erroring as the ip.src network is a different /24.
The other thing of note is that the tv does send messages to 224.0.0.7 with ttl=1. I don't know at this stage whether further ttl mangling is required or this is acceptable. I do see the tv ip as a registered source in pimd status page.
-
@pfnow
I have a Phillips AndroidTV and dug into the network traffic a bit. With the above setup the multicast and unicast traffic passes fine through the networks. But when the Youtube app on my pixel phone tries to open the Youtube app on the TV a 403 Error is returned which is I think the cause why the TV is not being shown in the list. I think like @wrightsonm said, the Chromecast possibly only allows casting from the local subnet. I'm thinking if it may be possible to bypass that with NAT, but I haven't tried that yet and I'm a bit reluctant since I want to avoid NAT as much as possible and find a better solution. Unfortunately I haven't yet found if my TV has this src ip restriction and since @JacobS successfully casted with this setup that restriction may not be a standard chromecast thing.