Sniffer configuration: Difference between revisions

From VoIPmonitor.org
(Add clarification about audio playback vs pre-generated files, explain saveaudio is independent and CPU intensive)
 
(102 intermediate revisions by 4 users not shown)
Line 1: Line 1:
Configuration file has only one section named [general] where all configuration directives belongs. List of directives will now follow with their description and recommendation values. Name in [ ] brackets is equivalent for command line which takes precendence over configuration file.
[[Category:Configuration]]
in case of running more voipmonitor instances on the same or another servers configured to save to one database and the same cdr table it is possible to differentiate CDR by id_sensor column. If you set id_sensor >= 0 the number will be saved in cdr.id_sensor column.
{{DISPLAYTITLE:Sniffer Configuration Reference (voipmonitor.conf)}}


= id_sensor =
'''Comprehensive reference for `/etc/voipmonitor.conf` parameters.''' Additional configuration snippets can be placed in `/etc/voipmonitor/conf.d/` (without `[general]` header).


This specifies on which interface will voipmonitor listen. It can listen on one interface or on all interfaces. To listen on all interfaces use interface = any
'''Related documentation:'''
The number is between 1 - 65535 (16bit number)
* [[Sniffer_installation|Installation Guide]] - Installing the sniffer
* [[Sniffer_distributed_architecture|Distributed Architecture]] - Client/server deployment
* [[Sniffer_troubleshooting|Troubleshooting]] - Common issues and solutions
* [[Scaling|Scaling Guide]] - Performance tuning for high traffic
* [[Data_Cleaning|Data Cleaning]] - Retention and cleanup configuration


id_sensor = 1
= General & Core Settings =


= interface =
== Sensor Identification & Time ==


listening interface. Can be 'any' which will listen on all interfaces - NOTE that "any" will not put intefaces into promiscuous mode and you have to do it with "ifconfig eth0 promisc". You can also sniff on multiple interfaces by providing list of them delimited by ',' example: interface = eth0,eth1
{| class="wikitable"
command line option is -i
! Parameter !! Default !! Description
#interface = eth0,eth1
|-
#interface = any
| <code>id_sensor</code> || unset || Unique numeric identifier (1-65535). '''Essential''' for multi-sensor deployments.
interface = eth0
|-
| <code>utc</code> || no || Store timestamps in UTC. '''Recommended''' for multi-timezone deployments.
|-
| <code>timezone</code> || system || Override system timezone with zoneinfo path (e.g., <code>/usr/share/zoneinfo/UTC</code>).
|}


= threading_mod =  
== Process Management ==
* default threading_mod = 1 uses one thread for reading from interface doing deduplication at once* threading_mod = 2 (which is automatically set if you have multiple interfaces (interface = eth0,eth1,...)) reads from each interface in separate thread which is better option on multi core systems than interface = any * threading_mod = 3 will do deduplication (if enabled) in separate thread which is needed for high traffic* threading_mod = 4 will do deduplication in more than one threads - use this option if you enable deduplication and your traffic is over 100Mbit
threading_mod = 1


{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>watchdog</code> || no || Auto-restart sensor on crash.
|-
| <code>watchdog_run_command</code> || unset || Custom restart command (e.g., <code>systemctl restart voipmonitor</code>).
|}


= mirror =
== Deprecated Options (v2025.09.1+) ==


since version 8 sniffer implements new mirroring option. Sender is packing data to compressed stream over the TCP to remote sniffer.  if you are going to use this sniffer only as a mirroring sniffer all you need is to set interface, packetbuffer_* set compression on and set packetbuffer_file_* so in case the connection to remote sniffer will die or will be temporarily slow the sender will not loose single packet. The mirroring is trying to reconnect in case of failure. Packets are mirrored including the the original timestamp and headers. this mirroring hopefully replaces pcapscandir feature which will be probably removed in favor of this approach.  
{{Warning|1=The following options are '''unsupported and ignored''' in sniffer version 2025.09.1+. Remove them from your configuration.}}


The sender needs to set only interface, ringbuffer, packetbuffer_*, filter and this two folling mirror_destination_*
{| class="wikitable"
mirror_destination_ip          =  
! Deprecated Option !! Modern Replacement
mirror_destination_port        =
|-
| <code>vxlan</code>, <code>vxlan_port</code>, <code>vxlan_skipcrc</code> || <code>udp_port_vxlan = 4789</code>
|-
| <code>packet_buffer_total_size</code> || <code>max_buffer_mem</code> (auto-managed)
|-
| <code>udp_reassembly</code>, <code>udp_reassembly_max_size</code> || <code>udpfrag = yes</code>
|-
| <code>sipdefrag</code>, <code>sipdefrag_maxpacket</code>, <code>defragment_*</code> || Auto-managed; use <code>max_sip_packets_in_call</code>
|-
| <code>max_sip_size</code>, <code>interface_snaplen</code> || <code>snaplen = 3200</code>
|-
| <code>sanity_checks</code>, <code>check_sip_header</code>, <code>ignore_sip_parsing_errors</code> || Built-in (cannot be disabled)
|}


On receiver set mirror_bind_ip and mirror_bind_port. Do not forget to set firewall so no other except the sender will be able to connect to the receiver
{{Tip|After removing deprecated options, check logs for warnings: <code>journalctl -u voipmonitor -f</code>}}


mirror_bind_ip              =  
= Database Configuration =
mirror_bind_port            =


= scanpcapdir =
== Connection Settings ==


{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>mysqlhost</code> || localhost || MySQL/MariaDB server address
|-
| <code>mysqlsocket</code> || unset || Socket path for local connections (faster than TCP)
|-
| <code>mysqlport</code> || 3306 || TCP port
|-
| <code>mysqlusername</code> || root || Database username
|-
| <code>mysqlpassword</code> || empty || Database password
|-
| <code>mysqldb</code> || voipmonitor || Database name (auto-created if missing)
|-
| <code>mysql_reconnect</code> || no || Auto-reconnect on connection loss
|}


scan pcap files folder and read file by file. This is in conjunction with running tcpdump which creates pcap file each 5 seconds (-G 5) storing pcap files named by UNIX_TIMESTAMP to /dev/shm/voipmonitor folder (do not forget create it) using 1GB ring buffer to avoid losing packets (-B500000 - you can lower it but not higher) filtering udp packets (udp parameter whcih you can change to your needs). voipmonitor then reads created files (and delete it after processing. This approach can be used for testing throughput or for very high voip traffic (>500Mbit). If the sniffer is able to process pcap files in realtime - there will be in /dev/shm/voipmonitor folder only one or two pcap files. If the sniffer is not able to process in realtime (blocking by I/O or by CPU) number of pcap files will grow faster then the sniffer is able process.
=== SSL/TLS for Database ===
<syntaxhighlight lang="ini">
mysqlsslkey = /etc/ssl/client-key.pem
mysqlsslcert = /etc/ssl/client-cert.pem
mysqlsslcacert = /etc/ssl/ca-cert.pem
</syntaxhighlight>


scanpcapdir = /dev/shm/voipmonitor
== Performance & Schema ==


WARNING: libpcap < 1.1 contains memory leak when pcap filter is set - do not set filter in this config or upgrade libpcap to the latest (debian 6 libpcap contains the leak) static compiled voipmonitor from voipmonitor.org contains the latest libpcap
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>query_cache</code> || yes || '''Critical:''' Queue SQL to disk (qoq* files) to prevent data loss during DB outages.
|-
| <code>quick_save_cdr</code> || no || CDR visibility delay: <code>no</code>=10s, <code>yes</code>=3s, <code>quick</code>=1s. Higher values increase load.
|-
| <code>cdr_partition</code> || yes || '''Essential:''' Daily table partitioning for performance.
|-
| <code>cdr_partition_by_hours</code> || no || Hourly partitions for extreme traffic (≥15k CPS).
|-
| <code>disable_partition_operations</code> || no || Disable auto partition management (for centralized DB).
|-
| <code>mysql_enable_set_id</code> || no || Central server generates CDR IDs (high-traffic client/server).
|}


tcpdump example command:
== Configuration Priority: File vs GUI ==
nice -n -20 tcpdump -B500000 -i eth2 udp -G 5 -w /dev/shm/voipmonitor 2>/dev/null 1>/dev/null &


= ringbuffer =
;<code>mysqlloadconfig = yes</code>
ringbuffer is circular memory queue directly in kernel memory space. libpcap is reading from this queue and delivers packets to voipmonitor. If the network rate is > 100 Mbit we recommend to set ringbuffer to at least 500. Maximum value is 2000 MB. ringbuffer = 50 [ --ring-buffer ]
:(Default: yes) Load settings from database (<code>sensor_config</code> table). '''GUI settings take priority over file settings.'''


= packetbuffer =
{{Warning|1=Setting <code>mysqlloadconfig = no</code> prevents loading the <code>manager_key</code> from the database, causing "failed read rsa key" startup errors in distributed deployments.}}
packet buffer is new voipmonitor buffering architecture (since version 8). If enabled new threads are created which raads packets from kernel ringbuffer and queues them into dynamically allocated memory. Packets are dequeued and passed to next threads which reads the content. This will ensure that kernel ringbuffer will not overrun due to CPU or disk I/O spikes.
packet buffer will dynamically grow until packetbuffer_total_maxheap is reached. Compression can be enabled (packetbuffer_compress) which compress the buffer with fast snappy algorythm with 50% compression ratio thus doubling the time when the buffer gets filled (600Mbit traffic consumes ~30% one one core Xeon E5-2620).


