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.


Use HAProxy and external IP for multi-server compatibility. 


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. Kazoo Block Diagram


FQDN check

It is necessary for  hostname and hostname -f to both return the fully qualified domain name.  If not the same or not a FQDN then edit /etc/hostname and reboot.  
Local FQDNs are ok for a single server install.
# For example:

If using a virtualization platform that overwrites /etc/hostname incorrectly on reboot, set the file to prevent overwriting.

chattr +i /etc/hostname

Disable Selinux

Check status.


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


Kazoo assumes UTC system time.  It is converted to the individual account timezones from there. Having system time set to something else will cause those conversions to be incorrect. 

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



yum -y install net-tools wget gdb yum-utils epel-release

Kazoo, Kamailio, and Freeswitch Repositories

Check for latest released version and modify 2600hz-release-x.x-x as necessary.

cd /usr/src
wget --no-check-certificate \
rpm -Uvh 2600hz-release-4.0-3.el7.centos.noarch.rpm

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


Clusterable NoSQL database.  Upgradeable to CouchDB v2.

yum install kazoo-bigcouch

systemctl enable kazoo-bigcouch
systemctl restart kazoo-bigcouch
systemctl status kazoo-bigcouch


# Check frontend API
curl localhost:5984

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


yum install kazoo-haproxy

systemctl enable kazoo-haproxy
systemctl restart kazoo-haproxy
systemctl status kazoo-haproxy


# 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


yum 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


yum 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 serverIP (x.x.x.x) variable
serverIP=$(ifconfig | sed -En 's/;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')

# Create serverFQDN variable

## Replace 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

## Add FreeSWITCH serverIP to the dispatcher list.
# If adding manually, make sure there is a carriage return at the end of the line.

echo ":1:sip\:$serverIP\:11000:0:0::aio-fs" >> /etc/kazoo/kamailio/dbtext/dispatcher

## 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

# Fix a legacy issue with Kamailio RPM
/usr/sbin/chkconfig kamailio off

Useful commands

​# Reload dispatcher
kamcmd dispatcher.reload

# Check dispatcher status
kamcmd dispatcher.list

# Check kamailio stats
kamcmd stats.get_statistics all

Config files are located at /etc/kazoo/kamailio


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

yum install kazoo-rabbitmq

systemctl enable kazoo-rabbitmq
systemctl restart kazoo-rabbitmq
systemctl status kazoo-rabbitmq


# 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

The RabbitMQ web UI is located at: 

user/pass = guest

Config file is located at /etc/kazoo/rabbitmq

Kazoo Applications

yum install kazoo-applications kazoo-application-*

systemctl enable kazoo-applications
systemctl restart kazoo-applications
systemctl status kazoo-applications

Check DB creation

# Check the total number of dbs created (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 internally to identify individual accounts
# It needs to be internally unique and in FQDN format but does not need to be resolvable
# IF ACCOUNTREALM is DNS resolvable, devices can access account by using realm instead of IP + realm. 

# 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.


Erlang call manager.  Abstracts and clusters Freeswitch.

# Start ecallmgr app
sup kapps_controller start_app ecallmgr

# Add ecallmgr app to the database so that it automatically starts on boot
# Replace x.x.x.x with the ServerIP in your web browser


# Add "ecallmgr" to "kapps" list at above link
# Check green check mark on right to update
# Select "Save Document" at top
# ecallmgr can also be started with systemd, "systemctl enable kazoo-ecallmgr"
# Enable ecallmgr as kapp or with systemd but not both.
# If using systemd, all ecallmgr commands must start with "-necallmgr".

Add Freeswitch and Kamailio

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

# Create serverFQDN variable

sup ecallmgr_maintenance add_fs_node freeswitch@$serverFQDN

# Add Kamailio serverIP to the SBC ACL so that Freeswitch allows the traffic
sup ecallmgr_maintenance allow_sbc kamailio1 $serverIP


# Check that Freeswitch is connected to ecallmgr.
fs_cli -x 'erlang status'
# Check that sip stack is running with at least one profile.
fs_cli -x 'sofia status'
# Check that Kamailio IP is in ACL
sup ecallmgr_maintenance acl_summary
# Check app status
# You should see 2 nodes listed.  Apps and Kamailio.
# 1 Freeswitch media server should be listed under apps.

kazoo-applications status
# Check that Kamailio sees FreeSWITCH
#flags=AP is good. flags=IP is not good, go back and rerun previous checks

kazoo-kamailio status


This 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 install monster-ui* httpd

systemctl enable httpd
systemctl restart httpd
systemctl status httpd

Configure and initialize

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

# 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 serverFQDN variable
# Create the virtual host

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



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
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="x.x.x.x" accept'

firewall-cmd --reload

SUP commands list

These are linux cli commands for communicating directly with Kazoo.

# Build list of 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 list
cat /usr/doc/sup_commands


The database structures.  Can help determine configurable properties.

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.

Some additional info.

Reference install guide