Skip to content

Instantly share code, notes, and snippets.

@mikhailov
Last active December 26, 2022 19:30
Show Gist options
  • Star 71 You must be signed in to star a gist
  • Fork 37 You must be signed in to fork a gist
  • Save mikhailov/3174601 to your computer and use it in GitHub Desktop.
Save mikhailov/3174601 to your computer and use it in GitHub Desktop.
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
@imfa1se
Copy link

imfa1se 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