It is also possible to use disk buffer if the packet buffer memory is filled by enabling packetbuffer_file_totalmaxsize which is usefull when sniffer is only mirroring data over TCP to another sniffer - if the connection brakes or slowed down and packet buffer gets filled it will start using file buffer until the connection reestablishes so no single packet is lost. Enabling file buffer in non mirroring mode to the same disk as spooldir will get not much benefit because if the process is blocked mainly due to disk I/O it has no benefit to add more I/O by caching unprocessed packets to the same I/O layer.
'''Diagnosing conflicts:'''
<syntaxhighlight lang="bash">
systemctl restart voipmonitor
grep 'Configuration valu' /var/log/syslog | grep ' / '
</syntaxhighlight>


packetbuffer_enable            = yes
'''Resolution options:'''
packetbuffer_total_maxheap      = 2000 #in MB 
* '''Option 1:''' Update settings via GUI (recommended)
packetbuffer_compress          = no #enable compression if you have >2 CPU cores 
* '''Option 2:''' Set <code>mysqlloadconfig = no</code> for file-only management
packetbuffer_file_totalmaxsize  = 0 #MB. Default is disabled. 
* '''Option 3:''' Delete specific entries from <code>sensor_config</code> table
packetbuffer_file_path          = /var/spool/voipmonitor/packetbuffer


= rtpthreads =
== SQL Queue Tuning ==


number of threads to process RTP packets. If not specified it will be number of available CPUs - 1. If equal to zero RTP threading is turned off. Each thread allocates default 20MB for buffers (increase to 100 on very high loads). This buffer can be controlled with rtpthread-buffer. For < 150 concurrent calls you can turn it off.
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>mysqlstore_concat_limit</code> || 400 || SQL statements per batch
|-
| <code>mysqlstore_max_threads_cdr</code> || 2 || Max parallel CDR write threads
|}


rtpthreads = 3
== Database Cleaning ==


= natalias =
See [[Data_Cleaning]] for detailed documentation.


in case the SIP(media) server is behind public IP (1.1.1.1) NATed to private IP (10.0.0.3) to sniff all traffic correctly you can specify alias for this case. You can specify more netaliases duplicating rows. In most cases this is not necessary because voipmonitor is able to track both RTP streams based on the other side IP. But if the stream is incoming from another IP then SIP source signalization and also from another IP than the SIP device which is also behind NAT its impossible to track the correct IP. Please note that this is for case where the SIP server is behind NAT and also the client is behind NAT. If your SIP server has public IP do not bother with this.
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>cleandatabase</code> || 0 || Master retention period in days (0=disabled)
|-
| <code>cleandatabase_cdr</code> || 0 || CDR/message table retention
|-
| <code>cleandatabase_rtp_stat</code> || 2 || RTP statistics retention
|-
| <code>partition_operations_enable_fromto</code> || 1-5 || Partition drop time window (e.g., 1-5 AM)
|}


natalias = 1.1.1.1 10.0.0.3
== CDR Summary (Aggregation) ==
natalias = 1.1.1.2 10.0.0.4


Pre-aggregates call data for faster dashboard queries.


= managerip =
<syntaxhighlight lang="ini">
cdr_summary = yes
cdr_summary_interval = 5  # minutes
</syntaxhighlight>


define bind address for manager interface. Default is 127.0.0.1 it is not recommended to change this unless really needed due to security. If you need it on some other IP make sure you set firewall and change the standard port for better security
= Network Interface & Sniffing =


managerip = 127.0.0.1
== Interface Selection ==


= managerport =  
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>interface</code> || eth0 || Interface(s) to capture. Comma-separated for multiple. <code>any</code> = all (no promisc).
|-
| <code>promisc</code> || yes || Promiscuous mode (doesn't work with <code>any</code>).
|-
| <code>interfaces_optimize</code> || yes || Auto-tune NIC settings via ethtool.
|-
| <code>snaplen</code> || 3200 || Packet capture length. Increase for large SIP packets.
|}


This specifies TCP port which will voipmonitor listen for incoming connections which controls voipmonitor or for getting information about calls. *reload configuration echo reload | nc localhost 5029 *get number of calls echo totalcalls | nc localhost 5029 *get list of calls in json format echo listcalls | nc localhost 5029 
== BPF Filtering ==


managerport = 5029 [ --manager-port <port number> ]
;<code>filter</code>
:BPF filter (tcpdump syntax). '''Warning:''' Can accidentally exclude important traffic.
<syntaxhighlight lang="ini">
# Example: Exclude specific subnets
filter = not net 192.168.0.0/16 and not net 10.0.0.0/8
</syntaxhighlight>


= managerclient =  
;<code>interface_ip_filter</code>
:CPU-efficient IP allow-list (no negation). Multiple lines supported.
<syntaxhighlight lang="ini">
interface_ip_filter = 192.168.0.0/24
interface_ip_filter = 10.0.0.0/8
</syntaxhighlight>


connects to server and listen for commands.
== Shared Server Optimization ==


managerclient = serverip or hostname
When the sniffer runs on the same server as the PBX, resource contention can cause voice breakage.
managerclientport = 1234


= sipport =
'''Symptoms:''' Audio jitter, packet loss, call lag that resolves when sniffer is stopped.


define SIP ports wihch will voipmonitor listen. For each port make new line with sipport = port (multiple lines)
'''Solutions:'''
<syntaxhighlight lang="ini">
# Solution 1: Specify interfaces (creates dedicated threads)
interface = ens192,ens224  # NOT 'any'


sipport = 5060
# Solution 2: Disable NIC optimization
sipport = 5061 sipport = 5062
interfaces_optimize = no


= rtptimeout =
# Solution 3: Reduce sniffer load
savertp = header
saveaudio = no
</syntaxhighlight>


rtptimeout is important value which specifies how much seconds from the last SIP packet or RTP packet is call closed and writen to database. It means that if you need to monitor ONLY SIP you have to set this to at leat 2 hours = 7200 assuming your calls is not longer than 2 hours. Take in mind that seting this to very large value will cause to keep call in memory in case the call lost BYE and can consume all memory and slows down the sniffer - so do not set it to very high numbers. Default is 300 seconds.  
'''Long-term:''' Move sensor to dedicated server with SPAN/Mirror. See [[Sniffer_distributed_architecture]].


rtptimeout = 300
== Packet Deduplication ==


= jitterbuffer =
Required when receiving same packets from multiple sources/interfaces.


By default voipmonitor uses three types of jitterbuffer simulators to compute MOS score. First variant is saved into cdr.[ab]_f1 and represents MOS score for devices which has only fixed 50ms jitterbuffer. Second variant is same as first but for fixed 200ms and is saved to cdr.[ab]_f2 Third varinat is adaptive jitterbuffer simulator up to 500ms Jitterbuffer simulator is the most CPU intensive task which is voipmonitor doing. If you are hitting CPU 100% turn off some of the jitterbuffer simulator. Recommended for higher loads is to use only fixed 200ms (f1)
<syntaxhighlight lang="ini">
deduplicate = yes
auto_enable_use_blocks = yes # Required for deduplication
deduplicate_ipheader = ip_only # Recommended for different network paths
</syntaxhighlight>


jitterbuffer_f1 = yes
{| class="wikitable"
jitterbuffer_f2 = yes
! Parameter !! Default !! Description
jitterbuffer_adapt = yes
|-
| <code>deduplicate</code> || no || Enable checksum-based deduplication (CPU intensive)
|-
| <code>auto_enable_use_blocks</code> || no || '''Required''' for deduplication and correct RTP association across interfaces/VLANs
|-
| <code>deduplicate_ipheader</code> || yes || <code>ip_only</code> recommended when packets have different TTL
|}


= callslimit =  
== Tunneling Protocol Support ==


callslimit will limit maximum numbers of calls processed by voipmonitor at the same time. If calls are over limit it will be ignored (INVITE)  
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>udp_port_tzsp</code> || 37008 || Mikrotik TZSP
|-
| <code>udp_port_l2tp</code> || 1701 || L2TP tunneling
|-
| <code>udp_port_vxlan</code> || 4789 || VXLAN (AWS/cloud)
|-
| <code>audiocodes</code> || no || AudioCodes proprietary tunnel. See [[Audiocodes_tunneling]].
|-
| <code>ipfix</code> || no || Oracle/ACME SBC IPFIX
|-
| <code>hep</code> || no || Homer Encapsulation Protocol
|}


callslimit = 0
== Scan PCAP Directory Mode ==


= cdrproxy =
Process PCAP files instead of live capture. Useful for Windows hosts without SPAN ports.
in case SIP session travels accross several proxies (and Call-ID header DOES not change) and you would like to track all sip proxies and make them searchable in GUI / database. If disabled cdr will store to destination sip column destination IP from the first INVITE. If enabled there will be destination IP from the latest invite and all proxy ip will be stored in cdr_proxy table.  


