📄 arnold.pl
字号:
#!/usr/bin/env perl## $Id$## Copyright 2003-2005 Norwegian University of Science and Technology## This file is part of Network Administration Visualized (NAV)## NAV is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## NAV is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with NAV; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA### Authors: John Magne Bredal <john.m.bredal@ntnu.no>#use strict;use Pg;use SNMP_util;$SNMP_Session::suppress_warnings = 2;use vars qw($opt_x $opt_h $opt_r $opt_t $opt_l $opt_f $opt_i $opt_u $opt_a $opt_c $opt_k $opt_s $opt_m $opt_e $opt_d $opt_z);use Getopt::Std;use Digest::MD5;use NAV;use NAV::Path;use NAV::Arnold;# First of all, parse configfile...it SHOULD be there# readconfig is in arnold.pmmy %cfg = &readconfig();# What letters do we have left...# bgjnopqvwymy $usage = "$0 [-x action] [-i identityid] [-f filename] [-a ipadresses] [-dhlks] [-m mailfile] [-r reason] [-u user] [-c comment] [-e days]\t-x enable or disable (required)\t-i sets the identityid (required if enable is set)\t-f specify a file with ip-adresses to block (required if disable is set and not -a)\t-a ip adresses to disable (separate with comma for more than one) required unless -f\t-l list all reasons for blocking\t-r specify reason, use -l option to see a list (required if disable set)\t-u specify user that runs script (otherwise you)\t-c write a comment\t-k if set locks an ip so that only internal users may enable it\t-s if set hides the tuple from non-internal users\t-t specify time for autoenable (an int representing number of days from disable)\t-e incremental increase since last time in days blocked, if not set prior, use option as days to set initially\t-h this helpstring\t-m send mail, uses \$home/etc/\$mailfile as config. Use \$reason for reason, and \$list for list of blocked ports.\t-d determined, does not open port even if computer is disabled behind another port\t-z enable only the one specified, added as we originally open all ports where a matching mac is found";# Pathsmy $home = $NAV::Path::bindir;my $etc = $NAV::Path::sysconfdir."/arnold";my $mailconfigpath = "$etc/mailtemplates";my $datapath = $NAV::Path::localstatedir."/arnold";my $logdir = $NAV::Path::localstatedir."/log/arnold";my $nonblockfile = "$etc/nonblock.cfg";my @nonblockedip;# First, get options.getopts('x:hf:lksm:r:i:u:a:c:t:e:dz');# Open logfilechomp (my $datetime = `date +%y%m%d-%H%M%S`);my $logfile = "arnold.log";umask (0117);open (LOG, ">>$logdir/$logfile") or die ("Could not open $logdir/$logfile: $!\n");print LOG "\n\n========== NEW LOGENTRY $datetime ==========\n\n";# Secondly, connect to the database (only block here in case listing of reasons)my $dbh_block = &NAV::connection('arnold','arnold');my $errorMessage = $dbh_block->errorMessage;if ($errorMessage eq PGRES_CONNECTION_BAD) { &reporterror("Could not connect to arnold-database."); exit(1);} else { print LOG "Connected successfully to block.\n";}# some global vars# snmpset(community@host:port:timeout:retries:backoff:version, OID, type, value,# The timeout, retries, and backoff parameters default to whatever# SNMP_Session.pm uses. For SNMP_Session.pm version 0.83 they are 2 seconds,# 5 retries, and a 1.0 backoff factor. The backoff factor is used as a# multiplier to increase the timeout after every retry. With a backoff factor# of 1.0 the timeout stays the same for every retry.my $timeout = 2;my $retries = 3;my $backoff = 2;# Treat all options and set variablesif ($opt_h) { print $usage; exit;}if ($opt_l) { my %temp = &getreasons(1); exit;}my $mailconfigfile;my $sendmail = 0;if ($opt_m) { my $temppath = "$mailconfigpath/$opt_m"; if (-e $temppath) { $mailconfigfile = $temppath; $sendmail = 1; printf LOG "Using mailfile %s.\n", $temppath; } else { printf LOG "WARNING: Could not find %s, no mail will be sent.\n", $temppath; }}my $incremental = 0;if ($opt_e) { $incremental = $opt_e; print LOG "Using incremental increase in blockdays (default $incremental).\n";}my $filename;my @iplist;my $id;my $action = $opt_x;my $reason;my $comment = "";unless ($opt_x) { print "You must specify an action with the -x parameter.\n"; print $usage; exit;}$comment = $opt_c if $opt_c;# We are a bit dependant on the -x option, must check a lot here...if ($action eq 'disable') { if ($opt_f) { print LOG "Setting filename = $datapath/$opt_f.\n"; $filename = $datapath/$opt_f; my $digestfile = "$filename.md5"; my $sum = "0"; if (-e $digestfile) { # Checking if file has changed from last time, mainly used for cron-jobs. open (DIG, $digestfile) or die ("Could not open $digestfile: $!\n"); $sum = <DIG>; close DIG; } open (FILE, $filename) or die ("Could not open $filename: $!\n"); binmode(FILE); my $sum2 = Digest::MD5->new->addfile(*FILE)->hexdigest; close FILE; if ($sum eq $sum2) { print LOG "File $filename has not changed since last run, exiting.\n"; exit(0); } else { open (DIG, ">$digestfile") or die ("Could not open $digestfile: $!\n"); print DIG $sum2; close DIG; } } elsif ($opt_a) { for (split(/,/,$opt_a)) { if (/^\d+\.\d+\.\d+\.\d+$/) { print LOG "Pushing $_ on iplist.\n"; push @iplist, [ $_ ]; } else { print LOG "$_ is not a valid ip-adress.\n"; } } } else { print LOG "You must specify a file or a list with ip-adresses to block.\n"; exit; } if ($opt_r) { print LOG "Setting reason to $opt_r.\n"; $reason = $opt_r; } else { print "You must specify a reason, use the -l parameter to list them.\n"; exit; } } elsif ($action eq 'enable') { if ($opt_i) { print LOG "Setting identityid to $opt_i.\n"; $id = $opt_i; } else { print "You must specify an identityid to unblock.\n"; exit; }} else { printf LOG "No such action %s\n",$opt_x; print $usage; exit;}# Checking usermy $user;if ($opt_u) { $user = $opt_u;} else { chomp ($user = `whoami`);}print LOG "User set to $user.\n";# Setting lock to the correct valuemy $lock;if ($opt_k) { $lock = 1; print LOG "Lock enabled.\n";} else { $lock = 0;}my $secret;if ($opt_s) { $secret = 1; print LOG "Hides the tuple.\n";} else { $secret = 0;}my $autoenable;my $autoenablestep;if ($opt_t) { $autoenablestep = $opt_t; $autoenable = "now() + '$opt_t days'"; printf LOG "Setting autoenable to %s.\n",$autoenable;} else { $autoenablestep = "NULL"; $autoenable = "NULL";}# We connect to manage here, because we wanted to check the parameters first.my $dbh_manage = &NAV::connection('arnold','manage');$errorMessage = $dbh_manage->errorMessage;if ($errorMessage eq PGRES_CONNECTION_BAD) { &reporterror("Could not connect to manage-database."); exit(1);} else { print LOG "Connected successfully to manage.\n";}my %reasons;my %mail;my @mailconfig;my %nonblock;if ($action eq 'disable') { unless (@iplist) { @iplist = &parsefile($filename); } # Get reasons for block %reasons = &getreasons(0); if ($reason) { unless ($reasons{$reason}) { printf LOG "No such reason %s, please use the -l option to see list of reasons and try again.\n",$reason; exit; } } # Assign the mail-array, read the mailconfig-file if ($sendmail) { open (MAILCONFIG, $mailconfigfile) or die ("Could not open $mailconfigfile: $!"); @mailconfig = <MAILCONFIG>; close MAILCONFIG; } # parse the file with info about what to not block %nonblock = &parseconfig($nonblockfile);}# SNMP-variablesmy $enable = 1;my $disable = 2;my %text;$text{1} = 'enabled';$text{2} = 'disabled';######################################### It goes like this:# If we are to disable, we take ip as input# Enabling is only possible with the appropriate identityid,# as this is used only from the web-page (hopefully)if ($action eq 'enable') { print LOG "Running enable\n"; # Run the enable-sub on all ports that this computer has disabled # z specifies that only this id must be unblocked if ($opt_z) { if (&enable($id)) { print LOG "Enabling of $id successful.\n"; } else { print LOG "Enabling if $id NOT successful.\n"; } } else { my $getmacs = "SELECT mac FROM identity WHERE identityid=$id"; my $rgetmacs = $dbh_block->exec($getmacs); my ($mac) = $rgetmacs->fetchrow; my $getall = "SELECT identityid FROM identity WHERE mac='$mac' AND blocked_status='disabled'"; my $rgetall = $dbh_block->exec($getall); while (my ($id) = $rgetall->fetchrow) { if (&enable($id)) { print LOG "Enabling of $id successful.\n"; } else { print LOG "Enabling if $id NOT successful.\n"; } } }} elsif ($action eq 'disable') { my @disabledlist; my @notdisabledlist; foreach my $element (@iplist) { my $ip = @$element[0]; my $rest = @$element[1]; print LOG "\n-- NEW IP --\n"; # Check if it must be skipped next if &skip($ip,0); my $netbios = ""; my $nmbtest = `which nmblookup 2> /dev/null`; if ($? == 0) { chomp $nmbtest; # Running nmblookup on comp uter print LOG "Running nmblookup on $ip..."; $netbios = `$nmbtest -A $ip -T | grep -v '<GROUP>' | grep -m1 '<00>'`; $netbios =~ s/\s+(\S+).*\n.*/$1/; print LOG "done\n"; } else { print LOG "Could not find nmblookup.\n"; } unless ($netbios) {$netbios = "N/A";} # Running host on computer print LOG "Running host on $ip..."; chomp (my $dns = `host $ip`); if ($dns =~ m/not\sfound/g) { $dns = "N/A"; } else { chop $dns; $dns = (split /\s/, $dns)[-1]; } print LOG "done.\n"; # Trying to disable port if (&disable($ip,$netbios,$dns,$rest)) { print LOG "Disabled successfully.\n"; push @disabledlist, "$ip, $netbios, $dns"; } else { print LOG "Disabling of $ip NOT successful.\n"; push @notdisabledlist, "$ip, $netbios, $dns";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -