Skip to content

SIP VAULT Configuration Guide

This guide details every configuration option for the SIP VAULT server, API, agent, retention policy, nginx reverse proxy, OpenSIPS integration, and quality analysis parameters.

Table of Contents


Server Configuration

The sipvault-server reads configuration from environment variables, with an optional fallback to a JSON config file at /etc/sipvault/server.conf. Environment variables always take precedence over the file.

The environment file is located at /etc/sipvault/server.env and is loaded by the systemd service.

Environment Variables

Variable Required Default Description
SIPVAULT_LISTEN_TCP No :9060 TCP listener address for agent connections. Format: [host]:port
SIPVAULT_LISTEN_HEP No :9060 UDP listener address for HEP v3 RTCP packets. Format: [host]:port
SIPVAULT_S3_ENDPOINT Yes -- Cloudflare R2 endpoint URL: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
SIPVAULT_S3_REGION No auto S3 region. Cloudflare R2 always uses auto
SIPVAULT_S3_ACCESS_KEY Yes -- Cloudflare R2 access key ID
SIPVAULT_S3_SECRET_KEY Yes -- Cloudflare R2 secret access key
SIPVAULT_CUSTOMERS Yes -- JSON array of customer configurations (see below)
SIPVAULT_LOG_LEVEL No info Log level: debug, info, warn, error

Customer Configuration (SIPVAULT_CUSTOMERS)

The SIPVAULT_CUSTOMERS variable is a JSON array where each element defines a customer:

[
  {
    "id": "acme",
    "token": "a1b2c3d4e5f6...",
    "bucket": "sipvault-acme-us"
  },
  {
    "id": "globex",
    "token": "f6e5d4c3b2a1...",
    "bucket": "sipvault-globex-eu"
  }
]
Field Required Description
id Yes Unique customer identifier. Used in S3 paths and token validation
token Yes Authentication token that agents use to connect. Must match the agent's [server] token
bucket Yes R2 bucket name for this customer. Convention: sipvault-{customer_id}-{region}

In a single-line environment variable:

SIPVAULT_CUSTOMERS=[{"id":"acme","token":"a1b2c3d4e5f6","bucket":"sipvault-acme-us"}]

Example server.env

SIPVAULT_LISTEN_TCP=:9060
SIPVAULT_LISTEN_HEP=:9060
SIPVAULT_S3_ENDPOINT=https://abcdef1234567890.r2.cloudflarestorage.com
SIPVAULT_S3_REGION=auto
SIPVAULT_S3_ACCESS_KEY=your_r2_access_key
SIPVAULT_S3_SECRET_KEY=your_r2_secret_key
SIPVAULT_CUSTOMERS=[{"id":"acme","token":"securetoken123","bucket":"sipvault-acme-us"}]
SIPVAULT_LOG_LEVEL=info

S3 Path Structure

The server writes call data to S3 using this path convention:

{bucket}/calls/{YYYY}/{MM}/{DD}/{call_id}/
  sip.pcap.gz          # SIP packets (GZIP compressed)
  rtcp.json.gz         # Raw RTCP reports (GZIP compressed)
  quality.json          # Quality analysis report
  log-000001.gz        # OpenSIPS log chunk 1 (GZIP compressed)
  log-000002.gz        # OpenSIPS log chunk 2
  ...

Call Session State Machine

The server manages call sessions with the following states:

State Timeout Trigger Description
PENDING 5 minutes INVITE received Waiting for call setup to complete
ACTIVE 30 minutes (inactivity) Call established Logs flush as 60-second GZIP chunks
CLOSING 5 seconds (grace period) BYE or CANCEL received Waiting for final packets
COMPLETE -- Grace period expires All data written to S3

API Configuration

The FastAPI service reads configuration from environment variables. The environment file is at /etc/sipvault/api.env.

Environment Variables

Variable Required Default Description
SIPVAULT_S3_ENDPOINT Yes -- Cloudflare R2 endpoint URL
SIPVAULT_S3_REGION No auto S3 region
SIPVAULT_HMAC_SECRET Yes -- HMAC-SHA256 secret for token validation. Must match the CDR Viewer integration secret
SIPVAULT_HMAC_MAX_AGE No 3600 Maximum token age in seconds (default: 1 hour)
SIPPULSE_API_URL No https://api.sippulse.ai/v1 SipPulse AI API endpoint for the chat feature
SIPPULSE_API_KEY No -- SipPulse AI API key
SIPPULSE_AI_MODEL No glm-4.7 AI model to use for chat analysis
ANTHROPIC_API_KEY No -- Anthropic API key (alternative AI provider)
AWS_ACCESS_KEY_ID Yes -- R2 access key for generating pre-signed URLs
AWS_SECRET_ACCESS_KEY Yes -- R2 secret key for generating pre-signed URLs