default = yes
<syntaxhighlight lang="ini">
scanpcapdir = /var/spool/voipmonitor/scanpcap
scanpcapmethod = newfile
</syntaxhighlight>


cdrproxy = yes
'''Workflow:'''
# Capture on source: <code>tcpdump -i eth0 udp -G 300 -w /path/dump.pcap</code>
# Transfer to VoIPmonitor server
# Sensor processes files automatically


= cdr_ua_enable=  
= SIP Configuration =
this option allows to skip storing cdr.a_ua and cdr.b_ua - this is workaround for those who has extreme cdr rate and number of user agents in database is over 1000 and CPU is not powerfull enough to store cdr in real time. In future this option will be removed once we optimize this rutine.
default = yes


cdr_ua_enable = yes
== Port Settings ==


= rtp-firstleg =
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>sipport</code> || 5060 || SIP ports. Multiple: <code>5060,5061,5070-5080</code>
|-
| <code>cdr_sipport</code> || yes || Store SIP ports in database
|-
| <code>cdr_country_code</code> || yes || Country code lookup for caller/called. Set <code>no</code> to disable country flags.
|}


this is important option if voipmonitor is sniffing on SIP proxy like kamailio or openser and sees both RTP leg of CALL. In that case use this option. It will analyze RTP only for the first LEG and not each 4 RTP streams which will confuse voipmonitor. Drawback of this switch is that voipmonitor will analyze SDP only for SIP packets which have the same IP and port of the first INVITE source IP and port. It means it will not work in case where phone sends INVITE from a.b.c.d:1024 and SIP proxy replies to a.b.c.d:5060.
== TCP Reassembly & UDP Fragmentation ==


rtp-firstleg = no [ --rtp-firstleg ]
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>sip_tcp_reassembly_ext</code> || yes || TCP reassembly for SIP over TCP
|-
| <code>udpfrag</code> || yes || '''Critical:''' IP fragment reassembly for large SIP messages
|-
| <code>max_sip_packets_in_call</code> || 2000 || Maximum SIP packets per call
|}


= allow-zerossrc =
= TLS/SSL & SRTP Decryption =


* since 8.0.2
== SIP TLS Decryption ==
* default = no


SSRC in RTP headers must not equal zero according to RFC so voipmonitor is ignoring such RTP by default. If you still need to parse such packets enable it
<syntaxhighlight lang="ini">
ssl = yes
ssl_ipport = 10.0.0.1:5061 /path/to/your.key
# Subnet with multiple keys:
ssl_ipport = 10.0.0.0/24:5061 /path/key1.pem,/path/key2.pem
</syntaxhighlight>


allow-zerossrc = yes
'''Keylogger support (for PFS/TLS 1.3):'''
<syntaxhighlight lang="ini">
ssl_sessionkey_udp = yes
ssl_sessionkey_udp_port = 1234
</syntaxhighlight>


= deduplicate =
See [[Tls]] for complete TLS decryption documentation.


duplicate check do md5 sum for each packet and if md5 is same as previous packet it will discard it. WARNING: md5 is expensive function (slows voipmonitor 3 times) so use it only if you have enough CPU or for pcap conversion only. Default is no.
== SRTP Configuration ==


deduplicate = yes
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>srtp_rtp</code> || no || Decrypt and store RTP data in PCAPs
|-
| <code>srtp_rtcp</code> || yes || Decrypt RTCP streams
|-
| <code>srtp_rtp_dtls</code> || yes || DTLS decryption (requires keylogger)
|-
| <code>ssl_dtls_boost</code> || no || '''Meta-parameter''' enabling aggressive DTLS decryption options
|}


= deduplicate_ipheader =  
= Caller/Called Identity =


*since 8.1
{| class="wikitable"
prior verison 8.0.1 deduplicate was comparing only data without ip header and udp header so duplicate packets was matched also in case the IP addresses differes. This was good for some cases but it leads to completely ignore RTP streams in other cases. Now default option is to check duplicates based on not only data but ip headers too. To change this set deduplicate_ipheader = no. default = yes.
! Parameter !! Default !! Description
deduplicate_ipheader = yes
|-
| <code>remoteparty_caller</code> || unset || Update caller from Remote-Party-ID (<code>calling</code>/<code>called</code>)
|-
| <code>passertedidentity</code> || no || Use P-Asserted-Identity for caller
|-
| <code>destination_number_mode</code> || 1 || Source for called number: <code>1</code>=To header, <code>2</code>=INVITE URI
|-
| <code>sipoverlap</code> || yes || Update destination from subsequent INVITEs (overlap dialing)
|}


= sipoverlap =  
= Performance & Threading =


enable/disable updating called number from To: header from each caller INVITE. Default is enabled so it supports overlap dialing (RFC 3578)if you want to disable this behaviour and see always number only from the first INVITE set sipoverlap = no
== Core Threading ==


sipoverlap = yes
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>t2_boost</code> || unset || Set to <code>high_traffic</code> for ≥1500Mbit. Fixes CPU bottlenecks where single defrag thread runs at 100%.
|-
| <code>threading_expanded</code> || yes || Modern multi-threaded engine. Set <code>high_traffic</code> for >5 Gbit/s.
|-
| <code>preprocess_rtp_threads</code> || 2 || Initial RTP preprocessing threads (auto-scales)
|-
| <code>rtpthreads</code> || CPU count || RTP processing threads
|}


== Buffer Configuration ==


= sip-register =
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>ringbuffer</code> || 50 || Ringbuffer size MB. ≥500 recommended for >100 Mbit. Max 2000.
|-
| <code>max_buffer_mem</code> || 2000 || Max buffer memory MB. Increase to 10000+ for high concurrent calls.
|-
| <code>packetbuffer_compress</code> || no || Enable in distributed setups to reduce bandwidth.
|}


== Thread Priority ==


Enable parsing of SIP REGISTER message. SQL register table stores active SIP registrations. Once it expires it is removed from the table to new sql register_state table. The register state table is used to store changes in registrations. SQL table register_failed is used to store all failed sip register. To not overload this table there is counter column which adds +1 for each failed register from the same source.
<syntaxhighlight lang="ini">
sched_pol_auto = prio -20  # Auto-elevate critical threads under load
sched_pol_auto_cpu_limit = 45  # CPU threshold for elevation
</syntaxhighlight>


sip-register = no [ -R ]
= Distributed Operation =


= sip-register-active-nologbin =
See [[Sniffer_distributed_architecture]] for complete documentation.
if mysql binlog is enabled, skip binlog inserts into active table (which is MEMORY type) if you still want to replicate this too (huge I/O impact) set it to = no sip-register-active-nologbin = yes


= nocdr =
<kroki lang="mermaid">
%%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 40}}}%%
flowchart LR
    subgraph "Local Processing (packetbuffer_sender=no)"
        A1[Remote Sensor] -->|"Analyzes locally"| A2[CDR + Stats]
        A2 -->|"Sends CDRs"| A3[Central Server]
        A1 -->|"Stores PCAP"| A4[(Local Disk)]
    end
    subgraph "Packet Mirroring (packetbuffer_sender=yes)"
        B1[Remote Sensor] -->|"Forwards packets"| B2[Central Server]
        B2 -->|"Analyzes & stores"| B3[(Central Disk)]
    end
</kroki>


if yes, voipmonitor will not save CDR to MySQL
== Client/Server Configuration ==


nocdr = no [ -c ]
'''Central Server:'''
<syntaxhighlight lang="ini">
server_bind = 0.0.0.0
server_bind_port = 60024
server_password = yourpassword
# CRITICAL: Exclude server port from sipport!
sipport = 1-60023,60025-65535
</syntaxhighlight>


'''Remote Sensor:'''
<syntaxhighlight lang="ini">
id_sensor = 2
server_destination = 10.0.0.1
server_destination_port = 60024
server_password = yourpassword
packetbuffer_sender = no  # or yes for packet mirroring
</syntaxhighlight>


= savesip =
{{Warning|1=When <code>packetbuffer_sender = yes</code>, '''all packets including RTP are transmitted''' regardless of <code>savertp</code> setting.}}


Store SIP packets to pcap file.
= Storage & File Management =


savesip = [ --sip-register ]
== Spool Directory ==
= savertp =
save RTP packets to pcap file. savertp = yes automatically saves RTCP packets you can also save only RTP header without AUDIO: savertp = header if save RTP is aneblad it will also save UDPTL packets (used for T.38)  you can also set savertp = no and control what calls will record RTP in mysql table filter_ip or filter_tel which is controled in GUI -> Capture rules. Sending reload command will reload configuration from filter_* table. You can also set savertp = yes but denies recording RTP based on rules in filter_* table.


savertp = yes | header [ -R ]
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>spooldir</code> || /var/spool/voipmonitor || Primary storage directory
|-
| <code>spooldir_2</code> || unset || Secondary storage for capture rules with "Store to second spooldir"
|-
| <code>cachedir</code> || unset || Temp storage (use RAM/SSD for performance)
|}


= pcapsplit =
{{Note|1=For GUI access to <code>spooldir_2</code>, configure "Sniffer second datapath" in GUI Settings > System Configuration > Basic.}}


