Videoconferencias en tu propio servidor con SylkServer

Tener un sistema con el que poder hacer videoconferencias ad-hoc en nuestro propio servidor es algo que puede resultarnos interesante.  Hoy vamos ha hacer eso mismo, instalando SylkServer y Sylk WebRTC client en un servidor con Ubuntu 16.04, de manera que el resultado sea el mismo que al visitar ésta web.

Paso 0, prerequisitos

Lo primero es instalar Ubuntu 16.04, obviamente 🙂 Y luego agregar los repositorios de AG Projects:

wget http://download.ag-projects.com/agp-debian-gpg.key 
apt-key add agp-debian-gpg.key
echo "deb http://ag-projects.com/ubuntu xenial main > /etc/apt/sources.list.d/ag-projects.list

Paso 1, SylkServer

apt update
apt install sylkserver-webrtc-gateway

Esto nos instalará SylkServer y todos los componentes necesarios de la parte servidor. Ahora vamos a configurarlo editando /etc/sylkserver/config.ini:

; SylkServer configuration file

[Server]

; The following settings are the default used by the software, uncomment
; them only if you want to make changes

default_application = webrtcgateway

; Statically map a Request URI to a specific application. In the example
; below, 123 is matched 1st against the domain part, than the username part
; of the Request URI This static mapping can be overwritten by adding
; X-Sylk-App header set to the value of a valid SylkServer application name
; application_map = echo:echo,123:conference,test:ircconference,gmail.com:xmppgateway
application_map =

; Disable the specified applications
disabled_applications = conference, xmppgateway, playback, echo, ircconference

; Directory where extra applications are stored
; extra_applications_dir =

trace_dir = /var/log/sylkserver
; trace_core = False
; trace_sip = False
; trace_msrp = False
; trace_notifications = False

; TLS is used by default for SIP signaling and MSRP media using a
; self-signed certificate.  You may want to use a properly signed X.509
; certificate and configure it below

; The X.509 Certificate Authorities file
ca_file = /etc/sylkserver/tls/ca.crt

; The file containing X.509 certificate and private key in unencrypted format
certificate = /etc/sylkserver/tls/default.crt

; verify_server = False

; Enable Bonjour capabilities for applications
; enable_bonjour = False

; Base directory for files created by the server, excluding log files
; spool_dir = /var/spool/sylkserver


[SIP]
; SIP transport settings

; IP address used for SIP signaling and RTP media; an empty string or 'any' means listening on
; the interface used by the default route
; local_ip =

; IP address to be advertised in the SDP, useful in 1-to-1 NAT scenarios such as Amazon EC2
; advertised_ip =

; Ports used for SIP transports, if not set to any value the transport will be disabled
local_udp_port = 0
local_tcp_port = 0
local_tls_port =

; If set, all outbound SIP requests will be sent through this SIP proxy
; The proxy address format is: proxy.example.com:5061;transport=tls
; Transport can be udp, tcp or tls, if skipped it is considered udp
; If only the hostname is set, RFC3263 lookups are performed to lookup 
; the outbound proxy server address
; outbound_proxy =

; A comma-separated list of hosts or networks to trust.
; The elements can be an IP address in CIDR format, a
; hostname or an IP address (in the latter 2 a mask of 32
; is assumed), or the special keywords 'any' and 'none'
; (being equivalent to 0.0.0.0/0 and 0.0.0.0/32
; respectively). It defaults to 'any'.
; trusted_peers =

; Toggle ICE support (RFC 5245)
; enable_ice = False


[MSRP]

; MSRP transport settings

; A valid X.509 certificate is required for MSRP to work over TLS.
; TLS is enabled by default, a default TLS certificate is provided with SylkServer.
; use_tls = True


[RTP]

; RTP transport settings

; Allowed codec list, valid values: opus, G722, speex, PCMU, PCMA, iLBC, GSM
; audio_codecs = opus,speex,G722,PCMU,PCMA