Example api.env

SIPVAULT_S3_ENDPOINT=https://abcdef1234567890.r2.cloudflarestorage.com
SIPVAULT_S3_REGION=auto
SIPVAULT_HMAC_SECRET=YOUR_HMAC_SECRET_HERE
SIPVAULT_HMAC_MAX_AGE=3600
SIPPULSE_API_URL=https://api.sippulse.ai/v1
SIPPULSE_API_KEY=your_sippulse_ai_key
SIPPULSE_AI_MODEL=glm-4.7
ANTHROPIC_API_KEY=your_anthropic_key
AWS_ACCESS_KEY_ID=your_r2_read_access_key
AWS_SECRET_ACCESS_KEY=your_r2_read_secret_key

Generating the HMAC Secret

Use a cryptographically secure random generator:

openssl rand -hex 32

This same secret must be configured in: - /etc/sipvault/api.env as SIPVAULT_HMAC_SECRET - The CDR Viewer integration code (PHP/Python/Node.js)


Agent Configuration

The agent reads its configuration from an INI-format file at /etc/sipvault/agent.conf. The file is divided into four sections.

Full Configuration Reference

[server]
# Server address in HOST:PORT format (required)
address = 10.0.0.1:9060

# Customer identifier, must match server SIPVAULT_CUSTOMERS[].id (required)
customer_id = acme

# Authentication token, must match server SIPVAULT_CUSTOMERS[].token (required)
token = securetoken123

[capture]
# Capture mode: auto, ebpf, or pcap (default: auto)
# auto = select based on kernel version (ebpf if >= 4.18, pcap otherwise)
mode = auto

# Comma-separated SIP ports to monitor (default: 5060)
sip_ports = 5060

# Network interface for packet capture (default: auto-detected from default route)
interface = eth0

# OpenSIPS log file path for pcap mode log tailing (default: empty = disabled)
# In eBPF mode, logs are captured via kprobe on sendmsg instead
log_file = /var/log/opensips.log

# RTP port range for RTCP capture (default: 10000-30000)
# Should match your RTPProxy/RTPEngine port range
rtp_port_min = 10000
rtp_port_max = 30000

[buffer]
# Path to the disk buffer file (default: /var/lib/sipvault/buffer.dat)
path = /var/lib/sipvault/buffer.dat

# Maximum disk buffer size in bytes (default: 104857600 = 100 MB)
# When the TCP connection to the server is lost, data is buffered locally
max_size = 104857600

[logging]
# Log level: debug, info, warn, error (default: info)
level = info

Section: [server]

Key Required Default Description
address Yes -- SIP VAULT server address as host:port
customer_id Yes -- Customer identifier
token Yes -- Authentication token

Section: [capture]

Key Required Default Description
mode No auto Capture mode: auto, ebpf, or pcap
sip_ports No 5060 Comma-separated list of SIP ports
interface No Auto-detected Network interface name
log_file No (empty) OpenSIPS log file for pcap mode
rtp_port_min No 10000 Minimum RTP port
rtp_port_max No 30000 Maximum RTP port

Section: [buffer]

Key Required Default Description
path No /var/lib/sipvault/buffer.dat Disk buffer file path
max_size No 104857600 (100 MB) Maximum buffer size in bytes

Section: [logging]

Key Required Default Description
level No info Log level

Capture Mode Comparison

Feature eBPF Mode pcap Mode
Kernel requirement >= 4.18 Any
SIP/RTCP capture XDP/tc BPF programs libpcap on SIP/RTP ports
Log capture kprobe on sendmsg File tailing (log_file config)
Build go build (no CGO) go build -tags pcap (needs libpcap-dev)
Capabilities CAP_BPF + CAP_NET_ADMIN + CAP_SYS_PTRACE root or CAP_NET_RAW
Supported OS Ubuntu 18.04+, Debian 10+, CentOS 8+ CentOS 6+, Debian 7+, Ubuntu 14.04+

Example: pcap Mode on CentOS 6/7

[server]
address = 10.0.0.1:9060
customer_id = acme
token = securetoken123

[capture]
mode = pcap
sip_ports = 5060
interface = eth0
log_file = /var/log/opensips.log
rtp_port_min = 10000
rtp_port_max = 30000

[buffer]
path = /var/lib/sipvault/buffer.dat
max_size = 104857600

[logging]
level = info

Retention Policy

The retention policy is configured in /etc/sipvault/retention.yml and determines how long each type of call data is kept in S3. A nightly cron job deletes expired data.

Configuration File

