
SylkServer installation guide
-----------------------------

This guide explains how to install SylkServer and related dependencies on a
Debian or Ubuntu Linux server with a minimal functional configuration for
inter-operating with SylkServer and generic SIP devices and Web clients.

At the end of this guide you will be able to:

 * Place calls and send messages between SIP devices registered on the same
server as well as to and from foreign domains.

 *  Use a web browser to make and received calls and organize multimedia
conferences.

 * Use offline messaging, file transfers and OpenPGP encryption


Replace SYLK.DOMAIN with your omain and PUBLIC.IP with your public IP
address and PRIVATE.IP with your private IP in case of using a NAT-ed
container.


Compatibility and requirements
------------------------------

Linux Debian Bookworm operating system.

A public IP address and an Internet domain, e.g. SYLK.DOMAIN.

A DNS server or DNS service with suport for SIP related records.

OpenSIPS 3.5 branch.

When OpenSIPS and SylkServer run on the same server, one must use different
ports for listening to SIP traffic.  Using these instructions, SylkServer
will listen on ports 5060 (TCP, UDP) and 5061 (TLS) and OpenSIPS will listen
on ports 15060 (TCP, UDP) and 15061 (TLS). 

When running inside a container with a private IP address you must
forward the following destination ports:

 - SIP signaling: UDP and TCP, 15060, TCP 15061 (OpenSIPS)
 - RTP media: UDP 60000:60500 (MediaProxy)
 - MSRP media: TCP 2855 (MSRPRelay)
 - Web server and WebRTC socket: TCP 443, 10888 (SylkServer)
 - WebRTC media: UDP 60500:61000 (Janus)

All ports can be configured in their respective applications.


DNS configuration
-----------------

To receive incoming calls from other domains you must add certain records to
the DNS zone.

The DNS zone template:

SYLK.DOMAIN.              600 IN    NAPTR   10 100 "s" "SIPS+D2T "" _sips._tcp.SYLK.DOMAIN.
SYLK.DOMAIN.              600 IN    NAPTR   20 100 "s" "SIP+D2T" ""  _sip._tcp.SYLK.DOMAIN.
SYLK.DOMAIN.              600 IN    NAPTR   30 100 "s" "SIP+D2U" ""  _sip._udp.SYLK.DOMAIN.
conference.SYLK.DOMAIN.   600 IN    NAPTR  100 100 "s" "SIP+D2T" ""  _sip._tcp.SYLK.DOMAIN.
_sips._tcp.SYLK.DOMAIN.   600 IN    SRV    100 100 15061 SYLK.DOMAIN
_sip._tcp.SYLK.DOMAIN.    600 IN    SRV    100 100 15060 SYLK.DOMAIN
_sip._udp.SYLK.DOMAIN.    600 IN    SRV    100 100 15060 SYLK.DOMAIN
_msrps._tcp.SYLK.DOMAIN.  600 IN    SRV	   100 100 2855 SYLK.DOMAIN.
SYLK.DOMAIN.              600 IN    A      PUBLIC.IP

Replace SYLK.DOMAIN and PUBLIC.IP with your real domain and real IP address.

You can create and manage your SIP enabled domain at http://mdns.sipthor.net

https://docs.sipthor.net/w/sip2sip/domain_enrollment/


Repositories
------------

Configure OpenSIPS 3.5 repository as explained here:

https://apt.opensips.org

Configure OpenSIPS CLI repository as explained here:

https://apt.opensips.org/packages.php?v=cli

Configure AG Projects repository as explained here:

https://docs-new.sipthor.net/w/debian_package_repositories/


Install the software
--------------------

sudo apt update

sudo apt install opensips-config-sylkserver


Configure and start the software
--------------------------------

Set the hostname:

sudo hostnamectl set-hostname SYLK.DOMAIN

Create OpenSIPS database:

cd /etc/opensips

sudo /usr/sbin/opensips-dbinit  

Enable OpenSIPS to run at system start:

Edit /etc/default/opensips:

RUN_OPENSIPS=yes


If the system hostname is properly setup, the IP address corresponding to the
default route will be automatically detected and used by OpenSIPS.  
If hostname -i returns this IP address, there is nothing to set.

If running inside a container with a private IP address edit the file:

/etc/opensips/config/settings.m4

And set:

