diff --git a/pandora_server/ChangeLog b/pandora_server/ChangeLog index 9a93f9cf6e..33c0777329 100644 --- a/pandora_server/ChangeLog +++ b/pandora_server/ChangeLog @@ -1,3 +1,10 @@ +2010-10-21 Sergio Martin + + * util/recon_scripts + util/recon_scripts/PandoraFMS + util/recon_scripts/snmpdevices.pl: Added the example recon script + that creates several modules for each searched interface + 2010-10-21 Junichi Satoh * lib/PandoraFMS/NetworkServer.pm: Deleted FreeBSD specific SNMPGET diff --git a/pandora_server/util/recon_scripts/PandoraFMS b/pandora_server/util/recon_scripts/PandoraFMS new file mode 120000 index 0000000000..d77e8a956e --- /dev/null +++ b/pandora_server/util/recon_scripts/PandoraFMS @@ -0,0 +1 @@ +../../bin/PandoraFMS/ \ No newline at end of file diff --git a/pandora_server/util/recon_scripts/snmpdevices.pl b/pandora_server/util/recon_scripts/snmpdevices.pl new file mode 100755 index 0000000000..855e7bbdc1 --- /dev/null +++ b/pandora_server/util/recon_scripts/snmpdevices.pl @@ -0,0 +1,279 @@ +#!/usr/bin/perl +# (c) Sancho Lerena 2010 +# SNMP Recon App script + +use POSIX qw(setsid strftime strftime ceil); + +use strict; +use warnings; + +use IO::Socket::INET; +use NetAddr::IP; + +# Default lib dir for RPM and DEB packages + +use lib '/usr/lib/perl5'; + +use PandoraFMS::Tools; +use PandoraFMS::DB; +use PandoraFMS::Core; +use PandoraFMS::Config; +########################################################################## +# Global variables so set behaviour here: + +my $target_timeout = 5; # Fixed to 5 secs by default +my $target_interval = 600; + +########################################################################## +# Code begins here, do not touch +########################################################################## +my $pandora_conf = "/etc/pandora/pandora_server.conf"; +my $task_id = $ARGV[0]; # Passed automatically by the server +my $target_group = $ARGV[1]; # Defined by user +my $create_incident = $ARGV[2]; # Defined by user + +# Used Custom Fields in this script +my $target_network = $ARGV[3]; # Defined by user +my $target_community = $ARGV[4]; # Defined by user +# Unused Custom Fields in this script +# my $field3 = $ARGV[5]; # Defined by user +# my $field4 = $ARGV[6]; # Defined by user + +########################################################################## +# Update recon task status. +########################################################################## +sub update_recon_task ($$$) { + my ($dbh, $id_task, $status) = @_; + + db_do ($dbh, 'UPDATE trecon_task SET utimestamp = ?, status = ? WHERE id_rt = ?', time (), $status, $id_task); +} + +########################################################################## +# Show help +########################################################################## +sub show_help { + print "\nSpecific Pandora FMS SNMP Recon Plugin for SNMP device autodiscovery\n"; + print "(c) Artica ST 2010 \n\n"; + print "Usage:\n\n"; + print " snmp_recon_app.pl \n\n"; + exit; +} + +########################################################################## +# Return the ID of the given address, -1 if it does not exist. +########################################################################## +sub get_addr_id ($$) { + my ($dbh, $addr) = @_; + + my $addr_id = get_db_value ($dbh, 'SELECT id_a FROM taddress WHERE ip = ?', $addr); + return (defined ($addr_id) ? $addr_id : -1); +} + +########################################################################## +# Return the ID of the agent with the given IP. +########################################################################## +sub get_agent_from_addr ($$) { + my ($dbh, $ip_address) = @_; + + return 0 if (! defined ($ip_address) || $ip_address eq ''); + + my $agent_id = get_db_value ($dbh, 'SELECT id_agent FROM taddress, taddress_agent, tagente + WHERE tagente.id_agente = taddress_agent.id_agent + AND taddress_agent.id_a = taddress.id_a + AND ip = ?', $ip_address); + return (defined ($agent_id)) ? $agent_id : -1; +} + +########################################################################## +# Add the given address to taddress. +########################################################################## +sub add_address ($$) { + my ($dbh, $ip_address) = @_; + + return db_insert ($dbh, 'INSERT INTO taddress (ip) VALUES (?)', $ip_address); +} + +########################################################################## +# Get SNMP response. +########################################################################## +sub get_snmp_response ($$$) { + my ($target_timeout, $target_community, $addr) = @_; + + # The OID used is the SysUptime OID + my $buffer = `/usr/bin/snmpget -v 1 -r0 -t$target_timeout -OUevqt -c '$target_community' $addr .1.3.6.1.2.1.1.3.0 2>/dev/null`; + print "/usr/bin/snmpget -v 1 -r0 -t$target_timeout -OUevqt -c '$target_community' $addr .1.3.6.1.2.1.1.3.0 2>/dev/null"; + # Remove forbidden caracters + $buffer =~ s/\l|\r|\"|\n|\<|\>|\&|\[|\]//g; + + return $buffer; +} + +########################################################################## +# Process a SNMP requestr and create the module XML +########################################################################## +sub process_module_snmp ($$$$$$$$$){ + + my ($dbh, $target_community, $addr, $oid, $type, $module_name, $module_type, $module_description, $conf) = @_; + + my %parameters; + + $parameters{'id_tipo_modulo'} = $module_type; + $parameters{'nombre'} = $module_name; + $parameters{'descripcion'} = $module_description; + $parameters{'id_agente'} = get_agent_from_addr ($dbh, $addr); + $parameters{'ip_target'} = $addr; + $parameters{'tcp_send'} = 1; + $parameters{'snmp_community'} = $target_community; + $parameters{'snmp_oid'} = $oid; + + # id_modulo = 2 for snmp modules + $parameters{'id_modulo'} = 2; + + pandora_create_module_from_hash ($conf, \%parameters, $dbh); + +} + +########################################################################## +########################################################################## +# M A I N C O D E +########################################################################## +########################################################################## + + +if ($#ARGV == -1){ + show_help(); +} + +# Pandora server configuration +my %conf; +$conf{"quiet"} = 0; +$conf{"verbosity"} = 1; # Verbose 1 by default +$conf{"daemon"}=0; # Daemon 0 by default +$conf{'PID'}=""; # PID file not exist by default +$conf{'pandora_path'} = $pandora_conf; + +# Read config file +pandora_load_config (\%conf); + +# Connect to the DB +my $dbh = db_connect ('mysql', $conf{'dbname'}, $conf{'dbhost'}, '3306', $conf{'dbuser'}, $conf{'dbpass'}); + + +# Start the network sweep +# Get a NetAddr::IP object for the target network +my $net_addr = new NetAddr::IP ($target_network); +if (! defined ($net_addr)) { + logger (\%conf, "Invalid network " . $target_network . " for SNMP Recon App task", 1); + update_recon_task ($dbh, $task_id, -1); + return -1; +} + +# Scan the network for hosts +my ($total_hosts, $hosts_found, $addr_found) = ($net_addr->num, 0, ''); +for (my $i = 1, $net_addr++; $net_addr < $net_addr->broadcast; $i++, $net_addr++) { + + my $addr = (split(/\//, $net_addr))[0]; + $hosts_found ++; + + # Update the recon task + update_recon_task ($dbh, $task_id, ceil ($i / ($total_hosts / 100))); + + # Does the host already exist? + next if (get_agent_from_addr ($dbh, $addr) > 0); + + my $alive = 0; + if (pandora_ping (\%conf, $addr) == 1) { + $alive = 1; + } + + next unless ($alive > 0); + + # Resolve the address + my $host_name = gethostbyaddr(inet_aton($addr), AF_INET); + $host_name = $addr unless defined ($host_name); + + logger(\%conf, "SNMP Recon App found host $host_name.", 10); + + # Add the new address if it does not exist + my $addr_id = get_addr_id ($dbh, $addr); + + my $resp; + my $oid; + my $module_type; + my $module_description; + my $module_name; + my $xml = ""; + my $ax; # Counter + my $conf = \%conf; + + $resp = ""; + + # Obtain SNMP response + $resp = get_snmp_response ($target_timeout, $target_community, $addr); + + # No valid SNMP response. + if ($resp eq ""){ + next; + } + + # Create agent if really has SNMP information + $addr_id = add_address ($dbh, $addr) unless ($addr_id > 0); + if ($addr_id <= 0) { + logger (\%conf, "Could not add address '$addr' for host '$host_name'", 3); + next; + } + + # Create a new agent + my $agent_id; + + $agent_id = pandora_create_agent (\%conf, $conf{'servername'}, $host_name, $addr, $target_group, 0, 11, '', 300, $dbh); + + # Assign the new address to the agent + db_insert ($dbh, 'INSERT INTO taddress_agent (`id_a`, `id_agent`) VALUES (?, ?)', $addr_id, $agent_id); + + # Generate an event + pandora_event (\%conf, "[RECON] New SNMP host [$host_name] detected on network [" . $target_network . ']', $target_group, $agent_id, 2, 0, 0, 'recon_host_detected', 0, $dbh); + + # SysUptime + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.1.3.0", "ticks", "SysUptime", "generic_data_string", "System uptime reported by SNMP", $conf); + + # SysName + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.1.5.0", "", "SysName", "generic_data_string", "System name reported by SNMP", $conf); + + # Local system total traffic + + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.4.3.0", "", "Local InReceives", "generic_data_inc", "System local incoming traffic (bytes)", $conf); + + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.4.10.0", "", "Local OutRequests", "generic_data_inc", "System local outgoing traffic (bytes)", $conf); + + # Process interface list + # Get interface limit + + my $interface_limit = `/usr/bin/snmpget -v 1 -r0 -t$target_timeout -OUevqt -c '$target_community' $addr .1.3.6.1.2.1.2.1.0 2>/dev/null`; + + + for ($ax = 1; $ax<$interface_limit; $ax++){ + + + my $interface = `/usr/bin/snmpget -v 1 -r0 -t$target_timeout -OUevqt -c '$target_community' $addr RFC1213-MIB::ifDescr.$ax 2>/dev/null`; + + # Remove forbidden caracters + $interface =~ s/\"|\n|\<|\>|\&|\[|\]//g; + + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.2.2.1.8.$ax", "interface", "$interface Status", "generic_proc", "Operative status for $interface at position $ax", $conf); + + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.2.2.1.10.$ax", "", "$interface Inbound bps", "generic_data_inc", "Incoming traffic for $interface", $conf); + + process_module_snmp ($dbh, $target_community, $addr, ".1.3.6.1.2.1.2.2.1.16.$ax", "", "$interface Outbound bps", "generic_data_inc", "Outgoing traffic for $interface", $conf); + + # Do a grace sleep to avoid destination server ban me + sleep 1; + + } + +} + +# Mark recon task as done +update_recon_task ($dbh, $task_id, -1); + +# End of code