Kazoo v4 Single Server Install Guide

Kazoo is a highly scalable API based VoIP telephony platform.  This guide shows how to install Kazoo v4 on one CentOS v7 server.  It can be used in conjunction with our Kazoo multiple server guide for more than one server.

Assumptions

To make this procedure more universal, some of the configurations are there for compatibility with multiple-server installs. 

Software

CentOS v7 minimal ISO
BigCouch NoSQL database v0.4
HAProxy http load balancer v1.5
FreeSWITCH media server v1.6
Kamailio SIP server v4
RabbitMQ message broker v3
Kazoo v4

Block diagram

Shown with a 3 server DB cluster.

PRE-INSTALL

FQDN check

It is necessary for  hostname and hostname -f to both return the fully qualified domain name.  If this is not correct the procedure will fail.
 
Set FQDN as follows.  Local FQDNs are ok for a single server install.
# For example, to set a local FQDN
hostnamectl set-hostname somedomain.local

If using a virtualization platform that overwrites /etc/hostname incorrectly on reboot, such that hostname command no longer returns the FQDN after reboot, set the file to prevent overwriting.

chattr +i /etc/hostname

Disable Selinux

Check status.

sestatus

If not disabled, do the following and reboot.

sed -i 's/\(^SELINUX=\).*/\SELINUX=disabled/' /etc/selinux/config

Disable firewall

It is sometimes helpful to disable the firewall during install.

systemctl disable firewalld
systemctl disable iptables
systemctl stop firewalld
systemctl stop iptables

Timezone

Kazoo assumes UTC system time.  It is converted to the individual account timezones from there.

yum install ntp
systemctl enable ntpd
systemctl start ntpd
timedatectl set-timezone UTC

Prerequisites

yum -y update
yum -y install net-tools wget gdb yum-utils bash-completion epel-release

Kazoo, Kamailio, and Freeswitch Repositories

This will install the necessary RPM repositories for the latest stable release of Kazoo.

cd /usr/src
wget --no-check-certificate \
https://packages.2600hz.com/centos/7/stable/2600hz-release/4.2/2600hz-release-4.2-0.el7.centos.noarch.rpm
rpm -Uvh 2600hz-release-4.2-0.el7.centos.noarch.rpm

yum-config-manager --disable 2600hz-experimental
yum-config-manager --disable 2600hz-staging
yum-config-manager --enable 2600hz-stable

Quick Install

Complete install in about 10 minutes.  Alternatively, skip down to the Detailed Install section for step by step with explanations and checks.

yum -y install kazoo-bigcouch kazoo-haproxy kazoo-rabbitmq kazoo-freeswitch kazoo-kamailio kazoo-applications kazoo-application-* monster-ui* httpd

systemctl enable kazoo-bigcouch kazoo-haproxy kazoo-rabbitmq kazoo-freeswitch kazoo-kamailio kazoo-applications kazoo-ecallmgr httpd

systemctl restart kazoo-bigcouch kazoo-haproxy kazoo-rabbitmq kazoo-freeswitch kazoo-kamailio kazoo-applications kazoo-ecallmgr httpd

/usr/sbin/chkconfig kamailio off

Verify that database creation has completed.

# Lower left number = 24 when complete.
curl localhost:15984/_all_dbs | python -mjson.tool | wc -l

Configure

sup kazoo_media_maintenance import_prompts /opt/kazoo/sounds/en/us/

# Create master account. Account name, realm and password can be changed afterwards via Monster UI.
sup crossbar_maintenance create_account master master.local superadmin somepassword

