📄 arnold.pl
字号:
} } if ($sendmail) { # Sending mail foreach my $address (keys %mail) { my @list; my @hosts = @{ $mail{$address} }; my $numberofhosts = 0; foreach my $host (@hosts) { $numberofhosts++; if (@$host[3]) { push @list, "@$host[0] (NETBIOS: @$host[1], DNS: @$host[2]) @$host[3]"; } else { push @list, "@$host[0] (NETBIOS: @$host[1], DNS: @$host[2])"; } } if ($numberofhosts > 0) { &send_mail($address,@list); } } } &mailnonblocked(); # Writing statusinfo when done with all ips print LOG "--- SUMMARY ---\n\n"; if ($#disabledlist >= 0) { printf LOG "The following computers were disabled (%s):\n",$#disabledlist + 1; for (@disabledlist) { print LOG "$_\n"; } } else { print LOG "No computers were disabled.\n"; } if ($#notdisabledlist >= 0) { printf LOG "\nThe following computers were NOT disabled (%s), see errorlog for reason:\n",$#notdisabledlist + 1; for (@notdisabledlist) { print LOG "$_\n"; } } }my $totalseconds = time - $^T;my $minutes = int $totalseconds / 60;my $seconds = $totalseconds - (60 * $minutes);if ($minutes > 0) { printf LOG "\n\nScript executed in %s minutes and %s seconds.\n",$minutes,$seconds;} else { printf LOG "\n\nScript executed in %s seconds.\n", $totalseconds;}close LOG;# From here and down there are only subs (sorted alphabetically)######################################### changeportstatus########################################sub changeportstatus { my ($sysname,$swip,$module,$port,$ifindex,$vendor,$flag,$community) = @_; my $ok = 0; my $response; if ($vendor eq '3com') { $response = &set3com($flag,$swip,$ifindex,$community); } elsif ($vendor eq 'hp') { $response = &setHP($flag,$swip,$module,$ifindex,$community); } elsif ($vendor eq 'cisco') { $response = &setCisco($flag,$swip,$ifindex,$community); } else { &reporterror("No such vendor supported: $vendor."); return 0; } if ($response == $flag) { printf LOG "Port %s:%s on %s set to %s.\n",$module,$port,$sysname,$text{$flag}; $ok = 1; } else { &reporterror("An error occured during changing of portstate - $response."); } return $ok;}######################################### disable########################################sub disable { my ($ip,$netbios,$dns,$rest) = @_; my ($email,$orgid); $comment = $rest if $rest; # Finding email address #my $q = "SELECT orgid,org2 FROM org LEFT JOIN prefiks USING (orgid) WHERE netaddr >> inet '$ip'"; my $q = "SELECT orgid,opt1 FROM org LEFT JOIN prefixreport USING (orgid) WHERE netaddr >> inet '$ip'"; my $r = $dbh_manage->exec($q); if ($r->ntuples > 0) { ($orgid,$email) = $r->fetchrow; print LOG "Found email $email\n"; } else { print LOG "Could not find email for $ip ($dns,$netbios)\n"; $email = 0; $orgid = 0; } # Find information about which switchport the box lies behind, mac-adress and so on. # The variable names should explain the meaning. my $query = "SELECT netbox.ip, netbox.rw, netbox.catid, cam.sysname, mac, type.vendorid, type.typename, swport.swportid, swport.ifindex, module.module, swport.port FROM arp LEFT JOIN cam USING (mac) LEFT JOIN netbox ON (cam.netboxid = netbox.netboxid) LEFT JOIN type USING (typeid) LEFT JOIN module ON (module.netboxid=netbox.netboxid) LEFT JOIN swport ON (module.moduleid=swport.moduleid) WHERE arp.ip='$ip' AND arp.end_time='infinity' AND cam.end_time = 'infinity' AND swport.ifindex=cam.ifindex AND swport.ifindex IS NOT NULL"; my $res = $dbh_manage->exec($query); #print "$query\n"; my ($swip, $community, $kat, $sysname, $mac, $vendorid, $typename, $swportid, $ifindex, $module, $port); # If we find only one match, we're happy and go on with the disabling of the port # and updating of database. if ($res->ntuples == 1) { ($swip, $community, $kat, $sysname, $mac, $vendorid, $typename, $swportid, $ifindex, $module, $port) = $res->fetchrow; # Setting allowedok to 1 if we find match of netboxtype in config-file. my $allowedok = 0; foreach my $confkat (split(/,/,$cfg{'allowtypes'})) { if ($kat eq $confkat) { $allowedok = 1; } } unless ($allowedok) { &reporterror($ip,$netbios,$dns,"$kat is not an allowed equipmenttype for blocking - skipping block."); return 0; } if (&skip($vendorid,$typename)) { &reporterror($ip,$netbios,$dns,"$vendorid-$typename is not supported."); return 0; } if (&skipid($ip,$swportid,$mac)) { &reporterror($ip,$netbios,$dns,"This port is already blocked."); return 0; } unless ($community) { &reporterror($ip,$netbios,$dns,"No snmp write-community found on $sysname."); return 0; } # Check if there are other computers behind this port # Disabled due to long execution time my $multiple = 1;# $q = "SELECT mac FROM cam WHERE sysname='$sysname' AND module='$module' AND port=$port AND end_time='infinity'";# $r = $dbh_manage->exec($q);# if ($r->ntuples > 1) {# $multiple = $r->ntuples;# printf LOG "There are %s computers behind this port, people may become unhappy...\n",$multiple;# } else {# $multiple = 1;# } # Disable the port if (&changeportstatus($sysname,$swip,$module,$port,$ifindex,$vendorid,$disable,$community)) { print LOG "Seemed to work.\n"; } else { &reporterror($ip,$netbios,$dns,"Disabling of port didn't work as expected, something wrong with the SNMP-query."); return 0; } # Put it into / update database unless (&updatedb($swportid,$sysname,$vendorid,$community,$swip,$mac,$ifindex,$module,$port,$disable,$ip,$dns,$netbios,$multiple,$email,$orgid)) { &reporterror($ip,$netbios,$dns,"Something went wrong when updating the database."); return 0; } unless ($opt_d) { # if there is another tuple in the database that has the same mac-address as key, AND is # disabled AND is not the same tuple, enable that port. $q = "SELECT identityid,swportid,mac FROM identity WHERE mac='$mac' AND blocked_status='disabled' AND swportid!=$swportid"; $r = $dbh_block->exec($q); while (my ($identityid,$swportid,$mac) = $r->fetchrow) { printf LOG "Oops, another tuple found (ID: %s, swid: %s, mac: %s), enabling it.\n",$identityid,$swportid,$mac; &enable($identityid); } } # Add it to the mail-hash if ($email) { push @{ $mail{$email} }, [$ip, $netbios, $dns, $rest]; print LOG "Pushing $ip ($netbios, $dns) on $email.\n"; } else { print LOG "Can't find email for $ip ($netbios, $dns)\n"; } print "$ip (connected to $sysname $module:$port) disabled successfully.\n"; # If more than one hit, we get confused and return 0 } elsif ($res->ntuples > 1) { my @swportids; while ( ($swip, $community, $kat, $sysname, $mac, $vendorid, $typename, $swportid, $ifindex, $module, $port) = $res->fetchrow) { push @swportids, $swportid; } my $text = "Query returned ".$res->ntuples." ifindexes - ".join (",", @swportids); &reporterror($ip,$netbios,$dns,$text); return 0; # If nothing else matters, we get even more confused and return 0 } else { &reporterror($ip,$netbios,$dns,"Could not find (a unique) port for blocking, the computer is either shut-down or has recently moved to another port."); return 0; } return 1; }######################################### enable########################################sub enable { my ($id) = @_; # 1. Check if it exists in the database, else skip my $query = "SELECT swportid,swsysname,swvendor,community,swip,swmodule,swport,swifindex,blocked_status,ip,mac,dns,netbios FROM identity WHERE identityid=$id"; my $res = $dbh_block->exec($query); my $nummatches = $res->ntuples; if ($nummatches < 1) { print LOG "No tuple in the database with id=$id.\n"; return 0; } # 2. If the last event indicated that it is disabled, enable the port and update the database. my ($swportid,$sysname,$vendor,$community,$swip,$module,$port,$ifindex,$status,$ip,$mac,$dns,$netbios) = $res->fetchrow; # 2.1 Enable the port(s) if (&changeportstatus($sysname,$swip,$module,$port,$ifindex,$vendor,$enable,$community)) { print LOG "Seemed to work.\n"; print "$ip (connected to $sysname $module:$port) enabled successfully.\n"; } else { print LOG "Didn't work as expected.\n"; return 0; } # 2.2 Update database. if (&updatedb($swportid,$sysname,$vendor,$community,$swip,$mac,$ifindex,$module,$port,$enable,0,0,0)) { return 1; } else { &reporterror($ip,$netbios,$dns,"Something went wrong when updating the database."); return 0; }}############################################################# getreasons# ----------# gets all reasons from the database and returns a hash# with the values.############################################################sub getreasons { my $bool = shift; my %hash; my $q = "SELECT * FROM blocked_reason"; my $r = $dbh_block->exec($q); print "Reasons for blocking currently in the database:\n" if $bool; while (my ($id,$text) = $r->fetchrow) { printf "%s: %s\n", $id,$text if $bool; $hash{$id} = $text; } return %hash;}############################################################# getstep# -------# Used to make incremental steps to the autoenablestep# so that the punishment is harder the more you are# blocked. We are some sadistic people.############################################################sub getstep { my ($reason, $id, $inc) = @_; my $newstep; my $oldstep; my $q = "SELECT autoenablestep FROM event WHERE identityid = $id AND blocked_reasonid = $reason AND autoenablestep IS NOT NULL ORDER BY eventtime DESC"; my $r = $dbh_block->exec($q); print LOG "$q\n"; if ($r->ntuples > 0) { ($oldstep) = $r->fetchrow; $newstep = $oldstep * 2; } else { $newstep = $inc; } return $newstep;}############################################################# matchip# -------# input - an ip and an iprange checks if the ip is in the # iprange returns 1 if yes, otherwise 0############################################################sub matchip { my ($ip,$iprange) = @_; my ($quad,$bits) = split /\//, $iprange; $bits = 32 - ($bits || 32); my $ipnum = unpack("N", pack("C4", split(/\./, $ip))) >> $bits; my $rangenum = unpack("N", pack("C4", split(/\./, $quad))) >> $bits; if ($ipnum == $rangenum) { return 1; } else { return 0; }}############################################################# parseconfig# -----------# parses the configfiles and puts the config in# appropriate hashes.############################################################sub parseconfig { my $filename = shift; my $dotypes = 0; my $doips = 0; my %hash; open (FILE, $filename) or die "Could not open $filename: $!"; while (<FILE>) { next if /^\#/; chomp $_; if (/^;netboxtypes/) { $doips = 0; $dotypes = 1; next; } elsif (/^;ip-ranges/) { $dotypes = 0; $doips = 1; next; } if ($dotypes && /^\w+/) { my $var = $_; my ($vendor,$type) = map { s/\s*(\S+)\s*/$1/; $_ } split (/,/, $var); $hash{$vendor}{$type} = 1; print LOG "Adding $vendor, $type to typehash.\n"; next; } if ($doips && /^\d+\.\d+\.\d+\.\d+$/) { $hash{'ip'}{$_} = 1; print LOG "Adding $_ to iplist.\n"; } elsif ($doips && /^\d+\.\d+\.\d+\.\d+\/\d+/) { $hash{'range'}{$_} = 1; print LOG "Adding $_ to iprangelist.\n"; } elsif ($doips && /^\d+\.\d+\.\d+\.\d+-\d+/) { $hash{'iplist'}{$_} = 1; print LOG "Adding $_ to iplist.\n"; } } close FILE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -