created alert script for mikrotik which sends a push notification in case new devices log into the network
This commit is contained in:
145
mikrotik/arp-monitor.rsc
Normal file
145
mikrotik/arp-monitor.rsc
Normal file
@ -0,0 +1,145 @@
|
||||
# ARP Table Monitor Script for MikroTik RouterOS
|
||||
# This script monitors ARP table and sends REST API notifications for new MAC+IP combinations
|
||||
|
||||
# Configuration variables
|
||||
:local apiEndpoint "http://10.10.10.6:8500/mikrotik-389210-instant"
|
||||
:local monitorInterfaces {"vlan-guest"; "vlan-iot"; "vlan-home"}
|
||||
|
||||
# Create global variable to store known MAC+IP combinations if it doesn't exist
|
||||
:global arpKnownDevices
|
||||
:if ([:typeof $arpKnownDevices] = "nothing") do={
|
||||
:set arpKnownDevices [:toarray ""]
|
||||
}
|
||||
# Uncomment while testing, comment for production
|
||||
# :set arpKnownDevices [:toarray ""]
|
||||
|
||||
# Get current ARP entries
|
||||
:local currentArpEntries [:toarray ""]
|
||||
:local arpEntries
|
||||
|
||||
# Get ARP entries - filter by interface if specified
|
||||
:if ([:len $monitorInterfaces] > 0) do={
|
||||
:set arpEntries [:toarray ""]
|
||||
:foreach iface in=$monitorInterfaces do={
|
||||
:do {
|
||||
:local ifaceEntries [/ip arp find interface=$iface]
|
||||
:foreach entry in=$ifaceEntries do={
|
||||
:if ([:len $arpEntries] = 0) do={
|
||||
:set arpEntries $entry
|
||||
} else={
|
||||
:set arpEntries ($arpEntries, $entry)
|
||||
}
|
||||
}
|
||||
} on-error={
|
||||
:log warning "Could not access interface: $iface"
|
||||
}
|
||||
}
|
||||
:if ([:len $arpEntries] > 0) do={
|
||||
:set arpEntries [:toarray $arpEntries]
|
||||
}
|
||||
} else={
|
||||
# Monitor all interfaces
|
||||
:set arpEntries [/ip arp find]
|
||||
}
|
||||
|
||||
# Check for new MAC+IP combinations
|
||||
:local newDevicesFound false
|
||||
:local requestBody ""
|
||||
|
||||
:if ([:len $arpEntries] > 0) do={
|
||||
:foreach arpEntry in=$arpEntries do={
|
||||
:local arpInfo [/ip arp get $arpEntry]
|
||||
|
||||
# Skip incomplete, invalid, or dynamic entries if desired
|
||||
:local arpStatus ($arpInfo->"status")
|
||||
:if ($arpStatus = "reachable" || $arpStatus = "stale" || $arpStatus = "delay") do={
|
||||
|
||||
:local macAddress ($arpInfo->"mac-address")
|
||||
:local ipAddress ($arpInfo->"address")
|
||||
:local interface ($arpInfo->"interface")
|
||||
|
||||
# Create unique identifier for MAC+IP combination
|
||||
:local deviceId ($macAddress . "-" . $ipAddress)
|
||||
|
||||
# Check if this MAC+IP combination is already known
|
||||
:local isKnown false
|
||||
:if ([:len $arpKnownDevices] > 0) do={
|
||||
:if ([:find $arpKnownDevices $deviceId] >= 0) do={
|
||||
:set isKnown true
|
||||
}
|
||||
}
|
||||
|
||||
# If not known, process as new device
|
||||
:if (!$isKnown) do={
|
||||
:set newDevicesFound true
|
||||
|
||||
# Get additional info
|
||||
:local arpComment ""
|
||||
:if ([:typeof ($arpInfo->"comment")] != "nothing") do={
|
||||
:set arpComment ($arpInfo->"comment")
|
||||
} else={
|
||||
:set arpComment "N/A"
|
||||
}
|
||||
|
||||
# Try to get hostname from DHCP lease table (if available)
|
||||
:local hostname "Unknown"
|
||||
:do {
|
||||
:local dhcpLease [/ip dhcp-server lease find address=$ipAddress]
|
||||
:if ([:len $dhcpLease] > 0) do={
|
||||
:local leaseInfo [/ip dhcp-server lease get [:pick $dhcpLease 0]]
|
||||
:if ([:typeof ($leaseInfo->"host-name")] != "nothing") do={
|
||||
:set hostname ($leaseInfo->"host-name")
|
||||
}
|
||||
}
|
||||
} on-error={
|
||||
# DHCP lookup failed, keep hostname as "Unknown"
|
||||
}
|
||||
|
||||
# Build notification body
|
||||
:set requestBody ($requestBody . "MAC+IP Address: " . $deviceId . "\n")
|
||||
:set requestBody ($requestBody . "Interface: " . $interface . "\n")
|
||||
:set requestBody ($requestBody . "ARP Status: " . $arpStatus . "\n")
|
||||
:set requestBody ($requestBody . "Hostname: " . $hostname . "\n")
|
||||
:set requestBody ($requestBody . "----------------------------------------\n")
|
||||
|
||||
# Add to known devices
|
||||
:if ([:len $arpKnownDevices] = 0) do={
|
||||
:set arpKnownDevices $deviceId
|
||||
} else={
|
||||
:set arpKnownDevices ($arpKnownDevices . "," . $deviceId)
|
||||
}
|
||||
|
||||
:log info "New ARP entry detected: $macAddress at $ipAddress on $interface"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Send REST API notification for new devices
|
||||
:if ($newDevicesFound) do={
|
||||
:do {
|
||||
/tool fetch \
|
||||
url=$apiEndpoint \
|
||||
http-method=post \
|
||||
http-header-field="Priority: 3,Title: New device detected in network,Tags: warning" \
|
||||
http-data=$requestBody \
|
||||
keep-result=no
|
||||
|
||||
:log info "ARP monitoring notification API request sent"
|
||||
} on-error={
|
||||
:log error "Failed to send ARP monitoring notification API request"
|
||||
}
|
||||
} else={
|
||||
:log info "No new mac/ip combinations in ARP"
|
||||
}
|
||||
|
||||
# Clean up known devices list if it gets too large
|
||||
:local knownCount 0
|
||||
:if ([:len $arpKnownDevices] > 0) do={
|
||||
:set knownCount [:len [:toarray $arpKnownDevices]]
|
||||
}
|
||||
:if ($knownCount > 2000) do={
|
||||
:log warning "Known ARP devices list is getting large ($knownCount entries), consider resetting it"
|
||||
# Uncomment the next line to auto-reset when list gets too large
|
||||
# :global arpKnownDevices ""
|
||||
}
|
||||
Reference in New Issue
Block a user