Register: Difference between revisions

From VoIPmonitor.org
(Review: opravy formátování (pre->syntaxhighlight, typo, heading hierarchy), zkrácení AI Summary)
(Rewrite: konsolidace a vylepšení struktury)
 
(4 intermediate revisions by the same user not shown)
Line 1: Line 1:
The SIP Register section shows three tables - Active registered SIP users, Failed registrations and State changes in SIP registrations. Those tables are filled once you enable sip-register = yes in /etc/voipmonitor.conf.
{{DISPLAYTITLE:SIP Registration Monitoring}}
[[Category:GUI manual]]
[[Category:Configuration]]


By default PCAP files are not saved for SIP register messages (it can easily overload file system). If you need to record SIP messages you can control this in capture rules main section and here in all three sections there are gray/red small circles which indicates if SIP messages are being recorded to pcap file so it can be retrieved by clicking on PCAP link. Clicking on the circle enables / disables recording. In the dialog window you can adjust values and set auto remove for the rule at specific date.
= SIP Registration Monitoring =
Note: If you need to record all register packets by the sniffer instance without need to create capture rules in a GUI use sip-register-save-all=yes in its config (/etc/voipmonitor.conf)


[[File:register-recording.png]]
The Register section in VoIPmonitor GUI tracks SIP REGISTER transactions across three views: '''Active''' (current registrations), '''Failed''' (unsuccessful attempts), and '''State''' (historical changes). This feature is '''disabled by default'''.


== Active table ==
== Quick Start ==
 
The active table shows current registered users with this columns:
 
[[File:register-active.png]]
 
*ID/sensor id shows internal unique ID and if enabled sensor id
*datetime is time creation
*User name / realm shows username and realm from REGISTER message
*Source IP / Destination IP
*From / To / Contact are values from SIP headers
*Expires at shows date when the registration expires
*User agent
*Commands - download PCAP
 
On the picture below you can see a detail area where a sub-grid with state changes and failed registrations from the user name is located. This holds quick filters for a particular active user where you can quickly see his history. Once the SIP registration is expired  the history is no longer in the Active table . Each expired registration is stored in the State table.
 
[[File:register-activesubstate.png]]
 
On the picture below you can see a detail area where a sub-grid with related CDR from the user name is located.
 
[[File:register-activesubcdr.png]]
 
== Failed table ==
 
The failed table shows failed SIP registrations. If some device fails to register continuously the counter column increases instead of creating a new row. If there is a one-hour gap between two failed registrations from the same user a new row will be created.
 
[[File:register-failed.png]]
 
== State table ==
 
The state table retains registration history where REGISTER, UNREGISTER and EXPIRE are saved. In each state row you can click on detail [+] to show all related SIP register messages to the selected user. If device registers in regular intervals it will not save state change in the state table (not true now, see bellow) but keeps the last registration status until the re-registration stops - then UNREGISTER will be the last register state change. If the device do not resend registration in time (register expires + 5 second) the last state will be EXPIRE (with red flag).
 
The same state is periodically saved due to e.g. graphing, etc. The default is 600 seconds. It can be changed by sip-register-state-timeout option in the sensor config.
 
[[File:register-state.png]]
 
== Configuration Location in Distributed Architecture ==
 
In distributed/client-server deployments, the location where you must enable <code>sip-register = yes</code> depends on your <code>packetbuffer_sender</code> configuration:


{| class="wikitable"
{| class="wikitable"
|-
|-
! Mode !! Configuration Location !! Processing Location
! Parameter !! Value !! Description
|-
| <code>sip-register</code> || <code>yes</code> || Enable registration tracking and DB storage
|-
|-
| '''<code>packetbuffer_sender = yes</code>''' (Packet Mirroring) || Central server || Central server processes raw packets from remote sensors
| <code>sip-register-save-all</code> || <code>yes</code> || Save PCAP files for all registrations
|-
|-
| '''<code>packetbuffer_sender = no</code>''' (Local Processing) || Remote sensor || Each sensor processes packets locally before sending CDRs to central server
| <code>sip-register-state-timeout</code> || <code>600</code> || State snapshot interval (seconds)
|}
|}
To determine where to configure <code>sip-register</code>:
;1. Check the <code>packetbuffer_sender</code> setting on your remote sensors:
<syntaxhighlight lang="bash">
grep packetbuffer_sender /etc/voipmonitor.conf
</syntaxhighlight>
;2. If <code>packetbuffer_sender = yes</code>:
* Configure <code>sip-register = yes</code> on the '''central server's''' <code>/etc/voipmonitor.conf</code>
* Restart the voipmonitor service on the central server
;3. If <code>packetbuffer_sender = no</code> (or not set):
* Configure <code>sip-register = yes</code> on the '''remote sensor's''' <code>/etc/voipmonitor.conf</code>
* Restart the voipmonitor service on the remote sensor(s)
For detailed information on distributed architectures and configuration locations, see [[Sniffer_distributed_architecture]].
== How the Active tab retrieves data ==
The Active table in the GUI displays registration data in two different ways, depending on whether the sip-register feature is enabled:
*'''When sip-register is disabled (default):''' The GUI retrieves active registration data directly from the running sniffer processes in real-time. The sniffer maintains an in-memory list of currently registered SIP devices and provides this information to the GUI. In this configuration, the database tables (register, register_state, register_failed) are '''not''' created or used. The Active tab will still function correctly and show live registration data.
*'''When sip-register = yes:''' Registration data is stored in database tables (register, register_state, register_failed) for persistent storage and historical reporting. The GUI can then query these tables to display both current and historical registration information.
== Displaying Multiple Registrations for the Same Account Independently ==
By default, multiple registrations for the same SIP account (same username) from different IP addresses or ports may be displayed as a single aggregated record in the GUI Active table. To view all registrations for the same account separately (differentiated by their source and destination IP addresses and ports), enable comparison options in the sniffer configuration file.
Add these lines to <code>/etc/voipmonitor.conf</code> (the configuration that processes <code>sip-register=yes</code>):


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
# Enable independent display of multiple registrations for the same account
# /etc/voipmonitor.conf - Basic setup
sip-register-compare-sipcallerip = yes
sip-register = yes
sip-register-compare-sipcallerport = yes
sip-register-compare-sipcalledip = yes
sip-register-compare-sipcalledport = yes
 
# Optional: Track registration state changes separately by From domain
# Useful when the same SIP account registers from different domains
sip-register-state-compare-from_domain = yes
</syntaxhighlight>
</syntaxhighlight>


These settings instruct the system to create separate registration entries when the source IP (sipcallerip), source port (sipcallerport), destination IP (sipcalledip), destination port (sipcalledport), or From domain differ. This allows you to see each registration instance independently rather than having them merged into a single record. The <code>sip-register-state-compare-from_domain</code> option is particularly useful for accurate alerting when multiple registrations from the same account should be tracked separately based on their originating domain.
{{Note|1=When <code>sip-register=no</code> (default), the Active tab still works using real-time data from the sniffer process. The error "Table 'voipmonitor.register' doesn't exist" is expected in this mode.}}
 
After modifying the configuration, reload or restart the voipmonitor service for changes to take effect.
 
In distributed architectures, apply these settings to the same location where <code>sip-register = yes</code> is configured (central server for <code>packetbuffer_sender=yes</code>, or remote sensor for <code>packetbuffer_sender=no</code>).
 
== Error: Table 'voipmonitor.register' doesn't exist ==
 
If you see the error message "Table 'voipmonitor.register' doesn't exist" when viewing the Active tab, this is '''expected and correct behavior''' when the sip-register feature is disabled.
 
The error message typically appears if the GUI attempts to query the database table for historical information while the feature is disabled. However, the Active tab will still display live registration data retrieved directly from the sniffer processes.
 
'''No action is required to fix this error.''' The system is functioning as intended. The error simply indicates that persistent database storage is not enabled for registration data.


If you want to enable persistent storage of registration history, add sip-register = yes to /etc/voipmonitor.conf and restart the sniffer. This will create the database tables and eliminate the error message, but it is optional for basic registration monitoring.
== Distributed Architecture ==


== Troubleshooting: Registration Data Missing Despite Traffic Being Present ==
Configuration depends on your <code>packetbuffer_sender</code> setting:
 
If SIP registration information is missing from the GUI even though traffic is confirmed present on your network mirror port, the issue is likely with packet capture rather than the sip-register configuration. Follow these troubleshooting steps:
 
;1. Verify packets are reaching the sensor host:
Run a packet capture directly on the sensor to verify REGISTER packets are arriving at the interface. Use <code>tcpdump</code> or <code>tshark</code> on the correct interface:
 
<syntaxhighlight lang="bash">
# Check for REGISTER packets on the sensor interface
tcpdump -i napa0 -s 0 -c 10 "port 5060 and udp"
 
# Or use tshark for more detailed analysis
tshark -i napa0 -Y "sip.Method == REGISTER" -c 10
</syntaxhighlight>
 
If no packets appear, the problem is with your network mirroring configuration (SPAN/TAP). See [[Sniffer_troubleshooting]] for detailed packet capture troubleshooting.
 
;2. Check for packet drops in the GUI:
Navigate to '''Settings → Sensors''' in the VoIPmonitor GUI. Expand the sensor details and check the '''# packet drops''' counter.


