|
|
| (4 intermediate revisions by the same user not shown) |
| Line 1: |
Line 1: |
| {{DISPLAYTITLE:Anti-Fraud Rules}} | | {{DISPLAYTITLE:Anti-Fraud Detection}} |
| Category:GUI manual | | [[Category:Configuration]] |
| | [[Category:Alerts]] |
|
| |
|
| == Anti-Fraud Rules ==
| | = Anti-Fraud Detection = |
|
| |
|
| 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.
| | VoIPmonitor provides GeoIP-based anti-fraud alerts to detect toll fraud, account hijacking, and brute-force attacks. |
|
| |
|
| === Overview ===
| | <kroki lang="mermaid"> |
| | | %%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 30}}}%% |
| <kroki lang="plantuml"> | | flowchart LR |
| @startuml
| | subgraph Detection |
| skinparam shadowing false
| | A[CDR/Register Data] --> B{GeoIP Lookup} |
| skinparam defaultFontName Arial
| | B --> C[Country/IP Analysis] |
| skinparam rectangle {
| | end |
| BackgroundColor<<realtime>> #E8F5E9
| | subgraph Alert Types |
| BackgroundColor<<cdr>> #E3F2FD
| | C --> D[Country Destination] |
| BackgroundColor<<action>> #FFF3E0
| | C --> E[CDR Country Change] |
| } | | C --> F[Register Country Change] |
| | | C --> G[Sequential Pattern] |
| rectangle "VoIPmonitor\nSensor" as sensor
| | C --> H[Failed Register] |
| rectangle "Realtime\nDetection" as realtime <<realtime>>
| | end |
| rectangle "CDR-based\nDetection" as cdr_detect <<cdr>>
| | subgraph Response |
| database "MySQL" as db
| | D & E & F & G & H --> I[Email Alert] |
| rectangle "Alert\nProcessor" as processor
| | end |
| rectangle "Custom\nScript" as script <<action>>
| |
| rectangle "Firewall\n(iptables)" as fw <<action>>
| |
| rectangle "Email\nNotification" as email <<action>>
| |
| | |
| sensor --> realtime : SIP packets\n(immediate)
| |
| sensor --> db : CDRs
| |
| realtime --> processor : Trigger
| |
| db --> cdr_detect : Query
| |
| cdr_detect --> processor : Threshold\nexceeded
| |
| processor --> script : Execute
| |
| processor --> email : Send
| |
| script --> fw : Block IP
| |
| | |
| legend right
| |
| |= Color |= Type |
| |
| | <#E8F5E9> | Realtime processing |
| |
| | <#E3F2FD> | CDR-based processing |
| |
| | <#FFF3E0> | Actions |
| |
| endlegend
| |
| @enduml
| |
| </kroki> | | </kroki> |
|
| |
|
| === List of Fraud/Watchdog Alerts === | | == Configuration == |
|
| |
|
| {| class="wikitable"
| | All anti-fraud alerts are configured in '''GUI → Alerts → Anti Fraud'''. |
| |-
| |
| ! 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)
| |
| |-
| |
| | Fraud: sequential || CDR-based || Detects high volume of calls to a destination within a time window
| |
| |-
| |
| | 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|Billing Watchdog]] || CDR-based || Billing anomaly detection
| |
| |}
| |
|
| |
|
| === Alert Processing Differences === | | {{Note|1=Anti-fraud features require GeoIP configuration. See [[#GeoIP Integration|GeoIP Integration]] below.}} |
|
| |
|
| VoIPmonitor processes alerts in two fundamentally different ways, which affects what data is available when the alert triggers:
| | == Alert Types == |
|
| |
|
| ==== Realtime Alerts ==== | | === Country/Continent Destination === |
| | |
| Processed directly by the sniffer as packets arrive. Triggered immediately based on packet inspection.
| |
|
| |
|
| {| class="wikitable"
| | Real-time detection of calls to specific countries or continents. Primary use case: detecting toll fraud where compromised accounts make expensive international calls. |
| |-
| |
| ! 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:''' | | '''Configuration:''' |
| * Immediate triggering (no database delay) | | * Select target countries/continents to monitor |
| * CDRs not yet available when alert fires | | * Set threshold for number of calls |
| * Only IP address available in <code>alert_info</code> (no source port) | | * Configure notification recipients |
|
| |
|
| ==== CDR-based Alerts ==== | | === Change CDR Country === |
|
| |
|
| Evaluated by the GUI after CDRs have been stored in the database.
| | Detects when the IP country of caller or callee changes between calls - indicates potential account compromise or SIP credential theft. |
|
| |
|
| {| class="wikitable"
| | '''Configuration:''' |
| |-
| | * Whitelist trusted countries (Exclude countries field) |
| ! Alert !! Trigger Condition
| | * Apply filters by phone numbers or IP addresses |
| |-
| |
| | 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:'''
| | === Change REGISTER Country === |
| * 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 ====
| | Detects device registration from unexpected countries - strong indicator of credential theft or account hijacking. |
|
| |
|
| Realtime alerts provide the attacker's IP address in <code>alert_info</code>, but do '''not''' include the SIP source port.
| | '''Example:''' User normally registers from Germany but suddenly registers from Russia → alert triggers. |
|
| |
|
| The source port can be queried from <code>cdr.caller_port</code>, but this has critical limitations:
| | === Fraud: Sequential === |
| * '''Delay''': CDRs are written after the realtime alert triggers
| |
| * '''Port may not exist''': Flood attacks are often detected before CDR creation
| |
|
| |
|
| '''Recommendation:'''
| | Detects high-volume sequential calling patterns to destination numbers within a time window. |
| * 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:
| |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Option !! Description | | ! Parameter !! Description !! Example Values |
| |- | | |- |
| | Enable hyperlinks || Makes email alert titles clickable links to rule definitions | | | '''interval''' || Time window (seconds) for counting calls || 600 (10 min), 3600 (1 hour) |
| |- | | |- |
| | IP include/exclude || Exclude IPs or networks (e.g., <code>10.0.0.0/8</code>) or use IP groups | | | '''limit''' || Max calls allowed before alert triggers || 50, 100, 500 |
| |- | | |- |
| | Suppress repeating alerts || Limit alerts to once per X hours to avoid spamming | | | '''number field''' || Target destination number (leave empty for ANY) || Empty or specific number |
| |-
| |
| | Numbers include/exclude || Filter source numbers/prefixes. This field supports regular expressions using the <code>R()</code> syntax (same as CDR filters). You can also use [[Groups|telephone number groups]] instead of entering patterns directly.
| |
| |-
| |
| | External script || Path to custom script for automated actions
| |
| |} | | |} |
|
| |
|
| '''International prefixes configuration:''' | | {{Warning|1='''Critical:''' Leave the number field '''empty''' to monitor ALL destination numbers. The alert fires when ANY single destination exceeds the limit within the interval.}} |
| {| class="wikitable"
| |
| |-
| |
| ! 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
| |
| |}
| |
| | |
| === Getting Passed Arguments ===
| |
| | |
| Custom scripts are invoked with command-line arguments containing alert information. The fourth argument (<code>$argv[4]</code> in PHP) contains a JSON-encoded object with detailed alert data.
| |
|
| |
|
| ==== Argument Structure ===
| | '''Configuration Steps:''' |
| | # Navigate to '''GUI → Alerts → Anti Fraud''' |
| | # Create new alert with type '''Fraud: sequential''' |
| | # Set '''interval''' (e.g., 600 for 10 minutes) |
| | # Set '''limit''' (e.g., 100 calls) |
| | # '''Leave number field empty''' to apply to ANY number |
| | # Configure recipient email |
| | # Save |
|
| |
|
| The script receives the following arguments:
| | '''Example Configurations:''' |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Argument Index !! Variable (PHP) !! Description | | ! Scenario !! interval !! limit !! number field |
| |- | | |- |
| | $argv[1] || alert ID || Numeric identifier of the triggered alert | | | >100 calls to any number in 10 min || 600 || 100 || Empty |
| |- | | |- |
| | $argv[2] || rule name || Name of the anti-fraud rule (e.g., "SIP REGISTER flood") | | | >500 calls to any number in 1 hour || 3600 || 500 || Empty |
| |- | | |- |
| | $argv[3] || timestamp || Unix timestamp when the alert triggered | | | >50 calls in 5 min (high-volume attack) || 300 || 50 || Empty |
| |- | | |- |
| | $argv[4] || alert data || JSON-encoded object with alert-specific data | | | Monitor specific premium number || 1800 || 200 || Specify number |
| |} | | |} |
|
| |
|
| ==== Alert Data Structure (JSON in $argv[4]) ===
| | {{Tip|1='''Fraud: sequential vs concurrent calls:''' Sequential alerts count total calls over a time window. Concurrent alerts detect simultaneous active calls at one moment. Use sequential for detecting volume spikes, concurrent for capacity monitoring.}} |
| | |
| The JSON structure varies by alert type:
| |
| | |
| ===== Realtime Alerts (REGISTER flood, PACKET flood, Concurrent calls) =====
| |
| | |
| <syntaxhighlight lang="json">
| |
| { | |
| "alert_info": {
| |
| "ip": "192.0.2.1",
| |
| "port": 5060,
| |
| "count": 1500
| |
| },
| |
| "rule_name": "SIP REGISTER flood",
| |
| "triggered_at": "2025-01-05 10:30:00"
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| ===== CDR-based Alerts (RTP, SIP Response, Country change) ===== | |
| | |
| <syntaxhighlight lang="json">
| |
| {
| |
| "cdr": [12345, 12346, 12347],
| |
| "alert_type": "MOS below threshold",
| |
| "threshold": 3.5,
| |
| "actual_value": 2.8,
| |
| "rule_name": "Low MOS Alert",
| |
| "triggered_at": "2025-01-05 10:30:00"
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| ===== Triggered Rules Structure (Multiple Rule Triggers) =====
| |
| | |
| Some alert types (like concurrent calls) return an array of triggered rules:
| |
| | |
| <syntaxhighlight lang="json">
| |
| [
| |
| {
| |
| "rule_name": "Concurrent calls limit",
| |
| "alert_info": {
| |
| "ip": "192.0.2.1",
| |
| "count": 250
| |
| }
| |
| },
| |
| {
| |
| "rule_name": "Concurrent calls limit",
| |
| "alert_info": {
| |
| "ip": "198.51.100.5",
| |
| "count": 180
| |
| }
| |
| }
| |
| ]
| |
| </syntaxhighlight>
| |
| | |
| ==== Accessing Data in Scripts ===
| |
| | |
| ===== PHP Example =====
| |
| | |
| <syntaxhighlight lang="php">
| |
| #!/usr/bin/php
| |
| <?php
| |
| // Parse alert data from 4th argument
| |
| $alertData = json_decode($argv[4]);
| |
| | |
| // Check if it's a single alert or array of rules
| |
| if (isset($alertData->alert_info)) {
| |
| // Single alert
| |
| echo "Alert: " . $argv[2] . "\n";
| |
| echo "IP: " . $alertData->alert_info->ip . "\n";
| |
| } else if (is_array($alertData)) {
| |
| // Array of triggered rules (concurrent calls)
| |
| foreach ($alertData as $rule) {
| |
| echo "Blocking: " . $rule->alert_info->ip . "\n";
| |
| }
| |
| }
| |
| | |
| // For CDR-based alerts
| |
| if (isset($alertData->cdr)) {
| |
| $cdrIds = implode(',', $alertData->cdr);
| |
| echo "Processing CDRs: " . $cdrIds . "\n";
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
| | |
| ===== Bash Example ===
| |
| | |
| <syntaxhighlight lang="bash">
| |
| #!/bin/bash
| |
| # Log all arguments for debugging
| |
| echo "$(date): Alert triggered" >> /tmp/anti_fraud.log
| |
| echo "Timestamp: $(date -d @$1)" >> /tmp/anti_fraud.log
| |
| echo "Rule: $2" >> /tmp/anti_fraud.log
| |
| echo "Alert Data: $4" >> /tmp/anti_fraud.log
| |
| | |
| # Extract IP address using jq (if available)
| |
| if command -v jq &> /dev/null; then
| |
| IP=$(echo "$4" | jq -r '.alert_info.ip // empty')
| |
| echo "Attacker IP: $IP" >> /tmp/anti_fraud.log
| |
| fi
| |
| </syntaxhighlight>
| |
| | |
| ==== Important Notes ===
| |
| | |
| * **Source Port in Realtime Alerts**: The <code>alert_info.ip</code> field contains the attacker IP, but source port may not be available for realtime alerts (processed before CDR creation).
| |
| * **CDR IDs**: For CDR-based alerts, use the <code>cdr</code> array to query additional information from the database.
| |
| * **Error Handling**: Always validate JSON structure and check for required fields before processing.
| |
| * **Script Permissions**: Ensure the custom script is executable (e.g., <code>chmod +x /path/to/script.sh</code>).
| |
| | |
| === 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 ===== | | === SIP Failed Register === |
|
| |
|
| 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.
| | Detects brute-force and credential stuffing attacks by monitoring failed registration attempts. |
| | |
| <syntaxhighlight lang="bash">
| |
| # Block using iptables
| |
| iptables -A INPUT -s <ATTACKER_IP> -j DROP
| |
| | |
| # Block using ipset (more efficient for multiple IPs)
| |
| ipset add blacklist <ATTACKER_IP>
| |
| </syntaxhighlight>
| |
| | |
| ===== 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: <code>sip-register = no</code> in <code>voipmonitor.conf</code>
| |
| * Filter REGISTER packets using firewall rules (block specific countries or networks)
| |
| * Use [[Capture_rules|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''')
| |
| | |
| ==== IP Filtering Capabilities and Limitations ====
| |
| | |
| The "'''BY'''" dropdown in the Realtime Concurrent Calls alert configuration only supports Source IP aggregation. This is a hard-coded limitation of the realtime detection logic, which monitors concurrent INVITEs per source address to detect attacks.
| |
| | |
| To monitor concurrent calls based on '''Destination IP''' (such as checking if a specific carrier or trunk exceeds a channel limit), use the standard '''Concurrent calls''' alert located in '''GUI > Alerts''' instead. The regular concurrent calls alert supports multiple aggregation options including Source IP, Destination IP (Called), Domain, and custom headers.
| |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Monitoring Need !! Recommended Alert Type !! GUI Location | | ! Parameter !! Description |
| |-
| |
| | Detect attacks from specific source IPs || '''Realtime concurrent calls''' || Alerts > Anti Fraud
| |
| |- | | |- |
| | Monitor trunk/capacity limits (by destination IP) || '''Concurrent calls''' || Alerts (main section)
| | | '''threshold''' || Maximum failed attempts before alert |
| |- | | |- |
| | Detect domain-specific concurrent call patterns || '''Concurrent calls''' || Alerts (main section)
| | | '''interval''' || Time window (seconds) for counting attempts |
| |} | | |} |
|
| |
|
| See [[Alerts#Fraud_Concurrent_Calls_vs_Regular_Concurrent_Calls_Alerts|Alerts - Fraud Concurrent Calls vs Regular Concurrent Calls Alerts]] for a detailed comparison.
| | == GeoIP Integration == |
| | |
| === Change CDR Country === | |
| | |
| Triggers when CDR IP source changes country/continent since last call.
| |
| | |
| ;Parameters:
| |
| :* '''Exclude countries from alert''': Whitelist countries to skip
| |
| | |
| ==== Number-Based Filtering
| |
| | |
| You can use the '''Numbers include/exclude''' parameter to limit this alert based on caller number patterns. This is useful when you want to trigger the alert only for specific call signatures, such as detecting fraud calls with malformed caller IDs containing letters.
| |
| | |
| ===== Using Regex Patterns Directly
| |
| | |
| Enter regex patterns in the '''Numbers include/exclude''' field:
| |
| | |
| :* Detect numbers containing letters:
| |
| :<code>R([a-zA-Z])</code>
| |
| | |
| :* Detect numbers that are NOT purely numeric (malformed caller IDs):
| |
| :<code>!R(^[+]?[0-9]+$)</code>
| |
| | |
| The <code>R()</code> syntax enables regular expression mode. See [[Call_Detail_Record_-_CDR#Regular_Expressions_for_Advanced_Number_Filtering|CDR filtering documentation]] for more regex examples.
| |
| | |
| ===== Using Telephone Number Groups (Recommended for Complex Patterns)
| |
| | |
| For complex patterns or when you want to reuse the filter across multiple alerts:
| |
| | |
| 1. Create a [[Groups|telephone number group]] at '''GUI > Groups > Tel. numbers'''
| |
| 2. Add regex patterns or specific numbers to the group (e.g., <code>[a-zA-Z]</code> for numbers containing letters)
| |
| 3. Test the group by applying it as a filter in the CDR view
| |
| 4. In the anti-fraud alert settings, click the '''Numbers include/exclude''' field selector
| |
| 5. Select your telephone number group from the dropdown list
| |
| | |
| Using groups is recommended because you can test the pattern against actual CDR data before applying it to alerts.
| |
| | |
| === Change REGISTER Country ===
| |
| | |
| Triggers when SIP REGISTER username changes country/continent since last successful registration.
| |
| | |
| ;Parameters:
| |
| :* '''Exclude countries from alert''': Whitelist countries to skip
| |
| | |
| === Detecting User-Agent Changes ===
| |
| | |
| There is '''no built-in alert''' for detecting changes to a SIP registration's User-Agent (UA) string. However, you can enable database-level tracking of UA changes by configuring the sniffer to create new register state records when the UA changes.
| |
| | |
| To enable UA change tracking, set <code>sip-register-state-compare-digest_ua = yes</code> (or its alias <code>sip-register-state-compare-ua = yes</code>) in <code>voipmonitor.conf</code>. This forces the sniffer to create a new record in the register state table whenever the UA changes, even if other registration details remain the same. See [[Sniffer_configuration#SIP_REGISTER,_OPTIONS,_SUBSCRIBE,_NOTIFY|Sniffer Configuration]] for details.
| |
| | |
| ;Alternative fraud alerts for registration anomalies:
| |
| :* '''Change REGISTER country''': Detects when registration source country changes
| |
| :* '''Change CDR country''': Detects when call source country changes
| |
| | |
| ;Custom detection:
| |
| :* Query the <code>register_state</code> database table to detect UA changes programmatically
| |
| :* Use custom scripts with anti-fraud rules to trigger actions based on database queries
| |
| | |
| === 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.
| |
| | |
| === Fraud: Sequential ===
| |
| | |
| Detects when a high volume of calls are made to any single destination number within a short time period. Use this alert to monitor for patterns like excessive sequential dialing to premium rate numbers or destination abuse.
| |
| | |
| ;Parameters:
| |
| :* '''Interval''': Time window in seconds to monitor call volume (e.g., 3600 for 1 hour)
| |
| :* '''Limit''': Maximum number of calls allowed within the interval (e.g., 100)
| |
| :* '''Called number filters''': Destination numbers/prefixes to monitor (leave empty to monitor all destinations)
| |
| | |
| ;Configuration for "Any Single Destination":
| |
| :* To alert on call volume to '''any''' destination number (not specific numbers), leave the called number field empty. The alert will then detect excessive calling to any single number within the configured time window.
| |
| | |
| ;Example Use Cases:
| |
| :* Alert when more than 50 calls are made to the same destination within 1 hour
| |
| :* Detect sequential dialing to premium rate numbers
| |
| :* Identify destination number abuse or toll fraud
| |
| :* Detect [[Sniffer_troubleshooting#Routing_Loops|routing loops]] by monitoring excessive calls to a single destination number (routing loops typically cause rapid repeated attempts to the same called number)
| |
| | |
| ;Important Limitation:
| |
| :* '''Aggregation method:''' This alert aggregates and monitors call volume '''by source IP address''', not by the calling (source) telephone number.
| |
| :* If you need to detect excessive use of a '''specific calling number''', use the '''CDR summary report''' instead (configure it with Summary type set to ''source number'').
| |
| | |
| === Custom Script Examples ===
| |
| | |
| 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 ====
| |
| | |
| Simple script to log all arguments for debugging:
| |
| | |
| <syntaxhighlight lang="bash">
| |
| #!/bin/bash
| |
| echo "$(date): $@" >> /tmp/alert_debug.txt
| |
| </syntaxhighlight>
| |
| | |
| ==== RTP Alert: Store Audio Files ====
| |
| | |
| Script to automatically download audio for calls that triggered an RTP alert:
| |
| | |
| <syntaxhighlight lang="php">
| |
| #!/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);
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
| | |
| ==== RTP Alert: Block IP After Threshold ====
| |
| | |
| Script to block IPs that exceed a threshold number of incidents:
| |
| | |
| <syntaxhighlight lang="php">
| |
| #!/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
| | Anti-fraud alerts require GeoIP for IP-to-country resolution. |
| 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");
| |
| }
| |
| }
| |
| }
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
|
| |
|
| ==== Concurrent Calls: Block Attacker IP ====
| | '''Configuration:''' GUI → Settings → System Configuration → GeoIP |
|
| |
|
| Script for blocking IPs based on concurrent calls alert. Enable "By caller IP" in alert settings.
| | '''Processing priority (fallback mechanism):''' |
| | # MaxMind API (commercial, highest accuracy) |
| | # IPInfoDB API |
| | # Local GeoIP database (GeoIPCity.dat or MySQL tables) |
| | # Free portals (backup) |
|
| |
|
| <syntaxhighlight lang="php">
| | For detailed GeoIP configuration, see [[Order_of_GeoIP_processing]]. |
| #!/usr/bin/php
| |
| <?php
| |
| // Parse triggered rules (4th argument)
| |
| $triggeredRules = json_decode($argv[4]);
| |
|
| |
|
| // Count triggers per IP address
| | == Best Practices == |
| $IPtriggers = [];
| |
| foreach ($triggeredRules as $rule) {
| |
| $ip = $rule->alert_info->ip;
| |
| $IPtriggers[$ip] = ($IPtriggers[$ip] ?? 0) + 1;
| |
| }
| |
|
| |
|
| // Block all IPs that triggered the rule | | * '''Toll fraud prevention:''' Configure Country/Continent Destination alerts for premium rate countries |
| foreach ($IPtriggers as $ip => $count) {
| | * '''Account protection:''' Enable Change REGISTER Country for all critical accounts |
| echo "Blocking $ip (triggered $count times)\n";
| | * '''Brute-force protection:''' Set SIP Failed Register with low threshold (e.g., 10 attempts in 60 seconds) |
| passthru("iptables -A INPUT -s $ip -j DROP", $ret);
| | * '''Volume monitoring:''' Use Fraud: sequential with empty number field to catch attacks on any destination |
| if ($ret != 0) {
| | * '''Granular control:''' Combine with [[Groups|IP Groups]] for provider-specific monitoring |
| echo "ERROR: Failed to block $ip\n";
| |
| exit(1);
| |
| }
| |
| }
| |
| echo "Blocked " . count($IPtriggers) . " IP(s)\n";
| |
| ?>
| |
| </syntaxhighlight>
| |
|
| |
|
| === See Also ===
| | == See Also == |
|
| |
|
| * [[Alerts|Alerts & Reports]] - General alert configuration | | * [[Alerts]] - General alert configuration and email setup |
| * [[Capture_rules|Capture Rules]] - Filter traffic before processing | | * [[Order_of_GeoIP_processing]] - GeoIP configuration details |
| * [[Sniffer_configuration|Sniffer Configuration]] - <code>sip-register</code> and other options | | * [[Groups]] - IP and telephone number groups for filtering |
| * [[Groups|Groups]] - IP groups and time periods for alerts | | * [[Register]] - SIP registration monitoring |
|
| |
|
| == AI Summary for RAG == | | == AI Summary for RAG == |
|
| |
|
| '''Summary:''' VoIPmonitor anti-fraud rules for detecting SIP attacks (REGISTER floods, packet floods), concurrent calls abuse, geographic anomalies, and high-volume sequential calling patterns. 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. | | '''Summary:''' VoIPmonitor anti-fraud detection guide using GeoIP-based alerts. Alert types: (1) Country/Continent Destination - real-time detection of calls to specific countries for toll fraud prevention; (2) Change CDR Country - detects IP country changes between calls indicating account compromise; (3) Change REGISTER Country - detects registration from unexpected countries indicating credential theft; (4) Fraud: sequential - detects high-volume calling patterns using interval (time window in seconds) and limit (max calls) parameters, CRITICAL: leave number field empty to monitor ALL destination numbers; (5) SIP Failed Register - detects brute-force attacks via failed registration monitoring. Configuration path: GUI → Alerts → Anti Fraud. Requires GeoIP configuration (Settings → System Configuration → GeoIP) with MaxMind API as highest priority. |
|
| |
|
| '''Keywords:''' anti-fraud, REGISTER flood, SIP attack, concurrent calls, country change, custom scripts, iptables, ipset, fail2ban, realtime alerts, CDR-based alerts, source port limitation, sequential calls, sequential dialing, destination abuse, high call volume, large volume of calls, destination number, short period, alert configuration, number filtering, regex patterns, telephone number groups, R() syntax, Change CDR Country, Change REGISTER Country, Numbers include/exclude, malformed caller IDs, letters in phone numbers | | '''Keywords:''' anti-fraud, toll fraud, fraud detection, GeoIP, country alert, Change CDR Country, Change REGISTER Country, Fraud sequential, interval, limit, number field empty, SIP failed register, brute-force, credential stuffing, account hijacking, premium rate numbers, sequential pattern detection, call volume monitoring |
|
| |
|
| '''Key Questions:''' | | '''Key Questions:''' |
| * What anti-fraud alerts are available in VoIPmonitor? | | * How do I configure anti-fraud alerts in VoIPmonitor? |
| * How to block SIP REGISTER flood attacks? | | * How do I detect toll fraud in VoIPmonitor? |
| * What is the difference between realtime and CDR-based alerts? | | * What is the Fraud: sequential alert and how do I configure it? |
| * How to create custom scripts for automated IP blocking?
| | * How do I detect high volume calls to any destination number? |
| * Why is source port not available in realtime alerts?
| | * Should I leave the number field empty in Fraud: sequential? |
| * How to configure an alert for a large volume of calls to any single destination number? | | * What is the difference between Fraud: sequential and concurrent calls alerts? |
| * What is the Fraud: sequential alert and how does it work? | | * How do I detect account hijacking in VoIPmonitor? |
| * How to filter anti-fraud alerts by caller number patterns? | | * How do I configure alerts for international calls? |
| * How to trigger "Change CDR Country" alert only for numbers containing letters? | | * What is the Change REGISTER Country alert? |
| * How to use regex patterns (R() syntax) in anti-fraud number filtering? | | * How do I detect brute-force attacks on SIP registration? |
| * How to use telephone number groups in anti-fraud alerts? | | * How does VoIPmonitor use GeoIP for fraud detection? |