2019-07-22 03:30 PM

Build and Install SIP Server Flexisip on Ubuntu18.04. VoIP Telephony Systems(050- phone, SNS Messengers and so on) enable us to communicate with each other by transmitting the text and voice messages in real time.

Most of the these VoIP sytems are managed SIP Server with SIP(Session Initiation Protocol). There are many open source binaries as the sip server(Asterisk and Others).

If you will install this system into the single board compute like the Rasberry Pi, it might enable an affordable interphone system in your home connecting to your mobile from remote.

Source Codes

GitLab

https://gitlab.linphone.org/BC/public/flexisip

Github

https://github.com/BelledonneCommunications/flexisip

Installed Flexisip Version

$ flexisip -v
flexisip  version: 1.0.13 (git: 1.0.13-247-g3ba0a222)
sofia-sip version 1.13.35bc

Compiled with:
- SNMP
- Transcoder
- Redis
- Soci
- Protobuf
- Presence
- Conference

Build and Install Environment

Linux 4.15.0-55-generic/Ubuntu18.04 x86_64 GNU/Linux

Preliminary

Install Docker CE for linphone-sdk and get the Domain for Flexisip SIP Server

  • Docker CE(make a container image and a container for linphone-sdk)
  • For making easy to modify the flexisip configration file, it's better to get the domain name.
    If you don't need the domain, replace it with the global IP at domain setting positions in a flexisip config file.
    Strings of the subdomain shouldn't be "sip".
    ex) "sip.freedomain.com" or "test.freedomain.com"

A.Build and Install Process

  1. Making the project folder
  2. Make the docker container image for linphone-sdk and run the container of it
  3. Download source codes(git clone)
  4. Making cmake scripts by prepare.py
  5. Build by make command
  6. Install deb packages
  7. Setting the path for binary and library

B.Install and configure the relational apps

  1. Install and setting the Redis Server
  2. Install and setting SNMP
  3. Install MariaDB and make the sql database and the table

C.Start and confirmation

  1. Port forwards for the router
  2. Configure the Flexisip and run
  3. Check the connection between 2 devices
  4. Check the Established sessions by Netstat

A.Build and Install Process


A-1.Making the project folder

Make the working directry and move to it

$ mkdir ~/build_project
$ cd build_project

A-2.Make the docker container image for linphone-sdk and run the container of it

Download the docker image and run the container of linphone-sdk, then move into the container shell.

(If you have made the container in the previous blog "Build Linphone-desktop", you can use it.)

$ docker run --name bc-flexisip -v $PWD:/home/bc -it gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:18.04

bc@container_id:~$

Please refer to the docker file for each, the following.

https://gitlab.linphone.org/BC/public/linphone-sdk/tree/feature/ubuntu_18.04_runner/docker-files

You can check the running containers on another terminal.

$ docker container ls

CONTAINER ID        IMAGE                                                                 COMMAND             CREATED             STATUS                      PORTS               NAMES
xxxxxxxxxxx        gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:18.04   "/bin/sh -c bash"   15 hours ago        Exited (0) 5 hours ago                          linphone-desktop

Following the process of No.3,4 and 5 are implemented in the container.

A-3.Download source codes(git clone)

Implement the following command in the container

$ cd /home/your_user_name/build_project

$ git clone https://gitlab.linphone.org/BC/public/flexisip.git

$ cd flexisip

A-4.Making cmake scripts by prepare.py

Making cmake scripts by prepare.py

$ ./prepare.py flexisip-rpm -DENABLE_REDIS=YES -DENABLE_TRANSCODER=YES -DENABLE_UNIT_TESTS=OFF -DENABLE_SOCI=YES -DENABLE_PRESENCE=YES -DENABLE_CONFERENCE=YES -DENABLE_SNMP=YES -DENABLE_DOC=OFF -DENABLE_PROTOBUF=YES -DENABLE_MDNS=NO -DENABLE_JWE_AUTH_PLUGIN=YES -DENABLE_EXTERNAL_AUTH_PLUGIN=YES -DENABLE_SOCI=YES"

Made flexisip-rpm folder in linphone-desktop/WORK

But an error will occur if as it is to make.(If you will use the previous made container for linphone-sdk, skip the error solution.)

Error

"%cmake error"

https://github.com/BelledonneCommunications/flexisip/issues/64

Error Solution

Download the following package, and copy the files in it to docker:/usr/lib/rpm directory. Implement these from another terminal(not implement in the container) .

https://rpmfind.net/linux/rpm2html/search.php?query=cmake-rpm-macros

