Network Effect: Streaming Services
Anyone that's asked my opinion on network configurations within the past six months has probably gotten an earful on Quality of Service and traffic prioritization. Ever since becoming homebound by COVID-19, bandwidth has become more precious; the kids relied on Zoom for their distance learning while they were in school, I'm under a constant barrage of conference calls over the various collaboration platforms (Zoom, Webex, Teams, etc.), and the like. When you factor in our (temporary) transplant to a cottage in the Berkshires – replete with aging DSL lines – the contention becomes more apparent.
I've been hunkering down over the past several weeks, doing some investigative analysis of my own family's network consumption. The fruits of this labor are appearing in the form of toolsets for helping the 128T device perform more intelligent application identification. The thought process is this: to extract the most value from a limited resource (network), it becomes of paramount importance to understand the consumers of that resource (appID), and give guidance to the network on priorities when the resource is under contention (QoS).
My blog series on Investigation in Isolation was one piece of this puzzle, and incidentally the lowest hanging fruit. Each of the purpose-built IoT devices tethered to my network typically has a small set of functions, and it's straightforward to quarantine each of them, categorize its network footprint, and put guard rails up around it to limit its scope and appetite. Good for security, good for resource management.
After systematically cordoning off all of my IoT devices, the next phase was moving up the stack to more complex equipment. This is more challenging; our tablets, smartphones, and laptops run a variety of applications that will complicate the investigative process. The obvious candidate for my next round of research was AppleTV.
Not only is AppleTV a "walled garden" of sorts, but its primary raison d'être is to stream video content from cloud providers to my television set. Because streaming video is the largest network consumer worldwide, this also means I'll get a lot of bang for my buck: isolating and prioritizing streaming video traffic appropriately can score a quick win for making the most of a scarce resource. Kids watching YouTube while I'm on a call with the boss? Not so fast, Tic Tac Toy!
You may be asking yourself: why not just put a bandwidth limiter on the AppleTV and be done with it? My answer is: what's the fun in that?
The two step approach
There are only two basic steps required for applying traffic prioritization rules on my 128T: first, identify the application; second, apply service-policy
configuration for each application. (Maybe I'm a bit of an odd case, but I find this sort of research fun and therapeutic.) Let's dig in.
Identifying the applications
This is an area where 128 Technology has invested heavily over the course of the past few years. There are two primary tools in your toolbox for this:
- AppID modules: these are typically implemented as Python scripts (though any executable will do), and will create JSON files that your 128T ingests to create dynamic services. For the ambitious, you can write your own – it's not too difficult, I've even done it myself... and I'm most assuredly not a software developer.
- Our DNS AppID plugin: this plugin dovetails with ans onboard DNS cache, and associates DNS responses to services dynamically, based on regex pattern matching. It's easy, it's fast, and it's extremely powerful.
When to choose one of these tools over the other is a bit of an art. My general rule of thumb: if a SaaS provider publishes a list of reachable addresses (including those advertised to the internet using BGP), it's best to use an AppID module. If a provider does not publish a list of addresses, the DNS AppID plugin is a good place to start.
The targets: YouTube, Netflix, and Hulu
At our house, these are the big three applications for streaming entertainment. My mission was to create AppID profiles for these applications.
For Netflix, I decided upon the module approach. This is because Netflix conveniently advertises all of their reachable IP addresses publicly using BGP, as AS2906, and RIPE provides a friendly way of grabbing them all in JSON format.
Note: the module I wrote for Netflix is available in the GitHub repo linked above.
For YouTube and Hulu I went with the DNS approach, although for different reasons. It made sense for YouTube, because there is no clean way to disambiguate between Google addresses and YouTube addresses based on BGP advertisements – there's a lot of overlap. For Hulu, while they do advertise their own prefixes into BGP, they also leverage Akamai as a CDN for a lot of their content.
For YouTube, here's my ruleset:
admin@labsystem1.fiedler# show config running authority router becket dns-app-id custom-apps YOUTUBE
config
authority
router becket
name becket
dns-app-id
custom-apps YOUTUBE
name YOUTUBE
description YouTube
patterns youtube\.com
patterns .*\.youtube\.com
patterns ytimg\.com
patterns .*\.ytimg\.com
patterns ytimg\.l\.google\.com
patterns .*\.ytimg\.l\.google\.com
patterns youtube\.l\.google\.com
patterns .*\.youtube\.l\.google\.com
patterns googlevideo\.com
patterns .*\.googlevideo\.com
exit
exit
exit
exit
exit
Here's the set for Hulu:
admin@labsystem1.fiedler# show config running authority router becket dns-app-id custom-apps HULU
config
authority
router becket
name becket
dns-app-id
custom-apps HULU
name HULU
description "source: https://www.reddit.com/r/PFSENSE/comments/aurnb7/help_with_firewall_aliases_for_hulu/"
patterns .*\.hulu\.com
patterns .*\.huluim\.com
patterns hulu\.com
patterns huluim\.com
patterns .*\.hulureplay\.com
patterns hulureplay\.com
patterns .*\.hulustream\.com
exit
exit
exit
exit
exit
You can see in my attribution in the Hulu ruleset that I found a redditor that did the heavy lifting for me in unearthing all of the various FQDNs that Hulu uses. I did validate them, of course.
Policy-based traffic control
Now, the fun part: applying configuration to my 128T to control the traffic appropriately.
Here's what I put in place for YouTube:
admin@labsystem1.fiedler# show config running authority service YOUTUBE.internet
config
authority
service YOUTUBE.internet
name YOUTUBE.internet
scope private
application-name YOUTUBE
access-policy trusted
source trusted
exit
access-policy guest
source guest
exit
access-policy appletv.iot
source appletv.iot
exit
service-policy video-streaming-scavenger
share-service-routes false
exit
exit
exit
This config fragment references application-name YOUTUBE
, which will associate the prefixes learned by the DNS AppID plugin with this service and create FIB entries accordingly. Astute 128T aficionados may have also noticed that my service
is named YOUTUBE.internet
. This is part of a soon-to-be-released feature wherein services can be organized hierarchically, like tenants. The benefit of the hierarchical organization is that it can leverage the same underpinnings of the parent service (internet
in this case) for route selection, yet still provide for the ability to override attributes of the parent service. In this case, I've overridden the generic internet
's service-policy
, and replaced it with video-streaming-scavenger
. You can probably intuit what that policy does for me.
The only other nuance here is that my access-policy
statements include the trusted
, guest
, and appletv.iot
tenants. This is because we all tend to watch YouTube videos on our phones, tablets, laptops, etc. in addition to AppleTV.
The service definitions for Hulu and Netflix look similar to one another. Here's Hulu's:
admin@labsystem1.fiedler# show config running authority service HULU.internet
config
authority
service HULU.internet
name HULU.internet
description "Hulu streaming"
scope private
application-name HULU
access-policy appletv.iot
source appletv.iot
exit
service-policy video-streaming
share-service-routes false
exit
exit
exit
Unlike YouTube, this is only available to AppleTV. (We don't use Hulu or Netflix on anything else; if we were to try, it would get "best effort" treatment using an internet
service.) Here we can see the service-policy
is video-streaming
– which, unlike its scavenger counterpart, uses DSCP AF31 (decimal 26) via the built-in MultimediaStreaming
service-class:
admin@labsystem1.fiedler# show config running authority service-policy video-streaming
config
authority
service-policy video-streaming
name video-streaming
description "Enterprise video streaming services"
service-class MultimediaStreaming
session-resiliency failover
path-quality-filter true
best-effort true
max-loss 5
max-latency 4000
exit
exit
exit
The values for session-resiliency, max-loss, and max-latency are all discussed in the document I wrote on Service Policy Baseline Defaults.
Conclusion
I'm now able to identify streaming video traffic on my network much more easily, and have controls in place to limit bandwidth for YouTube while prioritizing Hulu and Netflix for the times when we sit down for Family Movie Night.
I encourage all of you 128T owners to do your own exploration with the DNS AppID plugin and AppID modules. There's no limit to the things you can learn!