voipmonitor by default splits SIP and RTP packets to individual files (in case spooldiroldschema = no) which are located in SIP and RTP directories. This feature allows instance cleaning RTP streams differently then SIP packets to join two pcap files SIP+RTP use mergecap command line utility which is included in wireshark package default = yes | spooldiroldschema must be set to no
== TAR Storage Strategy ==
pcapsplit = yes
= savertcp =


Store RTCP packets to pcap file.
<syntaxhighlight lang="ini">
tar = yes  # Group PCAPs into minute-based archives (reduces I/O)
tar_compress_sip = zstd
tar_compress_graph = zstd
</syntaxhighlight>


savertcp = yes [ --save-rtcp ]
== Saving Options ==
= saveudptl =


save UDPTL packets (T.38). If savertp = yes the udptl packets are saved automatically. If savertp = no and you want to save only udptl packets enable saveudptl = yes and savertp = no
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>savesip</code> || yes || Save SIP packets
|-
| <code>savertp</code> || yes || <code>yes</code>=full, <code>header</code>=metadata only (no audio), <code>no</code>=disabled
|-
| <code>savertp_video</code> || no || Video RTP. '''Limitation:''' Only ONE video stream per call saved to PCAP.
|-
| <code>saveudptl</code> || no || T.38 fax packets
|-
| <code>savegraph</code> || yes || Call graph data
|}


  saveudptl = yes
'''Disable audio recording:'''
<syntaxhighlight lang="ini">
savertp = header # NOT 'no' - keeps RTP analysis tool working
saveaudio = no
</syntaxhighlight>


= savegraph =
== Spool Cleaning ==
This is usefull only if you have commercial WEB GUI which uses graph files for ploting graph


savegraph = plain [ -G or --save-graph=[gzip|plain] ]
{| class="wikitable"
= saveaudio =
! Parameter !! Default !! Description
save RTP payload to audio file. Choose 'wav' for WAV PCM or 'ogg' for OGG 25kbps format. please note that this has great impact on I/O and can overload your storage leading to lose packets. Better way is to store only sip+rtp and convert wav files on demand.
|-
saveaudio = wav
| <code>cleanspool</code> || yes || Enable automatic spool cleaning
|-
| <code>maxpoolsize</code> || 102400 || Size limit in MB
|-
| <code>maxpooldays</code> || unset || Age limit in days
|-
| <code>autocleanspoolminpercent</code> || 1 || Emergency cleaning trigger (% free)
|}


= convert_dlt_sll2en10 =
== Audio File Generation ==


*since 8.0.2
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>saveaudio</code> || no || Generate audio files: <code>wav</code>, <code>ogg</code>, <code>mp3</code>, or <code>yes</code>
|-
| <code>saveaudio_singlefolder</code> || unset || Dedicated directory for audio files
|-
| <code>saveaudio_stereo</code> || yes || Caller=left, called=right channel
|}
=== Understanding Audio Playback vs Pre-Generated Files ===


in case you need to have ethernet encapsulation and you are sniffing on interface = any set this to = yes. this is needed only in case you need to merge pcap files with different encapsulations. default is no.
VoIPmonitor provides '''two independent methods''' for audio playback:


convert_dlt_sll2en10 = no
{| class="wikitable"
! Method !! How it works !! Requirements !! Use Case
|-
| '''On-demand extraction''' (default) || GUI extracts audio from stored RTP packets in PCAP files || <code>savesip = yes</code>, <code>savertp = yes</code> || Standard operation - recommended
|-
| '''Pre-generated files''' || Sniffer creates .wav/.ogg/.mp3 files immediately during call processing || <code>saveaudio = wav</code> (or ogg/mp3) || Special requirements only
|}


= keycheck =
{{Note|1=The <code>saveaudio</code> option is '''NOT required''' for audio playback in the GUI. The GUI can extract audio on-demand from stored PCAP files whenever <code>savertp = yes</code>.}}
default path to WEB GUI used to construct path to key check for codecs
default paths: #keycheck = /var/www/voipmonitor/php/keycheck.php #keycheck = /var/www/html/voipmonitor/php/keycheck.php


= saverfc2833 =
'''Important considerations for <code>saveaudio</code>:'''
* '''CPU/IO intensive''' - Pre-generating audio files for every call significantly increases system load
* '''Independent option''' - Works regardless of <code>savertp</code>/<code>savesip</code> settings
* '''Storage overhead''' - Creates additional audio files beyond the PCAP storage
* '''Use sparingly''' - Only enable when you have specific requirements (e.g., external systems that need direct audio file access)


in case you are not saving RTP at all but you still want to save DTMF carried over RTP packets (RFC2833) you can enable this option. This feature slows down a bit processing RTP packets in main read thread in casse voipmonitor runs in threads. default = 0
'''To disable audio recording while keeping quality metrics:'''
<syntaxhighlight lang="ini">
savertp = header  # Saves RTP headers only - keeps MOS/jitter/packet loss metrics
# saveaudio is 'no' by default - audio cannot be played/extracted
</syntaxhighlight>


saverfc2833 = 0
'''To keep full audio capability (default):'''
<syntaxhighlight lang="ini">
savertp = yes      # Full RTP packets stored
# saveaudio is 'no' by default - GUI extracts audio on-demand from PCAP
</syntaxhighlight>
= Call Processing =


= dtmf2db =
== Timeouts ==
Enable storing DTMF (SIP INFO or RFC2833) to cdr_dtmf database. It will store DTMF time and key then it will be shown in SIP history in the GUI
dtmf2db = 0
= norecord-header =
if any of SIP message during the call contains header X-VoipMonitor-norecord call will be not converted to wav and pcap file will be deleted.
norecord-header = yes
= norecord-dtmf =if any of SIP message during the call contains DTMF INFO sequence "*0" call will be not converted to wav and pcap file will be deleted. default: disabled
norecord-dtmf = yes
= pauserecordingdtmf =
enable pausing RTP/WAV recording if DTMF sequence detected. default: disabled
pauserecordingdtmf = *9
= dumpallpackets =
dump all packets to /tmp/voipmonitor-[UNIX_TIMESTAMP].pcap
dumpallpackets = yes


= mos_g729 =
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>absolute_timeout</code> || 14400 || Force-end calls longer than this (seconds). Sets <code>cdr.bye = 102</code>.
|-
| <code>rtptimeout</code> || 300 || Close call if no RTP/RTCP for this duration
|-
| <code>sipwithoutrtptimeout</code> || 3600 || Close SIP call without RTP
|-
| <code>onewaytimeout</code> || 15 || End call if no reply from other side
|}


enable MOS score for G.729 codec. If enabled, all cdr with 0 packet loss and stable delays will have maximum MOS of 3.92 and for loss and unstable delay MOS will be calculated according to ITU-T objective PESQ method for G.729 codec. if you want to use MOS as good search value which corellates loss and delay into single value leave it disabled (which is by default). If set to no, all calls will be calculated like it is G.711. Recommended value = no
== Call Merging ==


mos_g729 = no
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>matchheader</code> || unset || SIP header to link call legs in GUI
|-
| <code>callidmerge_header</code> || unset || Header containing parent Call-ID for CDR merging
|-
| <code>call_id_alternative</code> || unset || Alternative identifiers (e.g., <code>Session-ID,Join</code> for CUCM)
|}


= custom_headers =
See [[Merging_or_correlating_multiple_call_legs]] for detailed documentation.


Since 7.0RC7.
== Recording Control ==


