nginx amb rtmp amb autenticació d’usuari

Objectiu:

Volem disposar d’un servidor d’streaming que accepti el protocol RTMP. A més volem poder autenticar d’alguna manera els usuaris per a permetre la reproducció o no.

Procediment:

Per dur a terme la tasca utilitzarem nginx i el compilarem amb el mòdul nginx-rtmp-module. Com sempre, utilitzarem el sistema operatiu Debian, en aquest cas la versió 7 (Wheezy).

Les comandes per compilar nginx a partir de les fonts de Debian són les següents:

$ apt-get install dpkg-dev git
$ cd /usr/src
$ apt-get source nginx
$ apt-get build-dep nginx
$ git clone https://github.com/arut/nginx-rtmp-module.git
$ cd nginx-[version-number]
$ pico debian/rules

En aquest punt modificarem les regles de compilació del paquet Debian. Veureu que hi ha tota una sèrie de seccions en la que s’afegeixen mòduls. En totes elles podem afegir, al final, la següent línia:

--add-module=/usr/src/nginx-rtmp-module \

Seguim:

dpkg-buildpackage -b

Ara s’ha d’esperar una estona a que es compili el paquet.

Quan hagi acabat l’instal·lem:

$ cd .. && dpkg -i nginx-common_[version-number].deb nginx-full_[version-number].deb

En aquest punt podem arrencar el servei nginx:

$ service nginx start

Configuració:

Anem ara a configurar l’nginx. Afegirem el següent a l’arxiu de configuració /etc/nginx/nginx.conf:

...
rtmp {
    server {
        listen 1935;
        application vod {
                play /var/flvs;
        }
    }
}
...

Això habilita una aplicació (vod) al servidor amb els arxius multimèdia que hi hagi a la carpeta /var/flvs. Aquesta carpeta no existeix, la creem (també es poden posar els arxius en qualsevol altre lloc, és clar):

$ mkdir -p /var/flvs 

Finalment reiniciem nginx:

$ service nginx restart

En aquest punt tenim el servei preparat. Des d’una aplicació, com ara VLC, podríem reproduir els vídeos utilitzant la següent URL: rtmp://[ip-o-nom-del-servidor]/vod/[stream].

stream es refereix a l’identificador de l’arxiu multimèdia a reproduir. El format pot ser un nom (video o video.mp4) o un format seguit d’un nom (mp4:video o mp4:video.mp4). Segons els tipus dels arxius i/o el client es podran accedir d’una manera o una altra.

El problema que se’ns presenta aquí és que qualsevol usuari, coneixent la URL del servidor pot reproduir els vídeos. Això, en aquest tutorial, no ens interessa. El que volem és autenticar l’usuari que està accedint al vídeo. Per a això utilitzarem una directiva de nginx-rtmp-module que, abans de reproduir un vídeo, consulti una pàgina web on durem a terme l’autenticació.

Autenticació:

Tornem a modificar la configuració de nginx i afegim aquestes dues línies:

on_play http://[ip-o-nom-del-servidor-web]/auth.php; 
notify_method get;

La secció complerta queda així:

rtmp {
    server {
        listen 1935;
        application vod {
                on_play http://[ip-o-nom-del-servidor-web]/auth.php; 
                notify_method get;
                play /var/flvs;
        }
    }
}

El que estem fent aquí és forçar el servei nginx a consultar una pàgina (auth.php) cada cop que es dugui a terme el play d’un arxiu multimèdia. Si el codi de retorn és 20X aleshores el vídeo es reproduirà, altrament (40X) no.

Només queda definir el contingut de l’arxiu auth.php amb la gestió de l’autenticació. Evidentment, cada cas serà diferent. Establim, doncs, el procediment bàsic i que cadascú esculli com autenticar els seus usuaris.

Un exemple d’arxiu d’autenticació podria ser el següent:

<?php
if (empty($_GET['user']) || empty($_GET['pass'])) {
    header('HTTP/1.0 404 Not Found');
    exit(1);
} else {
    $username = $_GET['user'];
    $password = $_GET['pass'];
}

$savedpassword = 'somesecret';
$saveduser = 'someuser';

if (strcmp($password, $savedpassword)==0 && strcmp($username, $saveduser)==0) { 
    echo "OK!";
} else {
    header('HTTP/1.0 404 Not Found');
}
?>

Aquest codi és molt bàsic però s’entén el que es pretén. Si es produeix un error d’autenticació el codi de retorn és el 404: el vídeo no es reproduirà. Si la pàgina conté qualsevol altre text es procedirà amb la reproducció.

Per enviar la informació d’autenticació modificarem la URL de connexió així: rtmp://[ip-o-nom-del-servidor]/vod/[stream]?user=usuari&pass=contrasenya. Quan l’nginx faci la crida a auth.php reenviarà la informació extra proporcionada a la URL apart de tota una sèrie de paràmetres propis. En la documentació de les directives de nginx-rtmp-module s’expliquen un a un si us interessa.

Client Web (flowplayer):

Quan fem la nostra pàgina web amb el reproductor, tipus YouTube o Dailymotion, haurem d’enviar el nom d’usuari i contrasenya. Aquesta informació s’haurà d’afegir al codi de la pàgina. Això vol dir que el nom d’usuari i la contrasenya seran visible en el navegador, concretament en el codi javascript. Això és força lleig pel que es recomana cercar altres sistemes d’autenticació que no suposin mostrar en clar la contrasenya de l’usuari. Mitjançant tokens, per exemple, seria una solució millor.

A continuació és mostra el codi bàsic per a muntar una pàgina amb el flowplayer i rtmp (plugin que es pot aconseguir des de la mateixa pàgina de flowplayer.org):

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="flowplayer-3.2.13.min.js"></script>
<title>My videos</title>
</head>
<body>
	<a style="display:block;width:520px;height:330px" id="player"></a>
	<script>flowplayer("player", "flowplayer-3.2.18.swf",{clip:{url:'mp4:video.mp4?user=usuari&pass=contrasenya',provider:'rtmp'},plugins:{rtmp:{url:'flowplayer.rtmp-3.2.13.swf',netConnectionUrl:'rtmp://[ip-o-nom-del-servidor]/vod'}}});</script>
</body>
</html>

Conclusió:

En aquest punt disposem d’un servidor nginx que pot fer de servidor d’streaming en rtmp. A més els usuaris es poden autenticar per a permetre l’accés al contingut del vídeo.

Documentació:

nginx: http://nginx.org
nginx-rtmp-module: https://github.com/arut/nginx-rtmp-module
flowplayer: Descàrregues