Anti-fraud: Difference between revisions

From VoIPmonitor.org
(Major restructure: add PlantUML diagram, convert indented code to syntaxhighlight, add tables, improve PHP formatting, streamline AI summary)
(Fix alert categorization (Country/Continent is Realtime not CDR), add color legend to diagram, add trigger condition tables, improve formatting)
Line 12: Line 12:
skinparam shadowing false
skinparam shadowing false
skinparam defaultFontName Arial
skinparam defaultFontName Arial
skinparam rectangle {
  BackgroundColor<<realtime>> #E8F5E9
  BackgroundColor<<cdr>> #E3F2FD
  BackgroundColor<<action>> #FFF3E0
}


rectangle "VoIPmonitor\nSensor" as sensor
rectangle "VoIPmonitor\nSensor" as sensor
rectangle "Realtime\nDetection" as realtime
rectangle "Realtime\nDetection" as realtime <<realtime>>
rectangle "CDR-based\nDetection" as cdr_detect
rectangle "CDR-based\nDetection" as cdr_detect <<cdr>>
database "MySQL" as db
database "MySQL" as db
rectangle "Alert\nProcessor" as processor
rectangle "Alert\nProcessor" as processor
rectangle "Custom\nScript" as script
rectangle "Custom\nScript" as script <<action>>
rectangle "Firewall\n(iptables)" as fw
rectangle "Firewall\n(iptables)" as fw <<action>>
rectangle "Email\nNotification" as email
rectangle "Email\nNotification" as email <<action>>


sensor --> realtime : SIP packets
sensor --> realtime : SIP packets\n(immediate)
sensor --> db : CDRs
sensor --> db : CDRs
realtime --> processor : Immediate trigger
realtime --> processor : Trigger
db --> cdr_detect : Query
db --> cdr_detect : Query
cdr_detect --> processor : Threshold exceeded
cdr_detect --> processor : Threshold\nexceeded
processor --> script : Execute action
processor --> script : Execute
processor --> email : Send alert
processor --> email : Send
script --> fw : Block IP
script --> fw : Block IP
legend right
  |= Color |= Type |
  | <#E8F5E9> | Realtime processing |
  | <#E3F2FD> | CDR-based processing |
  | <#FFF3E0> | Actions |