https://rpmfind.net/linux/mageia/distrib/cauldron/x86_64/media/core/release/cmake-rpm-macros-3.15.0-0.rc3.1.mga8.x86_64.rpm

$ docker cp cmake.prov container_name:/usr/lib/rpm/cmake.prov
$ docker cp cmake.req container_name:/usr/lib/rpm/cmake.req
$ docker cp cmake.attr container_name:/usr/lib/rpm/fileattrs/cmake.attr
$ docker cp macros.cmake container_name:/usr/lib/rpm/macros.d/macros.cmake

A-5.Build by make command

Implement make command in the container

$ make

A-6.Install deb packages

Exit from the container and install deb packages.

Made the deb packages in flexisip/WORK/desktop-rpm/rpmbuild/DEBS folder.

$ exit

In DEBS folder, install the packages.

$ cd WORK/desktop-rpm/rpmbuild/DEBS
$ sudo dpkg -i linphone-*.deb

A-7.Setting the path for binary and library

Binary Path: /opt/belledonne-communications/bin

Library Path: /opt/belledonne-communications/lib

Export binary path

Add the following line at the tail in .bashrc under home folder.

export PATH=$PATH:/opt/belledonne-communications/bin

Export library path

$ sudo nano /etc/ld.so.conf.d/flexisip.conf

/opt/belledonne-communications/lib

Activate library path

$ sudo ldconfig

Temporary

$ export PATH=$PATH:/opt/belledonne-communications/bin
$ export LD_LIBRARY_PATH=/opt/belledonne-communications/lib

B.Install and configure the relational apps


B-1. Install and setting the Redis Server

https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-18-04

To establish sessions between 2 mobiles, need to cache and store these devices IP information in Redis server.

Install Redis-server

$ sudo apt install redis-server

Adopt MD5 algorithm for password(optional)

$ echo your_password | md5sum

Modify /etc/redis/redis.conf, set the items "bind", "systemd" and "password"

sudo nano /etc/redis/redis.conf

################################## NETWORK #####################################

# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.

bind 127.0.0.1 ::1


################################# GENERAL #####################################

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes

# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
#   supervised no      - no supervision interaction
#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode
#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
#   supervised auto    - detect upstart or systemd method based on
#                        UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
#       They do not enable continuous liveness pings back to your supervisor.

supervised systemd


################################## SECURITY ###################################

# Require clients to issue AUTH < PASSWORD> before processing any other
# commands.  This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#

requirepass xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


B-2.Install and setting SNMP

Install SNMP daemon to monitor and manage the SIP server status(CPU, Memory, Disk, Network usage and so on).

SNMP: "Simple Network Management Protocol." Install the following pakages.

https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/SNMP/Modify /etc/snmp/snmpd.conf

$ sudo apt install snmp snmpd snmp-mibs-downloader

To enable SNMP Manager import the MIB file, Commented out "mibs :" in /etc/snmp/snmp.conf.

# As the snmp packages come without MIB files due to license reasons, loading
# of MIBs is disabled by default. If you added the MIBs you can reenable
# loading them by commenting out the following line.
#mibs : comment out

Modify /etc/snmp/snmpd.conf

sudo pico /etc/snmp/snmpd.conf

agentAddress  udp:127.0.0.1:161
master agentx

rocommunity public localhost
rwcommunity private localhost

rouser   authOnlyUser
rwuser   authPrivUser   priv

B-3. Install MariaDB and make the sql database and the table

To store the registration users, install MariaDB. Also install MariaDB Client Library to connect to the database by soci.

