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; } }