• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 887
  • Last Modified:

Random Syslog Event Generator

Hi,
Can someone build me a script that would generate random Syslog events?
I need to:
1. Specify the syslog server to log to
2. Be able to change the fequency of events
3. be able to randomize the syslog facility and priority
4. generate random network-like events such as link up link down messages

The message format needs to follow the normal syslog message format of course, something like:
Apr  9 22:19:47 EST: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to up
Apr 11 03:35:38 EST: %LINK-3-UPDOWN: Interface FastEthernet0/5, changed state to down
Apr 11 03:35:39 EST: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to down
Apr 11 03:35:40 EST: %LINK-3-UPDOWN: Interface FastEthernet0/5, changed state to up
Apr 11 03:35:41 EST: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to up

0
cdukes
Asked:
cdukes
  • 12
  • 7
1 Solution
 
ysreCommented:
Try using http://search.cpan.org/~lhoward/Net-Syslog-0.03/Syslog.pm , eg:
use Net::Syslog;
my $localsyslog=new Net::Syslog(Facility=>'local4',Priority=>'debug');
my $remotesyslog = new Net::Syslog (SyslogHost => '10.1.1.137', SyslogPort => '1514', Facility => 'local', Priority => 'debug');

Then use:
$localsyslog->send('see this in local syslog',Priority=>'info');
$remotesyslog->send('see this in the remote syslog',Priority=>'info');