enable storing custom sip headers to database column cdr_next.custom_header_headername. You can specify more headers delimited by ";".  
{| class="wikitable"
WARNING - when you enable this feature voipmonitor will autoupgrade cdr_next table which can take hours depending on how large the table is. In GUI there is new section [[Settings#CDR_Custom_header]].
! Parameter !! Default !! Description
|-
| <code>pauserecordingdtmf</code> || unset || DTMF sequence to pause recording (e.g., <code>*9</code>)
|-
| <code>pauserecordingdtmf_timeout</code> || 4 || Timeout between DTMF digits (seconds)
|-
| <code>norecord-dtmf</code> || no || Delete recording if <code>*0</code> is detected
|-
| <code>norecord-header</code> || no || Discard call if <code>X-VoipMonitor-norecord</code> header present
|}


custom_headers = X-asterisk-Info ; X-myheader
== Custom Headers ==


analogical for SIP message is custom_headers_message
<syntaxhighlight lang="ini">
custom_headers_message = X-asterisk-Info ; X-myheader
custom_headers = Referred-By, Diversion, X-Custom-Header
custom_headers_last_value = yes
custom_headers_max_size = 1024
</syntaxhighlight>


= match_header =
After adding headers, configure display in GUI: '''Settings > CDR Custom Headers'''.


enable saving content of custom header (typicaly in-reply-to) to cdr_next.match_header this header is used in related CDR GUI for matching legs to onen call
== SIP History ==


match_header = in-reply-to
;<code>save_sip_history</code>
= pcapcommand =
:(Default: no) Store SIP signaling for GUI filtering.
* <code>requests</code> - All SIP methods (PUBLISH, INFO, UPDATE, PRACK, REFER) in "SIP requests" filter
* <code>responses</code> - Full response text for searching (not just codes)
* <code>all</code> - Both requests and responses


pcapcommand will run command after pcap file is closed (after call ends). %pcap% is substitution for real pcap file name. execution is guaranteed to run in serialized way (not in parallel)WARNING - pcapcommand is implemented by forking program which is very expensive and is causing TLB shootouts on multicore system which can generate 500 000 interrupts / sec causing system to drop packets. Watch the performance carefuly (with "vmstat 1" column "in"). Gziping pcap files will be implemented as native function directly in C++ to obey TLB shootdowns.  
{{Warning|1=Enabling SIP history significantly increases database load and storage.}}


pcapcommand = gzip %pcap%


= filtercommand =


=== GUI Filters for SIP Response Searching ===


*since 8.3
There are two distinct SIP response filters in the CDR view. Understanding their differences prevents confusion:


{| class="wikitable"
! Filter !! What it searches !! Accepts !! Requires Configuration
|-
| '''Last SIP Response Code''' || Final response code in <code>cdr.lastSIPresponse</code> || Numeric codes (<code>404</code>, <code>503</code>), wildcards (<code>4%</code>, <code>5%</code>), '''and text''' (<code>%OK</code>, <code>%Busy%</code>) || '''None''' - always available
|-
| '''SIP responses''' || Full text of ALL SIP responses during the call || Full text search, any string || <code>save_sip_history = responses</code> or <code>save_sip_responses = yes</code>
|}


'''Key differences:'''


filtercommand will run command after each call which matches script == 1 in filter_ip or filter_telnum (capture rules in GUI)
* '''Last SIP Response Code''' searches only the '''final''' response. Examples:
WARNING - filtercommand is implemented by forking program which is very expensive and is causing TLB shootouts on multicore system which can generate 500 000 interrupts per seconds causing system to drop packets. Watch the performance carefuly (with "vmstat 1" column "in").
** <code>200</code> - exact numeric match
** <code>4%</code> - all 4xx errors
** <code>%OK</code> - responses ending with "OK"
** <code>%Busy%</code> - responses containing "Busy"


all non alphanum characters except '/' '#' ' ' '+' ':' '-' '.' and '@' in callid, dirname, caller, called and calldate are substituted to '_'
* '''SIP responses''' searches '''all''' SIP responses (180 Ringing, 183, provisional, etc.). Use for:
** Intermediate responses (e.g., 491 Request Pending mid-dialog)
** Custom SBC error messages
** Any response text, not just the final one


default is disabled
'''Example:''' A call completes with 200 OK but had a 503 from one provider during serial forking. "Last SIP Response Code = 503" won't find it, but "SIP responses = %503%" will.


filtercommand = myscript '%basename%' '%dirname%' '%caller%' '%called%' '%calldate%'
=== save_sip_history vs save_sip_responses ===


= filter =
These two parameters achieve the '''same result''' - storing SIP response text for the "SIP responses" filter. '''Do not enable both simultaneously''':


libpcap tcpdump style filter. Voipmonitor listens in default only for UDP packets. Unfortunatly filtering UDP packets will filter all VLAN tagged packets which means that you cannot filter only UDP if you want to listen to VLAN tagged packets.  
{| class="wikitable"
! Parameter !! Notes
|-
| <code>save_sip_history = responses</code> || Part of the multi-value <code>save_sip_history</code> option. Can combine with <code>requests</code> or use <code>all</code>.
|-
| <code>save_sip_responses = yes</code> || Standalone parameter for same functionality. Simpler if you only need response text.
|}
== RTP Processing ==


'''WARNING''' - if you need to sniff IPinIP (like mirrored packets from voipmonitor) filter = udp will filter all those packets. In this case just disable filter.
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>jitterbuffer_f1</code> || yes || 50ms fixed jitterbuffer simulation
|-
| <code>jitterbuffer_f2</code> || yes || 200ms fixed jitterbuffer simulation
|-
| <code>jitterbuffer_adapt</code> || yes || Adaptive jitterbuffer (up to 500ms)
|-
| <code>allow-zerossrc</code> || no || Accept RTP with zero SSRC (some legacy gateways)
|}


'''CPU optimization (saves ~30%):'''
<syntaxhighlight lang="ini">
mosf1 = no
mos_adapt = no
mosf2 = yes  # Keep only f2 for stable MOS metric
</syntaxhighlight>


filter = udp or (vlan and udp) [ -f ]
== Audio Analysis ==


= convertchar =
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>dtmf2db</code> || no || Store DTMF to database
|-
| <code>inbanddtmf</code> || no || In-band DTMF detection (G711 only, CPU intensive)
|-
| <code>silencedetect</code> || no || Silence detection (G711 only, CPU intensive)
|-
| <code>clippingdetect</code> || no || Audio clipping detection
|}


list characters that should be converted to underscore (_) in filenames if you want to include space, put it between other characters, like ': :' (will convert ':' and ' ' to '_') defaults to nore
See [[Silence_detection]] for detailed documentation.
# example - avoid ':' when Call-Id contains port number convertchar = :


= spooldir =
== NAT Handling ==


This is directory where all pcap/graph/wav files are stored.
<syntaxhighlight lang="ini">
natalias = 1.1.1.1 10.0.0.3  # Public to private IP mapping
sdp_reverse_ipport = no  # Reverse sniffing for NAT (use with caution)
</syntaxhighlight>


spooldir = /var/spool/voipmonitor [ -d ]
= Protocol Support =
= spooldiroldschema =
new spooldir schema stores all files to year-mon-day/hour/minute/[ALL|SIP|RTP|AUDIO] directories if you need to have the old schema year-mon-day/* enable spooldiroldschema = yes. default = no
spooldiroldschema = no


= cachedir =
== SIP REGISTER/OPTIONS/SUBSCRIBE ==
store pcap and graph file to <cache/dir> and move it after call ends to spool directory. Moving all files are guaranteed to be serialized which solves slow random write I/O on magnetic or other media. Typical cache directory is /dev/shm/voipmonitor which is in RAM and grows automatically or /mnt/ssd/voipmonitor which is mounted to SSD disk or some very fast SAS/SATA disk where spool can be network storage or raid5 etc. wav files are not implemented yet


cachedir = /dev/shm/voipmonitor
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>sip-register</code> || no || Process REGISTER messages (<code>yes</code>, <code>nodb</code>, <code>no</code>)
|-
| <code>sip-options</code> || no || Process OPTIONS messages
|-
| <code>sip-subscribe</code> || no || Process SUBSCRIBE messages
|-
| <code>sip-message</code> || yes || Process MESSAGE requests
|}


= cleandatabase =
See [[Register]] for detailed REGISTER documentation.


cleandatabase removes database partitions for tables cdr, cdr_next, cdr_rtp and cdr_dtmf older than X days. Cleandatabase parameter represents number of days - if you set 90 it will remove partition 90 days old. If the sniffer will not run for several days it will not clean partitions which was not cleaned even you start it. 
== Other Protocols ==


*default is disabled
{| class="wikitable"
*Added since 8.0RC6
! Parameter !! Default !! Description
|-
| <code>skinny</code> || no || Cisco Skinny/SCCP protocol
|-
| <code>mgcp</code> || no || MGCP protocol
|-
| <code>ss7</code> || no || SS7-over-IP (SIGTRAN)
|-
| <code>diameter</code> || no || Diameter protocol
|-
| <code>ipv6</code> || no || IPv6 support (requires IPv6 database columns)
|}


cleandatabase = 0 (disabled)
= Advanced Protocol Support =


== IPFIX Support ==


= cleanspool_interval =
IPFIX (IP Flow Information Export) is used with Oracle/ACME SBCs to receive call data.


'''IMPORTANT - PCAP Availability:''' IPFIX data is internally converted to packet format for processing. This means PCAP files CAN be downloaded from the GUI for IPFIX-sourced calls (SIP signaling is reconstructed). However, RTP streams are NOT included in the PCAP - only QoS metrics from the IPFIX data are available, not actual audio packets.


clean spool directory every two hours from oldest file until spooldir size = cleanspool_size (in MB)  WARNING - if you have milions files set cleanspool_interval to 24 hour (clean once per day)  cleaning is very slow and can overload I/O (in seconds). Default is disabled.
<syntaxhighlight lang="ini">
ipfix = yes
ipfix_bind_port = 12345
ipfix_qos_fill_rtp_streams = yes
# Include TLS port for SIPS/SRTP:
sipport = 5060,5061
</syntaxhighlight>


cleanspool_interval = 7200
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>ipfix</code> || no || Enable IPFIX receiver (Oracle/ACME SBC)
|-
| <code>ipfix_bind_ip</code> || 0.0.0.0 || Bind IP address for IPFIX listener
|-
| <code>ipfix_bind_port</code> || 4739 || UDP port for IPFIX data
|-
| <code>ipfix_qos_fill_rtp_streams</code> || no || Populate RTP stream statistics from IPFIX QoS data
|}


= cleanspool_size =
== SIPREC Support ==


<syntaxhighlight lang="ini">
siprec_bind = 0.0.0.0
siprec_bind_port = 5099
siprec_rtp_min = 10000
siprec_rtp_max = 20000
</syntaxhighlight>


set target size of the spool directory for cleaning script (in MB). Default is disabled.
== HEP Support ==


<syntaxhighlight lang="ini">
receiver_mode = yes  # Required!
hep = yes
hep_bind_port = 9060
hep_kamailio_protocol_id_fix = yes  # For Kamailio sources
</syntaxhighlight>


== Kamailio Mirroring ==


cleanspool_size = 50000
<syntaxhighlight lang="ini">
  #usefull command to clean all RTP files older 7 days # find /var/spool/voipmonitor -maxdepth 1 -type d -mtime +7 -name '20*' | (while read d; do rm -rf $d/*/*/RTP; done)