# /etc/sipvault/retention.yml
# Run nightly via cron: 0 3 * * * /usr/local/bin/sipvault-retention

default:
  sip_pcap_days: 7
  rtcp_raw_days: 7
  quality_json_days: 30
  log_chunks_days: 14

customers:
  # Per-customer overrides using the customer ID as key
  acme:
    sip_pcap_days: 30
    rtcp_raw_days: 30
    quality_json_days: 365
    log_chunks_days: 90

Data Type Retention

Data Type S3 Object Default Description
sip_pcap_days sip.pcap.gz 7 days Captured SIP packet trace
rtcp_raw_days rtcp.json.gz 7 days Raw RTCP report data
quality_json_days quality.json 30 days Computed quality analysis report
log_chunks_days log-NNNNNN.gz 14 days OpenSIPS log chunks

Cron Setup

Add the retention job to cron:

sudo crontab -e
0 3 * * * /usr/local/bin/sipvault-retention

This runs the cleanup daily at 3:00 AM.


nginx Configuration

The nginx configuration serves the dashboard SPA and reverse-proxies API requests to the FastAPI backend.

Configuration File

Location: /etc/nginx/sites-available/sipvault.conf

server {
    listen 443 ssl http2;
    server_name vault.example.com;

    ssl_certificate /etc/letsencrypt/live/vault.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/vault.example.com/privkey.pem;

    # Dashboard SPA
    root /opt/sipvault/dashboard;
    index index.html;

    location /api/ {
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # SSE support for AI chat streaming
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 300s;
    }

    # SPA fallback — serves index.html for all routes
    location / {
        try_files $uri $uri/ /index.html;
    }
}

# HTTP -> HTTPS redirect
server {
    listen 80;
    server_name vault.example.com;
    return 301 https://$host$request_uri;
}

