Guardian Paket angefangen, zum Testen muss Snort funktionieren ...

git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@720 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8
This commit is contained in:
maniacikarus
2007-07-25 18:02:01 +00:00
parent b8e4cbb73e
commit 7c4cc0d87b
10 changed files with 508 additions and 1 deletions

View File

@@ -268,7 +268,7 @@ sub updateifgraph {
"GPRINT:incoming:MIN:$Lang::tr{'in'}\\:%8.3lf %sBps",
"GPRINT:incoming:LAST:$Lang::tr{'in'}\\:%8.3lf %sBps\\j",
"GPRINT:outgoing:MAX:$Lang::tr{'out'}\\:%8.3lf %sBps",
"GPRINT:outgoing:AVERAGE:$$Lang::tr{'out'}\\:%8.3lf %sBps",
"GPRINT:outgoing:AVERAGE:$Lang::tr{'out'}\\:%8.3lf %sBps",
"GPRINT:outgoing:MIN:$Lang::tr{'out'}\\:%8.3lf %sBps",
"GPRINT:outgoing:LAST:$Lang::tr{'out'}\\:%8.3lf %sBps\\j");
$ERROR = RRDs::error;

View File

@@ -0,0 +1,33 @@
# The machines IP address that is visable to the internet
# If this is left undefined, then guardian will attempt to get the information
# from ifconfig, as long as it has an interface to use. This would be useful
# for people on ppp links, or dhcp machines, or if you are lazy :)
# HostIpAddr
# Here we define the interface which we will use to guess the IP address, and
# block incoming offending packets. This is the only option that is required
# for guardian to run. If the rest are undefined, guardian will use the default.
Interface ppp0
# The last octet of the ip address, which gives us the gateway address.
HostGatewayByte 1
# Guardian's log file
LogFile /var/log/guardian/guardian.log
# Snort's alert file. This can be the snort.alert file, or a syslog file
# There might be some snort alerts that get logged to syslog which guardian
# might not see..
AlertFile /var/log/snort/alert
# The list of ip addresses to ignore
IgnoreFile /var/ipfire/guardian.ignore
# This is a list of IP addresses on the current host, in case there is more
# than one. If this file doesn't exist, then it will assume you want to run
# with the default setup (machine's ip address, and broadcast/network).
TargetFile /var/ipfire/guardian.target
# The time in seconds to keep a host blocked. If undefined, it defaults to
# 99999999, which basicly disables the feature.
TimeLimit 86400

374
config/guardian/guardian.pl Normal file
View File

