Using Nginx' HttpSecureLinkModule

Table of Contents

This module is not compiled by default, so you may have to install it first. Please see the original HttpSecureLinkModule page for instructions.

Server

We will be securing our content in the directory /protected The configuration is the same as the example provided by the HttpSecureLinkModule page, except for the addition of the 'ism;' statement at the end of the location section '{ ... }'.

location ~ ^/protected/ {
  root   /var/www;

  # This must match the URI part related to the MD5 hash and expiration time.
  secure_link $arg_st,$arg_e; # this must match the URI part related

  # This is how the MD5 hash is built from a secret token, a URI and an expiration time.
  secure_link_md5 secret$uri$arg_e; # 'secret' is the secret token

  # If the hash is incorrect then $secure_link is a null string.
  if ($secure_link = "") {
    return 403;
  }

  ## The current local time is greater than the specified expiration time.
  if ($secure_link = "0") {
    return 403;
  }

  ## If everything is ok $secure_link is 1. This needs to be here otherwise you'll get a 404.
  rewrite ^/protected/(.*)$ /protected/$1 break;

  usp_handle_ism;
}

Client

On the client we generate an MD5 hash and an expiry time for a specific URL. For an expiry time one week from now you can use:

#!/bin/bash

ISM_TIMESTAMP=$(php -r "print time() + 7 * 24 * 60 * 60;")

The MD5 hash is calculated over your secret password, the path to the video server manifest file and the expiry timestamp. In the case of our example:

#!/bin/bash

ISM_HASH=$(php -r "print str_replace('=', '',strtr(base64_encode(md5('$(SECRET)/protected/alvin/alvin.ism$(ISM_TIMESTAMP)', TRUE)), '+/', '-_'));")

Again, please note that the path to the server manifest file is used in the hash calculation. Do not include anything after that like /Manifest, /alvin.m3u8, etc...

The last thing to do is to add the hash and expiry date parameters to the URLs that you would normally provide to the player.

For HSS:

http://localhost:/protected/alvin/alvin.ism/manifest?st=$(ISM_HASH)&e=$(ISM_TIMESTAMP)

For HLS:

http://localhost:/protected/alvin/alvin.ism/alvin.m3u8?st=$(ISM_HASH)&e=$(ISM_TIMESTAMP)

For HDS:

http://localhost:/protected/alvin/alvin.ism/alvin.f4m?st=$(ISM_HASH)&e=$(ISM_TIMESTAMP)

Adobe's OSMF player and Strobe Media Playback currently don't handle query parameters correctly. They simply tag on the 'Segx-Fragy' to the media URL specified in the manifest file. You have to update the player so it inserts the 'Segx-Fragy' and the end of the path and before any query parameters.

Notes

All the requests for a presentation (the playlists, the media playlists, the fragments) are secured, and thus all URLs must have the security hash and timestamp tagged on to their URL. Note that you do not have to do anything for this.

You only have to add the security attributes to the presentation manifest/playlist file. The webserver takes care of adding the security parameters to any URLs referenced in the playlists and media playlists.

Just make sure that you do not have static copies of the playlists (.m3u8 / .f4m / .ismc) stored on disk and let the webserver generate them dynamically.