Key Configuration Points

  • SSL/TLS is handled by Let's Encrypt certificates managed by certbot
  • API proxy strips the /api/ prefix when passing to the FastAPI backend (via proxy_pass http://127.0.0.1:8000/)
  • SSE support for the AI chat feature requires proxy_buffering off and proxy_cache off
  • Read timeout is set to 300 seconds to accommodate long-running AI chat responses
  • SPA fallback ensures client-side routing works by falling back to index.html

Domain Customization

The setup script replaces vault.example.com with your configured domain. To change it manually:

sudo sed -i 's/vault.example.com/your-domain.com/g' /etc/nginx/sites-available/sipvault.conf
sudo nginx -t && sudo systemctl reload nginx

OpenSIPS Configuration Requirements

For SIP VAULT to capture data correctly, the customer's OpenSIPS installation must meet certain configuration requirements.

Log Facility

OpenSIPS must log to a file (not just syslog) for the agent to capture log data in pcap mode:

# opensips.cfg
log_facility=LOG_LOCAL0
log_level=3

In /etc/rsyslog.d/opensips.conf:

local0.*    /var/log/opensips.log

The log_file parameter in the agent config must point to this file:

[capture]
log_file = /var/log/opensips.log

Socket Configuration

SIP VAULT captures traffic on the ports specified in the agent's sip_ports configuration. Ensure OpenSIPS listens on those ports:

# opensips.cfg
listen=udp:0.0.0.0:5060
listen=tcp:0.0.0.0:5060

Authentication

No changes to OpenSIPS authentication are needed. SIP VAULT passively captures packets; it does not inject or modify SIP traffic.

RTPProxy / RTPEngine Port Range

The agent's rtp_port_min and rtp_port_max must match the RTPProxy or RTPEngine port range:

# rtpproxy startup
rtpproxy -l 0.0.0.0 -m 10000 -M 30000

# opensips.cfg - modparam for rtpproxy
modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722")

Agent configuration to match:

[capture]
rtp_port_min = 10000
rtp_port_max = 30000

Split-Server RTCP (RTPProxy on Separate Machine)

When RTPProxy runs on a machine separate from OpenSIPS, use the acct_rtcp_hep module to send RTCP data directly to the SIP VAULT server via HEP. No agent is needed on the media server.

Configure RTPProxy to send RTCP via HEP:

# In OpenSIPS or RTPProxy configuration
# HEP destination: sipvault-server:9060/udp
modparam("rtpproxy", "rtpp_flags", "HEP=sipvault-server:9060")

The SIP VAULT server listens on UDP :9060 for HEP v3 packets.


Quality Thresholds and Verdicts

SIP VAULT uses the ITU-T G.107 E-model to compute voice quality metrics. The quality report (quality.json) includes a verdict based on the R-factor and MOS score.

E-Model Formula

The R-factor is calculated as:

R = 93.2 - Id - Ie_eff

Where: - Id (delay impairment): 0.024 * d + 0.11 * (d - 177.3) * H(d - 177.3), with d = RTT / 2 (one-way delay in ms) - Ie_eff (equipment impairment): Ie + (95 - Ie) * loss% / (loss% + Bpl), where Ie and Bpl are codec-specific constants - H(x) is the Heaviside step function (0 for x < 0, 1 for x >= 0)

MOS (Mean Opinion Score) is derived from the R-factor:

MOS = 1 + 0.035 * R + R * (R - 60) * (100 - R) * 7e-6

MOS is clamped to the range [1.0, 4.5].

Verdict Thresholds

The verdict is determined by the worst MOS average across both call directions (UAC and UAS):

Verdict R-Factor Range MOS Range User Satisfaction
Excellent > 90 > 4.34 Very satisfied
Good 80 - 90 4.03 - 4.34 Satisfied
Fair 70 - 80 3.60 - 4.03 Some users dissatisfied
Poor 60 - 70 3.10 - 3.60 Many users dissatisfied
Bad < 60 < 3.10 Nearly all users dissatisfied

Individual Metric Thresholds

In addition to MOS-based verdicts, individual metric thresholds also affect the verdict:

Metric Warning Threshold Severe Threshold Impact
Jitter > 20 ms > 50 ms Quality affected / Bad verdict
Latency (one-way = RTT/2) > 150 ms > 400 ms Conversation impaired / Bad verdict
Packet Loss > 1% > 5% Audible artifacts / Bad verdict

The verdict logic: - Bad: MOS < 3.10, OR jitter > 50ms, OR loss > 5%, OR latency > 400ms - Poor: MOS between 3.10 and 3.60 - Fair: MOS between 3.60 and 4.03, OR any warning threshold exceeded - Good: MOS > 4.03 and all metrics within warning thresholds

Audio Status Detection

SIP VAULT detects audio path issues from RTCP sample patterns:

Status Condition Description
Normal Both UAC and UAS have RTCP samples Two-way audio confirmed
OWA (One-Way Audio) Only one direction has RTCP samples One party cannot hear the other
NOA (No Audio) Neither direction has RTCP samples Media path completely broken

For OWA and NOA conditions, the quality report includes a diagnostic object with probable_cause and recommendation fields to assist troubleshooting.

Per-Direction Statistics

Each direction (UAC and UAS) produces the following statistical summaries:

Metric Fields Description
MOS avg, min, max, p5, p95 Mean Opinion Score
Jitter avg, min, max, p5, p95 Interarrival jitter in ms
Loss avg, min, max, p5, p95 Packet loss percentage
RTT avg, min, max, p5, p95 Round-trip time in ms

The timeseries provides 5-second bucketed data points with per-direction MOS, jitter, and loss.

Degraded Leg Detection

SIP VAULT identifies which leg is degraded: - "uac": Caller direction MOS average < 3.5 - "uas": Callee direction MOS average < 3.5 - "both": Both directions MOS average < 3.5 - (empty): Neither direction is degraded


Codec Support

SIP VAULT uses codec-specific impairment parameters from ITU-T G.113 Appendix I for accurate MOS calculation. The codec is detected from SDP negotiation during the INVITE dialog.

Supported Codecs

Codec Name Aliases Ie (Equipment Impairment) Bpl (Packet Loss Robustness) Notes
G.711 mu-law pcmu, g711 0 25 Default / reference codec
G.711 A-law pcma 0 25 Same as mu-law
G.722 g722 0 25 Wideband codec
G.729 g729, g729a 11 19 Low-bitrate, higher impairment
G.723.1 g723 15 16 Legacy low-bitrate
GSM-FR gsm 20 17 GSM full-rate
Opus opus 0 25 Modern adaptive codec
iLBC ilbc 11 20 Internet Low Bitrate Codec
AMR amr 5 20 Adaptive Multi-Rate
AMR-WB amr-wb 0 25 AMR Wideband
SILK silk 0 25 Skype codec
Speex speex 11 20 Open-source codec

Understanding Ie and Bpl

  • Ie (Equipment Impairment Factor): Represents the inherent quality loss from the codec's compression. G.711 (no compression) has Ie=0. G.729 has Ie=11 because the compression introduces some quality loss even with zero packet loss.

  • Bpl (Packet Loss Robustness Factor): Indicates how well the codec handles packet loss. Higher values mean the codec degrades more gracefully under packet loss. G.711 (Bpl=25) tolerates loss better than G.723 (Bpl=16).

Codec Lookup Behavior

The codec name is matched case-insensitively. If an exact match is not found, SIP VAULT attempts a substring match against known codec names. If no match is found, G.711 defaults (Ie=0, Bpl=25) are used.