Sunday, June 9, 2013

Secure links in nginx-rtmp

Many people ask me for secure link support in nginx-rtmp similar to nginx http secure links. The truth is no special support is needed to have that in nginx-rtmp. You can set secure links on on_connect, on_play or on_publish. I'll show how to do that for on_play. on_publish is very much the same, on_connect has no name argument, only app.



http {
    server {
        listen 8080;
        server_name localhost;

        location /on_play {

            # set connection secure link
            secure_link $arg_st,$arg_e;
            secure_link_md5 mysecretkey$arg_app/$arg_name$arg_e;

            # bad hash
            if ($secure_link = "") {
                return 501;
            }

            # link expired
            if ($secure_link = "0") {
                return 502;
            }

            return 200;
        }
    }
}
rtmp {
    server {
        listen 1935;
        notify_method get;

        # protected application
        application myapp {
            live on;
            on_play http://localhost:8080/on_play;
        }
    }
}


With the above configuration you cannot play any stream from myapp application without providing the right secure link.


> ffplay 'rtmp://localhost/myapp/mystream'
ffplay version 1.0.6 Copyright (c) 2003-2013 the FFmpeg developers
...
rtmp://localhost/myapp/mystream: Unknown error occurred


In error.log we have this message


notify: HTTP retcode: 5xx


Now let's construct valid secure RTMP link. Get current timestamp first and add 1 hour expire time to it.


> date +%s
1370777449
> echo $((1370777449+3600))
1370781049

Then construct the hash (watch config above for key)


> echo -n "mysecretkeymyapp/mystream1370781049" | openssl dgst -md5 -binary | 
         openssl enc -base64 | tr '+/' '-_' | tr -d '='
Mbjev5ld4mmCN00mwIqD7w


Now we have the hash. It's easy to construct the valid secure RTMP url.

> ffplay 'rtmp://localhost/myapp/mystream?e=1370781049&st=Mbjev5ld4mmCN00mwIqD7w'

16 comments:

  1. really useful post, thank you :)

    ReplyDelete
  2. Example you can show in jw player and php page.

    ReplyDelete
  3. Hi,

    How do i get IP address of client in on_play handler? Thanks you.

    ReplyDelete
    Replies
    1. $addr argument

      https://github.com/arut/nginx-rtmp-module/wiki/Directives

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hi,

    I have problem with secure link and multi workers. when i refresh page, it does not work, refresh again, sometime it work, sometime it does not.

    Pleas help me.

    ReplyDelete
  6. where did this code go nginx.conf or on player page...
    > date +%s
    1370777449
    > echo $((1370777449+3600))
    1370781049

    ReplyDelete
    Replies
    1. Use this code to generate secure link. That can be PHP script or manually created links.

      Delete
  7. if i put this in php file it gives error in php file...pls help
    Now let's construct valid secure RTMP link. Get current timestamp first and add 1 hour expire time to it.


    > date +%s
    1370777449
    > echo $((1370777449+3600))
    1370781049

    Then construct the hash (watch config above for key)


    > echo -n "mysecretkeymyapp/mystream1370781049" | openssl dgst -md5 -binary |
    openssl enc -base64 | tr '+/' '-_' | tr -d '='
    Mbjev5ld4mmCN00mwIqD7w

    ReplyDelete
    Replies
    1. it's shell, not php.
      obviously you can write that in any language you know

      Delete
  8. I'm trying to limit playback to my hosted player only. Will this allow me to do this?

    ReplyDelete
    Replies
    1. Well, it's supposed to .

      I d really like a full "how to" tutorial including one or two common player (let's say flowplayer or jwplayer) on how to implement this client side.

      A php (or else) script, how to write it, where to put it.. how to setup the player to use it...

      Delete
  9. http://www.leaseweblabs.com/2014/03/custom-http-secure-link-using-openresty-nginx-module/#comment-83010

    for a working php secure hash creator

    ReplyDelete
  10. hello mr Roman Arutyunyan,
    I use nginx-rtmp-module as live stream media server. And the server is deployed on internet. For example, the internet ip is: 210.118.37.58.
    I create an application on server. the application name is: myapp.
    Then i use adobe media encoder publish live stream. The publish url is: rtmp://210.118.37.58:1935/myapp/stream1.
    Then i use vlc player play the live stream.
    They are worked correctly.

    Now, my question is:
    1.How can i only allow publisher (which is authenticated by me) to publish stream to rtmp://210.118.37.58:1935/myapp/.
    2.How can i only allow player (which authenticated by me) to play rtmp://210.118.37.58:1935/myapp/

    Although you have answered the questions above, but i have not understand how to config the rtmp-module.
    Thanks.

    ReplyDelete
    Replies
    1. My email address is hdjhdq@163.com.
      Thank you so mush for you help.

      Delete
  11. I would like to known,
    How can i only allow publisher (which is authenticated by me) to publish stream to rtmp://210.118.37.58:1935/myapp/.

    As the person before me asked

    ReplyDelete