define(`SYLK_SERVER_IP', `PRIVATE.IP')
define(`SERVER_IP', `PRIVATE.IP')
define(`ADVERTISED_SERVER_IP', `PUBLIC.IP')

Custom OpenSIPS behaviour can be configured in the files located inside the folder:

/etc/opensips/config/siteconfig/

Generate OpenSIPS configuration file:

sudo /usr/sbin/opensips-config

Start OpenSIPS and enabled it at boot:

sudo systemctl start opensips

sudo systemctl enable opensips

To check for OpenSIPS activity in the system logs:

sudo journalctl -u opensips -f

If you want to use late forking and push, you need to enable it in settings.m4
and create the push tokens table in the OpenSIPS database.

sudo mysql opensips < gunzip /usr/share/doc/opensips-config/sylkserver/push_tokens.sql.gz


Create SIP accounts
-------------------

In this guide we shall use SYLK.DOMAIN as Internet domain:

Add SYLK.DOMAIN domain to OpenSIPS:

sudo mysql opensips -e "insert into domain (domain) values ('SYLK.DOMAIN')"

Multiple domains can be added in the same way.

Reload OpenSIPS domains:

sudo opensips-cli -x mi domain_reload

Add a new account:

sudo opensips-cli -x user add user@SYLK.DOMAIN somepassword

Change the password for an existing account:

sudo opensips-cli -x user password user@SYLK.DOMAIN someotherpassword

To see the registered SIP devices:

sudo opensips-cli -o output_type=lines -x mi ul_dump


MediaProxy configuration
------------------------

MediaProxy solves the issue of NAT traversal for RTP audio/video streams.

Copy the default TLS certificates:

sudo cp /usr/share/doc/mediaproxy-common/tls/* /etc/mediaproxy/tls/

Edit /etc/mediaproxy/config.ini and set in [Relay] section:

dispatchers = 127.0.0.1

Start the software:

sudo systemctl start mediaproxy-dispatcher
sudo systemctl start mediaproxy-relay
sudo systemctl enable mediaproxy-dispatcher
sudo systemctl enable mediaproxy-relay

If behind a 1-to-1 NAT-ed host, you must set the advertised_ip to 
the public IP and the port_range = 60000:60500 (or setup up your own range).


MSRP relay
----------

MSRP relay is needed for NAT traversal of chat and file transfers streams.

Edit /etc/msrprelay/config.ini 

[Relay]
certificate = /etc/sylkserver/tls/SYLK.DOMAIN.crt 
key = /etc/sylkserver/tls/SYLK.DOMAIN.crt 
backend = database
hostname = SYLK.DOMAIN

[Database]
uri = mysql://opensips:opensips@localhost/opensips

Start the relay:

sudo systemctl enable msrprelay

sudo systemctl restart msrprelay


SylkServer configuration
------------------------

Edit config.ini and configure [WebServer] section to use HTTPS:

certificate = /etc/sylkserver/tls/SYLK.DOMAIN.crt
hostname = SYLK.DOMAIN

For Let's encrypt certificate you must also set:

certificate_chain = /etc/sylkserver/tls/fullchain1.pem

Edit webrtcgateway.ini and configure the outbound proxy:

outbound_sip_proxy = proxy.SYLK.DOMAIN:15060;transport=tcp

You can test sylkserver by running it in the foreground using:

sudo /usr/bin/sylk-server --no-fork

If the software starts well, leave it running in the background:

sudo systemctl restart sylkserver

sudo systemctl enable sylkserver


MSRP conferencing
-----------------

Using a SIP client with support for MSRP conferencing, like Blink, you can
start a conference with both chat and audio.

Blink menu: Messages -> Join MSRP conference


OpenXCAP
--------

Edit /etc/openxcap/config.ini

Set the Xcap root: 

root = https://xcap.SYLK.DOMAIN/xcap-root

Set the database authentication:

[Database]

; The database connection URI for the datase with subscriber accounts
authentication_db_uri = mysql://opensips:opensips@localhost/opensips

; The database connection URI for the database that stores the XCAP documents
storage_db_uri = mysql://opensips:opensips@localhost/opensips



WebRTC setup
------------

Janus setup for NAT-ed scenario

Edit /etc/janus/janus.plugin.sip.jcfg and /etc/janus/janus.jcfg

Replace rtp_port_range in each file:

rtp_port_range = "60500-61000"

Set sdp_ip to the public IP of the server:

sdp_ip = "PUBLIC.IP"

Install the software:

sudo apt install npm nodejs nginx certbot python3-certbot-nginx git yarnpkg

Create a symlink required for building:

sudo ln -s /usr/bin/yarnpkg /usr/bin/yarn

Create a user in the system. In the folowing example we use agp as the username.

Login as user agp:

sudo su - agp
mkdir work

Clone sylk-webrtc repository, this is the website for the application:

cd work
git clone https://github.com/AGProjects/sylk-webrtc

Edit src/app/config.js with the correct domain name and ports.

Build Sylk website:

cd sylk-webrtc
./configure
make

The website is now available in /home/agp/work/sylk-webrtc/dist

The same website can be built into a standalone desktop app, see README.md

Start nginx webserver with its default configuration.

Backup default configuration file:

/etc/nginx/sites-enabled/default 

Create TLS certificates for SylkServer WebRTC server:

sudo certbot --nginx -d SYLK.DOMAIN

/etc/nginx/sites-enabled/default will be changed.

Create the a new virtual domain for nginx web server:

Edit /etc/nginx/sites-available/SYLK.DOMAIN

server {
        listen [::]:443 ssl ipv6only=on;
        listen 443 ssl; 
        ssl_certificate /etc/letsencrypt/live/SYLK.DOMAIN/fullchain.pem; 
        ssl_certificate_key /etc/letsencrypt/live/SYLK.DOMAIN/privkey.pem; 

        include /etc/letsencrypt/options-ssl-nginx.conf; 
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; 

        server_name SYLK.DOMAIN;

        root /home/agp/work/sylk-webrtc/dist;
        index index.html;

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

        location / {
                try_files $uri $uri/ /index.html;
        }
}

Enable the website:

sudo ln -s /etc/nginx/sites-available/SYLK.DOMAIN /etc/nginx/sites-enabled/

Modify /etc/nginx/sites-enabled/default which has been changed by certbot

Restart nginx server:

sudo systemctl restart nginx

Copy the TLS certificate to OpenSIPS:

sudo cp /etc/letsencrypt/archive/SYLK.DOMAIN/fullchain1.pem  /etc/opensips/tls/default.crt
sudo cp /etc/letsencrypt/archive/SYLK.DOMAIN/privkey1.pem  /etc/opensips/tls/default.key

sudo systemctl restart opensips

Copy the TLS certificate id SYLK.DOMAIN to SylkServer also:

sudo su -

cat /etc/letsencrypt/archive/SYLK.DOMAIN/fullchain1.pem  \
/etc/letsencrypt/archive/SYLK.DOMAIN/privkey1.pem >> \
/etc/sylkserver/tls/SYLK.DOMAIN.crt

Edit [WebServer] section of config.ini and enable TLS certificate:

certificate = /etc/sylkserver/tls/SYLK.DOMAIN.crt

sudo systemctl restart sylkserver

Copy the TLS certificate to MSRP Relay:

sudo cp /etc/letsencrypt/archive/SYLK.DOMAIN/fullchain1.pem  /etc/msrprelay/tls/msrprelay.crt
sudo cp /etc/letsencrypt/archive/SYLK.DOMAIN/privkey1.pem  /etc/msrprelay/tls/msrprelay.key

sudo systemctl restart msrprelay


Security considerations
-----------------------

Change MySQL password as soon as you have tested the server functionality. 

The password must be changed in these files:

/etc/opensips/dbinit.cf
/etc/opensips/opensips-cli.cfg 
/etc/opensips/config/settings.m4

Generate new TLS certificates for OpenSIPS, MediaProxy and SylkServer.

Enable TLS verification in /etc/opensips/config/settings.m4


Testing
-------

At this point you are ready to use a SIP or a Web client to make and receive calls
and messages.

Enter into your SIP device configuration:

Username  : user
Domain    : SYLK.DOMAIN 
Password  : somepassword
SIP Proxy : SYLK.DOMAIN
Transport : TLS on port 15061 or TCP/UDP on port 15060

If using Blink client set the conference server address to:

conference.SYLK.DOMAIN

You can receive calls and messages at user@SYLK.DOMAIN and call any SIP
address publicly reachable.

Using a web browser:

Login with the same SIP account at:

https://SYLK.DOMAIN/

Once logged in you can test your setup with:

 * playback - to test the audio output
 * echo - to test the microphone

Call any SIP address in the form of user@domain
 
To create a multi-party conference:

https://SYLK.DOMAIN/conference/test

Replace test with any name and share the link to other participants.


Sylk web client debugging
-------------------------

In the web browser go to Console.
window.blinkDebugger.enable('sylkrtc*,blinkrtc*');


SylkServer message storage
--------------------------

sudo sylk-db show user@SYLK.DOMAIN

This will display the storage information about the user, like the number of
messages and public key.