@@ -0,0 +1,374 @@
#!/usr/bin/perl
# V 1.7
# Read the readme file for changes
#
$OS=`uname`;
chomp $OS;
print "OS shows $OS\n";
require 'getopts.pl';
&Getopts ('hc:d');
if (defined($opt_h)) {
print "Guardian v1.7 \n";
print "guardian.pl [-hd] <-c config>\n";
print " -h shows help\n";
print " -d run in debug mode (doesn't fork, output goes to STDOUT)\n";
print " -c specifiy a configuration file other than the default (/etc/guardian.conf)\n";
exit;
}
&load_conf;
&sig_handler_setup;
print "My ip address and interface are: $hostipaddr $interface\n";
if ($hostipaddr !~ /\d+\.\d+\.\d+\.\d+/) {
print "This ip address is bad : $hostipaddr\n";
die "I need a good host ipaddress\n";
}
$networkaddr = $hostipaddr;
$networkaddr =~ s/\d+$/0/;
$gatewayaddr = $hostipaddr;
$gatewayaddr =~ s/\d+$/$hostgatewaybyte/;
$broadcastaddr = $hostipaddr;
$broadcastaddr =~ s/\d+$/255/;
&build_ignore_hash;
# This is the target hash. If a packet was destened to any of these, then the
# sender of that packet will get denied, unless it is on the ignore list..
%targethash = ( "$networkaddr" => 1,
"$broadcastaddr" => 1,
"0" => 1, # This is what gets sent to &checkem if no
# destination was found.
"$hostipaddr" => 1);
if ( -e $targetfile ) {
&load_targetfile;
}
if (!defined($opt_d)) {
print "Becoming a daemon..\n";
&daemonize;
} else { print "Running in debug mode..\n"; }
open (ALERT, $alert_file) or die "can't open alert file: $alert_file: $!\n";
seek (ALERT, 0, 2); # set the position to EOF.
# this is the same as a tail -f :)
$counter=0;
for (;;) {
sleep 1;
if (seek(ALERT,0,1)){
while (<ALERT>) {
chop;
if (/snort/) { #syslog file
if (defined($opt_d)) {print "$_\n";}
# This is *much* cleaner, and should work on all systems
@foo=split(/\s+/,$_);
($junk,$reason) = split (/\]:/,$_,2);
@array=();
foreach $str (@foo) {
if ($str=~/(\d+\.\d+\.\d+\.\d+)/) {
$array[$#array+1]=$1;
# write_log ("Found $array[$#array]\n");
}
}
if ($array[1] eq "") { $array[1]=0; }
# this should work if snort didn't report the target address.
# $array[1] should be the target address (portscans don't show this)
&checkem ($array[0], $array[1], $reason);
} else { # snort.alert type file for backwards compat
if (defined($opt_d)) {print "$_\n";}
if (/\[\*\*\]\s+(.*)\s+\[\*\*\]/){
$type=$1;
}
if (/(\d+\.\d+\.\d+\.\d+):\d+ -\> (\d+\.\d+\.\d+\.\d+):\d+/) {
&checkem ($1, $2, $type);
}
}
}
}
# Run this stuff every 30 seconds..
if ($counter == 30) {
&remove_blocks; # This might get moved elsewhere, depending on how much load
# it puts on the system..
&check_log_name;
$counter=0;
} else { $counter=$counter+1; }
}
sub check_log_name {
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = stat($alert_file);
if ($size < $previous_size) { # The filesize is smaller than last
close (ALERT); # we checked, so we need to reopen it
open (ALERT, "$alert_file"); # This should still work in our main while
$previous_size=$size; # loop (I hope)
write_log ("Log filename changed. Reopening $alert_file\n");
} else {
$previous_size=$size;
}
}
sub checkem {
my ($source, $dest,$type) = @_;
my $flag=0;
my $date = localtime();
return 1 if ($source eq $hostipaddr); # this should prevent is from nuking
# ourselves
return 1 if ($source eq $gatewayaddr); # or our gateway
if ($ignore{$source} == 1) { # check our ignore list..
&write_log("$date: ");
&write_log("$source\t$type\n");
&write_log("Ignoring attack because $source is in my ignore list\n");
return 1;
}
# if the offending packet was sent to us, the network, or the broadcast, then
if ($targethash{$dest} == 1) {
&write_log("$date: ");
&ipchain ($source, $dest, $type);
}
# you will see this if the destination was not in the $targethash, and the
# packet was not ignored before the target check..
else {
&write_log ("Odd.. source = $source, dest = $dest - No action done.\n");
if (defined ($opt_d)) {
foreach $key (keys %targethash) {
&write_log ("targethash{$key} = $targethash{$key}\n");
}
}
}
}
sub ipchain {
my ($source, $dest, $type) = @_;
&write_log ("$source\t$type\n");
if ($hash{$source} eq "") {
&write_log ("Running '$blockpath $source $interface'\n");
system ("$blockpath $source $interface");
$hash{$source} = time() + $TimeLimit;
} else {
# We have already blocked this one, but snort detected another attack. So
# we should update the time blocked..
$hash{$source} = time() + $TimeLimit;
}
}
sub build_ignore_hash {
# This would cause is to ignore all broadcasts if it
# got set.. However if unset, then the attacker could spoof the packet to make
# it look like it came from the network, and a reply to the spoofed packet
# could be seen if the attacker were on the local network.
# $ignore{$networkaddr}=1;
# same thing as above, just with the broadcast instead of the network.
# $ignore{$broadcastaddr}=1;
my $count =0;
$ignore{$gatewayaddr}=1;
$ignore{$hostipaddr}=1;
if ($ignorefile ne "") {
open (IGNORE, $ignorefile);
while (<IGNORE>) {
chop;
next if (/\#/); #skip comments
next if (/^\s*$/); # and blank lines
$ignore{$_}=1;
$count++;
}
close (IGNORE);
print "Loaded $count addresses from $ignorefile\n";
} else {
print "No ignore file was loaded!\n";
}
}
sub load_conf {
if ($opt_c eq "") {
$opt_c = "/etc/guardian.conf";
}
if (! -e $opt_c) {
die "Need a configuration file.. please use to the -c option to name a
configuration file\n";
}
open (CONF, $opt_c) or die "Cannot read the config file $opt_c, $!\n";
while (<CONF>) {
chop;
next if (/^\s*$/); #skip blank lines
next if (/^#/); # skip comment lines
if (/LogFile\s+(.*)/) {
$logfile = $1;
}
if (/Interface\s+(.*)/) {
$interface = $1;
}
if (/AlertFile\s+(.*)/) {
$alert_file = $1;
}
if (/IgnoreFile\s+(.*)/) {
$ignorefile = $1;
}
if (/TargetFile\s+(.*)/) {
$targetfile = $1;
}
if (/TimeLimit\s+(.*)/) {
$TimeLimit = $1;
}
if (/HostIpAddr\s+(.*)/) {
$hostipaddr = $1;
}
if (/HostGatewayByte\s+(.*)/) {
$hostgatewaybyte = $1;
}
# if (/ipchainsPath\s+(.*)/) {
# $ipchains_path = $1;
# }
}
if ($interface eq "") {
die "Fatal! Interface is undefined.. Please define it in $opt_o with keyword Interface\n";
}
if ($alert_file eq "") {
print "Warning! AlertFile is undefined.. Assuming /var/log/snort.alert\n";
$alert_file="/var/log/snort.alert";
}
if ($hostipaddr eq "") {
print "Warning! HostIpAddr is undefined! Attempting to guess..\n";
$hostipaddr = &get_ip($interface);
print "Got it.. your HostIpAddr is $hostipaddr\n";
}
if ($ignorefile eq "") {
print "Warning! IgnoreFile is undefined.. going with default ignore list (hostname and gateway)!\n";
}
if ($hostgatewaybyte eq "") {
print "Warning! HostGatewayByte is undefined.. gateway will not be in ignore list!\n";
}
if ($logfile eq "") {
print "Warning! LogFile is undefined.. Assuming debug mode, output to STDOUT\n";
$opt_d = 1;
}
if (! -w $logfile) {
print "Warning! Logfile is not writeable! Engaging debug mode, output to STDOUT\n";
$opt_d = 1;
}
foreach $mypath (split (/:/, $ENV{PATH})) {
if (-x "$mypath/guardian_block.sh") {
$blockpath = "$mypath/guardian_block.sh";
}
if (-x "$mypath/guardian_unblock.sh") {
$unblockpath = "$mypath/guardian_unblock.sh";
}
}
if ($blockpath eq "") {
print "Error! Could not find guardian_block.sh. Please consult the README. \n";
exit;
}
if ($unblockpath eq "") {
print "Warning! Could not find guardian_unblock.sh. Guardian will not be\n";
print "able to remove blocked ip addresses. Please consult the README file\n";
}
if ($TimeLimit eq "") {
print "Warning! Time limit not defined. Defaulting to absurdly long time limit\n";
$TimeLimit = 999999999;
}
}
sub write_log {
my $message = $_[0];
if (defined($opt_d)) { # we are in debug mode, and not daemonized
print STDOUT $message;
} else {
open (LOG, ">>$logfile");
print LOG $message;
close (LOG);
}
}
sub daemonize {
my ($home);
if (fork()) {
# parent
exit(0);
} else {
# child
&write_log ("Guardian process id $$\n");
$home = (getpwuid($>))[7] || die "No home directory!\n";
chdir($home); # go to my homedir
setpgrp(0,0); # become process leader
close(STDOUT);
close(STDIN);
close(STDERR);
print "Testing...\n";
}
}
sub get_ip {
my ($interface) = $_[0];
my $ip;
open (IFCONFIG, "/bin/netstat -iee |grep $interface -A7 |");
while (<IFCONFIG>) {
if ($OS eq "FreeBSD") {
if (/inet (\d+\.\d+\.\d+\.\d+)/) {
$ip = $1;
}
}
if ($OS eq "Linux") {
if (/inet addr:(\d+\.\d+\.\d+\.\d+)/) {
$ip = $1;
}
}
}
close (IFCONFIG);
if ($ip eq "") { die "Couldn't figure out the ip address\n"; }
$ip;
}
sub sig_handler_setup {
$SIG{TERM} = \&clean_up_and_exit; # kill
$SIG{QUIT} = \&clean_up_and_exit; # kill -3
# $SIG{HUP} = \&flush_and_reload; # kill -1
}
sub remove_blocks {
my $source;
my $time = time();
foreach $source (keys %hash) {
if ($hash{$source} < $time) {
&call_unblock ($source, "expiring block of $source\n");
delete ($hash{$source});
}
}
}
sub call_unblock {
my ($source, $message) = @_;
&write_log ("$message");
system ("$unblockpath $source $interface");
}
sub clean_up_and_exit {
my $source;
&write_log ("received kill sig.. shutting down\n");
foreach $source (keys %hash) {
&call_unblock ($source, "removing $source for shutdown\n");
}
exit;
}
sub load_targetfile {
my $count = 0;
open (TARG, "$targetfile") or die "Cannot open $targetfile\n";
while (<TARG>) {
chop;
next if (/\#/); #skip comments
next if (/^\s*$/); # and blank lines
$targethash{$_}=1;
$count++;
}
close (TARG);
print "Loaded $count addresses from $targetfile\n";
}

View File

@@ -0,0 +1,12 @@
#!/bin/sh
# this is a sample block script for guardian. This should work with ipchains.
# This command gets called by guardian as such:
# guardian_block.sh <source_ip> <interface>
# and the script will issue a command to block all traffic from that source ip
# address. The logic of weither or not it is safe to block that address is
# done inside guardian itself.
source=$1
interface=$2
/sbin/iptables -I INPUT -s $source -i $interface -j DROP

View File

@@ -0,0 +1,10 @@
#!/bin/sh
# this is a sample unblock script for guardian. This should work with ipchains.
# This command gets called by guardian as such:
# unblock.sh <source_ip> <interface>
# and the script will issue a command to remove the block that was created with # block.sh address.
source=$1
interface=$2
/sbin/iptables -D INPUT -s $source -i $interface -j DROP

View File

@@ -0,0 +1,4 @@
usr/local/bin/guardian.pl
usr/local/bin/guardian_block.sh
usr/local/bin/guardian_unblock.sh
var/ipfire/guardian/guardian.conf

70
lfs/guardian Normal file
View File

@@ -0,0 +1,70 @@
###############################################################################
# This file is part of the IPCop Firewall. #
# #
# IPCop 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. #
# #
# IPCop 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 IPCop; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
# #
# Makefiles are based on LFSMake, which is #
# Copyright (C) 2002 Rod Roard <rod@sunsetsystems.com> #
# #
###############################################################################
###############################################################################
# Definitions
###############################################################################
include Config
VER = ipfire
THISAPP = guardian-$(VER)
DIR_APP = $(DIR_SRC)/$(THISAPP)
TARGET = $(DIR_INFO)/$(THISAPP)
PROG = guardian
PAK_VER = 1.7
DESCDE = "Guardian ist Sicherheitstool, welches das Snort IDS Log auswertet und IP´s mit Hilfe von iptables block."
DESCEN = "Guardian is a security tool which will issue commands to the OS to block ip addresses which attacks may be coming from. Guardian requires an IDS (Intrusion detection system), and currently only works with snort."
###############################################################################
# Top-level Rules
###############################################################################
objects =
install : $(TARGET)
check :
download :
md5 :
dist:
@$(PAK)
###############################################################################
# Installation Details
###############################################################################
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
-mkdir -p /var/ipfire/guardian/
-mkdir -p /var/log/guardian/
touch /var/log/guardian/guardian.log
install -v -m 755 $(DIR_SRC)/config/guardian/guardian.conf /var/ipfire/guardian/
install -v -m 755 $(DIR_SRC)/config/guardian/guardian.pl /usr/local/bin/
install -v -m 755 $(DIR_SRC)/config/guardian/guardian_block.sh /usr/local/bin/
install -v -m 755 $(DIR_SRC)/config/guardian/guardian_unblock.sh /usr/local/bin/
@$(POSTBUILD)

View File

@@ -0,0 +1,4 @@
#!/bin/bash
. /opt/pakfire/lib/functions.sh
extract_files

View File

View File