Installation Guide

Most of the configuration tasks are related to setting up components outside CDRTool environment. Experience with configuring and running Apache with PHP, MySQL, FreeRadius, MediaProxy and OpenSIPS are required to successfully complete a CDRTool installation.

Setting up CDRTool is not a week-end project. This is complex stuff. Unless you know exactly why and what you are doing, you read carefully all the provided documentation and spent enough time to understand how the components above work, do not attempt trying out this software.

Given the diversity and multitude of software versions and their combinations, it could be that the information displayed in this guide may not be up to date or not reflect the latest version of the above mentioned components. For the particular configuration of each component visit the corresponding web site and consult the appropriate support forum. You may help keep this page up to date by reporting any inconsistencies to OpenSIPS users mailing list


You can install CDRTool in the following ways:

  1. As a debian package from ag-projects repository
  2. Generating the debian package
  3. Installing from the tar archive
  4. From the version control repository

a. Debian installation (stable version)

Add these lines to /etc/apt/sources.list:

# AG Projects software
deb unstable main
deb-src unstable main

Install the AG Projects debian software signing key:

apt-key add agp-debian-gpg.key

After that, run:

sudo apt-get update
sudo apt-get install cdrtool

b. Generating the debian package

The software can be downloaded as a tar archive from:

Extract it using tar xzvf cdrtool-version.tar.gz:

cd CDRTool

Assuming you have all the dependencies satisfied (if you are compiling opensips from source you’ll have them), it will generate a file called cdrtool_version_all.deb

You can install it with:

dpkg -i cdrtool_version_all.deb

c. Installing from the tar archive (stable version)

The software can be downloaded as a tar archive from:

Extract it using tar xzvf cdrtool-version.tar.gz and copy the directory under the your web root directory/CDRTool (/var/www/CDRTool on Debian systems).

d. Installing from the version control repository (development branch)

The source code is managed using darcs version control tool. The darcs repository can be fetched with:

darcs get

To obtain the incremental changes after the initial get:

cd cdrtool
darcs pull -a

The darcs repository is also mirrored on Github.

Create CDRTool database

You need MySQL root access with GRANT priviledges from the machine where CDRTool runs, otherwise copy the files required by setup/ to the MySQL machine and run the script locally.

Change the MySQL password of the cdrtool user from file:

Then run the database setup script:


The script performs the following:

  1. It adds to the MySQL server a user for cdrtool software
  2. It creates a new MySQL database "cdrtool"
  3. It creates a default web user admin/admin, you may use this initial account to login in the web interface
  4. It populates the cdrtool database with initial values

PHP setup and Apache setup

Install PHP and its dependencies. If you have chosen to install the debian package, the dependencies will be resolved during installation.

Configure php both the command line and apache module to support mysql.

Configure Apache2 server to support php scripting.

Create a virtual host for cdrtool web pages:

cp setup/apache2/sites-available/ /etc/apache2/sites-enabled
cp setup/apache2/conf.d/cdrtool /etc/apache2/conf.d/

Edit /etc/apache2/sites-enabled/ to suit your environment. Enable the virtual site using:


You may enable ssl using “a2enmod ssl” command. If you use ssl you must also generate a site certificate using the instructions provided by apache2 software.

Create CDRTool configuration file

cp /var/www/CDRTool/setup/ /etc/cdrtool/

Edit and setup your variables to match your system. The file contains a more elaborate example for setting up multiple datasources.

You must change at least the following settings:

  • The RatingEngine IP address
  • The mysql connection details to cdrtool, radius, opensisps, siptrace and mediaproxy MySQL databases, which are described in the following sections of this document
  • The mediaDispatcher address

Enable rating engine

The rating engine is used by the prepaid application and as price calculator for postpaid traffic. More info about rating engine you can find in the RATING.txt document.

For prepaid, an external call controll application is required, CDRTool itself provides only the maxsession time and debit balance functions. Call Control can be used to terminate the session based on these functions. For setting up Call Control see PREPAID.txt.

Set in the IP and port where the rating engine listens to:

