Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Nginx + secure pseudo-streaming
# Nginx can serve FLV/MP4 files by pseudo-streaming way without any specific media-server software.
# To do the custom build we use 2 modules: --with-http_secure_link_module --with-http_flv_module
# This module "secure-link" helps you to protect links from stealing away.
#
# NOTE: see more details at coderwall: http://coderwall.com/p/3hksyg
cd /usr/src
wget http://nginx.org/download/nginx-1.5.13.tar.gz
tar xzvf ./nginx-1.5.13.tar.gz && rm -f ./nginx-1.5.13.tar.gz
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.32.tar.gz
tar xzvf pcre-8.32.tar.gz && rm -f ./pcre-8.32.tar.gz
wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz
tar xzvf openssl-1.0.1g.tar.gz && rm -f openssl-1.0.1g.tar.gz
cd nginx-1.5.13 && ./configure --prefix=/opt/nginx --with-pcre=/usr/src/pcre-8.32 --with-openssl-opt=no-krb5 --with-openssl=/usr/src/openssl-1.0.1g --with-http_ssl_module --without-mail_pop3_module --without-mail_smtp_module --without-mail_imap_module --with-http_stub_status_module --with-http_secure_link_module --with-http_flv_module --with-http_mp4_module
make && make install
$ cd /opt/nginx/html
$ echo "<cross-domain-policy>
<allow-access-from domain='*.your_domain.com' />
</cross-domain-policy>" > crossdomain.xml
$ echo "User-Agent: *
Disallow: /" > robots.txt
# Nginx uses the protected links that build with md5 of YOUR_SECRET_PASSWORD_HERE, URI and Unix timestamp
user app;
worker_processes 2;
timer_resolution 100ms;
error_log logs/error.log;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log off;
sendfile on;
server_tokens off;
keepalive_timeout 65;
ssl_certificate /opt/nginx/ssl_certs/server.crt;
ssl_certificate_key /opt/nginx/ssl_certs/server.key;
ssl_session_timeout 15m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
server {
ssl on;
listen 443 default ssl;
access_log logs/access.log;
location /video/ {
rewrite /video/([a-zA-Z0-9_\-]*)/([0-9]*)/(.*)\.flv$ /flv/$3.flv?st=$1&e=$2;
}
location /flv/ {
internal;
secure_link $arg_st,$arg_e;
secure_link_md5 YOUR_SECRET_PASSWORD_HERE$arg_e$uri;
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 403; }
root /mnt/your_directory;
flv;
add_header Cache-Control 'private, max-age=0, must-revalidate';
add_header Strict-Transport-Security "max-age=16070400; includeSubdomains";
add_header X-Frame-Options DENY;
}
location =/ {
root /404.html;
}
location = /50x.html {
root html;
}
location ~ \.(php|html)$ {
deny all;
}
}
}
require 'rubygems'
require 'activesupport'
require 'digest/md5'
class Signature
PASSWORD = 'YOUR_SECRET_PASSWORD_HERE' # use this password for nginx directive "secure_link_md5"
DIR = 'flv' # the internal nginx location to access to media files
SERVER_NAME = 'http://your_server.com:8080' # nginx listen address and port
attr_reader :expiration_time, :file_name, :md5
def initialize(file_name)
@expiration_time = (Time.now + 2.hours).to_i
@file_name = file_name
md5_calculate
end
def generate
# nginx secured URL to access to media files, "video" is the location, not real directory on filesystem
"#{SERVER_NAME}/video/#{@md5}/#{expiration_time}/#{file_name}"
end
private
def md5_calculate
s = "#{PASSWORD}#{@expiration_time}/#{DIR}/#{@file_name}"
a = Base64.encode64(Digest::MD5.digest(s))
@md5 = a.tr("+/", "-_").sub('==', '').chomp
end
end
url = Signature.new('video1.flv')
puts url.expiration_time #=> 1326559618
puts url.md5 #=> HLz1px_YzSNcbcaskzA6nQ
puts url.generate #=> http://your_server.com:8080/video/HLz1px_YzSNcbcaskzA6nQ/1326559618/video1.flv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment