Getting HBO and Netflix to work on GNU/Linux

Edit: 2014-08: This guide is now outdated as pipelight is included in the main gentoo tree and does not require a crossdev environment to be set up to work any longer.


After my Mac Mini running OS X had a failed HDD I finally got an excuse to buy a nice Asus Vivo PC (Intel Core i5-3210M, 8GB RAM,128GB SSD, Intel HD 4000) and install my favorite OS; GNU/Linux, specifically running the Gentoo distribution.

Now, for all the good things there is about GNU/Linux (I'm not gonna spend time on mentioning them here), there is one obvious drawback, and that is that mainstream providers such as Netflix and HBO have no native support (Why aren't they just using HTML5?). However, thankfully there is a good alternative to enable these services, and that is Pipelight:

Pipelight is a special browser plugin which allows one to use windows only plugins inside Linux browsers. We are currently focusing on Silverlight, Flash, Shockwave and the Unity Webplayer. The project needs a patched version of Wine to execute the Silverlight DLL.

In addition Pipelight supports the Widevine used by HBO (and as only the DRM plugin is running in wine, with a rather low performance hit at that).

So how to go ahead installing Pipelight on a GNU/Linux machine running Gentoo? Well, first of all we'll make sure to have layman and crossdev installed.

emerge layman crossdev

As Pipelight require a patched version of wine we'll find both pipelight and the patched version in the overlay at:

layman -o https://raw.github.com/ryao/pipelight-overlay/master/overlay.xml -f -a pipelight

And in order to make sure that the overlay can be used we make sure layman is sourced

echo "source /var/lib/layman/make.conf" >> /etc/portage/make.conf

Rather than following the straight README for the overlay we want to set it up using crossdev. First we make sure that package.env, package.mask, package.use and package.keywords are directories rather than simple files, and if not convert it:

if [[ -f /etc/portage/package.env ]]; then mv /etc/portage/package.env /etc/portage/package.env.old && mkdir /etc/portage/package.env && mv /etc/portage/package.env.old /etc/portage/package.env/generic; fi
if [[ -f /etc/portage/package.keywords ]]; then mv /etc/portage/package.keywords /etc/portage/package.keywords.old && mkdir /etc/portage/package.keywords && mv /etc/portage/package.keywords.old /etc/portage/package.keywords/generic; fi
if [[ -f /etc/portage/package.mask ]]; then mv /etc/portage/package.mask /etc/portage/package.mask.old && mkdir /etc/portage/package.mask && mv /etc/portage/package.mask.old /etc/portage/package.mask/generic; fi
if [[ -f /etc/portage/package.use ]]; then mv /etc/portage/package.use /etc/portage/package.use.old && mkdir /etc/portage/package.use && mv /etc/portage/package.use.old /etc/portage/package.use/generic; fi

Then we delete the cross-compiler part already found in the overlay using

rm -rf /var/lib/layman/pipelight/cross-i686-w64-mingw32

and setup the crossdev toolchain using

echo "=cross-i686-w64-mingw32/mingw64-runtime-3.1.0 **" >> /etc/portage/package.keywords/generic

crossdev -S -t i686-w64-mingw32

Now to install pipelight itself, we do this using

echo "=www-plugins/pipelight-9999 **" >> /etc/portage/package.keywords/pipelight
echo "app-emulation/wine-compholio ~amd64" >> /etc/portage/package.keywords/pipelight
echo "app-emulation/wine-compholio abi_x86_32" >> /etc/portage/package.use/pipelight

emerge pipelight

With that we should have a working base. Before we proceed though we want to install  media-fonts/corefonts and app-arch/cabextract. The former is in particular necessary to get a working Netflix setup (without it, expect a player 1001 error).

emerge app-arch/cabextract media-fonts/corefonts

Now time to configure the actual plugin. As I intend on using this with Firefox, the last command to run as root privileges before switching back to the normal user is:

pipelight-plugin --create-mozilla-plugins

Now time to enable the actual plugins (as regular user):

pipelight-plugin --enable-plugin silverlight5.1
touch $HOME/.config/wine-wininet-installer.accept-license
pipelight-plugin --enable-plugin flash
pipelight-plugin --enable-plugin widevine

The actual installation happens upon a restart of firefox, and can be seen by visiting about:plugins.
As Netflix use a rather primitive user agent string check, we also need to switch the user agent string before attempting to play. I'm using user-agent-overrider and set it to Windows/firefox before attempting to visit netflix or HBO.