$RatingEngine = array(
    "socketIP"   => "",
    "socketPort" => "9024",
    "cdr_source" => "opensips_radius",
    "allow"      => array('10.0.0')

For non Debian systems you must create /etc/default/cdrtool as follows:


For non Debian systems copy the init script from setup/init.d/cdrtool to /etc/init.d/cdrtool

Then restart the rating engine, which you must do every time you made changes to

/etc/init.d/cdrtool restart

To verify that the rating engine has started correctly check syslog for errors. To verify the connection to the rating engine you can telnet to port 9024 and type ‘help’ command.

Insert default sample rates

cp /var/www/CDRTool/setup/csv/\* /var/spool/cdrtool

For more information about provisioning of rating tables see doc/RATING.txt.

CRON jobs setup

Some operations must be scheduled to run periodically by cron. Such operations are the scripts that block fraudulous accounts in OpenSIPS, normalize the call detail records, purge the old SIP traces. This is done automatically if you install the debian package. For other Linux systems modify and install the cron file from /var/www/CDRTool/setup/crontabs/

Freeradius setup

CDRTool works with Freeradius server from

OpenSIPS generates START and STOP radius messages when a session is established by INVITE request, 200 OK response combination and respectively terminated by a BYE request, these packets are handled by the Freeradius server, which writes them into the hosting MySQL database. For failed SIP sessions a radius packet type FAILED is generated. A failed SIP session is a session that has been rejected by the Proxy server or by the destination.

Unfortunately Freeradius server is not able to cope with FAILED packets. The server must be patched and recompiled if you wish to support accounting for failed SIP sessions.

The patches and instructions for how to apply them are found in setup/radius/FreeRadius/ and contrib/freeradius-brandinger/.

Install the server from Debian package or your own compiled version after you applied the patches:

apt-get install freeradius freeradius-mysql

Alternatively you can install the freeradius-xs debian package provided in the AG Projects debian repository that contains all required patches:

apt-get install freeradius-xs freeradius-xs-mysql

Create the database for radius tables on the MySQL server:

mysqladmin -u root create radius

Create RADIUS tables:

mysql -u root radius < /var/www/CDRTool/setup/radius/OpenSIPS/radacct.mysql

Configure Freeradius to write data into mysql:

cp /var/www/CDRTool/setup/radius/OpenSIPS/sql.conf /etc/freeradius/sql.conf

Load the MySQL stored procedures that create the monthly tables:

mysql -u root radius < /var/www/CDRTool/setup/radius/OpenSIPS/radius\_accounting.proc

Add RADIUS clients in clients.conf. Each device sending RADIUS accounting requests must be added to /etc/freeradius/clients.conf. Examples:

client {

Enable MySQL accounting in FreeRadius server. Edit radius.conf “sql” must be uncommented or added if missing:

accounting {

Copy the radius dictionaries from OpenSIPS and MediaProxy:

cp /var/www/CDRTool/setup/radius/OpenSIPS/dictionary.opensips to /etc/freeradius
cp /var/www/CDRTool/setup/radius/MediaProxy/dictionary.mediaproxy to /etc/freeradius

Edit /etc/freeradius/dictionary as follows:

# standard radius dictionary
$INCLUDE        /usr/share/freeradius/dictionary

# OpenSER dictionary
$INCLUDE        /etc/freeradius/dictionary.opensips

# MediaProxy dictionary
$INCLUDE        /etc/freeradius/dictionary.mediaproxy

Grant access to radius user to the radius database, replace PASSWORD and PRIVATE_IP_NETWORK with the real values:


OpenSIPS setup

Configure OpenSIPS for MySQL storage of subscribers and Radius accounting. For SIP tracing you need to configure the OpenSIPS to enable the siptrace module.

The documentation for how to setup OpenSIPS accounting is available here:

In OpenSIPS 1.6 trusted table has been dropped. You need to create a MySQL view to ‘emulate’ the trusted table:
DEFINER VIEW `trusted` AS select `address`.`id` AS `id`,`address`.`ip`
AS `src_ip`,`address`.`proto` AS `proto`,`address`.`pattern` AS
`from_pattern`,`address`.`context_info` AS `tag` from `address` where
(`address`.`grp` = 1)

You will also need a valid client.conf, you can copy the one in /etc/radiusclient-ng/radiusclient.conf and adapt it to suit your needs

To enable quota you must add one extra column in the subscriber table:

ALTER TABLE opensips.subscriber ADD COLUMN quota int NOT NULL;

Entries required in opensips.cfg (the example below is for OpenSIPS 1.4 branch):

loadmodule ""
loadmodule ""

# global acc parameters
modparam("acc", "failed_transaction_flag", 1)
modparam("acc", "report_cancels",     0)
modparam("acc", "report_ack",         0)
modparam("acc", "early_media",        0)

modparam("acc", "log_level",          1)
modparam("acc", "log_flag",           1)
modparam("acc", "log_missed_flag",    1)

modparam("acc", "radius_config",      "/etc/opensips/radius/client.conf")
modparam("acc", "radius_flag",        1)
modparam("acc", "radius_missed_flag", 1)
modparam("acc", "radius_extra",       "User-Name=$Au; \
                                       Calling-Station-Id=$from; \
                                       Called-Station-Id=$to; \
                                       Sip-Translated-Request-URI=$ru; \
                                       Sip-RPid=$avp(s:rpid); \
                                       Source-IP=$avp(s:source_ip); \
                                       Source-Port=$avp(s:source_port); \
                                       SIP-Proxy-IP=$avp(s:sip_proxy_ip); \
                                       Canonical-URI=$avp(s:can_uri); \
                                       Billing-Party=$avp(billing_party); \
                                       Divert-Reason=$avp(s:divert_reason); \
                                       User-Agent=$hdr(user-agent); \
                                       Contact=$hdr(contact); \
                                       Event=$hdr(event); \

modparam("siptrace", "db_url", "mysql://opensips:password@localhost/opensips")
modparam("siptrace", "traced_user_avp", "$avp(s:traced_user)")
modparam("siptrace", "trace_on",        1)
modparam("siptrace", "trace_flag",      2)

Entries required in opensips.cfg (the example below is for OpenSIPS 1.10 branch):

loadmodule ""
loadmodule ""
loadmodule ""

 global acc parameters
 modparam("acc", "failed_transaction_flag", 1)
 modparam("acc", "report_cancels",     0)
 modparam("acc", "early_media",        0)

 modparam("acc", "log_level",          1)
 modparam("acc", "log_flag",           1)
 modparam("acc", "log_missed_flag",    1)

 modparam("acc", "aaa_url",            "radius:/etc/opensips/radius/client.conf")
 modparam("acc", "aaa_flag",           1)
 modparam("acc", "aaa_missed_flag",    1)
 modparam("acc", "aaa_extra",          "User-Name=$Au; \
                                        Calling-Station-Id=$avp(calling_station); \
                                        Called-Station-Id=$to; \
                                        Sip-Translated-Request-URI=$ru; \
                                        Sip-RPid=$avp(asserted_identity); \
                                        Source-IP=$avp(source_ip); \
                                        Source-Port=$avp(source_port); \
                                        SIP-Proxy-IP=$avp(sip_proxy_ip); \
                                        Canonical-URI=$avp(can_uri); \
                                        Billing-Party=$avp(billing_party); \
                                        Divert-Reason=$avp(diversion_reason); \
                                        User-Agent=$hdr(user-agent); \
                                        Contact=$hdr(contact); \
                                        Event=$hdr(event); \
                                        ENUM-TLD=$avp(enum_tld); \
                                        From-Header=$hdr(from); \

modparam("siptrace", "db_url", "mysql://opensips:password@localhost/opensips")
modparam("siptrace", "traced_user_avp", "$avp(s:traced_user)")
modparam("siptrace", "trace_on",        1)
modparam("siptrace", "trace_flag",      2)

Further, you must enable siptrace and accounting in various parts of the routing script by setting the accounting flag and saving the AVP containing the proxy IP address.

Check OpenSIPS documentation for the version you are using for any differences in the was the accounting module has to be configured.

Copy /var/www/CDRTool/setup/radius/OpenSIPS/dictionary.opensips to /etc/opensips/radius/dictionary

Generation of the Canonical-URI

It is critical to save $avp(s:can_uri) after the Proxy has performed all possible lookups except DNS. The Canonical-URI will be used for rating the session. Example:

route {
    $avp(s:can_uri) = $ru;

The Canonical-URI must by synced with the class used to determine the E164 format of the destination. The default behavior of the rating engine is to consider an European dialing plan where a local number starts with a zero and an international number starts with two zeros.

See the Chapter 'Determination of the destination id' in RATING.txt for more information.

MediaProxy setup

MediaProy can log the IP bandwidth utilization, the codecs and the User Agents. MediaProxy logs this information into the database used by the Freeradius server in radacct table. !MediaProxy also corrects the session duration of CDRs for which no BYE messages have been received. See project:MediaProxy documentation for how to enable Radius and database accounting.

MediaProxy logs detailed information about each individual stream (its type, duration, time-out end point ports). The logging is performed in a separate mysql table (default mediaproxy.media_sessions). The MySQL schema is defined in setup/radius/MediaProxy/create_table_media_sessions.mysql. You do not need to create that table, the mediaproxy does it automatically if it has the rights to the configured database.

The detailed information about the media streams is displayed in the SIP trace web page, follow the link about media trace.

Enable accounting in /etc/mediaproxy/config.ini:

accounting = radius,database

dburi = mysql://mediaproxy:password@db/mediaproxy

config_file = /etc/opensips/radius/client.conf
additional_dictionary = radius/dictionary

It is possible to retrieve also real-time information about the ongoing sessions and streams, this can be used to plot usage statistics from external applications. The Usage and Sessions web pages display this information. The information is obtained from any mediaproxy dispatcher, which has connections to all configured relays.

Create or copy both a media relay certificate and its key to /etc/cdrtool/mediaproxy.hostname.pem:

cat /etc/mediaproxy/tls/relay.crt >> /etc/cdrtool/mediaproxy.hostname.pem
cat /etc/mediaproxy/tls/relay.key >> /etc/cdrtool/mediaproxy.hostname.pem

and set the option:

"mediaDispatcher"      => "tls:hostname:25061"

for each datasource that uses MediaProxy in

Replace the hostname with the real IP or hostname of the mediaproxy dispatcher.

Make sure your php is compiled with openssl support

Login accounts

To login to the web interface you must create login accounts. During the initial database the username 'admin' with the password 'admin' has been automatically created. You should change this password after the first time you login.

Click on the Login link to add or change existing login accounts. Each account has a set of Permissions that grant the login account with certain right. Also you must specify which datasource may be accessed by a login account.

You can experiment with the set of Permissions, their name should be self explanatory.

Beware that the 'admin' right simply mean that you can create other login accounts. You still need to select the appropriate permissions for the admin account in order to have access to various functionality controlled by the Permissions system.