(linphone-sdk orders "mariadblib" in Docker File: https://gitlab.linphone.org/BC/public/linphone-sdk/blob/master/docker-files/bc-dev-ubuntu-rolling)。

Install MariaDB

$ sudo apt install mariadb-server mariadb-client libmariadb3

Password setting

$ sudo mysql_secure_installation

Login by root

$ mysql -u root -p

Make user "flexisip" and database "flexisip", exit root login and re-login by user "flexisip", and make a table "accounts".

MariaDB [(none)]> create user 'flexisip'@'localhost' identified by 'password';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> grant all privileges on flexisip.* to 'flexisip'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> create database flexisip;


MariaDB [(none)]> system mysql -u flexisip -p

MariaDB [(none)]> use flexisip;

MariaDB [flexisip]> create table if not exists accounts ( registerID INT UNSIGNED NOT NULL AUTO_INCREMENT, login VARCHAR(20) NOT NULL DEFAULT 'loginid', domain VARCHAR(20) NOT NULL DEFAULT 'sip.server.com', authid VARCHAR(20) NOT NULL DEFAULT 'authid', password VARCHAR(40) NOT NULL DEFAULT 'dd02c7c2232759874e1c205587017bed', algorithm VARCHAR(10) NOT NULL DEFAULT 'MD5', phone VARCHAR(20) NOT NULL DEFAULT '818012345678', PRIMARY KEY (registerID) );
Query OK, 0 rows affected (0.51 sec)

MariaDB [flexisip]> SHOW TABLES;
+--------------------+
| Tables_in_flexisip |
+--------------------+
| accounts           |
+--------------------+
1 row in set (0.00 sec)

MariaDB [flexisip]> DESCRIBE accounts;
+------------+------------------+------+-----+----------------------------------+----------------+
| Field      | Type             | Null | Key | Default                          | Extra          |
+------------+------------------+------+-----+----------------------------------+----------------+
| registerID | int(10) unsigned | NO   | PRI | NULL                             | auto_increment |
| login      | varchar(20)      | NO   |     | loginid                          |                |
| domain     | varchar(20)      | NO   |     | sip.server.com                   |                |
| authid     | varchar(20)      | NO   |     | authid                           |                |
| password   | varchar(40)      | NO   |     | dd02c7c2232759874e1c205587017bed |                |
| algorithm  | varchar(10)      | NO   |     | MD5                              |                |
| phone      | varchar(20)      | NO   |     | 818012345678                     |                |
+------------+------------------+------+-----+----------------------------------+----------------+
7 rows in set (0.00 sec)

MariaDB [flexisip]> SHOW CREATE TABLE accounts \G
*************************** 1. row ***************************
       Table: accounts
Create Table: CREATE TABLE `accounts` (
  `registerID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `login` varchar(20) NOT NULL DEFAULT 'loginid',
  `domain` varchar(20) NOT NULL DEFAULT 'sip.server.com',
  `authid` varchar(20) NOT NULL DEFAULT 'authid',
  `password` varchar(40) NOT NULL DEFAULT 'dd02c7c2232759874e1c205587017bed',
  `algorithm` varchar(10) NOT NULL DEFAULT 'MD5',
  `phone` varchar(20) NOT NULL DEFAULT '818012345678',
  PRIMARY KEY (`registerID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.01 sec)

MariaDB [flexisip]> INSERT INTO accounts VALUES (1001, 'friend1','sip.server.com', 'friend1', '', '', '');
Query OK, 1 row affected (0.06 sec)

MariaDB [flexisip]> select * from accounts;
+------------+---------+----------------------+---------+----------+------------+-------+
| registerID | login   | domain               | authid  | password | algorithm  | phone |
+------------+---------+----------------------+---------+----------+------------+-------+
|       1001 | friend1 | sip.server.com       | friend1 |          |            |       |
+------------+---------+----------------------+---------+----------+------------+-------+
1 row in set (0.00 sec)

C.Start and confirmation


C-1.Port forwards for the router

Set firewall port forwards on router menu. Access from Global IP:5070/tcp,udp to LAN IP(flexisip-IP:192.168.x.xxx:5070 tcp/udp).

These settings might be varied depending on your routing device.

Also open the RTP Ports(Modified flexisip.conf and set [module::mediarelay] port range10000-10100 udp).

https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/#HFlexisipfirewallrules

C-2.Configure the Flexisip and run

Output the Flexisip default configuration file "flexisip.conf" to /etc/flexisip/ directory.

$ sudo /opt/belledonne-communications/bin/flexisip --dump-default all > /etc/flexisip/flexisip.conf

Modify /etc/flexisip/flexisip.conf. There are many options for functions, so the following settings might not be optimized.

[global]
log-directory=/var/opt/belledonne-communications/log/flexisip
log-level=error
syslog-level=error
user-errors-logs=false
contextual-log-filter=
contextual-log-level=debug
dump-corefiles=true
auto-respawn=true
aliases=sip.testsite.com localhost
default-servers=proxy presence

transports=sip:sip.testsite.com:5070;maddr=192.168.x.xxx

idle-timeout=3600
keepalive-interval=1800
proxy-to-proxy-keepalive-interval=0
require-peer-certificate=false
transaction-timeout=32000
udp-mtu=1460
enable-snmp=true
unique-id=
plugins-dir=/opt/belledonne-communications/lib/flexisip/plugins
plugins=

[stun-server]
enabled=true
bind-address=0.0.0.0
port=3478

[presence-server]
enabled=true
transports=sip:127.0.0.1:5065;transport=tcp
expires=600
notify-limit=200
leak-detector=false
long-term-enabled=true
bypass-condition=false
external-list-subscription-request=
soci-connection-string=db=flexisip user=flexisip password='password' host=localhost
max-thread=50
max-thread-queue-size=50

[conference-server]
enabled=true
transport=sip:127.0.0.1:6064;transport=tcp
conference-factory-uri=
enable-one-to-one-chat-room=true
outbound-proxy=sip:127.0.0.1:5070;transport=tcp
database-backend=mysql
database-connection-string=db=flexisip user=flexisip password='password' host=localhost
check-capabilities=true

[module::DoSProtection]
enabled=true
filter=
time-period=15000
packet-rate-limit=20
ban-time=1
iptables-chain=FLEXISIP

[module::SanityChecker]
enabled=true
filter=

[module::NatHelper]
enabled=true
filter= !(user-agent contains 'No NatHelper')
contact-verified-param=verified
fix-record-routes=false
fix-record-routes-policy=safe

[module::Authentication]
enabled=true
filter=
auth-domains=sip.testsite.com localhost
disable-qop-auth=false
no-403=false
nonce-expires=3600
realm-regex=
trusted-hosts=127.0.0.1
db-implementation=soci
cache-expire=1800
reject-wrong-client-certificates=false
new-auth-on-407=false
enable-test-accounts-creation=false
trust-domain-certificates=false
soci-password-request=select password from accounts where login = :id and domain = :domain
soci-user-with-phone-request=select login from accounts where phone = :phone
soci-users-with-phones-request=select login, domain, phone from accounts where phone in (:phones)
soci-poolsize=100
soci-backend=mysql
soci-connection-string=db=flexisip user=flexisip password='password' host=localhost
soci-max-queue-size=1000

[module::Presence]
enabled=true
filter=is_request && (request.method-name == 'PUBLISH' || request.method-name == 'NOTIFY' || request.method-name == 'SUBSCRIBE')
presence-server=sip:127.0.0.1:5065;transport=tcp
only-list-subscription=false
check-domain-in-presence-results=false

[module::Registrar]
enabled=true
filter=
reg-domains=sip.testsite.com
reg-on-response=false
max-contacts-by-aor=12
unique-id-parameters=+sip.instance pn-tok line
max-expires=86400
min-expires=60
force-expires= -1
static-records-file=
static-records-timeout=600
db-implementation=redis
redis-server-domain=localhost
redis-server-port=6379
redis-auth-password=xxxxxxxxxxxxxxxxxxxxxxxxxx
redis-server-timeout=1500
redis-record-serializer=protobuf
redis-slave-check-period=60
service-route=
name-message-expires=message-expires
register-expire-randomizer-max=0

[module::StatisticsCollector]
enabled=true
filter=is_request && request.method-name == 'PUBLISH'
collector-address=sip:sip.testsite.com:5070

[module::Router]
enabled=true
filter=
use-global-domain=false
fork=true
stateful=true
fork-late=false
fork-no-global-decline=false
treat-decline-as-urgent=false
treat-all-as-urgent=false
call-fork-timeout=20
call-fork-urgent-timeout=5
call-fork-current-branches-timeout=10
call-push-response-timeout=0
message-fork-late=true
message-delivery-timeout=60
message-accept-timeout=15
fallback-route=
allow-target-factorization=false
permit-self-generated-provisional-response=true
generated-contact-route=
generated-contact-expected-realm=
generate-contact-even-on-filled-aor=false
preroute=
resolve-routes=true
parent-domain-fallback=false

[module::MediaRelay]
enabled=true
filter=
nortpproxy=nortpproxy
sdp-port-range-min=10000
sdp-port-range-max=10500
bye-orphan-dialogs=false
max-calls=0
force-relay-for-non-ice-targets=true
prevent-loops=true
early-media-relay-single=true
max-early-media-per-call=0
inactivity-period=3600
force-public-ip-for-sdp-masquerading=false
drop-telephone-event=false

[module::Forward]
enabled=true
filter=
route=
add-path=true
rewrite-req-uri=false
default-transport=udp
params-to-remove=pn-tok pn-type app-id pn-msg-str pn-call-str pn-call-snd pn-msg-snd pn-timeout pn-silent

Run Flexisip as a service daemon

$ sudo service flexisip-proxy start

Confirm Flexisip Server status

$ sudo service flexisip-proxy status

● flexisip-proxy.service - Flexisip proxy server
   Loaded: loaded (/lib/systemd/system/flexisip-proxy.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-07-22 11:06:43 JST; 7h ago
     Docs: http://www.linphone.org/technical-corner/flexisip/overview
  Process: 26504 ExecStart=/opt/belledonne-communications/bin/flexisip --server proxy --daemon --syslog --pidfile /var/run/flexisip-proxy.pid (code=exited, status=0/SUCCESS)
 Main PID: 26527 (flexisipwd-prox)
    Tasks: 110 (limit: 4915)
   CGroup: /system.slice/flexisip-proxy.service
           ├─26527 /opt/belledonne-communications/bin/flexisip --server proxy --daemon --syslog --pidfile /var/run/flexisip-proxy.pid
           └─26528 /opt/belledonne-communications/bin/flexisip --server proxy --daemon --syslog --pidfile /var/run/flexisip-proxy.pid

 7月 22 11:06:42 thinkpad-e450 systemd[1]: Starting Flexisip proxy server...
 7月 22 11:06:42 thinkpad-e450 flexisip[26504]: Writing logs in : /var/opt/belledonne-communications/log/flexisip/flexisip-proxy.log
 7月 22 11:06:42 thinkpad-e450 flexisip[26504]: [LAUNCHER] Watchdog PID: 26527
 7月 22 11:06:43 thinkpad-e450 flexisip[26504]: NET-SNMP version 5.7.3 AgentX subagent connected
 7月 22 11:06:43 thinkpad-e450 systemd[1]: Started Flexisip proxy server.

C-3.Check the connection between 2 devices

Try to access to Flexisip SIP Server with the external devices from remote. Use the Linphone or ZoiPer as the SIP-VoIP Application.

  • Order SIP Port 5070/tcp(Depend on flexisip.conf)
  • DTMF:SIP
  • STUN server domain and port should be same as Flexisip domain and port.
  • Order Outbound Proxy(Call via SIP Proxy)

C-4.Check the Established sessions by Netstat

Confirm the established sessions between 2 devices by Netstat.

$ sudo netstat -antpu | grep flexisip

tcp        0      0 192.168.x.xxx:5070      0.0.0.0:*               LISTEN      8515/flexisip       
tcp        0      0 127.0.0.1:39338         127.0.0.1:6379          ESTABLISHED 8515/flexisip       
tcp        0      0 127.0.0.1:39336         127.0.0.1:6379          ESTABLISHED 8515/flexisip       
tcp        0      0 192.168.x.xxx:5070      39.122.226.44:63008     ESTABLISHED 8515/flexisip       
tcp        0      0 192.168.x.xxx:5070      150.66.94.119:45470     ESTABLISHED 8515/flexisip       
udp        0      0 0.0.0.0:10036           0.0.0.0:*                           8515/flexisip       
udp        0      0 0.0.0.0:10037           0.0.0.0:*                           8515/flexisip       
udp        0      0 0.0.0.0:10492           0.0.0.0:*                           8515/flexisip       
udp        0      0 0.0.0.0:10493           0.0.0.0:*                           8515/flexisip       
udp        0      0 0.0.0.0:3478            0.0.0.0:*                           8515/flexisip       
udp        0      0 192.168.x.xxx:5070      0.0.0.0:*                           8515/flexisip

I will follow this article to add the additional informations into my forum site on the same title.

Additional Contents(From Ficusonline Forum)2019/12/12


In case of adopting the encryption of MD5 or SHA-256

Not common to insert the password directly into the database, it should be encrypted.

Flexisip corresponds MD5 and SHA-256 encryption, but SHA-256 will be better.

Flexisip reads and write the password by the following format.

"youserID:domain:password"

MD5

MD5(‘acountID:domain:password’)

SHA-256

SHA2(‘acountID:domain:password’,256)

examples)

MD5

mysql> update table_name set password = MD5('user1:test.site.com:secretpass') where id=1;

SHA-256

mysql> update table_name set password = SHA2('user1:test.site.com:secretpass', 256) where id=1;

Reference : Flexisip soci code

https://github.com/BelledonneCommunications/flexisip/blob/master/src/authdb-soci.cc


Flexisip TLS Confuguration(Works under Docker Container)

https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/

cafile.pem created from fullchain.pem which is chained the medium certificate:chain.pem and the server certificate(issued from the certificate agency)cert.pem.

agent.pem created from the server certificate:cert.pem and the private key:key.pem.

$ docker exec -ti ubuntu(debian)-flexisip bash
# cd /etc/flexisip/tls/www.example.com
# ls
account_key.json  cert.pem  chain.pem  fullchain.pem  key.pem

# cp fullchain.pem cafile.pem
# awk 1 key.pem cert.pem > agent.pem

Edit the following items in /etc/flexisip/flexisip.conf

transports=sip:www.example.com:5070;maddr=172.18.0.5 sips:www.example.com:5071;maddr=172.18.0.5

tls-certificates-dir=/etc/flexisip/tls/www.example.com/