[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ossec-dev] Re: A few feature requests



Jeff Schroeder wrote:
3.) Some way to script the key creation / export / import process. If
> ossec works out, my team manages several hundred (more than 900)
> servers. Expect would work, but is a hack. If you want to be taken
> serious as an "enterprise" ids, batch operations should be though
> about.
> 
> Something like this would be perfect and unix-y:
> ssh ossec-server '/var/ossec/bin/export_key --id 002' > 002.key
> cat 002.key | ssh ossec-client-002 '/var/ossec/bin/import_key -'

I automated that with cfengine.  I'd imagine your using some sort of
config management platform?  Just steal my scripts!

http://www.ossec.net/wiki/index.php/Integration_%26_Deployment_with_cfengine

And I attached my scripts to this message..

-- 
Brad Lhotsky                            <lhotskyb@xxxxxxxxxxxx>
NCTS Computer Specialist                    Phone: 410.558.8006
"Darkness is a state of mind, I can go where you would stumble."
 -Wolfsheim, 'Blind'
#!/usr/bin/perl

use strict;
use warnings;

use Expect;
use Carp;
use File::Spec;
use Regexp::Common qw( net );
use MIME::Base64;
use Getopt::Long;


#------------------------------------------------------------------------#
# User Parameter Parsing
my %OPTS = ();
GetOptions(\%OPTS, qw(
	define=s
));
#------------------------------------------------------------------------#

#------------------------------------------------------------------------#
$Expect::Log_Stdout = 0;
my %BIN = (
	manage_agents		=> '/var/ossec/bin/manage_agents',
	list_agents			=> '/var/ossec/bin/list_agents',
);
#------------------------------------------------------------------------#
# Config
my %CFG = (
	key_dir		=> '/usr/local/cfkeys/ossec',
	mode		=> exists $OPTS{define} && length $OPTS{define} ? 'cfengine' : 'normal',
); 
#------------------------------------------------------------------------#

#------------------------------------------------------------------------#
# Clean Data
#------------------------------------------------------------------------#
my $HOSTNAME = lc shift;
my $IP = shift;
my $KEY = undef;
my $ID = undef;
my $restartAgent = undef;

$HOSTNAME =~ s/[^\w\d\-_]//g;
$IP =~ s/[^\d\.]//g;

croak "usage: $0 hostname ip\n" unless length($HOSTNAME) && length($IP);

#------------------------------------------------------------------------#
# Check the server to see if the agent is listed.
my %agents = ();
my $menuSeen = 0;
my $exp = new Expect();
$exp->spawn( $BIN{manage_agents} );
$exp->expect(30,
	[
		qr{Choose your action: A,E,L,R or Q:\s+},
		sub {
			my $fh = shift;
			if( $menuSeen == 1 ) {
				$fh->send("Q\n");
			}
			else {
				$fh->send("L\n");
				$menuSeen = 1;
			}
			exp_continue;
		}
	],
	[
		qr{ID: (\d+), Name: ([^\,]+), IP: $RE{net}{IPv4}{-keep}},
		sub {
			my $fh = shift;
			my ($id, $hostname, $ip) = $exp->matchlist;
			$agents{$id} = { hostname => $hostname, ip => $ip };
			exp_continue;
		}
	],
	[
		qr{Press ENTER to return to the main menu},
		sub {
			my $fh = shift;
			$fh->send("\n");
			exp_continue;
		}
	],

);

my @REMOVE = ();
my $createKey = 1;
foreach my $id ( keys %agents ) {
	my $host = $agents{$id}->{hostname};
	my $ip = $agents{$id}->{ip};
	if( $host eq $HOSTNAME ) {
		if( $ip eq $IP ) {
			$createKey = 0;
			last;	
		}
		else {
			push @REMOVE, { id => $id, hostname => $host, ip  => $ip };
		}
	}
}

#
# Remove any keys that we need to remove:
foreach my $href (@REMOVE) {
	showMessage("!! Removing key for pair ( $href->{hostname}, $href->{ip} )\n");
	my $exp = new Expect;
	my $menuSeen = 0;
	$exp = new Expect;
	$exp->spawn( $BIN{manage_agents} );
	$exp->expect( 30,
		[
			qr{Choose your action: A,E,L,R or Q:\s+},
			sub {
				my $fh = shift;
				if( $menuSeen == 1 ) {
					$fh->send("Q\n");
				}
				else {
					$fh->send("R\n");
					$menuSeen = 1;
				}
				exp_continue;
			}
		],
		[
			qr{Provide the ID of the agent to be removed.*:\s+},
			sub {
				my $fh = shift;
				$fh->send("$href->{id}\n");
				exp_continue;
			}
		],
		[
			qr{Confirm deleting it\?\(y/n\):\s+},
			sub {
				my $fh = shift;
				$fh->send("y\n");
				exp_continue;
			}
		],

	);

}

