A few months ago I went through the process of setting up VLANs for my home network. A short while after that I took it a step further and added Wireless VLANs. One of the things I wasn’t quite ready to deal with was how I was going to handle Chromecasts on my network. For those of you who aren’t aware of this; I have 10 Chromecasts in my house. 6 Chromecast Ultras, 2 Chromecast with Google TVs (terrible name, should have stayed with Sabrina), and 2 Chromecast gen 2s. Incase it wasn’t obvious; I really like Chromecasts. They’re small, easy to hide, simple to use, they’re not cluttered with ads like the horrendous Fire TV home page, I don’t have remotes laying around everywhere, and most importantly I can control them from anywhere in my house. This becomes particularly useful when my kids want to watch something on a TV and I’m busy in a different room. I don’t have to walk over to the room they’re in to find the show they want, I can just cast from my phone.
However, there is one issue with Chromecasts that causes some infrequent but annoying problems. Anytime I have someone stay at my house without me I have to make a risk calculation. Do I put their phone on my protected Wi-Fi or do I bring out my old Roku stick and set it up for them? If I allow them on my protected Wi-Fi then I have very little control over what they do. I practice Zero-Trust principles so they wouldn’t be able to access things like my PhotoPrism or NAS, but they could still abuse my network. If they had some sort of worm on their computer or phone then that could spread to my network. I can avoid this by simply setting up my Roku and giving them the remote but that’s just annoying to plug in every time and remove it afterwards.
Yes yes, I know. Setting up a Roku and leaving it plugged in is easier and works fine, but I’m a professional. Its time to find a way overcomplicated solution to a simple problem.
Like always whenever I mess with my network I always have to establish a set of requirements I’m looking to achieve. In this case the requirements were simple;
- Enable Guest LAN access to Chromecasts
- Limit Guest access to specific Chromecasts only
- Ensure that Trusted LAN continues to be able to reliably cast to Chromecasts
The requirements this time were pretty basic. I wanted people on my Guest LAN to be able to cast to the Chromecasts on my Trusted LAN, but I also wanted to make sure that they could only cast to specific ones. I also wanted to make sure that my family was able to use Chromecasts the exact same as they currently do.
My journey with Chromecasts has been temperamental at best. I started adding Chromecasts years ago but I didn’t really understand how they worked. This lead to major frustrations as we couldn’t reliably cast to certain devices at certain times. We’d have to reboot the device, reboot the router, open and close the app, etc in order to get our phones to see the Chromecasts. It took a lot of work and a lot of tweaking the network and research in order to get the Chromecasts in a reliable state where they were always visible and casting worked every time. (Hint your network needs UPnP on and mDNS capable). My wife has slowly come around to appreciating the simplicity that Chromecasts offer now that they’re set up properly. So the Chromecasts MUST still work after my update.
Step 1: mDNS reflection
The biggest issue facing inter-VLAN casting with Chromecasts is mDNS. mDNS is a multicast DNS system where devices in a network are addressed directly instead of sending DNS requests through a name server. The device being queried then responds to the entire network and every device then updates their mDNS cache with device MAC to IP pairing. Apple was one of the first to pioneer this service with their Bonjour printing service and Windows later included mDNS as part of the Windows 10 OS.
For my purposes though mDNS is essential for how Chromecast’s function. The Chromecasts make an mDNS request using the service _googlecast._tcp.local. Since this request is multicast devices on the network (like your phone) see these requests and “log” the existence of a Chromecast on the network.
The problem with how this works is that multicast communication is broadcast communication, which means it stays withing a broadcast domain. Meaning if even with Firewall rules allowing Guest to talk to Trusted the Chromecasts still would not appear on the Guest LAN because the broadcast traffic wouldn’t cross.
Enter Avahi. Avahi is an opensource mDNS proxy, or reflector depending on who you talk to. Avahi listens for mDNS broadcasts and reflects the traffic to a new broadcast domain. Then it takes the cast traffic and reflects that back to the casting device. The great news is that Avahi is already an option package in pfSense.
Installing Avahi takes only a few seconds and then it’s time to configure it. Recent updates to the Avahi plugin have made things very simple. After checking the box to enable it I select the interfaces I want the Avahi daemon to listen and send on (LAN and GUEST), enable reflection to repeat mDNS packets across the subnets, and then finally add the service in the reflection filtering section. Adding the service is technically optional as Avahi will by default automatically reflect all traffic, but again, I’m a security professional so we only reflect the services we actually need.
After enabling this service I immediately had Chromecast access on my Guest LAN but I could see all of my Chromecasts and other castable devices (Google Homes for music). This works, but is less than ideal. My biggest concern is that if someone isn’t familiar with using Chromecasts they might accidently send a video to my bedroom TV when I’m trying to sleep, or worse; send a video to one of my Kids’ TVs.
Step 1.5: Firewall Rules
My Guest network is relatively straight forward but still locked down. I permit access to ports 80, 443, 53, 110, 123, and 143 only. I had to add a rule allowing ports 5353 and 8008-8009 to ANY so that the Guest LAN could talk to the Chromecasts (more on this later).
Step 2: Locking down the Chromecasts
I now had the ability to cast from my Guest LAN but I did not want guests to be able to Cast to all of my devices (10 Chromecasts and 8 Google Homes). Since guests primarily stay in my living room or finished basement I wanted to limit access so my guest could cast to those two devices only.
The first thing I needed to do here was assign a static IP for the two Chromecasts. This would become important later when we work with Firewall rules. We don’t want the Chromecast to change IPs and therefore break the casting rule we’ll make later. I opened up my Google Home app and found the MAC address of the two Chromecasts I wanted to allow, then assigned them static IPs.
Next up I created two firewall aliases; the first was an alias of the Chromecast IPs and the second was an alias for ports used by the Chromecast. I made a firewall rule to allow my Guest LAN to access the Chromecast IP alias with the Ports Alias.
Once the rule was applied I checked an app again to see what devices were available, and low and behold I could only I could only see the Living Room and Basement Chromecast devices.
I was able to set up the Avahi mDNS reflector and limit it so that Guests could only cast to specific devices while still allowing my Trusted LAN To cast to any device. This opens up a whole new realm of possibilities when it comes to placement of my Chromecasts. I’ve been hesitant to put my Chromecasts on the IoT subnet because I didn’t want to cause issues with casting, again. However, now that I’ve managed to successfully set up the Avahi reflector I believe I can put the Chromecasts on the IoT subnet and allow my Trusted Subnet to cast to any device while still limiting my Guest subnet to only being able to cast to the limited devices.
Sounds like a project for another day.