Now, at this point, depending on your video card you should be able to stream both Netflix and HBO, however, for my nouveau driver I got " Direct rendering is disabled, most likely your 32-bit OpenGL drivers haven't been installed correctly (using GL renderer "Gallium 0.4 on NVC3", version "1.4 (3.0 Mesa 9.1.6)")" when attempting to play Netflix (HBO works). Turns out I hadn't given the user in question access to /dev/dri/card0 (video group). Adding the user and netflix as well worked.

As a final note; Netflix might require xattr to be enabled on the filesystem. To test if this is enabled you can run:

touch ~/.xattr_test && setfattr -n 'user.testAttr' -v 'attribute value' ~/.xattr_test &> /dev/null; getfattr ~/.xattr_test 2>&1 | grep -q user.testAttr && echo 'It works!' || echo 'No workie!'; rm ~/.xattr_test &> /dev/null

And voilla, a working Netflix and HBO on GNU/Linux (Gentoo)!

OpenPGP key statistics

Recently there has been some talk about the number of OpenPGP keys available on the various keyservers. My own contribution to this discussion is tracking the development at sks-keyservers.net . As can be seen on both the line chart of total number of keys, and the breakdown to a bar chart for daily addition, new keys are added at a higher rate today than it was just a few years ago, and without any statistical considerations, the change of rate seems to coincidentally correspond to the Snowden leaks.

 

LineChart BarChart

This post will look into some of the underlying data and hopefully provide a bit more information depth. The data was exported from one of my own keyservers yesterday and consists of 3,526,080 primary keys, of which 118 keys were invalid to the point that I've discarded them from the rest of the analysis (unable to properly parse the OpenPGP packets to extract the information). To emphasize; I have not looked into subkeys in any way for the purposes of this post and I have made no attempt to determine whether these keys are expired, revoked or otherwise inactive.

The overall majority (94.74%) were Version 4 keys c.f. RFC4880 with V3 keys representing 4.73% and V2 keys representing 0.53%. DSA keys represented 74.4%, while 25.6% were RSA keys and a minority ElGamal (0.03%), Elliptic Curve keys (35 keys) and keys in the experimental range (32 keys) .

The key lengths spans from 3 keys in the experimental range key with algo id 103 of 224 bits to 32,768 bits (3 keys, two of which are RSA and one DSA). Due to the low occurrence of ECC keys (that have an expectation of lower key lenghts for similar expected security levels -  normally in the 256-521 bit range, although there is a strong possibility that the aforementioned 224 bits keys should also fit in this category) I have not done any adjustment for these. A full 77.4% of the keys are included when looking at the aggregate figures up to and including 1024 bits, roughly 2.7 million of the keys, and the corresponding number when looking at a 2048 and 4096 bits respectively are 95.3% and 99.95% of all keys included.

key_length

Load-balancing SKS

The synchronizing key server (SKS) is the most used implementation of OpenPGP key servers. Despite its many strengths, however, its web frontend scales badly and should generally be placed behind a reverse proxy such as nginx, apache or varnish. For inclusion in the High-Availability (HA) pool of sks-keyservers.net this is a requirement, and it is also part of the weighting criteria for the various geographical sub pools. With the increase in number of keys I've been thinking of ways to ensure that the pool stays even more responsive, and currently considering (i) to make it a hard-requirement for inclusion in the pool to have a reverse proxy set up (ii) to reuse the HA pool for a set of servers that are even more available, by proving that they are load-balanced across multiple instances of SKS.

 

My own keyserver, for historical reasons named keys2.kfwebs.net (keys.kfwebs.net was located in another server facility and is currently not operational),  is running such a load balanced setup using Nginx's upstream module.But before getting back to that, some basic information about my SKS setup.

Two or three SKS servers (depending on whether I need to use one of them for experimenting with other projects such as the Key Signing Party list auto-generating lists based on publications to a keyserver) are running on different Virtual Machines, one server peering with the global network and the other servers peering internally. To ease the load on SKS, static pages are served by nginx directly using:

location / {
root /var/sks/web;
index   index.xhtml;
}

 

The actual data being served by SKS is in the /pks subdirectory and is being handled by the directive

location /pks {
proxy_pass http://sks_servers/pks;
proxy_pass_header  Server;
add_header Via "1.1 keys2.kfwebs.net";
proxy_ignore_client_abort on;
}

And this is where the load-balancing is starting to happen. "sks_servers" is not a hostname that is being referenced but an upstream directive in Nginx that states;

upstream sks_servers
{
server  localhost:11372;
server  192.168.0.27:11371;
}

When adding and removing servers I simply edit this directive and reload nginx, and here I also have the possibility of assigning weights to each of the servers (defaults to 1).
In the status list of the pool such load-balanced servers can be identified by a blue flag for RProx (Reverse Proxy). Hopefully enough operators will set up load-balanced systems for an even more responsive High-Availability pool to exist.