-
-
Save nguyenchilong/aee3c1701781554b10dd1c7bb39c6c83 to your computer and use it in GitHub Desktop.
Revisions
-
mrbar42 revised this gist
Oct 28, 2019 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -71,7 +71,7 @@ var crypto = require('crypto'); function generateSecurePathHash(expires, client_ip, secret) { if (!expires || !client_ip || !secret) throw new Error('Must provide all token components'); var input = expires + ' ' + client_ip + ' ' + secret; var binaryHash = crypto.createHash('md5').update(input).digest(); var base64Value = new Buffer(binaryHash).toString('base64'); return base64Value.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); -
mrbar42 revised this gist
May 21, 2018 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,7 @@ # Secured HLS setup with Nginx as media server This example is part of [this article](https://blog.peer5.com/practical-approaches-for-securing-your-video-streams/). This is an example for an HLS delivery with basic security. Nginx compiled with nginx-rtmp-module & secure-link is used as media server. Features: -
mrbar42 revised this gist
May 15, 2018 . 2 changed files with 17 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -13,6 +13,22 @@ Features: Throughout this example the host is assumed to be `example.com`. if you want to use this configurations, be sure to replace all instances of `example.com` with your domain. ### Compiling Nginx ```sh # install deps (Ubuntu) sudo apt-get install -y build-essential libpcre3 libpcre3-dev libssl-dev wget http://nginx.org/download/nginx-1.10.1.tar.gz tar -xf nginx-1.10.1.tar.gz cd nginx-1.10.1 ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module --with-http_secure_link_module make -j sudo make install # nginx is now installed in /usr/local/nginx ``` ### Pushing video to Nginx In order to push video to nginx i'm going to use ffmpeg which well supports RTMP as its output. I'm going to create an `I frame` roughly every 2 seconds which will allow nginx to achieve the 4s segment target. This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -14,6 +14,7 @@ <div id="player" style="width:640px"></div> <script> var player = new window.Clappr.Player({ // this is an example url - for this to work you'll need to generate fresh token source: 'https://example.com/video/hls/CIfZTIu8ygWzhXBSoQfPIQ/1526373226/live.m3u8', parentId: '#player' }); -
mrbar42 created this gist
May 15, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,73 @@ # Secured HLS setup with Nginx as media server This is an example for an HLS delivery with basic security. Nginx compiled with nginx-rtmp-module & secure-link is used as media server. Features: - Domain filtering - Referrer filtering - Embed buster - Session token for playlist, segments and AES keys - AES encryption - HTTPS only Throughout this example the host is assumed to be `example.com`. if you want to use this configurations, be sure to replace all instances of `example.com` with your domain. ### Pushing video to Nginx In order to push video to nginx i'm going to use ffmpeg which well supports RTMP as its output. I'm going to create an `I frame` roughly every 2 seconds which will allow nginx to achieve the 4s segment target. For simplicity i'll be using a static mp4 file and ingest it in infinite loop. ```sh ffmpeg -hide_banner \ -stream_loop -1 \ -re -i test-video.mp4 \ -c:a aac -c:v h264 -g 48 \ -f flv rtmp://localhost:1935/show/live ``` I'm using `live` as the stream name, the output hls will carry that same name - e.g. `live.m3u8`. ### Generating Session token The session token is based on this format (note the spaces): `MD5("EXPIREY_DATE_IN_SECONDS CLIENT_IP_ADDRESS SECRET")` here are several examples of generating the token: BASH ```sh get_customer_url() { local IP=${1:-127.0.0.1} local SECRET=${2:-VERY_COOL_SECRET} local EXPIRES="$(date -d "today + 30 minutes" +%s)"; local token="$(echo -n "${EXPIRES} ${IP} ${SECRET}" | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)" echo "https://example.com/video/hls/${token}/${EXPIRES}/live.m3u8" } get_customer_url 10.20.1.55 "uigfp(@#tfpIUDGPFiouGDF" ``` Node.JS (Javascript) ```js var crypto = require('crypto'); function generateSecurePathHash(expires, client_ip, secret) { if (!expires || !client_ip || !secret) throw new Error('Must provide all token components'); var input = expires + client_ip + ' ' + secret; var binaryHash = crypto.createHash('md5').update(input).digest(); var base64Value = new Buffer(binaryHash).toString('base64'); return base64Value.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); } function getStreamUrl(ip, secret) { const expiresTimestamp = new Date(Date.now() + (1000 * 60 * 30)).getTime(); const expires = String(Math.round(expiresTimestamp / 1000)); const token = generateSecurePathHash(expires, ip, secret); return `https://example.com/video/hls/${token}/${expires}/live.m3u8`; } getStreamUrl('127.0.0.1', 'uigfp(@#tfpIUDGPFiouGDF'); // https://example.com/video/hls/LdS-kcC-JGVHGNTFlX-6Sw/1526373776/live.m3u8 ``` This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,22 @@ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>example.com</title> <script> if (top != self) { top.location.replace(self.location.href); } </script> <script src="//cdn.jsdelivr.net/clappr/latest/clappr.min.js"></script> </head> <body> <div id="player" style="width:640px"></div> <script> var player = new window.Clappr.Player({ source: 'https://example.com/video/hls/CIfZTIu8ygWzhXBSoQfPIQ/1526373226/live.m3u8', parentId: '#player' }); </script> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,110 @@ worker_processes auto; events { worker_connections 4096; } # RTMP configuration rtmp { server { listen 1935; # Listen on standard RTMP port chunk_size 4000; application show { live on; # Turn on HLS hls on; hls_path /mnt/hls/; hls_fragment 4; hls_playlist_length 60; # Setup AES encryption hls_keys on; hls_key_path /mnt/hls/keys; hls_key_url keys/; hls_fragments_per_key 10; # disable consuming the stream from nginx as rtmp deny play all; } } } http { sendfile off; tcp_nopush on; directio 512; default_type application/octet-stream; access_log off; error_log off; # HTTPS certificate and key ssl_certificate ssl/example.com.cert; ssl_certificate_key ssl/example.com.key; server { listen 443 ssl; server_name example.com; root /mnt/; # Disable cache add_header 'Cache-Control' 'no-cache'; index index.html; default_type "text/html"; types { application/dash+xml mpd; application/vnd.apple.mpegurl m3u8; video/mp2t ts; plain/text key; } location =/ { # CORS setup add_header 'Access-Control-Allow-Origin' 'https://example.com' always; add_header 'Access-Control-Expose-Headers' 'Content-Length' always; add_header 'X-Frame-Options' 'DENY' always; } location /video { rewrite /hls/([a-zA-Z0-9_\-]*)/([0-9]*)/(.*)\.(ts|m3u8|key)$ /hls/$3.$4?token=$1&expires=$2; root /mnt/not-exist; } location /hls { internal; # The secure link is base on the folowing format # MD5("EXPIREY_DATE_IN_SECONDS CLIENT_IP_ADDRESS SECRET") # here is a BASH function that generates a secure link # get_token() { # local expires="$(date -d "today + 30 minutes" +%s)"; # local token="$(echo -n "${expires} 127.0.0.1 VERY_COOL_SECRET" | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =)" # echo "${token}/${expires}" # } # echo "https://example.com/video/hls/$(get_token)/live.m3u8" secure_link $arg_token,$arg_expires; secure_link_md5 "$secure_link_expires $remote_addr VERY_COOL_SECRET"; if ($secure_link = "") { return 403; } if ($secure_link = "0") { return 410; } # Referrer protection valid_referers server_names; if ($invalid_referer) { return 403; } # allow CORS preflight requests if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' 'https://example.com'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } } } server { listen 443 ssl default; server_name _; return 444; } }