Siremis (SIP Server Records Management Interface System) is a web-based management tool for Kamailio SIP Server. It provides a browser dashboard for managing subscribers, monitoring SIP registrations, viewing call detail records, configuring dispatcher routes, and tracking real-time server statistics. Instead of editing database tables and running RPC commands manually, Siremis gives you a clean web interface to handle day-to-day Kamailio administration.
The project was originally built on PHP, but the latest generation (v25.x) is rewritten in Go as a self-contained binary – no Apache, Nginx, or PHP stack required. It ships with its own built-in web server. This guide covers installing Siremis v25 on Ubuntu 24.04 LTS alongside an existing Kamailio deployment with a MariaDB backend.
Prerequisites
Before you begin, make sure these are in place:
- A server running Ubuntu 24.04 LTS with root or sudo access
- Kamailio SIP Server installed and running with a MySQL/MariaDB database backend
- MariaDB or MySQL server installed and accessible locally
- Kamailio database already created (via
kamdbctl createorkamcli db create) - Port 8284 (TCP) available for the Siremis web interface
- Kamailio JSONRPC socket enabled at
/run/kamailio/kamailio_rpc.sock
Step 1: Prepare the Kamailio Database for Siremis
Siremis reads from and writes to the Kamailio database directly. Your Kamailio database should already exist from the initial Kamailio setup. Siremis needs a few additional tables for accounting, CDR generation, and statistics tracking.
Connect to MariaDB as root:
sudo mysql -u root
Switch to the Kamailio database and create the accounting table for SIP transaction records:
USE kamailio;
CREATE TABLE IF NOT EXISTS `acc` (
`id` int(10) unsigned NOT NULL auto_increment,
`method` varchar(16) NOT NULL default '',
`from_tag` varchar(64) NOT NULL default '',
`to_tag` varchar(64) NOT NULL default '',
`callid` varchar(128) NOT NULL default '',
`sip_code` char(3) NOT NULL default '',
`sip_reason` varchar(32) NOT NULL default '',
`time` datetime NOT NULL default '2000-01-01 00:00:00',
`src_ip` varchar(64) NOT NULL default '',
`dst_ouser` VARCHAR(64) NOT NULL DEFAULT '',
`dst_user` varchar(64) NOT NULL default '',
`dst_domain` varchar(128) NOT NULL default '',
`src_user` varchar(64) NOT NULL default '',
`src_domain` varchar(128) NOT NULL default '',
`cdr_id` integer NOT NULL default '0',
INDEX acc_callid (`callid`),
PRIMARY KEY (`id`)
);
Create the missed calls table to track unanswered SIP calls:
CREATE TABLE IF NOT EXISTS `missed_calls` (
`id` int(10) unsigned NOT NULL auto_increment,
`method` varchar(16) NOT NULL default '',
`from_tag` varchar(64) NOT NULL default '',
`to_tag` varchar(64) NOT NULL default '',
`callid` varchar(128) NOT NULL default '',
`sip_code` char(3) NOT NULL default '',
`sip_reason` varchar(32) NOT NULL default '',
`time` datetime NOT NULL default '2000-01-01 00:00:00',
`src_ip` varchar(64) NOT NULL default '',
`dst_ouser` VARCHAR(64) NOT NULL DEFAULT '',
`dst_user` varchar(64) NOT NULL default '',
`dst_domain` varchar(128) NOT NULL default '',
`src_user` varchar(64) NOT NULL default '',
`src_domain` varchar(128) NOT NULL default '',
`cdr_id` integer NOT NULL default '0',
INDEX mc_callid (`callid`),
PRIMARY KEY (`id`)
);
Create the CDR (Call Detail Records) table that stores processed call records:
CREATE TABLE IF NOT EXISTS `cdrs` (
`cdr_id` bigint(20) NOT NULL auto_increment,
`src_username` varchar(64) NOT NULL default '',
`src_domain` varchar(128) NOT NULL default '',
`dst_username` varchar(64) NOT NULL default '',
`dst_domain` varchar(128) NOT NULL default '',
`dst_ousername` varchar(64) NOT NULL default '',
`call_start_time` datetime NOT NULL default '2000-01-01 00:00:00',
`duration` int(10) unsigned NOT NULL default '0',
`sip_call_id` varchar(128) NOT NULL default '',
`sip_from_tag` varchar(128) NOT NULL default '',
`sip_to_tag` varchar(128) NOT NULL default '',
`src_ip` varchar(64) NOT NULL default '',
`cost` integer NOT NULL default '0',
`rated` integer NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`cdr_id`),
UNIQUE KEY `uk_cft` (`sip_call_id`,`sip_from_tag`,`sip_to_tag`)
);
Create the statistics table for server performance tracking:
CREATE TABLE IF NOT EXISTS `statistics` (
`id` int(10) unsigned NOT NULL auto_increment,
`time_stamp` int(10) unsigned NOT NULL default '0',
`shm_used_size` int(10) unsigned NOT NULL default '0',
`shm_real_used_size` int(10) unsigned NOT NULL default '0',
`shm_max_used_size` int(10) unsigned NOT NULL default '0',
`shm_free_used_size` int(10) unsigned NOT NULL default '0',
`ul_users` int(10) unsigned NOT NULL default '0',
`ul_contacts` int(10) unsigned NOT NULL default '0',
`tm_active` int(10) unsigned NOT NULL default '0',
`rcv_req_diff` int(10) unsigned NOT NULL default '0',
`fwd_req_diff` int(10) unsigned NOT NULL default '0',
`2xx_trans_diff` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`)
);
Add the billing rates table for call rating:
CREATE TABLE IF NOT EXISTS `billing_rates` (
`rate_id` bigint(20) NOT NULL auto_increment,
`rate_group` varchar(64) NOT NULL default 'default',
`prefix` varchar(64) NOT NULL default '',
`rate_unit` integer NOT NULL default '0',
`time_unit` integer NOT NULL default '60',
PRIMARY KEY (`rate_id`),
UNIQUE KEY `uk_rp` (`rate_group`,`prefix`)
);
Insert the default domain entry if it does not exist already:
INSERT IGNORE INTO domain (domain, did) VALUES ('127.0.0.1', 'default');
EXIT;
Create a dedicated database user for Siremis if you do not want to reuse the Kamailio DB credentials:
sudo mysql -u root -e "GRANT ALL PRIVILEGES ON kamailio.* TO 'siremis'@'localhost' IDENTIFIED BY 'StrongPassword123'; FLUSH PRIVILEGES;"
Step 2: Create CDR Generation Stored Procedures
Siremis uses stored procedures to generate CDRs from raw accounting data. These procedures match INVITE and BYE transactions to calculate call durations and costs.
Create a SQL file with the CDR procedure:
sudo tee /tmp/siremis_procedures.sql > /dev/null << 'SQL'
DELIMITER %%
DROP PROCEDURE IF EXISTS `kamailio_cdrs`%%
CREATE PROCEDURE `kamailio_cdrs`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE bye_record INT DEFAULT 0;
DECLARE v_src_user,v_src_domain,v_dst_user,v_dst_domain,v_dst_ouser,v_callid,
v_from_tag,v_to_tag,v_src_ip VARCHAR(64);
DECLARE v_inv_time, v_bye_time DATETIME;
DECLARE inv_cursor CURSOR FOR SELECT src_user, src_domain, dst_user,
dst_domain, dst_ouser, time, callid,from_tag, to_tag, src_ip
FROM acc
where method='INVITE' and cdr_id='0';
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN inv_cursor;
REPEAT
FETCH inv_cursor INTO v_src_user, v_src_domain, v_dst_user, v_dst_domain,
v_dst_ouser, v_inv_time, v_callid, v_from_tag, v_to_tag, v_src_ip;
IF NOT done THEN
SET bye_record = 0;
SELECT 1, time INTO bye_record, v_bye_time FROM acc WHERE
method='BYE' AND callid=v_callid AND ((from_tag=v_from_tag
AND to_tag=v_to_tag)
OR (from_tag=v_to_tag AND to_tag=v_from_tag))
ORDER BY time ASC LIMIT 1;
IF bye_record = 1 THEN
INSERT INTO cdrs (src_username,src_domain,dst_username,
dst_domain,dst_ousername,call_start_time,duration,sip_call_id,
sip_from_tag,sip_to_tag,src_ip,created) VALUES (v_src_user,
v_src_domain,v_dst_user,v_dst_domain,v_dst_ouser,v_inv_time,
UNIX_TIMESTAMP(v_bye_time)-UNIX_TIMESTAMP(v_inv_time),
v_callid,v_from_tag,v_to_tag,v_src_ip,NOW());
UPDATE acc SET cdr_id=last_insert_id() WHERE callid=v_callid
AND from_tag=v_from_tag AND to_tag=v_to_tag;
END IF;
SET done = 0;
END IF;
UNTIL done END REPEAT;
END%%
DROP PROCEDURE IF EXISTS `kamailio_rating`%%
CREATE PROCEDURE `kamailio_rating`(`rgroup` varchar(64))
BEGIN
DECLARE done, rate_record, vx_cost INT DEFAULT 0;
DECLARE v_cdr_id BIGINT DEFAULT 0;
DECLARE v_duration, v_rate_unit, v_time_unit INT DEFAULT 0;
DECLARE v_dst_username VARCHAR(64);
DECLARE cdrs_cursor CURSOR FOR SELECT cdr_id, dst_username, duration
FROM cdrs WHERE rated=0;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cdrs_cursor;
REPEAT
FETCH cdrs_cursor INTO v_cdr_id, v_dst_username, v_duration;
IF NOT done THEN
SET rate_record = 0;
SELECT 1, rate_unit, time_unit INTO rate_record, v_rate_unit, v_time_unit
FROM billing_rates
WHERE rate_group=rgroup AND v_dst_username LIKE concat(prefix, '%')
ORDER BY prefix DESC LIMIT 1;
IF rate_record = 1 THEN
SET vx_cost = v_rate_unit * CEIL(v_duration/v_time_unit);
UPDATE cdrs SET rated=1, cost=vx_cost WHERE cdr_id=v_cdr_id;
END IF;
SET done = 0;
END IF;
UNTIL done END REPEAT;
END%%
DELIMITER ;
SQL
Import the stored procedures into the Kamailio database:
sudo mysql -u root kamailio < /tmp/siremis_procedures.sql
Verify the procedures were created successfully:
sudo mysql -u root -e "SHOW PROCEDURE STATUS WHERE Db='kamailio'\G"
You should see both kamailio_cdrs and kamailio_rating listed in the output:
*************************** 1. row ***************************
Db: kamailio
Name: kamailio_cdrs
Type: PROCEDURE
Definer: root@localhost
...
*************************** 2. row ***************************
Db: kamailio
Name: kamailio_rating
Type: PROCEDURE
Definer: root@localhost
...
Step 3: Download and Install Siremis
The new generation of Siremis (v25.x) is written in Go and ships as a self-contained binary. No Apache, Nginx, or PHP required - it includes its own web server. Download the latest release from the official GitHub repository.
Download the Linux amd64 binary:
cd /tmp
wget https://github.com/asipto/siremis/releases/download/v25.0.0/siremis-v25.0.0-linux-amd64.tar.gz
For ARM-based servers (like AWS Graviton instances), download the arm64 version instead:
wget https://github.com/asipto/siremis/releases/download/v25.0.0/siremis-v25.0.0-linux-arm64.tar.gz
Extract the archive and move it to a permanent location:
tar xzf siremis-v25.0.0-linux-amd64.tar.gz
sudo mv siremis /opt/siremis
sudo chown -R root:root /opt/siremis
Verify the binary runs correctly:
/opt/siremis/siremis -h
The help output shows available options for setting the listen address, port, TLS certificates, and other runtime parameters.
Step 4: Configure Siremis
Siremis uses JSON configuration files stored in the etc/ directory. Copy the sample files to create your working configuration:
cd /opt/siremis
sudo cp etc/siremis-config-sample.json etc/siremis-config.json
sudo cp etc/siremis-menu-sample.json etc/siremis-menu.json
sudo cp etc/siremis-charts-sample.json etc/siremis-charts.json
Edit the main configuration file to set your database credentials and admin password:
sudo vi /opt/siremis/etc/siremis-config.json
Update the following sections with your actual values:
{
"DefaultViewPath": "view/main",
"URLDir": "/siremis",
"PublicDir": "public",
"PublicDirWebPath": "public",
"SchemasDir": "schemas",
"TemplatesDir": "templates",
"AuthUsersFilePath": "",
"AuthUsers": [
{
"Username": "admin",
"Password": "text:YourSecurePassword",
"Role": "admin"
}
],
"DBData": {
"Database": "kamailio",
"Driver": "mysql",
"Host": "localhost",
"Port": "3306",
"Protocol": "tcp",
"Username": "siremis",
"Password": "StrongPassword123"
},
"JSONRPC": {
"Protocol": "unixgram",
"LAddress": "/tmp/siremis_rpc.sock",
"RAddress": "/run/kamailio/kamailio_rpc.sock",
"ViewForm": {
"Type": "dataset",
"CommandOptions": [
{
"Command": "core.uptime",
"Title": "Server Uptime"
},
{
"Command": "core.psx",
"Title": "List Processes"
},
{
"Command": "stats.fetchn all",
"Title": "Fetch All Statistics"
}
]
}
},
"ChartGroupsFilePath": "etc/siremis-charts.json",
"MenuFilePath": "etc/siremis-menu.json"
}
Key settings to change:
- AuthUsers - change the admin password from the default. The format is
text:YourPassword - DBData.Database - set to your Kamailio database name (usually
kamailio) - DBData.Username and DBData.Password - the database credentials created in Step 1
- JSONRPC.RAddress - path to the Kamailio JSONRPC socket. Confirm it matches your Kamailio config
Step 5: Configure Kamailio JSONRPC Module
Siremis communicates with Kamailio through JSONRPC over a Unix socket. Make sure the jsonrpcs module is loaded in your Kamailio configuration with a Unix datagram socket enabled.
Open your Kamailio configuration file:
sudo vi /etc/kamailio/kamailio.cfg
Ensure the jsonrpcs module is loaded and configured with the correct socket path:
loadmodule "jsonrpcs.so"
modparam("jsonrpcs", "dgram_socket", "/run/kamailio/kamailio_rpc.sock")
If you want Siremis to display real-time statistics charts, add the statistics collection modules and route. This collects server metrics every 5 minutes and stores them in the statistics table:
loadmodule "rtimer.so"
loadmodule "sqlops.so"
loadmodule "htable.so"
modparam("rtimer", "timer", "name=tst;interval=300;mode=1;")
modparam("rtimer", "exec", "timer=tst;route=STATS")
modparam("sqlops", "sqlcon",
"ca=>mysql://siremis:StrongPassword123@localhost/kamailio")
modparam("htable", "htable", "stats=>size=6;")
Add the STATS route block that collects and stores the metrics:
route[STATS] {
$var(tmc) = $var(tmc) + 1;
$var(x) = $var(tmc) mod 144;
if($var(x) == 0)
sql_query("ca",
"delete from statistics where time_stamp < $Ts - 864000",
"ra");
sql_query("ca",
"insert into statistics (time_stamp, shm_used_size, "
"shm_real_used_size, shm_max_used_size, shm_free_used_size, "
"ul_users, ul_contacts) values ($Ts, $stat(used_size), "
"$stat(real_used_size), $stat(max_used_size), $stat(free_size), "
"$stat(location_users), $stat(location_contacts))",
"ra");
if($var(tmc) == 1) {
$var(rcv_req_diff) = $stat(rcv_requests);
$var(fwd_req_diff) = $stat(fwd_requests);
$var(2xx_trans_diff) = $stat(2xx_transactions);
} else {
$var(rcv_req_diff) = $stat(rcv_requests) - $sht(stats=>last_rcv_req);
$var(fwd_req_diff) = $stat(fwd_requests) - $sht(stats=>last_fwd_req);
$var(2xx_trans_diff) = $stat(2xx_transactions)
- $sht(stats=>last_2xx_trans);
}
$sht(stats=>last_rcv_req) = $stat(rcv_requests);
$sht(stats=>last_fwd_req) = $stat(fwd_requests);
$sht(stats=>last_2xx_trans) = $stat(2xx_transactions);
sql_query("ca",
"update statistics set tm_active=$stat(inuse_transactions), "
"rcv_req_diff=$var(rcv_req_diff), fwd_req_diff=$var(fwd_req_diff), "
"2xx_trans_diff=$var(2xx_trans_diff) where time_stamp=$Ts",
"ra");
}
Restart Kamailio to apply the configuration changes:
sudo systemctl restart kamailio
Verify the service is running and the JSONRPC socket exists:
sudo systemctl status kamailio
The service should show active (running). Also confirm the RPC socket was created:
ls -la /run/kamailio/kamailio_rpc.sock
You should see the socket file with the correct permissions:
srw-rw-rw- 1 kamailio kamailio 0 Mar 22 10:00 /run/kamailio/kamailio_rpc.sock
Step 6: Create a Systemd Service for Siremis
Running Siremis as a systemd service ensures it starts on boot and restarts automatically on failure. Create the unit file:
sudo vi /etc/systemd/system/siremis.service
Add the following service definition:
[Unit]
Description=Siremis - Kamailio Web Management Interface
After=network.target mariadb.service kamailio.service
Wants=kamailio.service
[Service]
Type=simple
WorkingDirectory=/opt/siremis
ExecStart=/opt/siremis/siremis
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Enable and start the Siremis service:
sudo systemctl daemon-reload
sudo systemctl enable --now siremis
Check the service status to confirm it started successfully:
sudo systemctl status siremis
The output should show the service as active with the web server listening on port 8284:
● siremis.service - Siremis - Kamailio Web Management Interface
Loaded: loaded (/etc/systemd/system/siremis.service; enabled; preset: enabled)
Active: active (running) since Sat 2026-03-22 10:00:00 UTC; 5s ago
Main PID: 12345 (siremis)
CGroup: /system.slice/siremis.service
└─12345 /opt/siremis/siremis
Step 7: Configure the Firewall
If UFW is active on your server, open port 8284 for the Siremis web interface. In production, restrict access to your management network or VPN only.
sudo ufw allow from 10.0.1.0/24 to any port 8284 proto tcp comment "Siremis Web UI"
sudo ufw reload
Verify the rule was added:
sudo ufw status numbered
You should see the new rule allowing TCP traffic on port 8284 from your management subnet.
Step 8: Access the Siremis Dashboard
Open a web browser and navigate to your server's IP on port 8284:
http://your-server-ip:8284/siremis/
Log in with the admin credentials you set in the siremis-config.json file. The default username is admin with the password you configured in Step 4.
After logging in, the dashboard presents the main menu with access to all management sections. Siremis provides the following management modules:
- Subscriber Management - create, list, and search SIP subscriber accounts
- Location Management - view registered SIP endpoints and their contact addresses
- Domain Management - manage SIP domains served by Kamailio
- Dispatcher Management - configure load balancing destinations and gateway sets
- Permissions Management - manage address and trusted peer ACLs
- Dialog Management - view active SIP dialogs and dialog variables
- LCR Management - configure least cost routing gateways and rules
- Charts Service - view real-time shared memory and performance charts
Step 9: Monitor SIP Traffic with Siremis
Siremis makes it easy to monitor SIP traffic patterns without digging through database tables or log files. Several features are available out of the box.
View Active Registrations
Navigate to Location Management > List to see all currently registered SIP endpoints. This shows the same data as running kamctl ul show on the command line, but in a searchable web table format. Each entry shows the AOR (Address of Record), contact URI, expiry time, and user agent string.
Execute JSONRPC Commands
Under Json RPC Command > Execute, you can run Kamailio RPC commands directly from the browser. The preconfigured commands include server uptime, process listing, and full statistics. This is the same as running kamcmd from the terminal, but accessible from the web interface. You can add more commands by editing the CommandOptions section in siremis-config.json.
View Statistics Charts
If you configured the statistics collection route in Step 5, navigate to Charts Service > Shared Memory to view time-series graphs of Kamailio's performance metrics. The charts display shared memory usage, active users, contacts, transaction counts, and request rates. Data is collected every 5 minutes and retained for 10 days by default.
Step 10: Manage Kamailio Configurations Through Siremis
Beyond monitoring, Siremis lets you manage Kamailio's database-driven configuration without writing SQL directly.
Manage SIP Subscribers
Go to Subscriber Management > New to create SIP accounts. This inserts records into the subscriber table that Kamailio uses for authentication. You can also search and edit existing subscribers. This replaces running kamctl add commands manually.
Configure Dispatcher Sets
If you use the Kamailio dispatcher module for load balancing SIP traffic across media servers or gateways, navigate to Dispatcher Management > New to add destination entries. Each entry needs a setid, destination URI, flags, and priority. After adding or modifying entries, use the JSONRPC Execute page to reload the dispatcher list with dispatcher.reload.
Manage Permissions and ACLs
The Permissions Management section handles both address-based and trusted peer ACLs. Use Address entries to control which IP addresses can send traffic through Kamailio. Trusted entries define peers that bypass authentication. This maps directly to the Kamailio permissions module tables.
Secure Siremis with a Reverse Proxy and TLS
For production deployments, never expose the Siremis port directly to the internet. Place it behind a reverse proxy with TLS termination. A basic Nginx reverse proxy configuration looks like this:
sudo vi /etc/nginx/sites-available/siremis
Add the following configuration:
server {
listen 443 ssl;
server_name siremis.example.com;
ssl_certificate /etc/letsencrypt/live/siremis.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/siremis.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8284;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name siremis.example.com;
return 301 https://$host$request_uri;
}
Enable the site and restart Nginx:
sudo ln -s /etc/nginx/sites-available/siremis /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
When using a reverse proxy, update the UFW rules to block direct access to port 8284 from external networks and only allow HTTPS (443) traffic.
Conclusion
Siremis provides a practical web interface for managing Kamailio SIP Server without the friction of running CLI commands and SQL queries for every routine task. The new Go-based version simplifies deployment significantly - a single binary, a JSON config file, and you have a fully functional management dashboard.
For production environments, always put Siremis behind a reverse proxy with TLS, restrict access to management networks only, and change the default admin credentials. Consider setting up regular database backups and monitoring the Kamailio service health alongside Siremis for a complete VoIP operations workflow.