if( $createKey == 1 ) {
	showMessage("++ Creating key for $HOSTNAME at $IP..\n");
	$restartAgent = 1;
	my $exp = new Expect;
	my $menuSeen = 0;
	$exp = new Expect;
	$exp->spawn( $BIN{manage_agents} );
	$exp->expect( 30,
		[
			qr{Choose your action: A,E,L,R or Q:\s+},
			sub {
				my $fh = shift;
				if( $menuSeen == 1 ) {
					$fh->send("Q\n");
				}
				else {
					$fh->send("A\n");
					$menuSeen = 1;
				}
				exp_continue;
			}
		],
		[
			qr{\* A name for the new agent:\s+},
			sub {
				my $fh = shift;
				$fh->send("$HOSTNAME\n");
				exp_continue;
			}
		],
		[
			qr{\* The IP Address of the new agent:\s+},
			sub {
				my $fh = shift;
				$fh->send("$IP\n");
				exp_continue;
			}
		],
		[
			qr{\* An ID for the new agent\[\d+\]:\s+},
			sub {
				my $fh = shift;
				$fh->send("\n");
				exp_continue;
			}
		],
		[
			qr{Confirm adding it\?\(y/n\):\s+},
			sub {
				my $fh = shift;
				$fh->send("y\n");
				exp_continue;
			}
		],

	);
}

#
# Extract the Key
$menuSeen = 0;
my $grabKey = 0;
$exp = new Expect;
$exp->spawn( $BIN{manage_agents} );
$exp->expect( 10,
	[
		qr{Choose your action: A,E,L,R or Q:\s+},
		sub {
			my $fh = shift;
			if( $menuSeen == 1 ) {
				$fh->send("Q\n");
			}
			else {
				$fh->send("E\n");
				$menuSeen = 1;
			}
			exp_continue;
		}
	],
	[
		qr{\s+ID: (\d+), Name: ([^\,]+), IP: $RE{net}{IPv4}{-keep}},
		sub {
			my $fh = shift;
			my ($id, $hostname, $ip) = $exp->matchlist;
			if( $hostname eq $HOSTNAME && $ip eq $IP ) {
				$ID = $id;
			}
			exp_continue;
		}
	],
	[
		qr{extract the key .*:\s+},
		sub {
			my $fh = shift;
			if( defined $ID ) {
				$fh->send("$ID\n");
			}
			else {
				$fh->send("\\q\n");
			}
			exp_continue;
		}
	],
	[
			qr{Agent key information},
			sub {
				$grabKey = 1;
				exp_continue;
			},
	],
	[
			qr{^(\S+)\s+$},
			sub {
				my $fh = shift;
				my ($string) = $fh->matchlist();
				if( $grabKey ) {
					$KEY = $string;
					$grabKey = 0;
				}
				exp_continue;
			},
	],
	[
			qr{Press ENTER to return},
			sub {
				my ($fh) = @_;
				$fh->send("\n");
				exp_continue;
			},
	],

);

#
# Extract the key string:
my $KEYSTRING = decode_base64($KEY);
#
# Write to the client key file
my $filename = File::Spec->catfile( $CFG{key_dir}, $HOSTNAME . '.ossec' );
open(my $fh, '>', $filename) 
	or croak "unable to write to $filename: $!\n";
print $fh $KEYSTRING;
close $fh;
showMessage("$KEYSTRING\n");

if( $restartAgent && $CFG{mode} eq 'cfengine' ) {
	print $OPTS{define},"\n";
}

sub showMessage {
	if( $CFG{mode} eq 'normal' ) {
		for(@_) {
			print $_;
		}
	}
}

Attachment: ossec-scan.sh
Description: Bourne shell script


OSSEC home | Main Index | Thread Index


OSSEC project: www.ossec.net.
Mailling list information: http://www.ossec.net/en/mailing_lists.html.