diff --git a/LibreNMS/Snmptrap/Handlers/FgTrapAvOversize.php b/LibreNMS/Snmptrap/Handlers/FgTrapAvOversize.php new file mode 100644 index 0000000000..788ca98512 --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FgTrapAvOversize.php @@ -0,0 +1,50 @@ +. + * + * The Fortigate received a file that is larger than the proxy buffer for + * AV scanning. Nothing to do. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 Heath Barnhart + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FgTrapAvOversize implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + Log::event("$device->hostname received a file that exceeds proxy buffer, skipping AV scan", $device->device_id, 'trap', 2); + } +} diff --git a/LibreNMS/Snmptrap/Handlers/FgTrapIpsAnomaly.php b/LibreNMS/Snmptrap/Handlers/FgTrapIpsAnomaly.php new file mode 100644 index 0000000000..117dd433a4 --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FgTrapIpsAnomaly.php @@ -0,0 +1,51 @@ +. + * + * Fortigate DDoS Policy tripped. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 KanREN, Inc + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FgTrapIpsAnomaly implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + $srcIp = $trap->getOidData($trap->findOid('FORTINET-FORTIGATE-MIB::fgIpsTrapSrcIp')); + $proto = $trap->getOidData($trap->findOid('FORTINET-FORTIGATE-MIB::fgIpsTrapSigMsg')); + Log::event("DDoS prevention triggered. Source: $srcIp Protocol: $proto", $device->device_id, 'trap', 4); + } +} diff --git a/LibreNMS/Snmptrap/Handlers/FgTrapIpsPkgUpdate.php b/LibreNMS/Snmptrap/Handlers/FgTrapIpsPkgUpdate.php new file mode 100644 index 0000000000..4c4247ed30 --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FgTrapIpsPkgUpdate.php @@ -0,0 +1,49 @@ +. + * + * Trap sent when Fortigate IPS signature database was updated. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 KanREN, Inc. + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FgTrapIpsPkgUpdate implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + Log::event("IPS package updated on $device->hostname", $device->device_id, 'trap', 2); + } +} diff --git a/LibreNMS/Snmptrap/Handlers/FgTrapIpsSignature.php b/LibreNMS/Snmptrap/Handlers/FgTrapIpsSignature.php new file mode 100644 index 0000000000..6885800583 --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FgTrapIpsSignature.php @@ -0,0 +1,52 @@ +. + * + * Traffic pattern matches Fortigate IPS signature. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 Heath Barnhart + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FgTrapIpsSignature implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + $srcIp = $trap->getOidData($trap->findOid('FORTINET-FORTIGATE-MIB::fgIpsTrapSrcIp')); + $sigNum = $trap->getOidData($trap->findOid('FORTINET-FORTIGATE-MIB::fgIpsTrapSigId')); + $sigName = $trap->getOidData($trap->findOid('FORTINET-FORTIGATE-MIB::fgIpsTrapSigMsg')); + Log::event("IPS signature $sigName detected from $srcIp with Fortiguard ID $sigNum", $device->device_id, 'trap', 4); + } +} diff --git a/LibreNMS/Snmptrap/Handlers/FgTrapVpnTunDown.php b/LibreNMS/Snmptrap/Handlers/FgTrapVpnTunDown.php new file mode 100644 index 0000000000..77c59002c4 --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FgTrapVpnTunDown.php @@ -0,0 +1,51 @@ +. + * + * Fortigate VPN IPSec Tunnel UP. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 KanREN, Inc. + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FgTrapVpnTunDown implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + $remoteGw = $trap->getOidData($trap->findOid('FORTIGATE-MIB::fgVpnTrapRemoteGateway')); + $tunName = $trap->getOidData($trap->findOid('FORTIGATE-MIB::fgVpnTrapPhase1Name')); + Log::event("VPN tunnel $tunName to $remoteGw is down", $device->device_id, 'trap', 3); + } +} diff --git a/LibreNMS/Snmptrap/Handlers/FgTrapVpnTunUp.php b/LibreNMS/Snmptrap/Handlers/FgTrapVpnTunUp.php new file mode 100644 index 0000000000..4abf31381c --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FgTrapVpnTunUp.php @@ -0,0 +1,51 @@ +. + * + * Fortigate VPN IPSec Tunnel UP. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 KanREN, Inc. + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FgTrapVpnTunUp implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + $remoteGw = $trap->getOidData($trap->findOid('FORTIGATE-MIB::fgVpnTrapRemoteGateway')); + $tunName = $trap->getOidData($trap->findOid('FORTIGATE-MIB::fgVpnTrapPhase1Name')); + Log::event("VPN tunnel $tunName to $remoteGw is up", $device->device_id, 'trap', 1); + } +} diff --git a/LibreNMS/Snmptrap/Handlers/FmTrapLogRateThreshold.php b/LibreNMS/Snmptrap/Handlers/FmTrapLogRateThreshold.php new file mode 100644 index 0000000000..fecfb48d36 --- /dev/null +++ b/LibreNMS/Snmptrap/Handlers/FmTrapLogRateThreshold.php @@ -0,0 +1,52 @@ +. + * + * FortiAnalyzer will send this trap when the received log rate + * exceeds the suggested rate for the daily rate license. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2019 KanREN, Inc. + * @author Heath Barnhart + */ + +namespace LibreNMS\Snmptrap\Handlers; + +use App\Models\Device; +use LibreNMS\Interfaces\SnmptrapHandler; +use LibreNMS\Snmptrap\Trap; +use Log; + +class FmTrapLogRateThreshold implements SnmptrapHandler +{ + /** + * Handle snmptrap. + * Data is pre-parsed and delivered as a Trap. + * + * @param Device $device + * @param Trap $trap + * @return void + */ + public function handle(Device $device, Trap $trap) + { + $logRate = $trap->getOidData($trap->findOid('FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmLogRate')); + $logThresh = $trap->getOidData($trap->findOid('FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmLogRateThreshold')); + Log::event("Recommended log rate exceeded. Current Rate: $logRate Recommended Rate: $logThresh", $device->device_id, 'trap', 3); + } +} diff --git a/config/snmptraps.php b/config/snmptraps.php index f949686355..4bc79c7def 100644 --- a/config/snmptraps.php +++ b/config/snmptraps.php @@ -19,5 +19,14 @@ return [ 'MG-SNMP-UPS-MIB::upsmgUtilityRestored' => \LibreNMS\Snmptrap\Handlers\UpsmgUtilityRestored::class, 'EQUIPMENT-MIB::equipStatusTrap' => \LibreNMS\Snmptrap\Handlers\EquipStatusTrap::class, 'LOG-MIB::logTrap' => \LibreNMS\Snmptrap\Handlers\LogTrap::class, + 'FORTINET-FORTIGATE-MIB::fgTrapVpnTunDown' => \LibreNMS\Snmptrap\Handlers\FgTrapVpnTunDown::class, + 'FORTINET-FORTIGATE-MIB::fgTrapVpnTunUp' => \LibreNMS\Snmptrap\Handlers\FgTrapVpnTunUp::class, + 'FORTINET-FORTIGATE-MIB::fgTrapIpsSignature' => \LibreNMS\Snmptrap\Handlers\FgTrapIpsSignature::class, + 'FORTINET-FORTIGATE-MIB::fgTrapIpsAnomaly' => \LibreNMS\Snmptrap\Handlers\FgTrapIpsAnomaly::class, + 'FORTINET-FORTIGATE-MIB::fgTrapAvOversize' => \LibreNMS\Snmptrap\Handlers\FgTrapAvOversize::class, + 'FORTINET-FORTIGATE-MIB::fgTrapIpsPkgUpdate' => \LibreNMS\Snmptrap\Handlers\FgTrapIpsPkgUpdate::class, + 'FORTINET-CORE-MIB::fnTrapMemThreshold' => \LibreNMS\Snmptrap\Handlers\FnTrapMemThreshold::class, + 'FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmTrapLogRateThreshold' => \LibreNMS\Snmptrap\Handlers\FmTrapLogRateThreshold::class, + 'FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmTrapLogAlert' => \LibreNMS\Snmptrap\Handlers\FmTrapLogAlert::class, ] ]; diff --git a/tests/Feature/SnmpTraps/FgTrapAvOversizeTest.php b/tests/Feature/SnmpTraps/FgTrapAvOversizeTest.php new file mode 100644 index 0000000000..d56d8044ff --- /dev/null +++ b/tests/Feature/SnmpTraps/FgTrapAvOversizeTest.php @@ -0,0 +1,52 @@ +. + * + * Unit tests for Fortigate FgTrapAvOversized.php + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2019 KanREN, Inc + * @author Heath Barnhart + */ + +namespace LibreNMS\Tests\Feature\SnmpTraps; + +use App\Models\Device; +use LibreNMS\Snmptrap\Dispatcher; +use LibreNMS\Snmptrap\Trap; +use LibreNMS\Tests\LaravelTestCase; + +class FgTrapAvOversizeTest extends LaravelTestCase +{ + public function testAvOversize() + { + $device = factory(Device::class)->create(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIGATE-MIB::fgTrapAvOversize +FORTINET-CORE-MIB::fnSysSerial.0 $device->serial +SNMPv2-MIB::sysName.0 $device->hostname"; + + $message = "$device->hostname received a file that exceeds proxy buffer, skipping AV scan"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 2); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fgTrapIpsAvOversize'); + } +} diff --git a/tests/Feature/SnmpTraps/FgTrapIpsTest.php b/tests/Feature/SnmpTraps/FgTrapIpsTest.php new file mode 100644 index 0000000000..58c65e6524 --- /dev/null +++ b/tests/Feature/SnmpTraps/FgTrapIpsTest.php @@ -0,0 +1,97 @@ +. + * + * Unit tests for Fortigate IPS SNMP trap handlers (FgTrapIps*) + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2019 KanREN, Inc + * @author Heath Barnhart + */ + +namespace LibreNMS\Tests\Feature\SnmpTraps; + +use App\Models\Device; +use App\Models\Ipv4Address; +use LibreNMS\Snmptrap\Dispatcher; +use LibreNMS\Snmptrap\Trap; +use LibreNMS\Tests\LaravelTestCase; + +class FgTrapIpsTest extends LaravelTestCase +{ + public function testIpsAnomaly() + { + $device = factory(Device::class)->create(); + $ipv4 = factory(Ipv4Address::class)->make(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIGATE-MIB::fgTrapIpsAnomaly +FORTINET-CORE-MIB::fnSysSerial.0 $device->serial +SNMPv2-MIB::sysName.0 $device->hostname +FORTINET-FORTIGATE-MIB::fgIpsTrapSigId.0 2 +FORTINET-FORTIGATE-MIB::fgIpsTrapSrcIp.0 $ipv4->ipv4_address +FORTINET-FORTIGATE-MIB::fgIpsTrapSigMsg.0 tcp_src_session"; + + $message = "DDoS prevention triggered. Source: $ipv4->ipv4_address Protocol: tcp_src_session"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 4); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fgTrapIpsAnomaly trap'); + } + + public function testIpsPkgUdate() + { + $device = factory(Device::class)->create(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIGATE-MIB::fgTrapIpsPkgUpdate +FORTINET-CORE-MIB::fnSysSerial.0 $device->serial +SNMPv2-MIB::sysName.0 $device->hostname"; + + $message = "IPS package updated on $device->hostname"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 2); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fgTrapIpsPkgUpdate trap'); + } + + public function testIpsSignature() + { + $device = factory(Device::class)->create(); + $ipv4 = factory(Ipv4Address::class)->make(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIGATE-MIB::fgTrapIpsSignature +FORTINET-CORE-MIB::fnSysSerial.0 $device->serial +SNMPv2-MIB::sysName.0 $device->hostname +FORTINET-FORTIGATE-MIB::fgIpsTrapSigId.0 47173 +FORTINET-FORTIGATE-MIB::fgIpsTrapSrcIp.0 $ipv4->ipv4_address +FORTINET-FORTIGATE-MIB::fgIpsTrapSigMsg.0 UPnP.SSDP.M.Search.Anomaly"; + + $message = "IPS signature UPnP.SSDP.M.Search.Anomaly detected from $ipv4->ipv4_address with Fortiguard ID 47173"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 4); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fgTrapIpsSignature trap'); + } +} diff --git a/tests/Feature/SnmpTraps/FgTrapVpnTunTest.php b/tests/Feature/SnmpTraps/FgTrapVpnTunTest.php new file mode 100644 index 0000000000..ffcd23ac55 --- /dev/null +++ b/tests/Feature/SnmpTraps/FgTrapVpnTunTest.php @@ -0,0 +1,78 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2019 Tony Murray + * @author Tony Murray + */ + +namespace LibreNMS\Tests\Feature\SnmpTraps; + +use App\Models\Device; +use App\Models\Ipv4Address; +use LibreNMS\Snmptrap\Dispatcher; +use LibreNMS\Snmptrap\Trap; +use LibreNMS\Tests\LaravelTestCase; + +class FgTrapVpnTunTest extends LaravelTestCase +{ + public function testVpnTunDown() + { + $device = factory(Device::class)->create(); + $ipv4 = factory(Ipv4Address::class)->make(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIGATE-MIB::fgTrapVpnTunDown +FORTINET-CORE-MIB::fnSysSerial.0 $device->serial +SNMPv2-MIB::sysName.0 $device->hostname +FORTINET-FORTIGATE-MIB::fgVpnTrapLocalGateway.0 $device->ip +FORTINET-FORTIGATE-MIB::fgVpnTrapRemoteGateway.0 $ipv4->ipv4_address +FORTINET-FORTIGATE-MIB::fgVpnTrapPhase1Name.0 test_tunnel_down"; + + $message = "VPN tunnel test_tunnel_down to $ipv4->ipv4_address is down"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 3); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fgTrapVpnTunDown'); + } + + public function testVpnTunUp() + { + $device = factory(Device::class)->create(); + $ipv4 = factory(Ipv4Address::class)->make(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIGATE-MIB::fgTrapVpnTunUp +SNMPv2-MIB::sysName.0 $device->hostname +FORTINET-FORTIGATE-MIB::fgVpnTrapLocalGateway.0 $device->ip +FORTINET-FORTIGATE-MIB::fgVpnTrapRemoteGateway.0 $ipv4->ipv4_address +FORTINET-FORTIGATE-MIB::fgVpnTrapPhase1Name.0 test_tunnel_up"; + + $message = "VPN tunnel test_tunnel_up to $ipv4->ipv4_address is up"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 1); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fgTrapVpnTunUp'); + } +} diff --git a/tests/Feature/SnmpTraps/FmTrapLogRateThresholdTest.php b/tests/Feature/SnmpTraps/FmTrapLogRateThresholdTest.php new file mode 100644 index 0000000000..8451d52a18 --- /dev/null +++ b/tests/Feature/SnmpTraps/FmTrapLogRateThresholdTest.php @@ -0,0 +1,55 @@ +. + * + * Unit tests for Fortigate FmTrapLogRateThreshold.php + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2019 KanREN, Inc + * @author Heath Barnhart + */ + +namespace LibreNMS\Tests\Feature\SnmpTraps; + +use App\Models\Device; +use LibreNMS\Snmptrap\Dispatcher; +use LibreNMS\Snmptrap\Trap; +use LibreNMS\Tests\LaravelTestCase; + +class FgTrapLogRateThresholdTest extends LaravelTestCase +{ + + public function testAvOversize() + { + $device = factory(Device::class)->create(); + + $trapText = "$device->hostname +UDP: [$device->ip]:57602->[192.168.5.5]:162 +DISMAN-EVENT-MIB::sysUpTimeInstance 302:12:56:24.81 +SNMPv2-MIB::snmpTrapOID.0 FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmTrapLogRateThreshold +FORTINET-CORE-MIB::fnSysSerial.0 $device->serial +SNMPv2-MIB::sysName.0 $device->hostname +FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmLogRate.0 315 +FORTINET-FORTIMANAGER-FORTIANALYZER-MIB::fmLogRateThreshold.0 260"; + + $message = "Recommended log rate exceeded. Current Rate: 315 Recommended Rate: 260"; + \Log::shouldReceive('event')->once()->with($message, $device->device_id, 'trap', 3); + + $trap = new Trap($trapText); + $this->assertTrue(Dispatcher::handle($trap), 'Could not handle fmTrapLogRateThreshold trap'); + } +}