Why this project
Being a happy user of SOGo, I early on activated Turn configuration with long-term credentials. Problem is: the secret password of my turn user was visible and downloadable from the js script. Not optimal. I learnt that ephemeral credentials was the way to go to solve that issue. JSXC's github community helped me understand how to set it up and test it.
There is already a PHP script included with jsxc (might not be up-to-date on sjsxc) which enables dynamic creation of ephemeral credentials (timestamp is part of the equation, so it has to be on-demand). SOGo being objective-C, the server I got it running on has no PHP installed on it.
This was the perfect opportunity to write a little python script and install uwsgi to be able to call that script through nginx. Some extra info :
- integration of jsxc in SOGo (sjsxc) documentation can be found on jsxc's github Wiki under Install sjsxc (SOGo)
- a coturn server's configuration example can also be found on jsxc's github Wiki WebRTC How To
How it works
The cgi-bin directory contains all python-related files. Actual python files as well as the config files for uswgi and TURN authentication. Once everything is set up, anything reaching /cgi-bin/*
will invariably result in a call to the python script wsgi.py, which itself is a callable for getturncredentials.py
.
In the meantime, might be good to protect your config files from outsiders by adding in your nginx SOGo's configuration file :
# Turn credentials / config files
location ~ "(.*\.inc|.*\.json)$" { deny all; }
Now, install uwsgi, clone repository and start uwsgi daemon with provided config file:
apt-get install uwsgi uwsgi-core uwsgi-plugin-python python-crypto
cd /usr/lib/GNUstep/SOGo/WebServerResources/sjsxc/ajax
git clone https://gitlab.nomagic.fr/popi/jsxc-rtcpeerconfig.git .
mv cgi-bin/sjsxc.json /etc/uwsgi/apps-available/
ln -s /etc/uwsgi/apps-available/sjsxc.json /etc/uwsgi/apps-enabled/sjsxc.json
service uwsgi start sjsxc
Now you just have to tell Nginx to send everything addressed to /cgi-bin
to the uwsgi daemon.
At the end of SOGo's vhost, add:
location ~ /cgi-bin
{
uwsgi_pass unix:/tmp/uwsgi.sock;
include uwsgi_params;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
Here we use a unix socket to connect to uwsgi.
Reload nginx:
service nginx configtest
service nginx reload
Test via curl or browser:
curl https://example.com/SOGo/WebServerResources/sjsxc/ajax/cgi-bin/wsgi
{"iceServers": [{"urls": ["stun:stun.example.com", "stun:stun.example2.com"]}, {"username": "1483455638:userWebrtc", "credential": "wOk4VXXXXXXXXXO90=", "urls": ["turn:turn.example.com", "turn:turn.example2.com"]}], "ttl": 86400}
note : here the credential is a hash, not the real shared secret. The hash is generated from the secret and the username, which itself is a gathering of timestamp and username.
Finally, in you sjsxc/js folder on SOGo's server, modify sjsxc.js RTCPeedConfig url's setting. Go to directory and make a copy:
cd /usr/lib/GNUstep/SOGo/WebServerResources/sjsxc/js
cp -p sjsxc.js sjsxc.js.orig
Create the patch file sjsxc.patch containing:
--- sjsxc.js
+++ sjsxc.js
@@ -174 +174 @@
- url: '/SOGo.woa/WebServerResources/sjsxc/ajax/getturncredentials.php'
+ url: '/SOGo.woa/WebServerResources/sjsxc/ajax/cgi-bin/wsgi'
Apply patch:
patch -u < sjsxc.patch
That's it, reload you SOGo login page, you should be all set.
Conclusion
You should now have a symmetrical NAT-proofed WebRTC visio solution based on ephemeral credentials to authenticate your server on the TURN server.