; Port range used for RTP
; port_range = 50000:50500

; SRTP valid values: disabled, sdes, zrtp, opportunistic
; srtp_encryption = opportunistic

; RTP stream timeout, session will be disconnected after this value
; timeout = 30

; Audio sampling rate
; sample_rate = 32000


[WebServer]

; Global web server settings

; IP address used for serving HTTP(S) requests, empty string
; means listen on interface used by the default route
local_ip = 127.0.0.1

; Port where the web server will listen on, set to 0 for random
local_port = 10888

; X.509 server certificate for HTTPS connections, the certificate private
; key must be concatenated inside the same file, set to empty in order to
; disable HTTPS
certificate =

; Certificat chain file containing all the certificates that the server
; should present to the client.  If specified, it must also contain the
; certificate in the file specified by the 'certificate' option.
; certificate_chain

; Hostname used when publishing the server URL. Must match the common name
; of server X.509 certificate set above, otherwise clients will raise
; warning. If not set the listening IP address will be used
; hostname =

La mayoría de estas opciones no son necesarias porque vamos a utilizar SylkServer únicamente como servidor de videoconferencias, pero las dejamos ahí por si acaso 🙂

Paso 2, Sylk WebRTC client

A continuación vamos a instalar la interfaz web que nos permitira realizar las videoconferencias:

apt install nodejs nodejs-legacy npm git-core
npm install -g yarn

cd /opt
git clone --depth=1 https://github.com/AGProjects/sylk-webrtc
cd sylk-webrtc
yarn install
node_modules/.bin/gulp build --type production

Y pasaremos a editar la configuración en /opt/sylk-webrtc/src/app/config.js:

'use strict';

const defaultDomain = 'example.com';

const configOptions = {
    defaultDomain           : defaultDomain,
    enrollmentDomain        : defaultDomain,
    publicUrl               : 'https://example.com',
    enrollmentUrl           : 'https://example.com',
    defaultConferenceDomain : `videoconference.${defaultDomain}`,
    defaultGuestDomain      : `guest.${defaultDomain}`,
    wsServer                : `wss://${window.location.host}/ws`,
    iceServers              : [{urls: 'stun:stun.l.google.com:19302'}]
};


module.exports = configOptions;

Aquí podemos sustituir example.com por nuestro dominio, e incluir más servidores STUN o TURN, por ejemplo.

Paso 3, NGINX

Para finalizar vamos a instalar NGINX para poder servir la web cliente y hacer proxy pass de la conexión con el backend al servidor.  Esto nos permite tener ambas cosas en el mismo puerto (443) y así evitar problemas en algunas redes hostiles.

apt install nginx-light

Y pasamos a editar la configuración en /etc/nginx/nginx.conf:

user www-data;
daemon off;
worker_processes 4;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# Logging Settings
	##

        access_log /var/log/nginx-access.log;
        error_log /var/log/nginx-error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

        ##
        # Server
        ##

        server {
            listen 443 default;

            ssl_certificate           /etc/sylkserver/tls/default.crt;
            ssl_certificate_key       /etc/sylkserver/tls/default.crt;

            ssl on;
            ssl_session_cache  builtin:1000  shared:SSL:10m;
            ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
            ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
            ssl_prefer_server_ciphers on;

            root /opt/sylk-webrtc/dist;
            index index.html;

            location / {
                try_files $uri $uri/ =404;
            }

            location /ws {
                proxy_pass http://127.0.0.1:10888/webrtcgateway/ws;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
            }
    }
}

Aquí podemos configurar nuestros certificados TLS por ejemplo.  A modo de ejemplo he utilizado los que trae SylkServer, que son self-signed y por lo tanto producirán un error en el navegador.

Conclusión

Si has llegado hasta aquí, ¡enhorabuena! Ya puedes acceder a https://IP_DE_TU_SERVIDOR/#!/conference para poder crear conferencias ad-hoc.