receiver_mode = yes # Required!
= promisc =
kamailio_port = 5888
</syntaxhighlight>


This option is only relevant if you are mirroring traffic to your network card/cards. This will not work if interface = any - in this case, use ifconfig to put your desired interfaces to promis mode. Default value is yes and you want to turn it of on command line ues -n which will turn it off.
== Ribbon SBC Mirroring ==


promisc = yes [ -n ]
<syntaxhighlight lang="ini">
ribbonsbc = yes
ribbonsbc_bind_ip = 0.0.0.0
ribbonsbc_bind_port = 9514
</syntaxhighlight>


= database =
== Whisper Transcription ==


== sqldriver ==
<syntaxhighlight lang="ini">
audio_transcribe = yes
whisper_native = no
whisper_model = /path/to/ggml-base.bin
whisper_language = auto
</syntaxhighlight>


sqldriver = mysql  #sqldriver = odbc #odbcdriver = mssql #odbsdsn = voipmonitor #odbcuser = root #odbcpass =
See [[Whisper]] for detailed transcription documentation.
voipmonitor can connect to mysql server or odbc driver. connecting voipmonitor to msssql please refer to README.mssql
{{Note|1='''Oracle/ACME SBC''' and '''Ribbon SBC''' are products from '''different vendors''' with different integration methods:
* '''Oracle SBC''' (formerly Acme Packet, acquired by Oracle in 2013) → uses '''IPFIX''' protocol
* '''Ribbon SBC''' (formed from GENBAND + Sonus Networks merger in 2017) → uses '''Monitoring Profile''' with proprietary <code>ribbonsbc</code> protocol
Do not confuse these - they require different VoIPmonitor configuration.}}
= Expert & Debugging Options =


== cdr_partition ==
{{Warning|1=Only change these if instructed by support or you are an expert.}}


use partitioning cdr* tables by day. If you have schema without partitioning, you MUST start with new database. default is = yes
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>callslimit</code> || 0 || Max concurrent calls (0=unlimited)
|-
| <code>skipdefault</code> || no || Ignore all calls unless capture rules match
|-
| <code>openfile_max</code> || 65535 || Maximum open files
|-
| <code>coredump_filter</code> || 0x7F || Memory segments in coredump
|}


cdr_partition = yes
== Traffic Dumper ==


== disable_partition_operations (since 8.4RC9) ==  
<syntaxhighlight lang="ini">
traffic_dumper_path = /var/spool/voipmonitor/traffic
traffic_dumper_filter_ip = 192.168.1.100, 10.0.0.0/8
traffic_dumper_filter_port = 5060, 5061, 10000-20000
</syntaxhighlight>


disable partition creation which runs every 12 hours. If you have multiple sensors storing to one database it is redundant to create partitions by all sensors. default = no
== DEPRECATED DO NOT USE ==
disable_partition_operations = yes


== mysqlhost ==
<!-- This is a placeholder for correct deprecated options section -->


mysql server, default is 127.0.0.1 (localhost). Command line option is -h


mysqlhost = 127.0.0.1


== mysqldb ==


mysql database, default is voipmonitor. Command line option is -b


mysqldb = voipmonitor


== mysqlusername ==
mysql username, default is root


mysqlusername = root


= AI Summary for RAG =


== mysqlpassword ==
'''Summary:''' Comprehensive reference for <code>voipmonitor.conf</code> covering: sensor identification, database configuration (MySQL settings, partitioning, <code>mysqlloadconfig</code> for GUI vs file priority), network interface settings (BPF filters, deduplication with <code>auto_enable_use_blocks</code>), tunneling protocols (VXLAN, TZSP, HEP, AudioCodes), TLS/SRTP decryption, distributed client/server architecture (<code>packetbuffer_sender</code>), storage management (TAR archives, spool cleaning), call processing (timeouts, merging, recording control), SIP history storage, audio analysis, and protocol support (IPFIX, SIPREC, HEP, Kamailio, Ribbon SBC, Whisper). Deprecated options in v2025.09.1+ include <code>vxlan</code>, <code>packet_buffer_total_size</code>, <code>udp_reassembly</code>, <code>sipdefrag</code>.


mysql password, default is no password
'''Keywords:''' voipmonitor.conf, sniffer configuration, id_sensor, mysqlloadconfig, manager_key, deduplicate, auto_enable_use_blocks, packetbuffer_sender, savertp, TLS decryption, SRTP, ssl_dtls_boost, distributed architecture, client-server, maxpoolsize, cleandatabase, custom_headers, save_sip_history, t2_boost, threading, scanpcapdir, deprecated options, IPFIX, SIPREC, HEP, Kamailio, Ribbon SBC, Whisper, pauserecordingdtmf


mysqlpassword =
'''Key Questions:'''
* What are the most important settings in voipmonitor.conf?
* How do I configure the database connection?
* Why does the sniffer fail with "failed read rsa key"?
* How do I set up distributed client/server architecture?
* What is the difference between packetbuffer_sender = yes and no?
* How do I enable packet deduplication?
* How do I decrypt TLS/SRTP traffic?
* How do I disable audio recording while keeping RTP analysis?
* How do I capture custom SIP headers?
* How do I configure IPFIX/SIPREC/HEP receivers?
* Which options were deprecated in v2025.09.1?
* How do I fix CPU bottlenecks with t2_boost?
* How do I process PCAP files with scanpcapdir?

Latest revision as of 11:21, 13 January 2026


Comprehensive reference for `/etc/voipmonitor.conf` parameters. Additional configuration snippets can be placed in `/etc/voipmonitor/conf.d/` (without `[general]` header).

Related documentation:

General & Core Settings

Sensor Identification & Time

Parameter Default Description
id_sensor unset Unique numeric identifier (1-65535). Essential for multi-sensor deployments.
utc no Store timestamps in UTC. Recommended for multi-timezone deployments.
timezone system Override system timezone with zoneinfo path (e.g., /usr/share/zoneinfo/UTC).

Process Management

Parameter Default Description
watchdog no Auto-restart sensor on crash.
watchdog_run_command unset Custom restart command (e.g., systemctl restart voipmonitor).

Deprecated Options (v2025.09.1+)

⚠️ Warning: The following options are unsupported and ignored in sniffer version 2025.09.1+. Remove them from your configuration.

Deprecated Option Modern Replacement
vxlan, vxlan_port, vxlan_skipcrc udp_port_vxlan = 4789
packet_buffer_total_size max_buffer_mem (auto-managed)
udp_reassembly, udp_reassembly_max_size udpfrag = yes
sipdefrag, sipdefrag_maxpacket, defragment_* Auto-managed; use max_sip_packets_in_call
max_sip_size, interface_snaplen snaplen = 3200
sanity_checks, check_sip_header, ignore_sip_parsing_errors Built-in (cannot be disabled)

💡 Tip: After removing deprecated options, check logs for warnings: journalctl -u voipmonitor -f

Database Configuration

Connection Settings

Parameter Default Description
mysqlhost localhost MySQL/MariaDB server address
mysqlsocket unset Socket path for local connections (faster than TCP)
mysqlport 3306 TCP port
mysqlusername root Database username
mysqlpassword empty Database password
mysqldb voipmonitor Database name (auto-created if missing)
mysql_reconnect no Auto-reconnect on connection loss

SSL/TLS for Database

mysqlsslkey = /etc/ssl/client-key.pem
mysqlsslcert = /etc/ssl/client-cert.pem
mysqlsslcacert = /etc/ssl/ca-cert.pem

Performance & Schema

Parameter Default Description
query_cache yes Critical: Queue SQL to disk (qoq* files) to prevent data loss during DB outages.
quick_save_cdr no CDR visibility delay: no=10s, yes=3s, quick=1s. Higher values increase load.
cdr_partition yes Essential: Daily table partitioning for performance.
cdr_partition_by_hours no Hourly partitions for extreme traffic (≥15k CPS).
disable_partition_operations no Disable auto partition management (for centralized DB).
mysql_enable_set_id no Central server generates CDR IDs (high-traffic client/server).

Configuration Priority: File vs GUI

mysqlloadconfig = yes
(Default: yes) Load settings from database (sensor_config table). GUI settings take priority over file settings.

⚠️ Warning: Setting mysqlloadconfig = no prevents loading the manager_key from the database, causing "failed read rsa key" startup errors in distributed deployments.

Diagnosing conflicts:

systemctl restart voipmonitor
grep 'Configuration valu' /var/log/syslog | grep ' / '

Resolution options:

  • Option 1: Update settings via GUI (recommended)
  • Option 2: Set mysqlloadconfig = no for file-only management
  • Option 3: Delete specific entries from sensor_config table

SQL Queue Tuning

Parameter Default Description
mysqlstore_concat_limit 400 SQL statements per batch
mysqlstore_max_threads_cdr 2 Max parallel CDR write threads