serverIP=$(ifconfig | sed -En 's/127.0.0.*//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
serverFQDN=$(hostname)

sed -i "s/127\.0\.0\.1/$serverIP/g" /etc/kazoo/kamailio/local.cfg
sed -i "s/kamailio\.2600hz\.com/$serverFQDN/g" /etc/kazoo/kamailio/local.cfg
sed -i "s/localhost/$serverIP/" /var/www/html/monster-ui/js/config.js

systemctl restart kazoo-kamailio

sup -n ecallmgr ecallmgr_maintenance add_fs_node freeswitch@$serverFQDN

# The following command is run twice because it doesn't seem to always stick the first time.
sup -n ecallmgr ecallmgr_maintenance allow_sbc kamailio1 $serverIP
sup -n ecallmgr ecallmgr_maintenance allow_sbc kamailio1 $serverIP

sup crossbar_maintenance init_apps /var/www/html/monster-ui/apps http://$serverIP:8000/v2
 
echo "<VirtualHost *:80>
DocumentRoot \"/var/www/html/monster-ui\"
ServerName $serverFQDN
</VirtualHost>
" > /etc/httpd/conf.d/monster-ui.conf

systemctl reload httpd

Browse to Monster UI and login to master account.
http://ServerIP

Installation is complete.  Skip down to the Post Install section for additional information.

If you have problems run Kazoo Checks.

Detailed Install

BigCouch

Clusterable NoSQL database.  Upgradeable to CouchDB v2.

yum -y install kazoo-bigcouch
systemctl enable kazoo-bigcouch
systemctl restart kazoo-bigcouch
systemctl status kazoo-bigcouch

Checks

# Check frontend API
curl localhost:5984

# Check admin API
curl localhost:5986
Config files are located at/etc/kazoo/bigcouch

HAProxy

yum -y install kazoo-haproxy
systemctl enable kazoo-haproxy
systemctl restart kazoo-haproxy
systemctl status kazoo-haproxy

Checks

# Check BigCouch frontend API via HAproxy
curl localhost:15984

# Check BigCouch admin API via HAproxy
curl localhost:15986

You can now use port 5984 or 15984 locally, as long as HAproxy is running.

Config file is located at /etc/kazoo/haproxy

RabbitMQ

This is how the kazoo applications talk to each other and to Kamailio.

yum -y install kazoo-rabbitmq
systemctl enable kazoo-rabbitmq
systemctl restart kazoo-rabbitmq
systemctl status kazoo-rabbitmq

Checks

# Check status
kazoo-rabbitmq status

# Check API
curl -i -u guest:guest http://localhost:15672/api/aliveness-test/%2F
curl -u guest:guest http://localhost:15672/api/overview | python -m json.tool

RabbitMQ web GUI is located at: 
http://serverIP:15672

user/pass = guest

Config file is located at /etc/kazoo/rabbitmq

FreeSWITCH

yum -y install kazoo-freeswitch
systemctl enable kazoo-freeswitch
systemctl restart kazoo-freeswitch
systemctl status kazoo-freeswitch
# Check FreeSWITCH status
fs_cli -x status

Config files are located at /etc/kazoo/freeswitch

Kamailio

yum -y install kazoo-kamailio
​# Save a copy of config file for future reference
cp /etc/kazoo/kamailio/local.cfg /etc/kazoo/kamailio/local.cfg.orig
# Create and check serverIP (x.x.x.x) variable
serverIP=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
echo $serverIP

# Create and check serverFQDN variable
serverFQDN=$(hostname)
echo $serverFQDN

## Replace 127.0.0.1 with ServerIP
# This only works the first time.  The file needs to be updated manually after that

sed -i "s/127\.0\.0\.1/$serverIP/g" /etc/kazoo/kamailio/local.cfg

## Update the serverFQDN
# This only works the first time.  The file needs to be updated manually afterwards.

sed -i "s/kamailio\.2600hz\.com/$serverFQDN/g" /etc/kazoo/kamailio/local.cfg
systemctl enable kazoo-kamailio
systemctl restart kazoo-kamailio
systemctl status kazoo-kamailio

# Seeing ERROR: dispatcher is normal until we get further down the procedure.
​# Fix a legacy issue with Kamailio RPM
/usr/sbin/chkconfig kamailio off

Miscellaneous commands

# Check kamailio stats
kamcmd stats.get_statistics all

# List other commands
kamcmd ?

Config files are located at /etc/kazoo/kamailio

Kazoo

yum -y install kazoo-applications kazoo-application-*
systemctl enable kazoo-applications
systemctl restart kazoo-applications
systemctl status kazoo-applications

Check database creation

# Check the total number of databases (lower left)
# If less than 20 wait a few minutes and check again before proceeding further

curl localhost:15984/_all_dbs | python -mjson.tool | wc -l

Install sound files

# Check that the system_media db has been created
curl localhost:15984/system_media

# Import english sound files into database
sup kazoo_media_maintenance import_prompts /opt/kazoo/sounds/en/us/

# For alternative languages, install the relevant RPMs (core & freeswitch) and modify above command.
yum search kazoo-sounds

Create master account

# Check that the accounts db has been created
curl localhost:15984/accounts

# Create the master account and superadmin user, substituting in your own values.  
# ACCOUNTREALM is used to identify individual accounts and needs to be a unique valid local or global FQDN.
# IF ACCOUNTREALM is DNS resolvable, devices can access the account by using realm instead of IP + realm. 
# Account name, realm, and password can be changes afterwards via Monster UI.

# sup crossbar_maintenance create_account ACCOUNTNAME ACCOUNTREALM ADMINUSER ADMINPASS

# So for example
sup crossbar_maintenance create_account master master.local superadmin somepassword 

To understand the account hierarchy refer to this link.    In case that link does not work for some reason, this basic hierarchy diagram might be of some help.

To understand how account credentials are used refer to this link.  In case that link does not work, this account login diagram and this device lookup diagram might help.

Ecallmgr  

Erlang call manager.  Abstracts and clusters Freeswitch.

# Installed previously. Verify as follows
yum -y install kazoo-application-ecallmgr
systemctl enable kazoo-ecallmgr
systemctl restart kazoo-ecallmgr
systemctl status kazoo-ecallmgr

Add Freeswitch and Kamailio

# Create and check serverIP (x.x.x.x) variable
serverIP=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
echo $serverIP

# Create and check serverFQDN variable
serverFQDN=$(hostname)
echo $serverFQDN

# Add FreeSWITCH
sup -n ecallmgr ecallmgr_maintenance add_fs_node freeswitch@$serverFQDN

# Add Kamailio to ACL so that Freeswitch allows the traffic. 
# We run it twice because it doesn't seem to always stick the first time.
sup -n ecallmgr ecallmgr_maintenance allow_sbc kamailio1 $serverIP
sup -n ecallmgr ecallmgr_maintenance allow_sbc kamailio1 $serverIP

Kazoo Checks

Reboot and check overall system.

reboot
# Check that Freeswitch is connected to ecallmgr.
fs_cli -x 'erlang status'
# Check that Freeswitch sip stack is running with at least one profile.
fs_cli -x 'sofia status'
# Check that Kamailio IP is in ACL. 
sup -n ecallmgr ecallmgr_maintenance acl_summary

# Redo add Kamailio to ACL procedure in Ecallmgr section if the IP is not listed.
# Check that Freeswitch is in configuration
sup -n ecallmgr ecallmgr_maintenance get_fs_nodes
# Check Erlang nodes
epmd -names

# Should result in:
epmd: up and running on port 4369 with data:
name kazoo-rabbitmq at port 25672
name freeswitch at port 8031
name kazoo_apps at port 11502
name ecallmgr at port 11501
name bigcouch at port 11500
# Check overall system status
# You should see 3 nodes listed.  Kazoo Apps, Kamailio, and Ecallmgr.
# The Freeswitch media server should be listed under Ecallmgr node.
# Freeswitch IP on port 11000 with (AP) status should be listed beside Dispatcher 1 under Kamailio node.

kazoo-applications status
kazoo-applications status
Node          : kazoo_apps@somedomain.local
md5           : jFoOSYRl8EM8hPzqzjSIEw
Version       : 4.1.41 - 18
Memory Usage  : 76.44MB
Processes     : 1682
Ports         : 20
Zone          : local
Broker        : amqp://127.0.0.1:5672
Globals       : local (4)
Node Info     : kz_amqp_pool: 150/0/0 (ready)
WhApps        : blackhole(5m45s)         callflow(5m45s)          cdr(5m45s)               conference(5m45s)
                crossbar(5m44s)          fax(5m36s)               hangups(5m16s)           media_mgr(5m16s)
                milliwatt(5m16s)         omnipresence(5m16s)      pivot(5m16s)             registrar(5m16s)
                reorder(5m16s)           stepswitch(5m16s)        sysconf(5m45s)           tasks(5m16s)
                teletype(4m13s)          trunkstore(4m11s)        webhooks(4m11s)

Node          : kamailio@somedomain.local
Version       : 5.0.3
Memory Usage  : 15.27MB
Zone          : local
Broker        : amqp://127.0.0.1:5672
WhApps        : kamailio(6m2s)
Roles         : Dispatcher Presence Registrar
Dispatcher 1  : sip:serverIP:11000 (AP)
Subscribers   :
Subscriptions :
Presentities  : presence (0)  dialog (0)  message-summary (0)
Registrations : 0

Node          : ecallmgr@somedomain.local
md5           : 9hsLTuppG8oNQRSGmU6cwA
Version       : 4.1.41 - 18
Memory Usage  : 49.67MB
Processes     : 1134
Ports         : 28
Zone          : local
Broker        : amqp://127.0.0.1:5672
Globals       : remote (4)
Node Info     : kz_amqp_pool: 150/0/0 (ready)
WhApps        : ecallmgr(5m45s)
Channels      : 0
Registrations : 0
Media Servers : freeswitch@somedomain.local (5m39s)

Crossbar

Crossbar is the name of the REST API application.

# Check that crossbar is accessible
# 401 invalid credentials error is the expected response

curl http://x.x.x.x:8000/v2

Monster UI

An end user interface that interacts with the REST API.

yum -y install monster-ui* httpd
systemctl enable httpd
systemctl restart httpd
systemctl status httpd

Configure and initialize

# Create and check serverIP (x.x.x.x) variable
serverIP=$(ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
echo $serverIP

# Replace localhost with serverIP 
# This only works the first time 
# The IP needs to be changed manually after that 

sed -i "s/localhost/$serverIP/" /var/www/html/monster-ui/js/config.js 

# Initialize Monster Apps 
sup crossbar_maintenance init_apps /var/www/html/monster-ui/apps http://$serverIP:8000/v2

Change web server root directory

#Create and check serverFQDN variable
serverFQDN=$(hostname)
echo $serverFQDN
# Create the virtual host

echo "<VirtualHost *:80>
  DocumentRoot \"/var/www/html/monster-ui\"
  ServerName $serverFQDN
</VirtualHost>
" > /etc/httpd/conf.d/monster-ui.conf
# Reload web server for changes to take effect
systemctl reload httpd
Browse to Monster UI and login to master account.
http://serverIP

Post Install

Firewall

systemctl enable firewalld
systemctl restart firewalld
firewall-cmd --permanent --zone=public --add-service={http,https}
firewall-cmd --permanent --zone=public --add-port={8000,8443}/tcp
firewall-cmd --permanent --zone=public --add-port={5060,7000}/tcp
firewall-cmd --permanent --zone=public --add-port={5060,7000}/udp
firewall-cmd --permanent --zone=public --add-port=16384-32768/udp

#Administrator access.  Replace x.x.x.x with the public IP address of your admin computer.
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="x.x.x.x" accept'

firewall-cmd --reload

SUP

Kazoo supervisor.  Allows command line access to Erlang functions.

# View top level list of commands using bash completion
sup [TAB][TAB]

# To view next level down with autocomplete (using ecallmgr_maintenance as an example)
sup ecallmgr_m[TAB][TAB][TAB]

# Create a file listing all sup commands

mkdir /usr/doc
/opt/kazoo/lib/sup*/priv/build-autocomplete.escript \
/etc/bash_completion.d/sup.bash /opt/kazoo > /usr/doc/sup_commands

# View the file
cat /usr/doc/sup_commands

Schemas

The database structures.  Can help determine configurable properties.
https://github.com/2600hz/kazoo/tree/master/applications/crossbar/priv/couchdb/schemas

SIP Trunks

SIP trunks can be global or local.  Global trunks are added to the offnet database and are accessible by all accounts.  Local trunks are added to each account.

Monster UI does not currently have a public app for managing SIP trunks.  However, it is still possible to use the discontinued Kazoo UI in parallel for adding local trunks. 

For adding global SIP trunks, the easiest way is via the API.  There are tools such as postman and apiexplorer that help simplify it further.  There is a swagger.json file that can be imported into postman to add the API commands. 

Here is a reference document which explains the basics using command line.
https://gist.github.com/jamesaimonetti/36902f75f9f06ccca8c28921a3d331f4

Some additional info.
https://github.com/2600hz/kazoo/blob/master/applications/crossbar/doc/resources.md
https://2600hz.atlassian.net/wiki/pages/viewpage.action?pageId=79233046

Reference install guide

https://gist.github.com/jamesaimonetti/1e08a3e7e6cdbb59c6420d7132fafdfa