endlegend
@enduml
@enduml
</kroki>
</kroki>
Line 41: Line 53:
| Realtime concurrent calls || Realtime || Monitors concurrent calls per source IP
| Realtime concurrent calls || Realtime || Monitors concurrent calls per source IP
|-
|-
| SIP REGISTER flood/attack || Realtime || Detects REGISTER flooding
| SIP REGISTER flood/attack || Realtime || Detects REGISTER flooding from single IP
|-
|-
| SIP PACKETS flood/attack || Realtime || Detects generic SIP packet floods
| SIP PACKETS flood/attack || Realtime || Detects generic SIP packet floods
|-
|-
| Change CDR country || CDR-based || IP geolocation changed between calls
| Country/Continent destination || Realtime || Calls to specific country/continent (based on first INVITE)
|-
|-
| Change REGISTER country || CDR-based || REGISTER source country changed
| Change CDR country || CDR-based || Source IP geolocation changed between calls
|-
|-
| Country/Continent destination || Realtime || Calls to specific destinations
| Change REGISTER country || CDR-based || REGISTER source country changed since last success
|-
|-
| [[Billing#Watchdog|Billing Watchdog]] || CDR-based || Billing anomaly detection
| [[Billing#Watchdog|Billing Watchdog]] || CDR-based || Billing anomaly detection
Line 56: Line 68:
=== Alert Processing Differences ===
=== Alert Processing Differences ===


VoIPmonitor processes alerts in two different ways:
VoIPmonitor processes alerts in two fundamentally different ways, which affects what data is available when the alert triggers:
 
==== Realtime Alerts ====
 
Processed directly by the sniffer as packets arrive. Triggered immediately based on packet inspection.
 
{| class="wikitable"
|-
! Alert !! Trigger Condition
|-
| Realtime concurrent calls || N+ concurrent calls from same IP
|-
| SIP REGISTER flood || N+ REGISTER attempts from same IP in interval
|-
| SIP PACKETS flood || N+ SIP packets from same IP in interval
|-
| Country/Continent destination || Call to monitored destination (first INVITE)
|}
 
'''Characteristics:'''
* Immediate triggering (no database delay)
* CDRs not yet available when alert fires
* Only IP address available in <code>alert_info</code> (no source port)


;Realtime alerts:
==== CDR-based Alerts ====
:Processed directly by the sniffer as packets arrive. Triggered immediately based on packet inspection but CDRs are not yet available.
 
:* Realtime concurrent calls
Evaluated by the GUI after CDRs have been stored in the database.
:* SIP REGISTER flood
 
:* SIP PACKETS flood
{| class="wikitable"
|-
! Alert !! Trigger Condition
|-
| Change CDR country || IP geolocation differs from previous call
|-
| Change REGISTER country || REGISTER country differs from last successful registration
|-
| RTP alerts || Quality thresholds exceeded (MOS, jitter, loss)
|-
| SIP Response alerts || Specific SIP response codes
|}


;CDR-based alerts:
'''Characteristics:'''
:Evaluated by the GUI after CDRs have been stored in the database.
* Delay between call end and alert (CDR must be written first)
:* Change CDR country
* Full CDR data available (including source port, duration, etc.)
:* Change REGISTER country
* Can query database for additional context
:* Country/Continent destination
:* RTP alerts
:* SIP Response alerts


==== Important Limitation: Source Port in Realtime Alerts ====
==== Important Limitation: Source Port in Realtime Alerts ====


Realtime alerts provide the attacker's IP address in the <code>alert_info</code> object, but do '''not''' include the SIP source port.
Realtime alerts provide the attacker's IP address in <code>alert_info</code>, but do '''not''' include the SIP source port.


The source port can be queried from <code>cdr.caller_port</code> in the database, but this has critical limitations:
The source port can be queried from <code>cdr.caller_port</code>, but this has critical limitations:
* '''Delay''': CDRs are written after the realtime alert triggers, adding latency
* '''Delay''': CDRs are written after the realtime alert triggers
* '''Port may not exist''': Flood attacks may be detected before CDR creation
* '''Port may not exist''': Flood attacks are often detected before CDR creation


'''Recommendation:'''
'''Recommendation:'''
* For real-time defense: Block by IP address only
* For real-time defense: Block by IP address only (accept temporary impact on legitimate traffic from same IP)
* For non-real-time blocking: Use CDR-based alerts with database queries
* For non-real-time blocking: Use CDR-based alerts with database queries


Line 104: Line 146:


'''International prefixes configuration:'''
'''International prefixes configuration:'''
* '''International prefixes''': Distinguish local/international calls (default: <code>+</code>, <code>00</code>)
{| class="wikitable"
* '''Min international length''': Numbers shorter than this are treated as local
|-
* '''Local numbers are in''': Country for classifying international-prefixed calls as local
! Setting !! Description !! Default
|-
| International prefixes || Prefixes indicating international calls || <code>+</code>, <code>00</code>
|-
| Min international length || Numbers shorter than this are treated as local || varies
|-
| Local numbers are in || Country for classifying international-prefixed calls as local || your country
|}


=== SIP REGISTER Flood/Attack ===
=== SIP REGISTER Flood/Attack ===
Line 120: Line 169:
Configure a custom script in the SIP REGISTER flood alert rule to automatically block the attacker IP. The <code>alert_info</code> object contains the attacker's IP address.
Configure a custom script in the SIP REGISTER flood alert rule to automatically block the attacker IP. The <code>alert_info</code> object contains the attacker's IP address.


Block using iptables:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Block using iptables
iptables -A INPUT -s <ATTACKER_IP> -j DROP
iptables -A INPUT -s <ATTACKER_IP> -j DROP
</syntaxhighlight>


Block using ipset (more efficient for multiple IPs):
# Block using ipset (more efficient for multiple IPs)
<syntaxhighlight lang="bash">
ipset add blacklist <ATTACKER_IP>
ipset add blacklist <ATTACKER_IP>
</syntaxhighlight>
</syntaxhighlight>


===== 2. Network Edge Blocking (Recommended) =====
===== 2. Network Edge Blocking (Recommended for Prevention) =====


For long-term protection, block at your network edge:
For long-term protection, block at your network edge before traffic reaches VoIPmonitor:
* '''Session Border Controller (SBC)''': Configure rate limiting and IP blocking
* '''Session Border Controller (SBC)''': Configure rate limiting and IP blocking
* '''Firewall''': Block malicious IPs at the perimeter before reaching VoIPmonitor
* '''Firewall''': Block malicious IPs at the perimeter
* '''Fail2ban''': Automatically block IPs after repeated REGISTER failures
* '''Fail2ban''': Automatically block IPs after repeated REGISTER failures


Line 140: Line 187:


* Disable REGISTER processing if not needed: <code>sip-register = no</code> in <code>voipmonitor.conf</code>
* Disable REGISTER processing if not needed: <code>sip-register = no</code> in <code>voipmonitor.conf</code>
* Filter REGISTER packets using firewall rules
* Filter REGISTER packets using firewall rules (block specific countries or networks)
* Use [[Capture_rules|capture rules]] to exclude known good REGISTER sources
* Use [[Capture_rules|capture rules]] to exclude known good REGISTER sources from processing


=== Realtime Concurrent Calls ===
=== Realtime Concurrent Calls ===
Line 175: Line 222:
=== Custom Script Examples ===
=== Custom Script Examples ===


Custom scripts receive alert data as command-line arguments. Use <code>json_decode($argv[4])</code> in PHP to parse the alert data.
Custom scripts receive alert data as command-line arguments. The fourth argument (<code>$argv[4]</code> in PHP) contains JSON-encoded alert data.


==== Logging Passed Arguments ====
==== Logging Passed Arguments ====
Line 183: Line 230:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
#!/bin/bash
#!/bin/bash
echo "$@" >> /tmp/passed_info.txt
echo "$(date): $@" >> /tmp/alert_debug.txt
</syntaxhighlight>
</syntaxhighlight>


Line 202: Line 249:
`mkdir -p $destdir`;
`mkdir -p $destdir`;


// Parse alert data
// Parse alert data (4th argument contains JSON)
$alert = json_decode($argv[4]);
$alert = json_decode($argv[4]);


// Download audio for each CDR in the alert
// Download audio for each CDR in the alert
foreach ($alert->cdr as $cdr) {
foreach ($alert->cdr as $cdr) {
     $params = '{"task":"getVoiceRecording", "user": "admin", "password": "admin", "params": {"cdrId": "' . $cdr . '"}}';
     $params = json_encode([
        'task' => 'getVoiceRecording',
        'user' => 'admin',
        'password' => 'admin',
        'params' => ['cdrId' => $cdr]
    ]);
     $command = "php $guiDir/php/api.php > $destdir/file_id_$cdr.pcap";
     $command = "php $guiDir/php/api.php > $destdir/file_id_$cdr.pcap";
     exec("echo $params | $command", $arr, $val);
     exec("echo '$params' | $command", $arr, $val);
}
}
?>
?>
Line 216: Line 268:
==== RTP Alert: Block IP After Threshold ====
==== RTP Alert: Block IP After Threshold ====


Script to block IPs that exceed a threshold number of alerts:
Script to block IPs that exceed a threshold number of incidents:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
Line 222: Line 274:
<?php
<?php
// Configuration
// Configuration
$Limit = 19;
$Limit = 19;                                             // Block after this many incidents
$blockCommand = "ssh root@pbx -p2112 ipset add blacklist";
$blockCommand = "ssh root@pbx -p2112 ipset add blacklist"; // Remote blocking command
$verbose = 1; // 1 = dry-run (print only), 0 = execute blocking
$verbose = 1;                                             // 1 = dry-run, 0 = execute


// Parse alert data
// Parse alert data
$alertsData = json_decode($argv[4]);
$alertsData = json_decode($argv[4]);


// Build list of CDR IDs
// Build comma-separated list of CDR IDs
$cdrIds = $alertsData->cdr;
$cdrIds = implode(',', $alertsData->cdr);
$out = '';
foreach ($cdrIds as $id) {
    $out .= "$id,";
}
$out = substr($out, 0, -1);


// Query database for caller IPs and incident counts
// Query database for caller IPs and incident counts
$query = "SELECT INET_NTOA(sipcallerip), COUNT(*) as incidents
$query = "SELECT INET_NTOA(sipcallerip) as ip, COUNT(*) as incidents
           FROM voipmonitor.cdr
           FROM voipmonitor.cdr
           WHERE id IN ($out)
           WHERE id IN ($cdrIds)
           GROUP BY INET_NTOA(sipcallerip)
           GROUP BY sipcallerip
           ORDER BY incidents DESC\\G";
           ORDER BY incidents DESC";
$command = "mysql -h MYSQLHOST -u MYSQLUSER -pMYSQLPASS -e '$query'";
$command = "mysql -h MYSQLHOST -u MYSQLUSER -pMYSQLPASS -N -e \"$query\"";
exec($command, $arr);
exec($command, $results);


// Parse results
// Process results and block IPs exceeding limit
$resultip = array();
foreach ($results as $line) {
$resultcnt = array();
     list($ip, $count) = preg_split('/\s+/', trim($line));
foreach ($arr as $nth => $line) {
     if ($count > $Limit) {
     if (strpos($line, 'INET') === FALSE) continue;
    $pos = strpos($line, ":");
    $resultip[] = substr($line, $pos + 2);
    $resultcnt[] = substr($arr[$nth + 1], strpos($arr[$nth + 1], ":") + 2);
}
 
// Block IPs that exceed limit
if (!count($resultip)) exit;
foreach ($resultip as $n => $ip) {
     if ($resultcnt[$n] > $Limit) {
         if ($verbose) {
         if ($verbose) {
             echo "$ip : $resultcnt[$n] incidents\n$blockCommand $ip\n\n";
             echo "$ip: $count incidents - would block\n";
         } else {
         } else {
             exec($blockCommand . " $ip", $ar, $rc);
             exec("$blockCommand $ip", $output, $rc);
            if ($rc != 0) {
                error_log("Failed to block $ip");
            }
         }
         }
     }
     }
Line 277: Line 317:
#!/usr/bin/php
#!/usr/bin/php
<?php
<?php
// Parse triggered rules
// Parse triggered rules (4th argument)
$triggedRules = json_decode($argv[4]);
$triggeredRules = json_decode($argv[4]);


// Count triggers per IP address
// Count triggers per IP address
$IPtriggers = array();
$IPtriggers = [];
foreach ($triggedRules as $rule) {
foreach ($triggeredRules as $rule) {
     $keyIP = $rule->alert_info->ip;
     $ip = $rule->alert_info->ip;
     $when = $rule->at;
     $IPtriggers[$ip] = ($IPtriggers[$ip] ?? 0) + 1;
 
    if (!isset($IPtriggers[$keyIP])) {
        $IPtriggers[$keyIP] = 1;
    } else {
        $IPtriggers[$keyIP] += 1;
    }
}
}


// Block all IPs that triggered any rule
// Block all IPs that triggered the rule
foreach ($IPtriggers as $IPKey => $nmGuilt) {
foreach ($IPtriggers as $ip => $count) {
     passthru('iptables -A INPUT -s ' . $IPKey . ' -j DROP', $ret);
    echo "Blocking $ip (triggered $count times)\n";
     passthru("iptables -A INPUT -s $ip -j DROP", $ret);
     if ($ret != 0) {
     if ($ret != 0) {
         echo "Problem setting firewall!\n";
         echo "ERROR: Failed to block $ip\n";
         exit(1);
         exit(1);
     }
     }
}
}
echo "Blocked " . count($IPtriggers) . " IP(s)\n";
?>
?>
</syntaxhighlight>
</syntaxhighlight>
Line 309: Line 345:
* [[Capture_rules|Capture Rules]] - Filter traffic before processing
* [[Capture_rules|Capture Rules]] - Filter traffic before processing
* [[Sniffer_configuration|Sniffer Configuration]] - <code>sip-register</code> and other options
* [[Sniffer_configuration|Sniffer Configuration]] - <code>sip-register</code> and other options
* [[Groups|Groups]] - IP groups and time periods for alerts


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


'''Summary:''' VoIPmonitor anti-fraud rules for detecting SIP attacks (REGISTER floods, packet floods), concurrent calls abuse, and geographic anomalies. Includes realtime vs CDR-based alert differences, custom script examples for automated IP blocking, and mitigation strategies.
'''Summary:''' VoIPmonitor anti-fraud rules for detecting SIP attacks (REGISTER floods, packet floods), concurrent calls abuse, and geographic anomalies. Covers realtime vs CDR-based alert processing differences, custom script examples for automated IP blocking via iptables/ipset, and mitigation strategies for SIP REGISTER spam.


'''Keywords:''' anti-fraud, REGISTER flood, SIP attack, concurrent calls, country change, custom scripts, iptables, ipset, fail2ban, realtime alerts, CDR-based alerts
'''Keywords:''' anti-fraud, REGISTER flood, SIP attack, concurrent calls, country change, custom scripts, iptables, ipset, fail2ban, realtime alerts, CDR-based alerts, source port limitation


'''Key Questions:'''
'''Key Questions:'''

Revision as of 18:44, 4 January 2026

Category:GUI manual

Anti-Fraud Rules

Anti-fraud rules are accessed via GUI > Alerts > Anti Fraud. Rules combat fraud and attacks, with ongoing additions. Each rule supports custom scripts for actions like firewall rules, besides email alerts. Alerts are archived in Sent Alerts.

Overview

List of Fraud/Watchdog Alerts

Alert Type Processing Description
Realtime concurrent calls Realtime Monitors concurrent calls per source IP
SIP REGISTER flood/attack Realtime Detects REGISTER flooding from single IP
SIP PACKETS flood/attack Realtime Detects generic SIP packet floods
Country/Continent destination Realtime Calls to specific country/continent (based on first INVITE)
Change CDR country CDR-based Source IP geolocation changed between calls
Change REGISTER country CDR-based REGISTER source country changed since last success
Billing Watchdog CDR-based Billing anomaly detection

Alert Processing Differences

VoIPmonitor processes alerts in two fundamentally different ways, which affects what data is available when the alert triggers:

Realtime Alerts

Processed directly by the sniffer as packets arrive. Triggered immediately based on packet inspection.

Alert Trigger Condition
Realtime concurrent calls N+ concurrent calls from same IP
SIP REGISTER flood N+ REGISTER attempts from same IP in interval
SIP PACKETS flood N+ SIP packets from same IP in interval
Country/Continent destination Call to monitored destination (first INVITE)

Characteristics:

  • Immediate triggering (no database delay)
  • CDRs not yet available when alert fires
  • Only IP address available in alert_info (no source port)

CDR-based Alerts

Evaluated by the GUI after CDRs have been stored in the database.

Alert Trigger Condition
Change CDR country IP geolocation differs from previous call
Change REGISTER country REGISTER country differs from last successful registration
RTP alerts Quality thresholds exceeded (MOS, jitter, loss)
SIP Response alerts Specific SIP response codes

Characteristics:

  • Delay between call end and alert (CDR must be written first)
  • Full CDR data available (including source port, duration, etc.)
  • Can query database for additional context

Important Limitation: Source Port in Realtime Alerts

Realtime alerts provide the attacker's IP address in alert_info, but do not include the SIP source port.

The source port can be queried from cdr.caller_port, but this has critical limitations:

  • Delay: CDRs are written after the realtime alert triggers
  • Port may not exist: Flood attacks are often detected before CDR creation

Recommendation:

  • For real-time defense: Block by IP address only (accept temporary impact on legitimate traffic from same IP)
  • For non-real-time blocking: Use CDR-based alerts with database queries

Common Configuration

Options shared across anti-fraud rules:

Option Description
Enable hyperlinks Makes email alert titles clickable links to rule definitions
IP include/exclude Exclude IPs or networks (e.g., 10.0.0.0/8) or use IP groups
Suppress repeating alerts Limit alerts to once per X hours to avoid spamming
Numbers include/exclude Filter source numbers/prefixes
External script Path to custom script for automated actions

International prefixes configuration:

Setting Description Default
International prefixes Prefixes indicating international calls +, 00
Min international length Numbers shorter than this are treated as local varies
Local numbers are in Country for classifying international-prefixed calls as local your country

SIP REGISTER Flood/Attack

Triggers when >= N registration attempts from an IP occur within the set interval.

Mitigation Strategies

When SIP REGISTER floods cause excessive CPU usage or system unresponsiveness:

1. Immediate Blocking via Custom Scripts

Configure a custom script in the SIP REGISTER flood alert rule to automatically block the attacker IP. The alert_info object contains the attacker's IP address.

# Block using iptables
iptables -A INPUT -s <ATTACKER_IP> -j DROP

# Block using ipset (more efficient for multiple IPs)
ipset add blacklist <ATTACKER_IP>
2. Network Edge Blocking (Recommended for Prevention)

For long-term protection, block at your network edge before traffic reaches VoIPmonitor:

  • Session Border Controller (SBC): Configure rate limiting and IP blocking
  • Firewall: Block malicious IPs at the perimeter
  • Fail2ban: Automatically block IPs after repeated REGISTER failures
3. Reducing REGISTER Noise
  • Disable REGISTER processing if not needed: sip-register = no in voipmonitor.conf
  • Filter REGISTER packets using firewall rules (block specific countries or networks)
  • Use capture rules to exclude known good REGISTER sources from processing

Realtime Concurrent Calls

Tracks source IPs in realtime (not CDR-based) for concurrent calls. Useful against high-channel attacks.

Parameters
  • Concurrent calls limit: Trigger on international, local, or both exceeding limits
  • Time period rules: Vary alerts by work/after hours (defined in Groups > TimePeriods)

Change CDR Country

Triggers when CDR IP source changes country/continent since last call.

Parameters
  • Exclude countries from alert: Whitelist countries to skip

Change REGISTER Country

Triggers when SIP REGISTER username changes country/continent since last successful registration.

Parameters
  • Exclude countries from alert: Whitelist countries to skip

Country/Continent Destination

Triggers on calls to specific country/continent, based on first SIP INVITE (realtime processing).

SIP PACKETS Flood/Attack

Triggers when >= N packets from an IP occur within the set interval.

Custom Script Examples

Custom scripts receive alert data as command-line arguments. The fourth argument ($argv[4] in PHP) contains JSON-encoded alert data.

Logging Passed Arguments

Simple script to log all arguments for debugging:

#!/bin/bash
echo "$(date): $@" >> /tmp/alert_debug.txt

RTP Alert: Store Audio Files

Script to automatically download audio for calls that triggered an RTP alert:

#!/usr/bin/php
<?php
// Configuration
$directory = '/home/alerts/audio';
$date = trim(`date '+%Y-%m-%d'`);
$guiDir = '/var/www/voipmonitor';
$destdir = $directory . '/' . $date;

// Create destination directory
`mkdir -p $destdir`;

// Parse alert data (4th argument contains JSON)
$alert = json_decode($argv[4]);

// Download audio for each CDR in the alert
foreach ($alert->cdr as $cdr) {
    $params = json_encode([
        'task' => 'getVoiceRecording',
        'user' => 'admin',
        'password' => 'admin',
        'params' => ['cdrId' => $cdr]
    ]);
    $command = "php $guiDir/php/api.php > $destdir/file_id_$cdr.pcap";
    exec("echo '$params' | $command", $arr, $val);
}
?>

RTP Alert: Block IP After Threshold

Script to block IPs that exceed a threshold number of incidents:

#!/usr/bin/php
<?php
// Configuration
$Limit = 19;                                              // Block after this many incidents
$blockCommand = "ssh root@pbx -p2112 ipset add blacklist"; // Remote blocking command
$verbose = 1;                                             // 1 = dry-run, 0 = execute

// Parse alert data
$alertsData = json_decode($argv[4]);

// Build comma-separated list of CDR IDs
$cdrIds = implode(',', $alertsData->cdr);

// Query database for caller IPs and incident counts
$query = "SELECT INET_NTOA(sipcallerip) as ip, COUNT(*) as incidents
          FROM voipmonitor.cdr
          WHERE id IN ($cdrIds)
          GROUP BY sipcallerip
          ORDER BY incidents DESC";
$command = "mysql -h MYSQLHOST -u MYSQLUSER -pMYSQLPASS -N -e \"$query\"";
exec($command, $results);

// Process results and block IPs exceeding limit
foreach ($results as $line) {
    list($ip, $count) = preg_split('/\s+/', trim($line));
    if ($count > $Limit) {
        if ($verbose) {
            echo "$ip: $count incidents - would block\n";
        } else {
            exec("$blockCommand $ip", $output, $rc);
            if ($rc != 0) {
                error_log("Failed to block $ip");
            }
        }
    }
}
?>

Concurrent Calls: Block Attacker IP

Script for blocking IPs based on concurrent calls alert. Enable "By caller IP" in alert settings.

#!/usr/bin/php
<?php
// Parse triggered rules (4th argument)
$triggeredRules = json_decode($argv[4]);

// Count triggers per IP address
$IPtriggers = [];
foreach ($triggeredRules as $rule) {
    $ip = $rule->alert_info->ip;
    $IPtriggers[$ip] = ($IPtriggers[$ip] ?? 0) + 1;
}

// Block all IPs that triggered the rule
foreach ($IPtriggers as $ip => $count) {
    echo "Blocking $ip (triggered $count times)\n";
    passthru("iptables -A INPUT -s $ip -j DROP", $ret);
    if ($ret != 0) {
        echo "ERROR: Failed to block $ip\n";
        exit(1);
    }
}
echo "Blocked " . count($IPtriggers) . " IP(s)\n";
?>

See Also

AI Summary for RAG

Summary: VoIPmonitor anti-fraud rules for detecting SIP attacks (REGISTER floods, packet floods), concurrent calls abuse, and geographic anomalies. Covers realtime vs CDR-based alert processing differences, custom script examples for automated IP blocking via iptables/ipset, and mitigation strategies for SIP REGISTER spam.

Keywords: anti-fraud, REGISTER flood, SIP attack, concurrent calls, country change, custom scripts, iptables, ipset, fail2ban, realtime alerts, CDR-based alerts, source port limitation

Key Questions:

  • What anti-fraud alerts are available in VoIPmonitor?
  • How to block SIP REGISTER flood attacks?
  • What is the difference between realtime and CDR-based alerts?
  • How to create custom scripts for automated IP blocking?
  • Why is source port not available in realtime alerts?