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
@junierkl

This comment has been minimized.

Copy link

commented Apr 19, 2016

Hi, thank you very much for this beautiful work, i was wondering if there is a way to limit the video by ip just like google and other sites does. thank you

@iKalin

This comment has been minimized.

Copy link

commented Jul 4, 2016

wich version of ruby you use?

@imfa1se

This comment has been minimized.

Copy link

commented Dec 26, 2018

Anyone about to offer some assistance with this thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.