Database Cleaning

See Data_Cleaning for detailed documentation.

Parameter Default Description
cleandatabase 0 Master retention period in days (0=disabled)
cleandatabase_cdr 0 CDR/message table retention
cleandatabase_rtp_stat 2 RTP statistics retention
partition_operations_enable_fromto 1-5 Partition drop time window (e.g., 1-5 AM)

CDR Summary (Aggregation)

Pre-aggregates call data for faster dashboard queries.

cdr_summary = yes
cdr_summary_interval = 5  # minutes

Network Interface & Sniffing

Interface Selection

Parameter Default Description
interface eth0 Interface(s) to capture. Comma-separated for multiple. any = all (no promisc).
promisc yes Promiscuous mode (doesn't work with any).
interfaces_optimize yes Auto-tune NIC settings via ethtool.
snaplen 3200 Packet capture length. Increase for large SIP packets.

BPF Filtering

filter
BPF filter (tcpdump syntax). Warning: Can accidentally exclude important traffic.
# Example: Exclude specific subnets
filter = not net 192.168.0.0/16 and not net 10.0.0.0/8
interface_ip_filter
CPU-efficient IP allow-list (no negation). Multiple lines supported.
interface_ip_filter = 192.168.0.0/24
interface_ip_filter = 10.0.0.0/8

Shared Server Optimization

When the sniffer runs on the same server as the PBX, resource contention can cause voice breakage.

Symptoms: Audio jitter, packet loss, call lag that resolves when sniffer is stopped.

Solutions:

# Solution 1: Specify interfaces (creates dedicated threads)
interface = ens192,ens224  # NOT 'any'

# Solution 2: Disable NIC optimization
interfaces_optimize = no

# Solution 3: Reduce sniffer load
savertp = header
saveaudio = no

Long-term: Move sensor to dedicated server with SPAN/Mirror. See Sniffer_distributed_architecture.

Packet Deduplication

Required when receiving same packets from multiple sources/interfaces.

deduplicate = yes
auto_enable_use_blocks = yes  # Required for deduplication
deduplicate_ipheader = ip_only  # Recommended for different network paths
Parameter Default Description
deduplicate no Enable checksum-based deduplication (CPU intensive)
auto_enable_use_blocks no Required for deduplication and correct RTP association across interfaces/VLANs
deduplicate_ipheader yes ip_only recommended when packets have different TTL

Tunneling Protocol Support

Parameter Default Description
udp_port_tzsp 37008 Mikrotik TZSP
udp_port_l2tp 1701 L2TP tunneling
udp_port_vxlan 4789 VXLAN (AWS/cloud)
audiocodes no AudioCodes proprietary tunnel. See Audiocodes_tunneling.
ipfix no Oracle/ACME SBC IPFIX
hep no Homer Encapsulation Protocol

Scan PCAP Directory Mode

Process PCAP files instead of live capture. Useful for Windows hosts without SPAN ports.

scanpcapdir = /var/spool/voipmonitor/scanpcap
scanpcapmethod = newfile

Workflow:

  1. Capture on source: tcpdump -i eth0 udp -G 300 -w /path/dump.pcap
  2. Transfer to VoIPmonitor server
  3. Sensor processes files automatically

SIP Configuration

Port Settings

Parameter Default Description
sipport 5060 SIP ports. Multiple: 5060,5061,5070-5080
cdr_sipport yes Store SIP ports in database
cdr_country_code yes Country code lookup for caller/called. Set no to disable country flags.

TCP Reassembly & UDP Fragmentation

Parameter Default Description
sip_tcp_reassembly_ext yes TCP reassembly for SIP over TCP
udpfrag yes Critical: IP fragment reassembly for large SIP messages
max_sip_packets_in_call 2000 Maximum SIP packets per call

TLS/SSL & SRTP Decryption

SIP TLS Decryption

ssl = yes
ssl_ipport = 10.0.0.1:5061 /path/to/your.key
# Subnet with multiple keys:
ssl_ipport = 10.0.0.0/24:5061 /path/key1.pem,/path/key2.pem

Keylogger support (for PFS/TLS 1.3):

ssl_sessionkey_udp = yes
ssl_sessionkey_udp_port = 1234

See Tls for complete TLS decryption documentation.

SRTP Configuration

Parameter Default Description
srtp_rtp no Decrypt and store RTP data in PCAPs
srtp_rtcp yes Decrypt RTCP streams
srtp_rtp_dtls yes DTLS decryption (requires keylogger)
ssl_dtls_boost no Meta-parameter enabling aggressive DTLS decryption options

Caller/Called Identity

Parameter Default Description
remoteparty_caller unset Update caller from Remote-Party-ID (calling/called)
passertedidentity no Use P-Asserted-Identity for caller
destination_number_mode 1 Source for called number: 1=To header, 2=INVITE URI
sipoverlap yes Update destination from subsequent INVITEs (overlap dialing)

Performance & Threading

Core Threading

Parameter Default Description
t2_boost unset Set to high_traffic for ≥1500Mbit. Fixes CPU bottlenecks where single defrag thread runs at 100%.
threading_expanded yes Modern multi-threaded engine. Set high_traffic for >5 Gbit/s.
preprocess_rtp_threads 2 Initial RTP preprocessing threads (auto-scales)
rtpthreads CPU count RTP processing threads

Buffer Configuration

Parameter Default Description
ringbuffer 50 Ringbuffer size MB. ≥500 recommended for >100 Mbit. Max 2000.
max_buffer_mem 2000 Max buffer memory MB. Increase to 10000+ for high concurrent calls.
packetbuffer_compress no Enable in distributed setups to reduce bandwidth.

Thread Priority

sched_pol_auto = prio -20  # Auto-elevate critical threads under load
sched_pol_auto_cpu_limit = 45  # CPU threshold for elevation

Distributed Operation

See Sniffer_distributed_architecture for complete documentation.

Client/Server Configuration

Central Server:

server_bind = 0.0.0.0
server_bind_port = 60024
server_password = yourpassword
# CRITICAL: Exclude server port from sipport!
sipport = 1-60023,60025-65535

Remote Sensor:

id_sensor = 2
server_destination = 10.0.0.1
server_destination_port = 60024
server_password = yourpassword
packetbuffer_sender = no  # or yes for packet mirroring

⚠️ Warning: When packetbuffer_sender = yes, all packets including RTP are transmitted regardless of savertp setting.

Storage & File Management

Spool Directory

Parameter Default Description
spooldir /var/spool/voipmonitor Primary storage directory
spooldir_2 unset Secondary storage for capture rules with "Store to second spooldir"
cachedir unset Temp storage (use RAM/SSD for performance)

ℹ️ Note: For GUI access to spooldir_2, configure "Sniffer second datapath" in GUI Settings > System Configuration > Basic.

TAR Storage Strategy

tar = yes  # Group PCAPs into minute-based archives (reduces I/O)
tar_compress_sip = zstd
tar_compress_graph = zstd

Saving Options

Parameter Default Description
savesip yes Save SIP packets
savertp yes yes=full, header=metadata only (no audio), no=disabled
savertp_video no Video RTP. Limitation: Only ONE video stream per call saved to PCAP.
saveudptl no T.38 fax packets
savegraph yes Call graph data

Disable audio recording:

savertp = header  # NOT 'no' - keeps RTP analysis tool working
saveaudio = no

Spool Cleaning

Parameter Default Description
cleanspool yes Enable automatic spool cleaning
maxpoolsize 102400 Size limit in MB
maxpooldays unset Age limit in days
autocleanspoolminpercent 1 Emergency cleaning trigger (% free)

Audio File Generation

Parameter Default Description
saveaudio no Generate audio files: wav, ogg, mp3, or yes
saveaudio_singlefolder unset Dedicated directory for audio files
saveaudio_stereo yes Caller=left, called=right channel

Understanding Audio Playback vs Pre-Generated Files

VoIPmonitor provides two independent methods for audio playback:

Method How it works Requirements Use Case
On-demand extraction (default) GUI extracts audio from stored RTP packets in PCAP files savesip = yes, savertp = yes Standard operation - recommended
Pre-generated files Sniffer creates .wav/.ogg/.mp3 files immediately during call processing saveaudio = wav (or ogg/mp3) Special requirements only

ℹ️ Note: The saveaudio option is NOT required for audio playback in the GUI. The GUI can extract audio on-demand from stored PCAP files whenever savertp = yes.

Important considerations for saveaudio:

  • CPU/IO intensive - Pre-generating audio files for every call significantly increases system load
  • Independent option - Works regardless of savertp/savesip settings
  • Storage overhead - Creates additional audio files beyond the PCAP storage
  • Use sparingly - Only enable when you have specific requirements (e.g., external systems that need direct audio file access)

To disable audio recording while keeping quality metrics:

savertp = header   # Saves RTP headers only - keeps MOS/jitter/packet loss metrics
# saveaudio is 'no' by default - audio cannot be played/extracted

To keep full audio capability (default):

savertp = yes      # Full RTP packets stored
# saveaudio is 'no' by default - GUI extracts audio on-demand from PCAP

Call Processing

Timeouts

Parameter Default Description
absolute_timeout 14400 Force-end calls longer than this (seconds). Sets cdr.bye = 102.
rtptimeout 300 Close call if no RTP/RTCP for this duration
sipwithoutrtptimeout 3600 Close SIP call without RTP
onewaytimeout 15 End call if no reply from other side

Call Merging

Parameter Default Description
matchheader unset SIP header to link call legs in GUI
callidmerge_header unset Header containing parent Call-ID for CDR merging
call_id_alternative unset Alternative identifiers (e.g., Session-ID,Join for CUCM)

See Merging_or_correlating_multiple_call_legs for detailed documentation.

Recording Control

Parameter Default Description
pauserecordingdtmf unset DTMF sequence to pause recording (e.g., *9)
pauserecordingdtmf_timeout 4 Timeout between DTMF digits (seconds)
norecord-dtmf no Delete recording if *0 is detected
norecord-header no Discard call if X-VoipMonitor-norecord header present

Custom Headers

custom_headers = Referred-By, Diversion, X-Custom-Header
custom_headers_last_value = yes
custom_headers_max_size = 1024

After adding headers, configure display in GUI: Settings > CDR Custom Headers.

SIP History

save_sip_history
(Default: no) Store SIP signaling for GUI filtering.
  • requests - All SIP methods (PUBLISH, INFO, UPDATE, PRACK, REFER) in "SIP requests" filter
  • responses - Full response text for searching (not just codes)
  • all - Both requests and responses

⚠️ Warning: Enabling SIP history significantly increases database load and storage.


GUI Filters for SIP Response Searching

There are two distinct SIP response filters in the CDR view. Understanding their differences prevents confusion:

Filter What it searches Accepts Requires Configuration
Last SIP Response Code Final response code in cdr.lastSIPresponse Numeric codes (404, 503), wildcards (4%, 5%), and text (%OK, %Busy%) None - always available
SIP responses Full text of ALL SIP responses during the call Full text search, any string save_sip_history = responses or save_sip_responses = yes

Key differences:

  • Last SIP Response Code searches only the final response. Examples:
    • 200 - exact numeric match
    • 4% - all 4xx errors
    • %OK - responses ending with "OK"
    • %Busy% - responses containing "Busy"
  • SIP responses searches all SIP responses (180 Ringing, 183, provisional, etc.). Use for:
    • Intermediate responses (e.g., 491 Request Pending mid-dialog)
    • Custom SBC error messages
    • Any response text, not just the final one

Example: A call completes with 200 OK but had a 503 from one provider during serial forking. "Last SIP Response Code = 503" won't find it, but "SIP responses = %503%" will.

save_sip_history vs save_sip_responses

These two parameters achieve the same result - storing SIP response text for the "SIP responses" filter. Do not enable both simultaneously:

Parameter Notes
save_sip_history = responses Part of the multi-value save_sip_history option. Can combine with requests or use all.
save_sip_responses = yes Standalone parameter for same functionality. Simpler if you only need response text.

RTP Processing

Parameter Default Description
jitterbuffer_f1 yes 50ms fixed jitterbuffer simulation
jitterbuffer_f2 yes 200ms fixed jitterbuffer simulation
jitterbuffer_adapt yes Adaptive jitterbuffer (up to 500ms)
allow-zerossrc no Accept RTP with zero SSRC (some legacy gateways)

CPU optimization (saves ~30%):

mosf1 = no
mos_adapt = no
mosf2 = yes  # Keep only f2 for stable MOS metric

Audio Analysis

Parameter Default Description
dtmf2db no Store DTMF to database
inbanddtmf no In-band DTMF detection (G711 only, CPU intensive)
silencedetect no Silence detection (G711 only, CPU intensive)
clippingdetect no Audio clipping detection

See Silence_detection for detailed documentation.

NAT Handling

natalias = 1.1.1.1 10.0.0.3  # Public to private IP mapping
sdp_reverse_ipport = no  # Reverse sniffing for NAT (use with caution)

Protocol Support

SIP REGISTER/OPTIONS/SUBSCRIBE

Parameter Default Description
sip-register no Process REGISTER messages (yes, nodb, no)
sip-options no Process OPTIONS messages
sip-subscribe no Process SUBSCRIBE messages
sip-message yes Process MESSAGE requests

See Register for detailed REGISTER documentation.

Other Protocols

Parameter Default Description
skinny no Cisco Skinny/SCCP protocol
mgcp no MGCP protocol
ss7 no SS7-over-IP (SIGTRAN)
diameter no Diameter protocol
ipv6 no IPv6 support (requires IPv6 database columns)

Advanced Protocol Support

IPFIX Support

IPFIX (IP Flow Information Export) is used with Oracle/ACME SBCs to receive call data.

IMPORTANT - PCAP Availability: IPFIX data is internally converted to packet format for processing. This means PCAP files CAN be downloaded from the GUI for IPFIX-sourced calls (SIP signaling is reconstructed). However, RTP streams are NOT included in the PCAP - only QoS metrics from the IPFIX data are available, not actual audio packets.

ipfix = yes
ipfix_bind_port = 12345
ipfix_qos_fill_rtp_streams = yes
# Include TLS port for SIPS/SRTP:
sipport = 5060,5061
Parameter Default Description
ipfix no Enable IPFIX receiver (Oracle/ACME SBC)
ipfix_bind_ip 0.0.0.0 Bind IP address for IPFIX listener
ipfix_bind_port 4739 UDP port for IPFIX data
ipfix_qos_fill_rtp_streams no Populate RTP stream statistics from IPFIX QoS data

SIPREC Support

siprec_bind = 0.0.0.0
siprec_bind_port = 5099
siprec_rtp_min = 10000
siprec_rtp_max = 20000

HEP Support

receiver_mode = yes  # Required!
hep = yes
hep_bind_port = 9060
hep_kamailio_protocol_id_fix = yes  # For Kamailio sources

Kamailio Mirroring

receiver_mode = yes  # Required!
kamailio_port = 5888

Ribbon SBC Mirroring

ribbonsbc = yes
ribbonsbc_bind_ip = 0.0.0.0
ribbonsbc_bind_port = 9514

Whisper Transcription

audio_transcribe = yes
whisper_native = no
whisper_model = /path/to/ggml-base.bin
whisper_language = auto

See Whisper for detailed transcription documentation.

ℹ️ Note: Oracle/ACME SBC and Ribbon SBC are products from different vendors with different integration methods:

  • Oracle SBC (formerly Acme Packet, acquired by Oracle in 2013) → uses IPFIX protocol
  • Ribbon SBC (formed from GENBAND + Sonus Networks merger in 2017) → uses Monitoring Profile with proprietary ribbonsbc protocol

Do not confuse these - they require different VoIPmonitor configuration.

Expert & Debugging Options

⚠️ Warning: Only change these if instructed by support or you are an expert.

Parameter Default Description
callslimit 0 Max concurrent calls (0=unlimited)
skipdefault no Ignore all calls unless capture rules match
openfile_max 65535 Maximum open files
coredump_filter 0x7F Memory segments in coredump

Traffic Dumper

traffic_dumper_path = /var/spool/voipmonitor/traffic
traffic_dumper_filter_ip = 192.168.1.100, 10.0.0.0/8
traffic_dumper_filter_port = 5060, 5061, 10000-20000

DEPRECATED DO NOT USE

AI Summary for RAG

Summary: Comprehensive reference for voipmonitor.conf covering: sensor identification, database configuration (MySQL settings, partitioning, mysqlloadconfig for GUI vs file priority), network interface settings (BPF filters, deduplication with auto_enable_use_blocks), tunneling protocols (VXLAN, TZSP, HEP, AudioCodes), TLS/SRTP decryption, distributed client/server architecture (packetbuffer_sender), storage management (TAR archives, spool cleaning), call processing (timeouts, merging, recording control), SIP history storage, audio analysis, and protocol support (IPFIX, SIPREC, HEP, Kamailio, Ribbon SBC, Whisper). Deprecated options in v2025.09.1+ include vxlan, packet_buffer_total_size, udp_reassembly, sipdefrag.

Keywords: voipmonitor.conf, sniffer configuration, id_sensor, mysqlloadconfig, manager_key, deduplicate, auto_enable_use_blocks, packetbuffer_sender, savertp, TLS decryption, SRTP, ssl_dtls_boost, distributed architecture, client-server, maxpoolsize, cleandatabase, custom_headers, save_sip_history, t2_boost, threading, scanpcapdir, deprecated options, IPFIX, SIPREC, HEP, Kamailio, Ribbon SBC, Whisper, pauserecordingdtmf

Key Questions:

  • What are the most important settings in voipmonitor.conf?
  • How do I configure the database connection?
  • Why does the sniffer fail with "failed read rsa key"?
  • How do I set up distributed client/server architecture?
  • What is the difference between packetbuffer_sender = yes and no?
  • How do I enable packet deduplication?
  • How do I decrypt TLS/SRTP traffic?
  • How do I disable audio recording while keeping RTP analysis?
  • How do I capture custom SIP headers?
  • How do I configure IPFIX/SIPREC/HEP receivers?
  • Which options were deprecated in v2025.09.1?
  • How do I fix CPU bottlenecks with t2_boost?
  • How do I process PCAP files with scanpcapdir?