{| class="wikitable"
{| class="wikitable"
|-
|-
! Packet Drops Value !! Meaning !! Action
! Mode !! Where to Configure
|-
|-
| 0 || Normal || No drop issues
| <code>packetbuffer_sender = yes</code> || '''Central server''' only
|-
|-
| Non-zero value || Sensor is dropping packets || See [[Sniffer_troubleshooting#Check_Sensor_Statistics_in_GUI|Sniffer Troubleshooting: Sensor Statistics]]
| <code>packetbuffer_sender = no</code> || Each '''remote sensor'''
|}
|}


;3. If using Napatech hardware:
== GUI Views ==
Standard capture tools may show no packets if Napatech interfaces are in a DOWN state. This is a common issue with Napatech cards.


Check interface status:
=== Active Table ===
<syntaxhighlight lang="bash">
ip link show napa0
</syntaxhighlight>
 
If the interface shows DOWN instead of UP, the solution is to use a custom <code>libpcap</code> library provided by Napatech. See [[Napatech#Troubleshooting:_Napatech_Interfaces_in_DOWN_State|Napatech Troubleshooting]] for detailed steps to:
* Check if Napatech drivers are loaded
* Verify voipmonitor is linked against Napatech libpcap
* Rebuild the sniffer with the correct library


The key command to verify:
Displays currently registered SIP users:
<syntaxhighlight lang="bash">
# Check which libpcap voipmonitor is using
ldd /usr/local/sbin/voipmonitor | grep pcap


# Should show: /opt/napatech3/lib/libpcap.so.1
* Registration timestamp, username, realm
# NOT: /lib/x86_64-linux-gnu/libpcap.so.1
* Source/destination IP addresses
</syntaxhighlight>
* SIP headers (From, To, Contact)
* Expiration time and User-Agent
* Sub-grids: state changes, failed attempts, related CDRs
* PCAP download (if enabled)


;4. Additional troubleshooting resources:
=== Failed Table ===
* [[Sniffer_troubleshooting]] - Comprehensive guide for diagnosing packet capture issues
* [[Sniffer_troubleshooting#Is_Network_Traffic_Reaching_the_Server|Network traffic verification with tshark]]
* [[Sniffer_troubleshooting#Check_the_VoIPmonitor_Configuration]] - Verify interface, sipport, and filter settings


== Slow Queries on register_state Table ==
Shows unsuccessful registration attempts:


If queries on the <code>register_state</code> table are extremely slow or time out when filtering by text fields (Username, Domain, Number), especially for older data, this indicates missing indexes on frequently queried columns.
* Consecutive failures from the same device increment a counter (no duplicate rows)
* New entry created after >1 hour gap between attempts
* Red flag indicates failure status


=== Problem Description ===
=== State Table ===


The <code>register_state</code> table stores SIP registration history (REGISTER, UNREGISTER, EXPIRE events). Because SIP devices re-register frequently (typically every 30-60 seconds), this table accumulates rows very quickly. Queries filtering by text fields without proper indexes require full table scans, which are extremely slow on large tables.
Historical registration events (REGISTER, UNREGISTER, EXPIRE):


=== Common Symptoms ===
* Periodic snapshots at <code>sip-register-state-timeout</code> interval (default 600s)
* EXPIRE status: device missed renewal deadline by >5 seconds
* Used for graphing registration trends


* Queries with filters on Username, Domain, or Number time out
== Advanced Configuration ==
* Searches for specific registration events take 30+ seconds or indefinite
* GUI Register State tab is unresponsive when applying filters
* MySQL shows high CPU usage from register_state queries


=== Solution: Create Missing Indexes ===
=== Multiple Registration Tracking ===


The root cause is almost always missing indexes on columns used in WHERE clauses. Create indexes manually on the most frequently queried columns.
Display separate entries when the same SIP account registers from different locations:
 
First, verify which indexes already exist:
 
<syntaxhighlight lang="sql">
-- Show current indexes on register_state
SHOW INDEX FROM register_state;
</syntaxhighlight>
 
Look for indexes on:
* <code>digestusername</code>
* <code>digest_from_number</code>
* <code>digest_to_number</code>
* <code>digest_to_domain</code>
* <code>digest_realm</code>
 
If these indexes are missing, create them:
 
<syntaxhighlight lang="sql">
-- Create index on username (most common query)
CREATE INDEX digestusername ON register_state (digestusername);
 
-- Create indexes on other frequently queried columns
CREATE INDEX digest_from_number ON register_state (digest_from_number);
CREATE INDEX digest_to_number ON register_state (digest_to_number);
CREATE INDEX digest_to_domain ON register_state (digest_to_domain);
CREATE INDEX digest_realm ON register_state (digest_realm);
</syntaxhighlight>
 
{{Warning|
<code>CREATE INDEX</code> operations on large tables can be very slow and may block write operations to the table. Schedule index creation during a maintenance window or low-traffic periods.
}}
 
=== Additional Performance Optimization ===
 
If performance is still insufficient after adding indexes:
 
1. Increase <code>innodb_buffer_pool_size</code> in MySQL configuration (see [[Scaling#Memory_Configuration|Scaling Guide]])
2. Configure <code>cleandatabaseregister = 7</code> (or 30) in <code>/etc/voipmonitor.conf</code> to limit data retention (see [[Data_Cleaning]])
 
{{Note|
For MySQL 5.6+ or MariaDB 10.1+, use online index creation to avoid blocking writes:
<code>CREATE INDEX digestusername ON register_state (digestusername) ALGORITHM=INPLACE, LOCK=NONE;</code>
}}
 
=== Calculating Required innodb_buffer_pool_size for High-Volume REGISTER Data ===
 
For systems with high REGISTER volume (e.g., 30 million records per day), determining the maximum history you can store without performance degradation requires calculating the correct <code>innodb_buffer_pool_size</code>.
 
==== Understanding the Limit ====
 
The "maximum" history you can query efficiently is determined by the amount of data that fits entirely within MySQL's <code>innodb_buffer_pool_size</code>. If the database tables and indexes exceed this memory allocation, queries must read from disk (I/O), which is significantly slower.
 
==== Step-by-Step Calculation ====
 
Follow these steps to calculate the required buffer pool size based on your specific daily volume and query requirements:
 
1. '''Calculate the size of database partitions for a single day:'''
 
<syntaxhighlight lang="bash">
ls -lat /var/lib/mysql/voipmonitor | grep pYYMMDD | cut -d' ' -f 7 | paste -s -d+ - | bc
</syntaxhighlight>
 
Replace <code>pYYMMDD</code> with the actual partition date format (e.g., <code>p250101</code> for January 1, 2025).
 
2. '''Multiply by the number of days you need to query quickly:'''
 
For example, if each day is 15GB and you need to query last 7 days efficiently:
15GB × 7 days = 105GB minimum buffer pool
 
3. '''Configure MySQL to use this calculated value:'''
 
Edit your MySQL configuration file (e.g., <code>/etc/mysql/my.cnf</code> or <code>/etc/mysql/mariadb.conf.d/50-server.cnf</code>):


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
[mysqld]
# Show each IP/port combination independently
# Set to the calculated value or higher
sip-register-compare-sipcallerip = yes
innodb_buffer_pool_size = 128G
sip-register-compare-sipcallerport = yes
</syntaxhighlight>
sip-register-compare-sipcalledip = yes
 
sip-register-compare-sipcalledport = yes
4. '''Ensure sufficient physical RAM:'''
sip-register-state-compare-from_domain = yes
 
The server must have enough physical RAM to accommodate the <code>innodb_buffer_pool_size</code> '''plus''' operating system, application, and other MySQL memory allocations. Avoid using swap, as swap usage leads to severe performance degradation.
 
==== Practical Guidelines ====
 
For high-volume REGISTER environments:
 
* '''30+ million records/day:''' Expect 15-20+ GB per day. Require 64GB+ RAM for 3-7 day history.
* '''Partition-based storage:''' VoIPmonitor uses MySQL partitioning by date. Query performance drops sharply when filters span partitions not cached in the buffer pool.
* '''Set aggressive retention policy:''' Use <code>cleandatabaseregister = 3</code> (or lower) to maintain manageable table sizes. See [[Data_Cleaning]] for retention options.
 
==== Query Timing Warnings ====
 
To avoid performance impact on real-time monitoring:
 
* '''Avoid running large range reports during peak traffic hours.''' History queries spanning multiple days can monopolize I/O resources.
* '''Avoid running reports during the partition maintenance window (1:00 AM - 5:00 AM).''' This is when automatic partition cleanup occurs, competing for database resources.
* '''Schedule large historical queries during maintenance windows or off-peak hours.'''
 
== AI Summary for RAG ==
 
'''Summary:''' The SIP Register section displays Active, Failed, and State tables for monitoring SIP registrations. Enable with <code>sip-register = yes</code> in voipmonitor.conf for persistent database storage; the Active tab works in real-time even when disabled (data retrieved directly from sniffer process). In distributed architectures, configure <code>sip-register</code> on the central server if <code>packetbuffer_sender=yes</code>, or on remote sensors if <code>packetbuffer_sender=no</code>. By default, PCAP files are not saved for REGISTER messages to prevent disk overload; enable via capture rules or <code>sip-register-save-all=yes</code> globally. To display multiple registrations for the same account independently (instead of aggregated), enable comparison options: <code>sip-register-compare-sipcallerip</code>, <code>sip-register-compare-sipcallerport</code>, <code>sip-register-compare-sipcalledip</code>, <code>sip-register-compare-sipcalledport</code>, and optionally <code>sip-register-state-compare-from_domain</code>. For slow queries on register_state table, create indexes on digestusername, digest_from_number, digest_to_number, digest_to_domain, digest_realm. For high-volume environments (30M+ records/day), calculate required <code>innodb_buffer_pool_size</code> based on daily partition size × days to retain. Avoid large reports during partition maintenance window (1:00-5:00 AM).
 
'''Keywords:''' SIP Register, Active, Failed, State, sip-register, packetbuffer_sender, distributed architecture, central server, remote sensor, multiple registrations, aggregated registrations, sip-register-compare-sipcallerip, sip-register-compare-sipcallerport, sip-register-compare-sipcalledip, sip-register-compare-sipcalledport, sip-register-state-compare-from_domain, register_state, slow query, index, digestusername, innodb_buffer_pool_size, cleandatabaseregister, PCAP recording, sip-register-save-all, Napatech, packet drops, tcpdump, tshark
 
'''Key Questions:'''
* How do I enable SIP registration monitoring in VoIPmonitor?
* Where do I configure sip-register in distributed architecture?
* Why does the Active tab show "Table 'voipmonitor.register' doesn't exist"?
* How to display multiple registrations for the same account separately?
* Why are fewer SIP trunks shown in the Registered client list than actually registered?
* How to fix aggregated registrations showing as single record?
* Why are queries on register_state table so slow?
* How to create indexes on register_state columns?
* How to calculate innodb_buffer_pool_size for high-volume REGISTER data?
* What is the partition maintenance window time?
* How to verify packets are reaching the sensor interface?
* How to troubleshoot Napatech interfaces in DOWN state?
upgrade on a development/staging system first if possible
* Major version upgrades (e.g., 5.7 to 8.0) require additional planning and testing
* Review the MySQL upgrade documentation for your version for any breaking changes
 
=== Which Recovery Method to Use ===
 
'''Use Table-Level Repair (First Attempt when MySQL is running):'''
* MySQL/MariaDB service is running and accessible
* Only specific tables are corrupted (not entire database)
* You want to preserve CDR data as much as possible
* Corruption appears mild and detected early
* System is experiencing poor performance but still accessible
 
This method uses <code>mysqlcheck --repair</code> or <code>REPAIR TABLE</code> to fix individual tables without dropping the database. See the <code>Solution: Table-Level Repair</code> section above.
 
'''Use Drop and Recreate Database (Simplest, when MySQL is running):'''
* MySQL/MariaDB service is running and accessible
* Only the voipmonitor database is corrupted
* You do not need to preserve CDR data (historical call records are acceptable to lose)
* You want to restore service quickly with minimal downtime
* GUI configuration loss is acceptable or will be reconfigured
 
'''Use innodb_force_recovery (Recommended for filesystem corruption/InnoDB assertion failures):'''
* MySQL fails to start after a filesystem issue (Read-only file system errors)
* InnoDB assertion failures during startup
* PCAP files may or may not be available in the spool directory
* You need to preserve GUI configuration (users, sensors, settings)
* You are willing to lose all CDR data if it cannot be restored from PCAP
 
'''Use PCAP restore (Alternative):'''
* PCAP files are definitely available and intact in the spool directory
* You want to restore historical CDR data along with GUI configuration
* The innodb_force_recovery method did not work
* You have time for a lengthy re-processing operation
 
=== Solution: Drop and Recreate Database (Simplest, When MySQL is Running) ===
 
If MySQL/MariaDB is running but only the voipmonitor database is corrupted, the fastest recovery method is to drop the corrupted database and let the sensor recreate it automatically.
 
'''Warning:''' This procedure will result in complete loss of all CDR data, call recordings, and GUI configuration. You will need to reconfigure sensors, users, and settings in the GUI.
 
==== Step 1: Stop All VoIPmonitor Sensor Processes ====
 
Stop all VoIPmonitor sensors to prevent further database corruption during the recovery process.
 
<syntaxhighlight lang="bash">
# Stop all VoIPmonitor sensor services
systemctl stop voipmonitor
 
# If running distributed (client/server mode), stop all sensor services:
# - On server sensors: systemctl stop voipmonitor-server
# - On client sensors: systemctl stop voipmonitor-client
# - Check all running sensors: ps aux | grep voipmonitor
</syntaxhighlight>
 
If you are using a client/server architecture, stop ALL sensors first, including both client and server sensors.
 
==== Step 2: Drop the Corrupted VoIPmonitor Database ====
 
Delete the corrupted voipmonitor database from MySQL/MariaDB.
 
<syntaxhighlight lang="bash">
# Connect to MySQL as root
mysql -u root -p
</syntaxhighlight>
 
Run the following SQL command:
 
<syntaxhighlight lang="sql">
DROP DATABASE IF EXISTS voipmonitor;
EXIT;
</syntaxhighlight>
 
Replace the database name <code>voipmonitor</code> if you are using a custom database name in your configuration.
 
==== Step 3: Restart a Single Sensor to Create Fresh Database ====
 
Start ONE sensor instance (preferably the server sensor in client/server mode) so it can automatically create a fresh, empty database with all required tables.
 
<syntaxhighlight lang="bash">
# Start the primary sensor (or server sensor in client/server mode)
systemctl start voipmonitor
 
# Verify the sensor is running
systemctl status voipmonitor
 
# Monitor the sensor log for database creation messages
journalctl -u voipmonitor -f
</syntaxhighlight>
 
The sensor will automatically create the voipmonitor database, all tables, functions, and routines. You should see log messages indicating the database structure is being created.
 
==== Step 4: Start All Remaining Sensors ====
 
Once the database is created, start any additional sensors (client sensors in distributed mode).
 
<syntaxhighlight lang="bash">
# Start any remaining sensors
systemctl start voipmonitor-client1
systemctl start voipmonitor-client2
# ... etc for all sensors
</syntaxhighlight>
</syntaxhighlight>


==== Step 5: Verify System Functionality ====
=== User-Agent Change Detection ===
 
Verify that the system is operating correctly.
 
* Access the VoIPmonitor web GUI and log in
* You may need to reconfigure the GUI (create users, sensors, capture rules, alerts)
* Check that the sniffer service is running and capturing:
  <syntaxhighlight lang="bash">systemctl status voipmonitor</syntaxhighlight>
* Confirm that new calls are being captured and processed
 
==== Step 6: Prevent Future Corruption with Automatic Database Cleanup ====


To prevent future database corruption due to excessive data accumulation, configure automatic database cleanup using the <code>cleandatabase*</code> options in your sensor configuration file (<code>/etc/voipmonitor.conf</code>).
Track when a device's User-Agent changes (potential fraud indicator):
 
Edit the configuration file:
 
<syntaxhighlight lang="bash">
sudo nano /etc/voipmonitor.conf
</syntaxhighlight>
 
Add or adjust the following parameters based on your requirements:


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
# Automatically delete CDR records older than X days
sip-register-state-compare-digest_ua = yes
cleandatabase = 90;  # Delete CDRs older than 90 days
 
# Optionally control per-table cleanup
cleandatabasecdr = 90;      # Delete cdr table records older than 90 days
cleandatabasemsg = 30;        # Delete message table records older than 30 days
cleandatabaseregister = 7;    # Delete register table records older than 7 days
cleandatabasesip = 30;        # Delete sip table records older than 30 days
cleandatabasequeue = 180;    # Delete queue table records older than 180 days
 
# Optionally control cleanup timing
cleandatabasehour = 3;        # Run cleanup at 3:00 AM daily
cleandatabaseminute = 0;      # At 00 minutes past the hour
</syntaxhighlight>
 
For more information on data retention and cleanup options, see the [[Data_Cleaning]] page.
 
Restart the sensor after making configuration changes:
 
<syntaxhighlight lang="bash">
systemctl restart voipmonitor
</syntaxhighlight>
 
=== Solution: Using innodb_force_recovery (Recommended for Filesystem Corruption and InnoDB Assertion Failures) ===
 
If the database is corrupted after a filesystem issue and MySQL/MariaDB fails to start with InnoDB assertion errors, you can attempt to recover using the MySQL <code>innodb_force_recovery</code> parameter. This method starts MySQL in a read-only recovery mode, allowing you to back up and restore the GUI configuration.
 
'''Warning:''' This procedure will result in complete loss of CDR data. Only the GUI configuration can be preserved.
 
==== Step 1: Ensure Filesystem Issues Are Resolved ====
 
Before attempting MySQL recovery, the underlying filesystem issue that caused the corruption must be fixed. MySQL will likely fail again if the disk is still having problems.
 
===== Detailed Filesystem Check (fsck) Procedure =====
 
If a partition becomes read-only due to filesystem errors, follow these steps to repair it:
 
1. '''Identify the problematic partition:'''
<syntaxhighlight lang="bash">
# Check mount points to see which partition is affected
df -h
 
# Check for read-only mount or I/O errors in dmesg
dmesg | tail -100 | grep -i "read-only\|i/o error\|ext4-fs"
</syntaxhighlight>
 
2. '''Stop services writing to the partition:'''
Important: You must stop any services (voipmonitor, mariadb, etc.) that are writing to the affected partition before unmounting it.
<syntaxhighlight lang="bash">
# Example: Stop services that write to /home partition
systemctl stop voipmonitor mariadb
# Adjust these services based on which partition is affected
</syntaxhighlight>
 
3. '''Unmount the partition:'''
<syntaxhighlight lang="bash">
# Unmount the affected partition
umount /home
# Replace /home with your actual mount point from df -h
</syntaxhighlight>
 
4. '''Run filesystem check:'''
<syntaxhighlight lang="bash">
# Standard partition (e.g., /dev/sda1)
fsck -t ext4 -y /dev/sda1
 
# LVM partition (e.g., /dev/mapper/vg_northvoipmonitorr630-lv_home)
fsck -t ext4 -y /dev/mapper/vg_northvoipmonitorr630-lv_home
</syntaxhighlight>
 
The <code>-t ext4</code> flag specifies the filesystem type (ext3, ext4, xfs, etc.). Use <code>df -T</code> to check the filesystem type. The <code>-y</code> flag automatically answers 'yes' to all repair prompts.
 
5. '''Remount the partition:'''
<syntaxhighlight lang="bash">
mount /home
# Replace with your mount point
</syntaxhighlight>
</syntaxhighlight>


6. '''Restart the services:'''
{{Warning|1=This setting detects UA changes but does '''NOT''' trigger GUI alerts. For alerting, use '''GUI > Alerts > Anti Fraud''' with "Change REGISTER Country Alert" or custom SQL queries.}}
<syntaxhighlight lang="bash">
systemctl start mariadb voipmonitor
# Adjust these services based on what you stopped
</syntaxhighlight>


7. '''Verify the filesystem is healthy:'''
== API Access ==
<syntaxhighlight lang="bash">
# Check mount status and free space
df -h


# Verify mounted read-write (not read-only)
Query active registrations programmatically via the Manager API.
mount | grep "on /home type"


# Check system logs for filesystem errors
=== Configuration ===
dmesg | grep -i ext4 | tail -20
</syntaxhighlight>
 
'''Summary Checklist:'''
* Check <code>dmesg</code> or <code>/var/log/syslog</code> for I/O errors
* Ensure the partition is mounted Read-Write (not Read-Only)
* Stop services writing to the partition before unmounting
* Unmount and run <code>fsck</code> on the unmounted device
* Remount and restart services
* Verify filesystem health with <code>df -h</code>, <code>mount</code>, and <code>dmesg</code>
 
==== Step 2: Enable innodb_force_recovery Mode ====
 
Add the recovery parameter to MySQL's configuration to start it in read-only mode. This allows MySQL to start despite InnoDB corruption.
 
Edit the MySQL/MariaDB configuration file:
 
<syntaxhighlight lang="bash">
sudo nano /etc/my.cnf
# or
sudo nano /etc/mysql/my.cnf
</syntaxhighlight>
 
Add the following line to the <code>[mysqld]</code> section:


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
[mysqld]
# /etc/voipmonitor.conf
innodb_force_recovery=6
manager_ip = 127.0.0.1
manager_port = 5029
# Alternative: Unix socket
# manager_socket = /tmp/vm_manager_socket
</syntaxhighlight>
</syntaxhighlight>


The <code>innodb_force_recovery=6</code> setting is the most aggressive recovery mode. It allows MySQL to start in read-only mode even with severe InnoDB corruption. See the [[#Understanding innodb_force_recovery Levels|innodb_force_recovery levels]] section below for details on each level.
=== Query Examples ===
 
==== Step 3: Back Up GUI Configuration ====
 
With MySQL in recovery mode, back up the GUI configuration before proceeding.


'''TCP with filter:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
cd /var/www/html
echo 'listregisters {"zip":"no","limit":30,"states":"OK","filter":{"digestusername":"user"},"sort_field":"calldate","sort_dir":"desc"}' | nc 127.0.0.1 5029
php php/run.php backupGuiTables -t config -f /root/backup.zip
</syntaxhighlight>
</syntaxhighlight>


This command exports all GUI settings (users, sensors, capture rules, alerts, etc.) to a backup file. For more information on GUI backup and restore, see the [[Backing_Up_GUI_Configuration]] page.
'''Unix socket:'''
 
==== Step 4: Stop MySQL and Back Up Corrupted Data ====
 
Stop the MySQL service and create a backup of the corrupted MySQL data directory.
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Stop MySQL
echo 'listregisters' | nc -U /tmp/vm_manager_socket
systemctl stop mysql
# or
systemctl stop mariadb
 
# Move the corrupted data directory to a backup location
sudo mv /var/lib/mysql /var/lib/mysql-corrupted
</syntaxhighlight>
</syntaxhighlight>


==== Step 5: Re-initialize MySQL Data Directory ====
'''GUI API (auto-detects connection method):'''
 
Create a new, empty MySQL data directory.
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Reinitialize MySQL data directory
php /var/www/html/php/run.php send_manager_cmd -s NULL -c 'listregisters'
sudo mysql_install_db --user=mysql --datadir=/var/lib/mysql
# or on newer systems:
sudo mysqld --initialize --user=mysql
</syntaxhighlight>
 
==== Step 6: Remove innodb_force_recovery and Start MySQL ====
 
Remove the recovery parameter from the configuration file and start MySQL normally.
 
First, edit the configuration file and remove or comment out the line:
 
<syntaxhighlight lang="ini">
[mysqld]
# innodb_force_recovery=6  <-- Comment out or remove this line
</syntaxhighlight>
</syntaxhighlight>


Then start MySQL:
'''Key parameters:''' <code>filter</code> (digestusername, sipcallerip), <code>limit</code>, <code>sort_field</code>, <code>sort_dir</code>


<syntaxhighlight lang="bash">
== Database Optimization ==
systemctl start mysql
# or
systemctl start mariadb


# Verify MySQL is running
=== Create Indexes ===
systemctl status mysql
</syntaxhighlight>
 
MySQL should now be able to start with a fresh, empty database.
 
==== Step 7: Create VoIPmonitor Database ====


Create a new database for VoIPmonitor:
For slow queries on large datasets:
 
<syntaxhighlight lang="bash">
mysql -u root -p
</syntaxhighlight>
 
Run the following SQL commands:


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
CREATE DATABASE voipmonitor;
CREATE INDEX digestusername ON register_state (digestusername);
CREATE USER 'voipmonitor'@'localhost' IDENTIFIED BY 'your_password_here';
CREATE INDEX digest_from_number ON register_state (digest_from_number);
GRANT ALL PRIVILEGES ON voipmonitor.* TO 'voipmonitor'@'localhost';
CREATE INDEX digest_to_number ON register_state (digest_to_number);
FLUSH PRIVILEGES;
CREATE INDEX digest_to_domain ON register_state (digest_to_domain);
EXIT;
CREATE INDEX digest_realm ON register_state (digest_realm);
</syntaxhighlight>
</syntaxhighlight>


==== Step 8: Restore GUI Configuration ====
=== Data Retention ===


Restore the GUI configuration from the backup file created in Step 3.
Control storage with <code>cleandatabaseregister</code> parameter:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="ini">
cd /var/www/html
# /etc/voipmonitor.conf
php php/run.php restoreGuiTables -t config -f /root/backup.zip
cleandatabaseregister = 7  # Days to retain
</syntaxhighlight>
</syntaxhighlight>


==== Step 9: Verify System Functionality ====
=== Buffer Pool Sizing ===


Verify that the GUI and sniffer are working correctly.
For high-volume environments (30M+ records/day):


* Access the VoIPmonitor web GUI and log in
<code>innodb_buffer_pool_size</code> = daily partition size x retention days
* Verify that sensors, users, and other settings are present
* Check that the sniffer service is running:
  <syntaxhighlight lang="bash">systemctl status voipmonitor</syntaxhighlight>
* Confirm that new calls are being captured and processed


'''Note:''' All historical CDR data has been lost. Only the GUI configuration was preserved. The system will begin accumulating new CDR data from this point forward.
''Example: 15GB daily x 7 days = 105GB minimum''


==== Understanding innodb_force_recovery Levels ====
== Troubleshooting ==
 
The <code>innodb_force_recovery</code> parameter accepts values from 1 to 6, each enabling progressively more aggressive recovery options:


{| class="wikitable"
{| class="wikitable"
|-
|-
! Value
! Symptom !! Solution
! Meaning
|-
|-
| 1
| No registrations appear || Verify packets: <code>tcpdump -i eth0 port 5060</code>
| (SRV_FORCE_IGNORE_CORRUPT) Runs the server even if it detects a corrupt page
|-
|-
| 2
| "Table doesn't exist" error || Normal when <code>sip-register=no</code>; Active tab still works
| (SRV_FORCE_NO_BACKGROUND) Prevents the master thread from running; prevents crash recovery
|-
|-
| 3
| Missing data with Napatech || Check <code>ip link show napa0</code> and libpcap path
| (SRV_FORCE_NO_TRX_UNDO) Does not run transaction rollbacks after recovery
|-
|-
| 4
| Packet drops || Check '''Settings > Sensors''' for drop counters
| (SRV_FORCE_NO_IBUF_MERGE) Prevents insert buffer merge operations
|-
| 5
| (SRV_FORCE_NO_UNDO_LOG_SCAN) Does not look at undo logs when starting the database
|-
| 6
| (SRV_FORCE_NO_LOG_REDO) Does not apply the redo log from crash recovery (most aggressive)
|}
|}


For maximum recovery capability, use <code>innodb_force_recovery=6</code>. This mode enables all recovery strategies and allows MySQL to start even with severe InnoDB corruption.
{{Tip|Avoid large historical queries during peak traffic hours and partition maintenance windows (1:00-5:00 AM).}}
 
=== Solution: Restore from PCAP Files (Alternative) ===
 
If you have PCAP files available in the spool directory, you can restore CDR data from them instead of using <code>innodb_force_recovery</code>. This preserves your call recordings and metadata by reprocessing the packet captures.
 
'''When to use PCAP restore:'''
* PCAP files are available in the spool directory
* You want to restore historical CDR data, not just GUI configuration
* <code>innodb_force_recovery</code> method did not work
 
'''Warning:''' This procedure requires stopping the VoIPmonitor services and may take significant time depending on the amount of data to restore.
 
The following diagram illustrates the restoration workflow:
 
<kroki lang="plantuml">
@startuml
skinparam shadowing false
skinparam defaultFontName Arial
skinparam activityFontSize 12
skinparam arrowFontSize 11
 
title Database Restore from PCAP Files
 
start
 
:Stop VoIPmonitor services;
note right: voipmonitor, manager, gui
 
:Backup corrupted database;
note right: /var/lib/mysql-backup-corrupted
 
:Remove corrupted database;
note right: /var/lib/mysql/voipmonitor
 
:Start MySQL/MariaDB;
 
:Create fresh database;
note right: CREATE DATABASE voipmonitor
 
:Run sniffer in restore mode;
note right: --readpcapdir /var/spool/voipmonitor
 
while (All PCAP files processed?) is (no)
  :Process next PCAP file;
  :Generate CDR records;
endwhile (yes)
 
:Stop restore process;
 
:Start normal service;
note right: systemctl start voipmonitor
 
:Verify Web GUI access;
 
stop
 
@enduml
</kroki>
 
==== Step 1: Stop VoIPmonitor Services ====
 
Stop all VoIPmonitor services to prevent further database corruption:
 
<syntaxhighlight lang="bash">
# Stop the sniffer service
systemctl stop voipmonitor
 
# Stop sniffer manager (if running)
systemctl stop voipmonitor-manager
 
# Stop any other VoIPmonitor services
systemctl stop voipmonitor-gui
</syntaxhighlight>
 
==== Step 2: Backup the Corrupted Database ====
 
Although corrupted, create a backup of the existing database for troubleshooting purposes:
 
<syntaxhighlight lang="bash">
# Stop MySQL/MariaDB service
systemctl stop mysql
 
# Create a backup of the MySQL data directory
sudo cp -a /var/lib/mysql /var/lib/mysql-backup-corrupted
</syntaxhighlight>
 
==== Step 3: Remove the Corrupted Database ====
 
Move or remove the corrupted database files to prepare for a fresh database:
 
<syntaxhighlight lang="bash">
# Remove the corrupted VoIPmonitor database directory
sudo rm -rf /var/lib/mysql/voipmonitor
 
# Alternatively, move it instead of deleting:
sudo mv /var/lib/mysql/voipmonitor /var/lib/mysql/voipmonitor.corrupted
</syntaxhighlight>
 
==== Step 4: Start MySQL/MariaDB Service ====
 
Restart the MySQL/MariaDB service:
 
<syntaxhighlight lang="bash">
# Start MySQL/MariaDB
systemctl start mysql
 
# Verify the service is running
systemctl status mysql
</syntaxhighlight>
 
==== Step 5: Create a Fresh VoIPmonitor Database ====
 
Create a new empty database for VoIPmonitor:
 
<syntaxhighlight lang="bash">
# Log in to MySQL as root
mysql -u root -p
</syntaxhighlight>
 
Run the following SQL commands:
 
<syntaxhighlight lang="sql">
CREATE DATABASE voipmonitor;
CREATE USER 'voipmonitor'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON voipmonitor.* TO 'voipmonitor'@'localhost';
FLUSH PRIVILEGES;
EXIT;
</syntaxhighlight>
 
Replace <code>your_password_here</code> with a strong password.
 
==== Step 6: Restore CDRs from PCAP Files ====
 
Instruct the sniffer to reprocess all PCAP files from the spool directory and populate the new database:
 
<syntaxhighlight lang="bash">
# 1. Verify your spool directory path
# Check voipmonitor.conf for the spooldir setting (default: /var/spool/voipmonitor)
grep "^spooldir" /etc/voipmonitor.conf
 
# 2. Clear the sniffer's manager socket for the restore process
# This ensures clean communication with the sniffer
rm -f /tmp/vmsck
 
# 3. Start the sniffer in restore mode
# The sniffer will read all PCAP files from the spool directory
# and regenerate CDR records in the new database
voipmonitor --config-file /etc/voipmonitor.conf --readpcapdir /var/spool/voipmonitor
</syntaxhighlight>
 
'''Note:''' The <code>--readpcapdir</code> parameter instructs the sniffer to process all PCAP files in the specified directory. This may take considerable time depending on the amount of historical data.
 
==== Step 7: Monitor the Restore Process ====
 
Monitor the restore progress:
 
<syntaxhighlight lang="bash">
# Monitor sniffer output for progress
journalctl -u voipmonitor -f
 
# Alternatively, check the database for new CDR records
mysql -u root -p voipmonitor -e "SELECT COUNT(*) FROM cdr;"
</syntaxhighlight>
 
==== Step 8: Restart Normal Service ====
 
Once the restore is complete, restart the sniffer in normal operation mode:
 
<syntaxhighlight lang="bash">
# Stop the restore process (Ctrl+C if running manually)
# Then start the normal sniffer service
systemctl start voipmonitor
 
# Verify the sniffer is running and capturing
systemctl status voipmonitor
 
# Test Web GUI access
# Navigate to http://your-server/ in your browser
</syntaxhighlight>
 
=== Prevention: Database Backup Strategies ===
 
To avoid future data loss due to database corruption:
 
==== Automatic Filesystem Backup ====
 
Configure regular backups of the MySQL data directory:
 
<syntaxhighlight lang="bash">
# Example: Daily backup using cron
0 2 * * * /usr/bin/rsync -av --delete /var/lib/mysql/ /backup/mysql-$(date +\%Y\%m\%d)/
</syntaxhighlight>
 
==== MySQL Replication ====
 
Set up MySQL master-slave replication for redundancy:
* See the [[Mysql_master-slave_replication_hints]] guide for detailed instructions
* This provides a real-time backup database that can be promoted if corruption occurs
 
==== VoIPmonitor Database Replication ====
 
Use VoIPmonitor's built-in database backup mode ([[Redundant_database]]):
* This replicates CDR data to a secondary database server
* No traditional MySQL replication required
* Useful for GUI migrations and disaster recovery
 
== RRD Graph Errors After Hardware Upgrades ==
 
After a hardware upgrade or system migration, RRD (Round Robin Database) graphs in the VoIPmonitor GUI may display errors indicating that Data Sources (DS) are missing from RRD files. This occurs because RRD files are created with a specific hardware-dependent schema that may become incompatible after system changes.
 
=== Symptoms ===
 
* RRD graphs in the Web GUI show display errors instead of rendering data
* Error message: <code>ERROR: No DS called '...' in '/var/spool/voipmonitor/rrd/..."'</code>
* Example: <code>ERROR: No DS called 'SQLq-SM' in '/var/spool/voipmonitor/rrd/3db-SQL.rrd'</code>
* The error appears after hardware upgrades, CPU changes, or system migrations
* Multiple RRD files may be affected, affecting various graph types
 
=== RRD File Location ===
 
RRD files are stored in the RRD directory within the VoIPmonitor spool directory:
 
<code>/var/spool/voipmonitor/rrd/</code>
 
=== Root Cause ===
 
RRD (Round Robin Database) files contain time-series data with a schema defined at creation time. Some data sources in RRD files are hardware-specific (e.g., CPU metrics tied to specific CPU identifiers). When hardware changes, the schema information stored in the RRD files may no longer match the current system configuration, resulting in missing Data Source (DS) errors.
 
=== Solution: Delete Corrupted RRD Files ===
 
The VoIPmonitor service will automatically recreate RRD files with the correct schema if they are missing. This is a safe operation because:
 
* New RRD files will be created with the current hardware's correct schema
* Historical RRD data is typically short-term (graph display purposes only)
* CDR data and call recordings are stored separately and are not affected
 
==== Step 1: Stop the VoIPmonitor Service ====
 
Stop the voipmonitor service to prevent file access conflicts:
 
<syntaxhighlight lang="bash">
systemctl stop voipmonitor
</syntaxhighlight>
 
==== Step 2: Remove Corrupted RRD Files ====
 
Delete the affected RRD files from the RRD directory. You can remove individual problematic files or the entire RRD directory:
 
<syntaxhighlight lang="bash">
# Option 1: Remove specific corrupted RRD file (recommended)
rm /var/spool/voipmonitor/rrd/3db-SQL.rrd
 
# Option 2: Remove all RRD files if multiple errors exist
rm /var/spool/voipmonitor/rrd/*
</syntaxhighlight>
 
Replace <code>3db-SQL.rrd</code> with the actual filename from the error message.
 
==== Step 3: Start the VoIPmonitor Service ====
 
Start the voipmonitor service to recreate the RRD files:
 
<syntaxhighlight lang="bash">
systemctl start voipmonitor
</syntaxhighlight>
 
The service will automatically detect the missing RRD files and recreate them with the correct schema based on the current hardware configuration. New graph data will begin accumulating immediately.
 
==== Step 4: Verify RRD Graphs ====
 
Check the Web GUI to verify that RRD graphs are now displaying correctly:
 
* Navigate to the VoIPmonitor Web GUI
* Access dashboard or reporting pages with RRD graphs
* Verify that graphs render without errors
* Note: Historical data in the affected RRD files will be lost, but new data will start appearing
 
=== Rerunning with Different Hardware ===
 
If you need to preserve RRD data when moving to different hardware (for example, testing on a different machine), consider these options:
 
* '''Don't copy RRD files''' - Let the new system create fresh RRD files with appropriate schemas
* '''Use rrdtool dump/restore''' - For advanced users, you can modify RRD file contents using rrdtool export/import tools
* '''Accept data loss''' - RRD data is typically short-term monitoring data, not critical call records
 
=== Related Information ===
 
* RRD files are separate from CDR data (cdr table in MySQL) and PCAP recordings
* The VoIPmonitor <code>spooldir</code> location is configurable in /etc/voipmonitor.conf
* RRD files are automatically created by the sniffer service when needed
 
== Faxes Cannot Be Displayed in the GUI ==
 
If faxes cannot be displayed in the GUI and an error message appears, the issue is likely that the required package for fax conversion is not installed.
 
=== Symptoms ===
 
* Faxes are not displayed in the GUI or a generic error message appears when attempting to view fax contents
* Other GUI features work normally
* No error in browser console related to failed binary execution
 
=== Root Cause ===
 
The GUI requires the `tiff2pdf` utility to convert fax TIFF images for display in the web browser. This utility is part of the `libtiff-tools` package on Debian/Ubuntu systems or related packages on other distributions.
 
=== Solution: Install libtiff-tools Package ===
 
Install the required package using your system's package manager.
 
'''For Debian/Ubuntu:'''
 
<syntaxhighlight lang="bash">
# SSH into the GUI host
sudo apt-get update
sudo apt-get install libtiff-tools
</syntaxhighlight>
 
'''For CentOS/RHEL/AlmaLinux:'''
 
<syntaxhighlight lang="bash">
sudo yum install libtiff-tools
# or on newer systems:
sudo dnf install libtiff-tools
</syntaxhighlight>
 
=== Verifying the Fix ===
 
Verify that the `tiff2pdf` binary is accessible and executable by the web server user:
 
<syntaxhighlight lang="bash">
# Check if tiff2pdf is available system-wide
which tiff2pdf
 
# Verify the web server user can access tiff2pdf
# For Debian/Ubuntu (www-data)
runuser -u www-data -- which tiff2pdf
 
# For CentOS/RHEL (apache)
runuser -u apache -- which tiff2pdf
</syntaxhighlight>
 
If the command returns a path (e.g., `/usr/bin/tiff2pdf`), the binary is correctly installed and accessible.
 
After installing the package, reload the GUI and try to display faxes again. The ability to view faxes in the GUI should now be restored.
 
=== Related Information ===
 
* The `tiff2pdf` utility converts TIFF image files to PDF format for web browser display
* Faxes are captured by VoIPmonitor as TIFF images in T.38 fax sessions
* This conversion is required because not all browsers can display TIFF images natively
* Other GUI features (audio playback, graphs, etc.) may have different package requirements
 
== Incorrect Ownership / Permission Errors ==
 
If the GUI reports an "incorrect ownership" error even after verifying that the web server user (e.g., apache or www-data) has write permissions to the web root directory, the actual error may be hidden. The web server user needs **execute permissions** on all binary files in the `./bin` directory of the GUI installation.
 
=== Symptoms ===
 
* GUI displays "incorrect ownership" or permission errors
* Error persists even after fixing ownership/permissions on the web root directory
* Binary files in the bin directory cannot be executed by the web server
 
=== Root Cause ===
 
The GUI requires the web server user to have execute permissions on all binary files in the `bin` directory (e.g., `sox-x86_64`, `ffmpeg`, etc.). These binaries are used by the GUI for audio processing, call playback, and other features. If the binaries lack execute permissions, the GUI cannot run them.
 
=== Solution: Set Execute Permissions on Binaries ===
 
Check and fix permissions on all files in the `./bin` directory:
 
<syntaxhighlight lang="bash">
# Navigate to the GUI installation directory (default is /var/www/html)
cd /var/www/html
 
# Check the bin directory
ls -la bin/
 
# Set execute permissions on all files in the bin directory
chmod +x bin/*
 
# For specific binaries, you can set execute permissions individually
chmod +x bin/sox-x86_64
chmod +x bin/ffmpeg
</syntaxhighlight>
 
=== Verifying the Fix ===
 
Test that the binaries can be executed by the web server user:
 
<syntaxhighlight lang="bash">
# For Debian/Ubuntu (www-data)
su - www-data -s /bin/bash -c "/var/www/html/bin/sox-x86_64 --version"
# or
su - www-data -s /bin/bash -c "ls -x /var/www/html/bin/"
 
# For CentOS/RHEL (apache)
su - apache -s /bin/bash -c "/var/www/html/bin/sox-x86_64 --version"
# or
su - apache -s /bin/bash -c "ls -x /var/www/html/bin/"
</syntaxhighlight>
 
If the binaries can now be executed, the GUI should work correctly.
 
=== Troubleshooting Symlinks ===
 
Sometimes the `bin` directory contains symlinks to other locations. Check both the symlink and its target:
 
<syntaxhighlight lang="bash">
# Check if files are symlinks and their targets
ls -lah bin/
 
# If a symlink cannot be accessed, check permissions on the target
# For example, if bin/sox-x86_64 is a symlink:
ls -l bin/sox-x86_64
ls -l /path/to/real/location/sox-x86_64
 
# Fix permissions on the target if needed
chmod +x /path/to/real/location/sox-x86_64
</syntaxhighlight>
 
=== Reproducing the Error ===
 
To verify that missing execute permissions cause this error, you can temporarily remove execute permissions:
 
<syntaxhighlight lang="bash">
# Remove execute permissions (reproduces the error)
chmod -x bin/sox-x86_64
 
# Test the GUI - should show "incorrect ownership" error
 
# Restore execute permissions
chmod +x bin/sox-x86_64
</syntaxhighlight>
 
=== Common Binaries in bin/ Directory ===
 
Typical binaries that require execute permissions include:
 
* `sox-x86_64` - Audio conversion tool
* `ffmpeg` - Video/audio processing
* `soxr` - Audio resampling library
* Other utility binaries used by the GUI
 
== IonCube Loader Issues ==
 
The VoIPmonitor GUI is protected with IonCube, which requires proper PHP configuration. Common issues include permission errors on temporary directories and security module interference.
 
=== Unable to create lock file / temp directory not writable ===
 
If you see errors like "Unable to create lock file" or "System temp directory check fails... not writable" from IonCube Loader, follow these troubleshooting steps:
 
==== Step 1: Update the system and restart ====
 
First, ensure your system packages are up to date:
 
<syntaxhighlight lang="bash">
# Debian/Ubuntu
sudo apt update && sudo apt upgrade -y
 
# RHEL/CentOS/AlmaLinux
sudo yum update -y
# or
sudo dnf update -y
 
# Then restart the server
sudo reboot
</syntaxhighlight>
 
==== Step 2: Check SELinux or AppArmor ====
 
Security modules like SELinux (default on RHEL/CentOS/Red Hat systems) or AppArmor (default on Ubuntu/Debian) can block IonCube from accessing temporary directories.
 
'''Check if SELinux is enabled:'''
 
<syntaxhighlight lang="bash">
# Check current status
getenforce
 
# Common values: Enforcing (active), Permissive (logging only), Disabled
 
# To temporarily disable SELinux for testing:
sudo setenforce 0
</syntaxhighlight>
 
If disabling SELinux resolves the issue, you can permanently configure it:
 
<syntaxhighlight lang="bash">
# Edit the SELinux configuration file
sudo nano /etc/selinux/config
 
# Change SELINUX= to either:
# SELINUX=permissive
# or
# SELINUX=disabled
 
# Then reboot the server
sudo reboot
</syntaxhighlight>
 
'''Check if AppArmor is enabled:'''
 
<syntaxhighlight lang="bash">
# Check AppArmor status
sudo aa-status
 
# If AppArmor is running, temporarily disable individual profiles:
sudo aa-disable /etc/apparmor.d/*php*
 
# Or disable it entirely for testing:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
</syntaxhighlight>
 
==== Step 3: Check systemd PrivateTmp ====
 
Some systemd service configurations use <code>PrivateTmp=true</code>, which creates a private temporary directory for each service. This can cause issues if the private tmp directory has restrictive permissions.
 
Check if your web server is using PrivateTmp:
 
<syntaxhighlight lang="bash">
# For Apache
systemctl show httpd | grep PrivateTmp
# or
systemctl show apache2 | grep PrivateTmp
 
# For PHP-FPM
systemctl show php-fpm | grep PrivateTmp
</syntaxhighlight>
 
If PrivateTmp is enabled (value=1), disable it in the service file:
 
<syntaxhighlight lang="bash">
# Create override directory if it doesn't exist
sudo mkdir -p /etc/systemd/system/httpd.service.d
 
# Create override file
sudo nano /etc/systemd/system/httpd.service.d/privatetmp.conf
</syntaxhighlight>
 
Add the following content:
 
<syntaxhighlight lang="ini">
[Service]
PrivateTmp=false
</syntaxhighlight>
 
Then reload and restart:
 
<syntaxhighlight lang="bash">
# Reload systemd and restart the service
sudo systemctl daemon-reload
sudo systemctl restart httpd
# or
sudo systemctl restart apache2
</syntaxhighlight>
 
==== Step 4: Verify PHP Temporary Directory Configuration ====
 
Check which temporary directory PHP is using:
 
Create a PHP info file:
 
<syntaxhighlight lang="bash">
echo '<?php phpinfo(); ?>' > /var/www/html/info.php
</syntaxhighlight>
 
Visit <code>http://your-server-ip/info.php</code> in your browser and search for:
* <code>upload_tmp_dir</code>
* <code>sys_get_temp_dir</code>
* <code>session.save_path</code>
 
Ensure these directories are writable by the web server user:


<syntaxhighlight lang="bash">
== See Also ==
# Check ownership
ls -ld /tmp


# Fix ownership if needed
* [[Anti-fraud]] - Registration country change alerts
sudo chown www-data:www-data /tmp  # Debian/Ubuntu
* [[Capture_rules]] - Per-registration PCAP rules
# or
* [[Data_Cleaning]] - Database retention settings
sudo chown apache:apache /tmp      # CentOS/RHEL
* [[Sniffer_distributed_architecture]] - Central vs. distributed processing
 
# Fix permissions
sudo chmod 1777 /tmp
</syntaxhighlight>
 
'''Important:''' Clean up after troubleshooting:
 
<syntaxhighlight lang="bash">
rm /var/www/html/info.php
</syntaxhighlight>
 
==== Step 5: Check open_basedir restrictions ====
 
If the above steps don't resolve the issue, check if PHP's <code>open_basedir</code> is restricting access to the temp directory:
 
<syntaxhighlight lang="bash">
# Check open_basedir in php.ini
grep open_basedir /etc/php/*/apache2/php.ini
# or
grep open_basedir /etc/php.ini
</syntaxhighlight>
 
Ensure the temp directory is included in the list, e.g.:
 
<code>open_basedir = /var/www/html:/tmp:/var/tmp</code>
 
=== Failed check Ioncube.com PHP Loader for php cli ===
 
If the GUI installation check fails with the error "Failed check Ioncube.com PHP Loader for php cli : no ionCube extension enabled in PHP cli" even though IonCube appears to be correctly installed from the command line, the issue is often a difference between the PHP CLI environment tested by root and the PHP environment used by the web server.
 
==== Diagnosis: Exact Web Server Environment Test ====
 
To diagnose the issue, run the exact command the GUI uses as the web server user instead of root:
 
<syntaxhighlight lang="bash">
# Test IonCube extension as the web server user
sudo -u www-data PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin php -r 'echo extension_loaded("ionCube Loader")?"yes":"no";' 2>&1
 
# For CentOS/RHEL systems, replace www-data with apache
sudo -u apache PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin php -r 'echo extension_loaded("ionCube Loader")?"yes":"no";' 2>&1
</syntaxhighlight>
 
If this command returns "no" but the same command as root returns "yes", there is a configuration difference between users.
 
Note the <code>PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin</code> parameter is critical - it ensures the web server user can find the correct PHP binary.
 
==== Compare PHP Configuration Files ====
 
The CLI PHP may use a different configuration file than the web server PHP. Compare the configurations:
 
<syntaxhighlight lang="bash">
# Check which configuration file CLI PHP uses
php --ini
 
# Create phpinfo file to check web server configuration
echo '<?php phpinfo(); ?>' > /var/www/html/info.php
 
# Visit http://your-server-ip/info.php in your browser
# Look for "Loaded Configuration File" and "Additional .ini files parsed"
</syntaxhighlight>
 
==== Verify zend_extension Directive Placement ====
 
Ensure the <code>zend_extension</code> directive for IonCube Loader is in the correct PHP configuration file used by the web server, not just in the CLI configuration:
 
<syntaxhighlight lang="bash">
# Check for IonCube in web server config
grep -r "ioncube_loader" /etc/php/*/apache2/conf.d/
grep -r "ioncube_loader" /etc/php/*/fpm/conf.d/
# or for CentOS/RHEL
grep -r "ioncube_loader" /etc/php.d/
 
# Check CLI config
grep -r "ioncube_loader" /etc/php/*/cli/conf.d/
</syntaxhighlight>
 
If the web server config is missing the <code>zend_extension = ioncube_loader_lin_*.so</code> line, add it in the appropriate directory:
 
<syntaxhighlight lang="bash">
# Example for PHP 8.1 on Debian/Ubuntu (Apache)
echo 'zend_extension = ioncube_loader_lin_8.1.so' | sudo tee /etc/php/8.1/apache2/conf.d/00-ioncube.ini
 
# Example for PHP 8.1 on Debian/Ubuntu (FPM)
echo 'zend_extension = ioncube_loader_lin_8.1.so' | sudo tee /etc/php/8.1/fpm/conf.d/00-ioncube.ini
 
# Example for CentOS/RHEL
echo 'zend_extension = ioncube_loader_lin_8.1.so' | sudo tee /etc/php.d/00-ioncube.ini
</syntaxhighlight>
 
Restart the web server after making changes:
 
<syntaxhighlight lang="bash">
# Debian/Ubuntu with Apache
sudo systemctl restart apache2
 
# Debian/Ubuntu with PHP-FPM
sudo systemctl restart php8.1-fpm
 
# CentOS/RHEL with httpd
sudo systemctl restart httpd
 
# CentOS/RHEL with PHP-FPM
sudo systemctl restart php-fpm
</syntaxhighlight>
 
Clean up the test file:
 
<syntaxhighlight lang="bash">
rm /var/www/html/info.php
</syntaxhighlight>
 
== /dev/shm Filesystem Capacity Issues ==
 
After a period of operation, user sessions may start logging out and new logins become impossible. This occurs when the <code>/dev/shm</code> filesystem (tmpfs) reaches its capacity limit. The VoIPmonitor GUI stores PHP session files in <code>/dev/shm</code> by default for performance reasons.
 
=== Symptoms ===
 
* Users are frequently logged out from the GUI
* New logins fail or immediately redirect to login screen
* <code>/dev/shm</code> is reported as full (100% capacity)
* GUI behavior improves temporarily after clearing session files
 
=== Diagnosis ===
 
Check the current <code>/dev/shm</code> usage:
 
<syntaxhighlight lang="bash">
# Check /dev/shm usage and available space
df -h /dev/shm
 
# Check how much space is used by session files
du -sh /dev/shm/php_sessions/*
 
# Count session files
ls /dev/shm/php_sessions/ | wc -l
</syntaxhighlight>
 
=== Solution: Increase /dev/shm Size ===
 
==== Temporary Increase (Until Reboot) ====
 
To temporarily increase the size of <code>/dev/shm</code> without rebooting:
 
<syntaxhighlight lang="bash">
# Remount /dev/shm with increased size (example: 1GB)
mount -o remount,size=1G /dev/shm
 
# Verify the new size
df -h /dev/shm
</syntaxhighlight>
 
Adjust the size parameter (<code>size=1G</code>) based on your server's RAM and expected number of concurrent users.
 
==== Permanent Configuration (Persistent After Reboot) ====
 
To make the size increase permanent, edit the <code>/etc/fstab</code> file:
 
<syntaxhighlight lang="bash">
# Edit /etc/fstab as root
sudo nano /etc/fstab
</syntaxhighlight>
 
Find the line for <code>/dev/shm</code>. It typically looks like this:
<pre>tmpfs /dev/shm tmpfs defaults 0 0</pre>
 
Modify it to include the size parameter:
<pre>tmpfs /dev/shm tmpfs defaults,size=1G 0 0</pre>
 
Save the file and apply the changes without rebooting:
 
<syntaxhighlight lang="bash">
# Remount all filesystems from /etc/fstab
mount -a
 
# Verify the new size
df -h /dev/shm
</syntaxhighlight>
 
=== Prevention: Session Cleanup Configuration ===
 
Ensure that PHP is configured to clean up old session files from <code>/dev/shm</code>. Check the following PHP configuration settings:
 
<syntaxhighlight lang="bash">
# Check session configuration
php -i | grep -i session
 
# Look for these directives in php.ini:
# session.gc_maxlifetime - Session lifetime in seconds (default: 1440 = 24 minutes)
# session.gc_probability - Probability of garbage collection (default: 0)
# session.gc_divisor - Garbage collection divisor (default: 1000)
</syntaxhighlight>
 
For automatic cleanup, ensure <code>session.gc_probability</code> is set to a non-zero value. The probability is calculated as <code>gc_probability / gc_divisor</code>. For example:
 
* <code>session.gc_probability = 1</code> and <code>session.gc_divisor = 100</code> = 1% chance each session start
* <code>session.gc_probability = 1</code> and <code>session.gc_divisor = 10</code> = 10% chance each session start
 
=== Related Information ===
 
* <code>/dev/shm</code> is a tmpfs filesystem backed by RAM
* Increasing <code>/dev/shm</code> size consumes physical RAM - monitor total memory usage
* The GUI typically stores session files in <code>/dev/shm/php_sessions/</code> when configured for performance
* Alternative session handlers (memcached, redis) can be considered for very high-traffic deployments
 
== Alternative: MySQL General Log ==
 
If you need a persistent server-side log of all database queries (not just from the GUI), you can enable the MySQL general log:
 
<syntaxhighlight lang="sql">
-- Enable general log
SET GLOBAL general_log = 'ON';
 
-- Perform actions in the GUI...
 
-- Disable when done (important for performance)
SET GLOBAL general_log = 'OFF';
</syntaxhighlight>
 
The log file location is typically <code>/var/lib/mysql/hostname.log</code> or as defined in your MySQL configuration.
 
'''Warning:''' The general log can grow very quickly on a busy system. Always disable it after debugging.


== AI Summary for RAG ==
== AI Summary for RAG ==


'''Summary:''' This page covers GUI troubleshooting techniques including debug mode activation, MySQL/MariaDB database corruption restoration, and filesystem repair procedures. The database corruption section includes FOUR recovery methods with clear decision criteria: (1) Table-Level Repair (FIRST ATTEMPT when MySQL is running and corruption is limited to specific tables - use mysqlcheck --repair or REPAIR TABLE) by stopping voipmonitor, running mysqlcheck --repair voipmonitor, repairing specific InnoDB tables with "REPAIR TABLE cdr; REPAIR TABLE cdr_next_partition;", checking and trimming large tables with DELETE/OPTIMIZE or configuring cleandatabase options, restarting services, and optionally upgrading MySQL to latest version in branch (e.g., 5.7.33 to latest 5.7.x), (2) Drop and recreate database (SIMPLEST AND FASTEST - use when MySQL is running, corruption is widespread, data loss is acceptable, and quick service restoration is needed) by stopping sensors with systemctl stop voipmonitor, dropping the database with DROP DATABASE IF EXISTS voipmonitor, restarting one sensor to auto-recreate the database, then starting remaining sensors, (3) innodb_force_recovery parameter (ONLY for InnoDB assertion failures after filesystem corruption where MySQL fails to start - this is more complex and requires GUI backup/restore) to save GUI configuration when MySQL cannot start normally, and (4) restore from PCAP files (alternative when PCAP files are available and you want to restore historical CDR data). For recovery, ALWAYS try table-level repair first (mysqlcheck) if MySQL is running, then drop/recreate if repair fails or data loss is acceptable, then innodb_force_recovery for severe InnoDB corruption. Corruption indicators in MySQL logs include "semaphore waits", "page corruption detected", "Table is marked as crashed", "InnoDB Assertion failure". Prevention: Configure cleandatabase* options (cleandatabase=90 etc.) in /etc/voipmonitor.conf to prevent future corruption from excessive data accumulation. The filesystem check section provides complete fsck procedure for repairing read-only partitions (stop services, unmount, run fsck -t ext4 -y, remount, restart services, verify). Other topics include browser cache issues after GUI upgrade (clear cache or hard refresh Ctrl+F5/Cmd+Shift+R), faxes not being displayed in the GUI (missing libtiff-tools package with tiff2pdf utility), incorrect ownership errors caused by missing execute permissions on GUI binaries in the ./bin directory, incorrect web root directory ownership causing "Invalid compressed data in update file" error, RRD graph errors after hardware upgrades (delete RRD files, service auto-recreates), upgrade issues (web portal inaccessible after upgrade requiring web server restart, blank screen with JavaScript errors, conflicting constants.php file, blank white screen due to SELinux), apilicensecheck.php fatal error (DO NOT reinstall entire GUI - replace only the patched file), IonCube Loader problems, and /dev/shm filesystem capacity issues.
'''Summary:''' VoIPmonitor SIP Register monitoring tracks registration events in three GUI tables: Active (current registrations with real-time data even when DB storage disabled), Failed (unsuccessful attempts with counter deduplication), and State (historical REGISTER/UNREGISTER/EXPIRE events). Enable with <code>sip-register=yes</code> in voipmonitor.conf. In distributed architecture, configure on central server if <code>packetbuffer_sender=yes</code>, otherwise on each remote sensor. PCAP files require <code>sip-register-save-all=yes</code>. Advanced options include multi-registration tracking (<code>sip-register-compare-*</code> parameters) and User-Agent change detection (<code>sip-register-state-compare-digest_ua=yes</code>) for fraud detection. API access via Manager port 5029 with <code>listregisters</code> command. Database optimization requires indexes on register_state table and proper <code>innodb_buffer_pool_size</code> sizing.


'''Keywords:''' GUI troubleshooting, debug mode, MySQL corruption, MariaDB corruption, database restore, PCAP restore, CDR restore, drop database, recreate database, drop and recreate, DROP DATABASE, sensor auto-create, database corruption recovery, cleandatabase, cleandatabasecdr, cleandatabasemsg, cleandatabaseregister, cleandatabasesip, cleandatabasequeue, automatic database cleanup, prevent corruption, innodb_force_recovery, InnoDB assertion failure, read-only filesystem, filesystem repair, filesystem check, fsck, partition repair, umount, remount, ext4, filesystem errors, I/O errors, disk check, partition readonly, read-only partition, GUI configuration backup, GUI configuration restore, table-level repair, mysqlcheck, mysqlcheck --repair, REPAIR TABLE, repair corrupted tables, table corruption, semaphore waits, page corruption, InnoDB page corruption, database error log, check MySQL error log, trim large tables, DELETE old data, OPTIMIZE TABLE, upgrade MySQL server, MySQL upgrade, latest MySQL version, MySQL 5.7.33, MySQL 5.7 upgrade, faxes not displaying, cannot display faxes, fax error, FAX, T.38, fax TIFF, TIFF images, PDF conversion, tiff2pdf, missing tiff2pdf, libtiff-tools, install libtiff-tools, fax package, fax conversion, fax preview, fax missing, incorrect ownership, permission errors, bin directory, execute permissions, chmod +x, sox-x86_64, ffmpeg, symlinks, web root ownership, chown -R, Invalid compressed data in update file, web server user, apache, www-data, nginx, directory ownership fix, update fails, RRD graphs, RRD error, Round Robin Database, hardware upgrade, No DS called, delete RRD files, systemctl stop voipmonitor, upgrade issues, web portal inaccessible, restart httpd, restart apache2, restart php-fpm, systemctl restart, IonCube, SELinux, AppArmor, PrivateTmp, temporary directory, permissions, open_basedir, blank screen, blank white screen, JavaScript errors, constants.php, PEAR, ReferenceError, setenforce, /dev/shm, dev shm, tmpfs, session logout, login failed, mount -o remount, fstab, session gc, session.gc_maxlifetime, session.gc_probability, php_sessions, apilicensecheck.php, findExecutableFile, patched file, license check API, Check License, undefined function, call to undefined function, PHP Fatal error, DO NOT reinstall, full reinstall not required, replace single file, backup original file, chown www-data:www-data, chmod 644, browser cache, clear cache, hard refresh, Ctrl+F5, Cmd+Shift+R, cookies, stale assets, GUI upgrade cache issues
'''Keywords:''' SIP register, registration monitoring, Active table, Failed table, State table, sip-register, sip-register-save-all, sip-register-state-timeout, sip-register-compare-sipcallerip, sip-register-compare-sipcallerport, sip-register-state-compare-digest_ua, User-Agent change, fraud detection, listregisters, Manager API, port 5029, cleandatabaseregister, register_state, distributed architecture, packetbuffer_sender


'''Key Questions:'''
'''Key Questions:'''
* How do I enable debug mode in the GUI to see SQL queries?
* How do I enable SIP registration monitoring in VoIPmonitor?
* IP lookup stopped working after GUI upgrade - what do I do?
* Where should I configure sip-register in a distributed architecture?
* Features stop working immediately after GUI upgrade - how do I fix it?
* How do I track the same SIP account registering from multiple locations?
* How do I clear browser cache and cookies after a GUI upgrade?
* How do I detect User-Agent changes for fraud detection?
* What is a hard refresh and how do I perform it (Ctrl+F5, Cmd+Shift+R)?
* How do I query active registrations via API?
* Why should I clear browser cache after upgrading the GUI?
* What indexes should I create for register_state performance?
* GUI features broken after upgrade but web server restart doesn't help - what now?
* Why do I see "Table doesn't exist" error for register table?
* Icons or styling appear wrong after GUI upgrade - how do I fix it?
* How do I configure data retention for registration data?
* Faxes cannot be displayed in the GUI - what do I do?
* What package do I need to install to view faxes in the GUI?
* How do I fix fax display errors in VoIPmonitor?
* Why are faxes not showing in my VoIPmonitor GUI?
* tiff2pdf command not found - how do I fix fax display?
* How do I verify tiff2pdf is accessible to the web server?
* What is the tiff2pdf utility used for in VoIPmonitor?
* How do I install libtiff-tools for fax display?
* GUI update fails with "Invalid compressed data in update file" - what do I do?
* The GUI reports an incorrect ownership error but web server user has permissions - what do I check?
* My MySQL database is corrupted, data loss is acceptable, and I need to restore service quickly - what do I do?
* What is the FASTEST way to restore service when MySQL database is corrupted?
* How do I quickly fix a corrupted voipmonitor database when MySQL is running?
* Should I use drop and recreate or innodb_force_recovery for database corruption?
* When should I use DROP DATABASE vs innodb_force_recovery?
* What is the simplest way to restore service when the voipmonitor database is corrupted?
* How do I use the sensor to auto-create a fresh database?
* What should I do if the MySQL/MariaDB database is corrupted but the service is running?
* How do I use mysqlcheck --repair to fix corrupted tables?
* What is the table-level repair method for database corruption?
* How do I use REPAIR TABLE to fix InnoDB corruption?
* How do I trim large tables to free disk space?
* How do I upgrade MySQL server after database corruption?
* What are the MySQL error log indicators for database corruption (semaphore waits, page corruption, InnoDB Assertion failure)?
* How do I fix a corrupted voipmonitor database when MySQL is running?
* How do I drop and recreate the voipmonitor database?
* How do I configure cleandatabase options to prevent future database corruption?
* What cleandatabase parameters should I set for automatic database cleanup?
* How do I prevent database corruption due to excessive data accumulation?
* How do I stop sensors and restart them to recreate the database?
* What is the DROP DATABASE command for corrupted voipmonitor database?
* How do I choose between drop/recreate and innodb_force_recovery for database corruption?
* How do I fix incorrect ownership errors related to the bin directory?
* What files need execute permissions in the GUI bin directory?
* How do I use chmod +x on GUI binaries like sox-x86_64?
* Why do GUI binaries need execute permissions?
* How do I verify that the web server user can execute binaries in the bin directory?
* What should I do if the MySQL/MariaDB database is corrupted after a filesystem issue?
* How do I choose between innodb_force_recovery and PCAP restore for database corruption?
* MySQL fails to start after filesystem crash with InnoDB assertion failures - which method should I use?
* How do I use innodb_force_recovery to recover MySQL from InnoDB corruption?
* What is the innodb_force_recovery parameter in MySQL?
* How do I back up and restore GUI configuration using backupGuiTables and restoreGuiTables?
* MySQL fails to start with InnoDB assertion failure - how do I fix it?
* How do I reinitialize MySQL data directory after corruption?
* How do I restore CDR data from PCAP files after database corruption?
* When should I use innodb_force_recovery versus PCAP restore for database corruption?
* RRD graphs show error "No DS called 'SQLq-SM'" after hardware upgrade - how do I fix it?
* How do I fix web portal inaccessible after GUI upgrade?
* Should I restart the web server after upgrading the GUI?
* What web server commands should I use after a GUI upgrade?
* How do I fix RRD graph errors appearing after system migration or CPU change?
* Can I delete RRD files and will voipmonitor recreate them automatically?
* Where are VoIPmonitor RRD files stored?
* How do I fix "Unable to create lock file" errors from IonCube Loader?
* How do I check if SELinux or AppArmor is blocking the GUI?
* What is systemd PrivateTmp and how does it affect the GUI?
* Why is my GUI showing a blank screen with JavaScript ReferenceError after an update?
* How do I fix ReferenceError: _AuditActivity_download_wav is not defined?
* My GUI shows a blank white screen after login without JavaScript errors - is this caused by SELinux?
* How do I disable SELinux to fix blank white screen in the GUI?
* What is the command to temporarily disable SELinux (setenforce 0)?
* How do I permanently disable SELinux in /etc/selinux/config?
* How do I check if SELinux is enabled with getenforce?
* My Check License API call fails with "Call to undefined function findExecutableFile()" - how do I fix it?
* Call to undefined function findExecutableFile in apilicensecheck.php - should I reinstall the entire GUI?
* How do I replace apilicensecheck.php with a patched file from support?
* What is the correct fix for apilicensecheck.php PHP Fatal error?
* How do I fix the apilicensecheck.php fatal error requiring a patched file?
* Users are being logged out and cannot login - /dev/shm is full - what do I do?
* How do I increase /dev/shm size?
* How do I permanently change /dev/shm size in /etc/fstab?
* How do I configure PHP to clean up old session files from /dev/shm?
* A Linux partition becomes read-only due to filesystem errors - how do I fix it?
* How do I run fsck to repair a read-only filesystem?
* What is the procedure for fixing a filesystem that is mounted read-only?
* How do I stop services before running fsck on a partition?
* How do I unmount a partition to run filesystem check?
* What fsck command do I use to repair a read-only partition?
* How do I check the filesystem type before running fsck?
* What should I do after running fsck on a corrupted filesystem?
* How do I verify the filesystem is healthy after running fsck?
* What is the correct order: fsck first or MySQL recovery first?

Latest revision as of 16:48, 8 January 2026


SIP Registration Monitoring

The Register section in VoIPmonitor GUI tracks SIP REGISTER transactions across three views: Active (current registrations), Failed (unsuccessful attempts), and State (historical changes). This feature is disabled by default.

Quick Start

Parameter Value Description
sip-register yes Enable registration tracking and DB storage
sip-register-save-all yes Save PCAP files for all registrations
sip-register-state-timeout 600 State snapshot interval (seconds)
# /etc/voipmonitor.conf - Basic setup
sip-register = yes

ℹ️ Note: When sip-register=no (default), the Active tab still works using real-time data from the sniffer process. The error "Table 'voipmonitor.register' doesn't exist" is expected in this mode.

Distributed Architecture

Configuration depends on your packetbuffer_sender setting:

Mode Where to Configure
packetbuffer_sender = yes Central server only
packetbuffer_sender = no Each remote sensor

GUI Views

Active Table

Displays currently registered SIP users:

  • Registration timestamp, username, realm
  • Source/destination IP addresses
  • SIP headers (From, To, Contact)
  • Expiration time and User-Agent
  • Sub-grids: state changes, failed attempts, related CDRs
  • PCAP download (if enabled)

Failed Table

Shows unsuccessful registration attempts:

  • Consecutive failures from the same device increment a counter (no duplicate rows)
  • New entry created after >1 hour gap between attempts
  • Red flag indicates failure status

State Table

Historical registration events (REGISTER, UNREGISTER, EXPIRE):

  • Periodic snapshots at sip-register-state-timeout interval (default 600s)
  • EXPIRE status: device missed renewal deadline by >5 seconds
  • Used for graphing registration trends

Advanced Configuration

Multiple Registration Tracking

Display separate entries when the same SIP account registers from different locations:

# Show each IP/port combination independently
sip-register-compare-sipcallerip = yes
sip-register-compare-sipcallerport = yes
sip-register-compare-sipcalledip = yes
sip-register-compare-sipcalledport = yes
sip-register-state-compare-from_domain = yes

User-Agent Change Detection

Track when a device's User-Agent changes (potential fraud indicator):

sip-register-state-compare-digest_ua = yes

⚠️ Warning: This setting detects UA changes but does NOT trigger GUI alerts. For alerting, use GUI > Alerts > Anti Fraud with "Change REGISTER Country Alert" or custom SQL queries.

API Access

Query active registrations programmatically via the Manager API.

Configuration

# /etc/voipmonitor.conf
manager_ip = 127.0.0.1
manager_port = 5029
# Alternative: Unix socket
# manager_socket = /tmp/vm_manager_socket

Query Examples

TCP with filter:

echo 'listregisters {"zip":"no","limit":30,"states":"OK","filter":{"digestusername":"user"},"sort_field":"calldate","sort_dir":"desc"}' | nc 127.0.0.1 5029

Unix socket:

echo 'listregisters' | nc -U /tmp/vm_manager_socket

GUI API (auto-detects connection method):

php /var/www/html/php/run.php send_manager_cmd -s NULL -c 'listregisters'

Key parameters: filter (digestusername, sipcallerip), limit, sort_field, sort_dir

Database Optimization

Create Indexes

For slow queries on large datasets:

CREATE INDEX digestusername ON register_state (digestusername);
CREATE INDEX digest_from_number ON register_state (digest_from_number);
CREATE INDEX digest_to_number ON register_state (digest_to_number);
CREATE INDEX digest_to_domain ON register_state (digest_to_domain);
CREATE INDEX digest_realm ON register_state (digest_realm);

Data Retention

Control storage with cleandatabaseregister parameter:

# /etc/voipmonitor.conf
cleandatabaseregister = 7  # Days to retain

Buffer Pool Sizing

For high-volume environments (30M+ records/day):

innodb_buffer_pool_size = daily partition size x retention days

Example: 15GB daily x 7 days = 105GB minimum

Troubleshooting

Symptom Solution
No registrations appear Verify packets: tcpdump -i eth0 port 5060
"Table doesn't exist" error Normal when sip-register=no; Active tab still works
Missing data with Napatech Check ip link show napa0 and libpcap path
Packet drops Check Settings > Sensors for drop counters

💡 Tip: Avoid large historical queries during peak traffic hours and partition maintenance windows (1:00-5:00 AM).

See Also

AI Summary for RAG

Summary: VoIPmonitor SIP Register monitoring tracks registration events in three GUI tables: Active (current registrations with real-time data even when DB storage disabled), Failed (unsuccessful attempts with counter deduplication), and State (historical REGISTER/UNREGISTER/EXPIRE events). Enable with sip-register=yes in voipmonitor.conf. In distributed architecture, configure on central server if packetbuffer_sender=yes, otherwise on each remote sensor. PCAP files require sip-register-save-all=yes. Advanced options include multi-registration tracking (sip-register-compare-* parameters) and User-Agent change detection (sip-register-state-compare-digest_ua=yes) for fraud detection. API access via Manager port 5029 with listregisters command. Database optimization requires indexes on register_state table and proper innodb_buffer_pool_size sizing.

Keywords: SIP register, registration monitoring, Active table, Failed table, State table, sip-register, sip-register-save-all, sip-register-state-timeout, sip-register-compare-sipcallerip, sip-register-compare-sipcallerport, sip-register-state-compare-digest_ua, User-Agent change, fraud detection, listregisters, Manager API, port 5029, cleandatabaseregister, register_state, distributed architecture, packetbuffer_sender

Key Questions:

  • How do I enable SIP registration monitoring in VoIPmonitor?
  • Where should I configure sip-register in a distributed architecture?
  • How do I track the same SIP account registering from multiple locations?
  • How do I detect User-Agent changes for fraud detection?
  • How do I query active registrations via API?
  • What indexes should I create for register_state performance?
  • Why do I see "Table doesn't exist" error for register table?
  • How do I configure data retention for registration data?