Didn't try it out (no remote syslog server here in my local lan), but should work.
On no. 2: It's upon you to decide when to send stuff (or not).
On no. 3: Create a list of allowed facilities / priorities and choose randomly for each call (eg. $listofprios[int(rand($#listofprios))] for the priority part in the ->send call.

Besides I'm not quite sure what you mean by no. 4..

Ys
0
 
Adam314Commented:
For #2, you should be able to use either of these:

$SIG{ALRM} = ***Your function here, that does syslog***
alarm(***time***)

or

while(1) {
    sleep(***time***)
    ***Your code here, that does syslog***
}


For #3:
@pri=('priority1','priority2','priority3');    #list all priorities

$randpri=$pri[rand($#pri+1)];     #randomly pick one of those



Also, not sure what you mean by #4
0
 
cdukesAuthor Commented:
I'm familiar with sys:syslog, but don't know perl very well.

I need some help coding it out :-)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ysreCommented:
Nobody seems to understand what it actually is you want to do, cdukes :)
And I'm one of them hehe.

Today's homework for you: Create a UMS diagram of what it is you want to do (in detail!) ;).

IOW: Describe _exactly_ what you want to do, because the point of what you're trying to do seems to have evaded me till now :)

Ys
0
 
cdukesAuthor Commented:
lol, ok, how about this:

Here's what I have so far:

   use Net::Syslog;
    my @facilities = ("kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpri
   v", "ftp", "local0", "local1", "local2", "local3", "local4", "local5", "local6");
    my @priorities = ("debug", "info", "notice", "warning", "err", "crit", "alert", "emerg");
    # not used yet # my @events = ("LINEPROTO-5-UPDOWN", "SYS-5-CONFIG_I", "CDP", "DUPLEX");
    my $localsyslog=new Net::Syslog(Facility=>[rand(@facilities)],Priority=>[rand(@priorities)]);
    my $random_file = 'random.txt';
    my $delimiter = "%%\n";
    open(FILE, "<$random_file")
   or die "Can't open $random_file: $!\n";
    my @phrases;
    {
    local $/ = $delimiter;
    chomp (@phrases = <FILE>);
    }
    my $phrase = $phrases[rand(@phrases)];
    print $phrase;
    $localsyslog->send("$phrase",Priority=>[rand(@priorities)]);
    close(FILE);

My random.txt file has the following:
LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to up
%%
SYS-5-CONFIG_I: Configured from console by vty0 (192.168.32.1)
%%
LINK-3-UPDOWN: Interface FastEthernet0/5, changed state to up
%%
LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to down

Now, in my syslog server I see:
localhost local5 19:20:47 loggen.pl[20536]: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/5, changed state to up
localhost local5 19:20:44 loggen.pl[20535]: SYS-5-CONFIG_I: Configured from console by vty0 (192.168.32.1)


Here's what I have left for this to work:
1. How can I make it come from random hosts instead of all from localhost?
2. Is there a way to remove the "loggen.pl[20536]: " part of the syslog message?
3. How can I run this and have it stay running and logging messages every 1-3 seconds?

4. Optionally -- Instead of using a file, how can I just define and generate events from inside the perl script. I was thinking of defining each token and then generating random messages based on that - note above where I defined "my @events "
But I would need multiple random events like:
@events ( some text for the first token, some other text for the first )
@events_2 ( some text for the second token, some other text for the second )
@events_3 ( some text for the third token, some other text for the third )

The tokens are taken from the syslog standard (Cisco Systems)

System Log Message Elements  
Element  Description  
mm/dd/yyy:hh/mm/ss
 
facility
 Indicates the facility to which the message refers (for example, SNMP, SYS, etc.).
 
severity
 Single-digit code from 0 to 7 that indicates the severity of the message.
 
MNEMONIC
 Text string that uniquely describes the error message.
 
description
 Text string containing detailed information about the event being reported.
 

Example:
1999 Apr 16 10:01:26 %MLS-5-MLSENABLED:IP Multilayer switching is enabled
1999 Apr 16 10:01:26 %MLS-5-NDEDISABLED:Netflow Data Export disabled
1999 Apr 16 10:01:26 %SYS-5-MOD_OK:Module 1 is online
1999 Apr 16 10:01:47 %SYS-5-MOD_OK:Module 3 is online
1999 Apr 16 10:01:42 %SYS-5-MOD_OK:Module 6 is online
1999 Apr 16 10:02:27 %PAGP-5-PORTTOSTP:Port 3/1 joined bridge port 3/1
1999 Apr 16 10:02:28 %PAGP-5-PORTTOSTP:Port 3/2 joined bridge port 3/2

0
 
ysreCommented:
Well first thing's first.
If you are triggering a local syslog  you'll get the script/app name that triggered the syslog event (eg. loggen.pl[pid] in your case).
If it's being done remotely you should see some ip/port (or so I guess).

1. Unless you want to spoof data in your local syslog  you'd have to have other computers connecting to your local syslog and send the messages :)
2. (loggen.pl part) Don't do it locally.. Eg. if your kernel triggers a syslog message there usually is a big fat "kernel: " in the message.. Same for other software.
3. Put a while (1) { /* your stuff */ sleep (1 + rand(2)); } # end while    around it
4. Why not create a hash with your fake messages based on event type?
eg.
our %myevents = (
  'pagp' => (
    'foo message 1',
    'bar message 2',
    'baz message 3',
  ),
  'mls' => (
    'bar message 2',
    'baz message 3',
  ),
  'sys' => (
    'bar message 2',
    'baz message 3',
  )
);

our %mynames = (
  'sys' => (
    'first sys fac',
    'second sys fac',
  ),
  'mls' => (
    'first mls fac',
    'second mls fac',
  ),
  'pagp' => (
    'first pagp fac',
    'second pagp fac',
  )
);


Then to get your message call a function like this:
sub get_rand_event
{
  my $evttype = shift;
  $evttype = "sys" if ((!defined($evttype)) or ($evttype eq ""));

  my @namesarr = @{$mynames{$evttype}};
  my @msgarr = @{$myevents{$evttype}};
  return ( $namearr[rand($#namearr)], $msgarr[rand($#msgarr)] );
}


Call it like this:    my ($curr_fakename, $curr_fakeevent) = get_rand_event ('mls');
And supply those infos to your Net::Syslog object, eg.

my $localsyslog = new Net::Syslog (Name => $curr_fakename, Facility=>[rand(@facilities)], Priority=>[rand(@priorities)]);
$localsyslog->send($curr_fakeevent, Priority=>[rand(@priorities)]);

This should get around the loggen.pl thingy, too (just looked that up in Net::Syslog). :)

Ys

0
 
cdukesAuthor Commented:
Ok, so I have this:
 use Net::Syslog;
   #while (1) { /* your stuff */
    my @facilities = ("kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpri
   v", "ftp", "local0", "local1", "local2", "local3", "local4", "local5", "local6");
    my @priorities = ("debug", "info", "notice", "warning", "err", "crit", "alert", "emerg");
   # #my @events = ("LINEPROTO-5-UPDOWN", "SYS-5-CONFIG_I", "CDP", "DUPLEX");
   # my $localsyslog=new Net::Syslog(Facility=>[rand(@facilities)],Priority=>[rand(@priorities)]);
   # my $random_file = 'random.txt';
   # my $delimiter = "%%\n";
   # open(FILE, "<$random_file")
   #or die "Can't open $random_file: $!\n";
   # my @phrases;
   # {
   # local $/ = $delimiter;
   # chomp (@phrases = <FILE>);
   # }
   # my $phrase = $phrases[rand(@phrases)];
   # print $phrase;
   # $localsyslog->send("$phrase",Priority=>[rand(@priorities)]);
   # close(FILE);
   our %myevents = (
     'pagp' => (
       'foo message 1',
       'bar message 2',
       'baz message 3',
     ),
 'mls' => (
       'bar message 2',
       'baz message 3',
     ),
     'sys' => (
       'bar message 2',
       'baz message 3',
     )
   );
   
   our %mynames = (
     'sys' => (
       'first sys fac',
       'second sys fac',
     ),
     'mls' => (
       'first mls fac',
       'second mls fac',
     ),
     'pagp' => (
       'first pagp fac',
       'second pagp fac',
     )
   );
   
   sub get_rand_event
   {
     my $evttype = shift;
     $evttype = "sys" if ((!defined($evttype)) or ($evttype eq ""));
   
     my @namesarr = @{$mynames{$evttype}};
     my @msgarr = @{$myevents{$evttype}};
     return ( $namearr[rand($#namearr)], $msgarr[rand($#msgarr)] );
   }
 my ($curr_fakename, $curr_fakeevent) = get_rand_event ('mls');
   my $localsyslog = new Net::Syslog (Name => $curr_fakename, Facility=>[rand(@facilities)], Priority=>[rand(@pri
   orities)]);
   $localsyslog->send($curr_fakeevent, Priority=>[rand(@priorities)]);


But it returns:
Global symbol "@namearr" requires explicit package name at ./loggen.pl line 77.
Global symbol "@namearr" requires explicit package name at ./loggen.pl line 77.

What's missing?
0
 
ysreCommented:
You are using "use strict;" without stating so.. Thanks for not telling me ...

Note: Net::Syslog warns me to death here.. Seems there is a bugfix for that on rt.cpan.org, but I can't really download it without creating an account :)

Anyways here's what I bugfixed of what you gave me:

use strict;
use Net::Syslog;

### our fake stuff
   our %myevents = (
     'pagp' => [
       'foo message 1',
       'bar message 2',
       'baz message 3',
     ],
     'mls' => [
       'bar message 2',
       'baz message 3',
     ],
     'sys' => [
       'bar message 2',
       'baz message 3',
     ]
   );

   our %mynames = (
     'sys' => [
       'first sys fac',
       'second sys fac',
     ],
     'mls' => [
       'first mls fac',
       'second mls fac',
     ],
     'pagp' => [
       'first pagp fac',
       'second pagp fac',
     ]
   );

   our @facilities = ("kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", "local0", "local1", "local2", "local3", "local4", "local5", "local6");
   our @priorities = ("debug", "info", "notice", "warning", "err", "crit", "alert", "emerg");

### /fake stuff


### main ###

while (1)
{
 my ($curr_fakename, $curr_fakeevent) = get_rand_event ('mls');
 my ($curr_fakeprio, $curr_fakefac) = ( int(rand($#facilities+1)), int(rand($#priorities+1)) );

 my $localsyslog = new Net::Syslog ( Name => $curr_fakename, Facility => $curr_fakefac, Priority => $curr_fakeprio );
    $localsyslog->send ( $curr_fakeevent, Priority => $curr_fakeprio );

}



### our subs ###

sub get_rand_event
{
  my $evttype = shift;
  $evttype = "sys" if ((!defined($evttype)) or ($evttype eq ""));

  my @namesarr = @{$mynames{$evttype}};
  my @msgarr = @{$myevents{$evttype}};
  return ( $namesarr[rand($#namesarr+1)], $msgarr[rand($#msgarr+1)] );
}



Works great except for the Net::Syslog Exporter-bug (never used, yet still bugging me).

Ys
0
 
cdukesAuthor Commented:
Actually, I get no complaints whatsoever, thanks for the help :-)

I am noticing, however, that it's not getting inserted into syslog?
if I add:
 print "$curr_fakeevent, Priority => $curr_fakeprio\n";
to the end of the loop, the screen outputs:
bar message 2, Priority => 0
bar message 2, Priority => 17
bar message 2, Priority => 4
baz message 3, Priority => 11
bar message 2, Priority => 7
bar message 2, Priority => 9
bar message 2, Priority => 9
bar message 2, Priority => 3
baz message 3, Priority => 4

How are the priorities coming out as integers?
Also, what does $# indicate? as in $#facilities+1 ?
and what does "our" indicate versus "my"?
and sorry about the strict thing, I thought that was what you were supposed to use?

(learning perl here, sorry if I'm ignorant)

0
 
cdukesAuthor Commented:
Actually, it did insert into syslog, I just didn't wait long enough for mysql/php :-)
0
 
cdukesAuthor Commented:
Still wondering about the other items:

How are the priorities coming out as integers?
Also, what does $# indicate? as in $#facilities+1 ?
and what does "our" indicate versus "my"?
0
 
cdukesAuthor Commented:
Also,
It's only randomizing mls events. I think the problem is here:
my ($curr_fakename, $curr_fakeevent) = get_rand_event ('mls');

How do I tell it to randomize all 3 sections?

Here's what I have so far:

#!/usr/bin/perl

#
# loggen.pl
$| = 1;
 use strict;
 use Net::Syslog;
 
### our fake stuff
 our %myevents = (
     'pagp' => [
       'Line protocol on Interface FastEthernet0/5, changed state to up',
       'Line protocol on Interface FastEthernet0/7, changed state to up',
       'Configured from console by vty0 (192.168.2.3)',
     ],
     'mls' => [
       'IP Multilayer switching is enabled',
       'Netflow Data Export disabled',
     ],
     'sys' => [
       'Module 1 is online',
       'Module 3 is online',
     ]
   );

   our %mynames = (
     'sys' => [
       '%SYS-5-MOD_OK:',
       '%SPANTREE-5-PORTDEL_SUCCESS:',
     ],
     'mls' => [
       '%MLS-5-MLSENABLED:',
       '%MLS-5-NDEDISABLED:',
     ],
     'pagp' => [
       '%PAGP-5-PORTTOSTP:',
       '%PAGP-6-PORTTOSTP:',
     ]
   );

   our @facilities = ("kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", "local0", "local1", "local2", "local3", "local4", "local5", "local6");
   our @priorities = ("debug", "info", "notice", "warning", "err", "crit", "alert", "emerg");

### /fake stuff


### main ###

while (1)
{
 my ($curr_fakename, $curr_fakeevent) = get_rand_event ('mls');
 my ($curr_fakeprio, $curr_fakefac) = ( int(rand($#facilities+1)), int(rand($#priorities+1)) );

 my $localsyslog = new Net::Syslog ( Name => $curr_fakename, Facility => $curr_fakefac, Priority => $curr_fakeprio );
    $localsyslog->send ( $curr_fakeevent, Priority => $curr_fakeprio );
print "$curr_fakeevent, Priority => $curr_fakeprio\n";
sleep (1 + rand(2));
}



### our subs ###

sub get_rand_event
{
  my $evttype = shift;
  $evttype = "sys" if ((!defined($evttype)) or ($evttype eq ""));

  my @namesarr = @{$mynames{$evttype}};
  my @msgarr = @{$myevents{$evttype}};
  return ( $namesarr[rand($#namesarr+1)], $msgarr[rand($#msgarr+1)] );
}

0
 
cdukesAuthor Commented:
Also, all messages are coming in as local5, Warn
0
 
cdukesAuthor Commented:
Ok, I figured out the integer issue, I think all I have now is to figure out a way to spoof different host sources so that everything doesn't come from localhost.


Here's what I have now: (P.S. Isn't there a way to loop the sys, mls and pagp instead of defining them each time?)

#!/usr/bin/perl

#
# loggen.pl
#
 
$| = 1;
 use strict;
 use Net::Syslog;
 
### our fake stuff
 our %myevents = (
     'pagp' => [
       'Line protocol on Interface FastEthernet0/5, changed state to up',
       'Line protocol on Interface FastEthernet0/7, changed state to up',
       'Configured from console by vty0 (192.168.4.35)',
     ],
     'mls' => [
       'IP Multilayer switching is enabled',
       'Netflow Data Export disabled',
     ],
     'sys' => [
       'Module 1 is online',
       'Module 3 is online',
     ]
   );

   our %mynames = (
     'sys' => [
       '%SYS-5-MOD_OK:',
       '%SPANTREE-5-PORTDEL_SUCCESS:',
     ],
     'mls' => [
       '%MLS-5-MLSENABLED:',
       '%MLS-5-NDEDISABLED:',
     ],
     'pagp' => [
       '%PAGP-5-PORTTOSTP:',
       '%PAGP-6-PORTTOSTP:',
     ]
   );

   our @facilities = ("kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", "local0", "local1", "local2", "local3", "local4", "local5", "local6");
   our @priorities = ("debug", "info", "notice", "warning", "err", "crit", "alert", "emerg");

### /fake stuff


### main ###

while (1)
{
my      $index   = rand @priorities;
my      $pri = $priorities[$index];  
my      $index   = rand @facilities;
my      $fac = $facilities[$index];  

# SYS Messages
 my ($curr_fakename, $curr_fakeevent) = get_rand_event ('sys');
 my $localsyslog = new Net::Syslog ( Name => $curr_fakename, Facility => $fac, Priority => $pri );
    $localsyslog->send ( $curr_fakeevent, Priority => $pri );
print "$curr_fakeevent, Priority => $pri, Facility => $fac\n";

# MLS Messages
 my ($curr_fakename, $curr_fakeevent) = get_rand_event ('mls');
 my $localsyslog = new Net::Syslog ( Name => $curr_fakename, Facility => $fac, Priority => $pri );
    $localsyslog->send ( $curr_fakeevent, Priority => $pri );
print "$curr_fakeevent, Priority => $pri, Facility => $fac\n";

# PAGP Messages
 my ($curr_fakename, $curr_fakeevent) = get_rand_event ('pagp');
 my $localsyslog = new Net::Syslog ( Name => $curr_fakename, Facility => $fac, Priority => $pri );
    $localsyslog->send ( $curr_fakeevent, Priority => $pri );
print "$curr_fakeevent, Priority => $pri, Facility => $fac\n";

sleep (1 + rand(2));
}



### our subs ###

sub get_rand_event
{
  my $evttype = shift;
  $evttype = "sys" if ((!defined($evttype)) or ($evttype eq ""));

  my @namesarr = @{$mynames{$evttype}};
  my @msgarr = @{$myevents{$evttype}};
  return ( $namesarr[rand($#namesarr+1)], $msgarr[rand($#msgarr+1)] );
}
0
 
cdukesAuthor Commented:
Ok, I have the loop figured out, any ide how to fix the hostname problem?


Here's the (almost) final script:

#!/usr/bin/perl

#
# loggen.pl
#


$| = 1;
use strict;
use Net::Syslog;

### our fake stuff
our %myevents = (
        'pagp' => [
        'Line protocol on Interface FastEthernet0/5, changed state to up',
        'Line protocol on Interface FastEthernet0/7, changed state to up',
        'Configured from console by vty0 (192.168.4.35)',
        ],
        'mls' => [
        'IP Multilayer switching is enabled',
        'Netflow Data Export disabled',
        ],
        'sys' => [
        'Module 1 is online',
        'Module 3 is online',
        ]
);

our %mynames = (
        'sys' => [
        '%SYS-5-MOD_OK:',
        '%SPANTREE-5-PORTDEL_SUCCESS:',
        ],
        'mls' => [
        '%MLS-5-MLSENABLED:',
        '%MLS-5-NDEDISABLED:',
        ],
        'pagp' => [
        '%PAGP-5-PORTTOSTP:',
        '%PAGP-6-PORTTOSTP:',
        ]
);

our @facilities = ("kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", "local0", "local1", "local2", "local3", "local4", "local5", "local6");
our @priorities = ("debug", "info", "notice", "warning", "err", "crit", "alert", "emerg");

### /fake stuff


### main ###

while (1)
{
        my      @evtypes = ('sys', 'mls', 'pagp');

        foreach my $eventtype (@evtypes)
        {
                my      $index   = rand @priorities;
                my      $pri = $priorities[$index];  
                my      $index   = rand @facilities;
                my      $fac = $facilities[$index];  
                my ($curr_fakename, $curr_fakeevent) = get_rand_event ($eventtype);
                my $localsyslog = new Net::Syslog ( Name => $curr_fakename, Facility => $fac, Priority => $pri );
                $localsyslog->send ( $curr_fakeevent, Priority => $pri );
                print "$curr_fakeevent, Priority => $pri, Facility => $fac\n";
        }

        sleep (1 + rand(2));
}



### our subs ###

sub get_rand_event
{
        my $evttype = shift;
        $evttype = "sys" if ((!defined($evttype)) or ($evttype eq ""));

        my @namesarr = @{$mynames{$evttype}};
        my @msgarr = @{$myevents{$evttype}};
        return ( $namesarr[rand($#namesarr+1)], $msgarr[rand($#msgarr+1)] );
}

0
 
ysreCommented:
Nah, I just made a minor hickup which I didn't test in all of the script ;)
Notice that I defined your list of @priorities above the actual code?
I forgot to use the gotten random number in finding the entry in @priorities (how it should be done  can be seen on the last line of get_rand_event ;)).

About the $#somearray+1 .. Try an array with 2 entries (0 and 1) and do a rand.
Without $#foo+1 you only get the first entry, since the latter entry (1) which is the max border for this rand(..) call and thus happens veeery rarely.
Not like I think you would want (which is 1:1 probability for two entries in an array).

Use +1 :P

About the hostname.. Not really.. Unless you start a script like this on other hosts, all syslog'ing to the wanted syslogd :)

Of course you should just run one locally AND ip-spoof (_IF_ there's no firewall running).

Good luck,
Ys
0
 
cdukesAuthor Commented:
How could I spoof? You'd think I would know that being a network engineer...but is there a way to get perl spoof?
0
 
ysreCommented:
Well, you do it the same way in Perl as you do it in C ;)
Sending out raw packets et al ;)

It's quite simple actually.. But don't ask me how..
It's out of my field of expertise (and interest ;)).

Ys
0
 
cdukesAuthor Commented:
Fair enough, thanks so much for the help!
0
 
ysreCommented:
np,
thanks for the points :)

Ys
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 12
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now