Plex, pfSense, OpenDNS and DNS Rebinding

I’m starting to use pfSense a lot more at home now, making use of the advanced security features rather than it just being a router. I got quite frustrated last night when my girlfriend and I sat down to watch a film on Plex to discover that my Xbox One (Plex Client) could not see the Plex Server that was sat right next to it, on the same network. Further investigation proved that neither could my smart TV. I could access the server remotely via the Plex web app, so it wasn’t a port forwarding issue – I had already allowed 32400/tcp through pfSense to the Plex server anyway.

It turns out it was some security protection against DNS Rebinding. DNS Rebinding attacks are where someone directs you to an address which resolves to an internal IP. Loads of appliances and broadband routers use this functionality to present you with captive portals, and so on. I had seen a lot of people having similar trouble with Plex behind pfSense, so I followed the instructions. In fact, Plex themselves even provide you with instructions on their How To Use Secure Connections support page.

Actually, you should follow the DD-WRT dnsmasq instructions if you use the “DNS Forwarder” on pfSense as this is dnsmasq. The config line goes in Services -> DNS Forwarder in the Custom Options section, like this:

So, I had configured pfSense as Plex support advised, but I was still unable to connect to the server. Eventually I read up on how the plex.direct domain name is used. When you log in to your Plex account you’re granted an authentication token which looks like any other guid (some long random hex string). The Plex service creates a wildcard HTTPS certificate for *.guid.plex.direct which is unique to your account. It then tries to access your Plex server at https://ipaddress.guid.plexdirect:32400/ substituting the dots in the IP address for dashes. So such a URL could look like

https://192-168-0-1.a6b0cf6c7cx949da9845f9ab816c70ad.plex.direct:32400/

I saw this URL pop up in the Developer Tools -> Network section of my browser when using the Plex web app at https://app.plex.tv/web/app with some security warning or other. When I browsed to that address, I got an OpenDNS page saying that it had blocked some malware!

That’s right folks, I’m also using OpenDNS and it also has some DNS Rebind protection built in! It can be completely disabled via Settings -> Security and unchecking Suspicious Responses. However to retain the layer of security OpenDNS was providing I created a “Never block” entry under Settings -> Web Content Filtering for plex.direct which seems to have done the trick.

The 2 lessons here are

  1. When employing a multi-layered approach to security and creating an exception make sure you create the exception at every layer
  2. Never assume that you know how network protocols work because someone will always find some obscure way of using totally standard stuff that makes no sense.

Modifying SquidGuard in pfSense for email notifications

I recently set up a pfSense box as a trial for transparent proxying in a school. The driver behind this was to try and meet the UK’s Prevent legislation in a cash-strapped organisation. I’m a huge advocate of pfSense, I think it’s an excellent product with a staggering feature set for free. Alternative UTM products could have run the school into thousands of pounds of hardware, support costs and subscription charges, not to mention the cost of a consultant to come in and set it up.

pfSense can use the open source Squid proxy with the SquidGuard filtering add-on as a transparent proxy. SquidGuard can make use of freely available online lists to categorise websites and control access to those categories. However one thing it doesn’t do is notify you when someone hits a blocked category. You can view the logs in realtime and the SquidGuard logs are separated off from the main Squid ones, so you can only see policy contraventions (as well as it rewriting search URLs to enforce SafeSearch, for example) but you have to be looking. A requirement from the school’s IT administrator was that they wanted an email the second someone tried to access something forbidden.

Now given that pfSense is FreeBSD under the hood that should be easy right, just call sendmail, job done. However it’s a very stripped down FreeBSD installation designed for absolutely minimal hardware requirements, so it doesn’t have sendmail. No sendmail, no postfix, no mail command. Email notifications are handled internally via PHP. There is a PHP script in place of mail (mail.php) which you can pipe text to. However the SquidGuard block page is PHP already, and it includes a tonne of pfSense functions out of the box, so why not just use the built in notification handler. Adding the following line to /usr/local/www/sgerror.php worked lovely:

send_smtp_message($cl['a'] . " tried to browse to " . $cl['u'], "SquidGuard Blacklist Hit");