[SOLVED] /var/log/secure parse with perl script - guidance needed
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
/var/log/secure parse with perl script - guidance needed
Let's dispense with the foreplay, I don't know jack about perl, however...In a desire to increase my personal skill-set and Linux SysAdmin value to the community,
I decided to undertake the exercises in Perl for System Administration. I'll admit I jumped to Chapter 9 after reading the intro. and (because it mentioned the log files all us admins have to manipulate).
I am trying to massage some important data from /var/log/secure using a perl script as a template I found here....
It processes just fine but doesn't return any records and this is where I need help.
The source document was written less than a year ago and didn't run as "copied" from that site, I had to add 3 lines of code to even get this far.
Now this returned nothing for me, and you may well need to remove some of the round brackets as they are there to store data for later, but it could well be, as it is
for me, that this data does not exist in the secure log you are checking.
Do you have an example of what you're expecting the RE to match?
Sure, sorry I didn't include a sample:
Code:
Oct 16 13:55:13 domain.com sshd[21141]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33279 ssh2
Oct 16 13:55:14 domain.com sshd[21149]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33894 ssh2
Oct 16 13:55:14 domain.com sshd[21153]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33406 ssh2
Oct 16 13:55:15 domain.com sshd[21168]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33965 ssh2
Oct 16 13:55:15 domain.com sshd[21169]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33427 ssh2
Oct 16 13:55:15 domain.com sshd[21189]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33475 ssh2
Oct 16 13:55:16 domain.com sshd[21188]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34058 ssh2
Oct 16 13:55:16 domain.com sshd[21195]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33494 ssh2
Oct 16 13:55:20 domain.com sshd[21205]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34328 ssh2
Oct 16 13:55:20 domain.com sshd[21209]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33670 ssh2
Oct 16 13:55:32 domain.com sshd[21221]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 35322 ssh2
Oct 16 13:55:34 domain.com sshd[21225]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 34595 ssh2
"also the example in the link has \s after from so the RE matches from followed by space rather than froms"
grail: I am working on some out using your code snippet, which also returns nothing here on /var/log/secure as well. I am not concerned with my localhost atm, these are mixed CentOS and Ubuntu flavored remote hosts
Thank you, I can accept your estimate that the log file format may have changed, but "crude"? How can I tell?
Alas, your snippet doesn't work on the target.
I did find my bash script that has a one-liner in that does process the "Failed passwords" on 9 hosts' /var/log/secure (after I scp them down) and that line is
Code:
perl -ne 'if (/Failed password for.* from (.*?) /) {print $1, "\n"}' "$CONFDIR"/*" | sed -e 's/::ffff://g'
Now how I can turn that into a working replacement for
I copied some of your log file output into a file called 'text' and tried this:
Code:
# perl -ne '/[Ff]ailed\spassword\sfor\s(.*?)\sfrom\s.*?(\d+\.\d+\.\d+\.\d+)/; print "$1 $2\n";' text
invalid user postgres 74.86.64.194
invalid user postgres 67.228.13.82
invalid user postgres 74.86.64.194
invalid user postgres 67.228.13.82
invalid user postgres 74.86.64.194
invalid user postgres 74.86.64.194
althought the previous version looked to have worked as well. It may be the regex isn't actually getting used in the script.
...If the documentation "didn't work" then I'd have to suppose 20,000 of Larry's friends would know it, so it must be my RE expression.
you are trying to find the string 'Failed' inside of string 'line' which won't match. Earlier you used $line so I'm assuming that's a typo. Did you mean to try something more like:
Code:
"Oct 16 13:55:13 domain.com sshd[21141]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33279 ssh2" =~ /Failed/; # which would be a match
Thanks. Yes, it was/is a typo missing the "$".
I am still having trouble associating what the perl code does (and what people are saying it does)
"if ($blah =~ /stuff/) { # this code gets run if $blah contains 'stuff' }'"
says this 2008 reference.
and
a 2000 dated article titled "Common RegEx Gotchas" in the "Specifying Too Much" section says...
"...Suppose that you want to find the word Serial, followed by a colon and then a nine-digit number. The data lines might look like this: my $line = "Name: Some Soldier, Rank: Leftenant, Serial: 426879824, Boots: black";
A regex novice might bite off more than he could chew with the following:
If all you're interested in is the Serial number, only ask for that. It'll make your regex simpler, and it will handle deviations from what you think the line ought to look like. (That happens more often than you want to think.)
Code:
$line =~ /[Ss]erial: (\d{9})/;
Seems pretty consistent from 2000 to 2008.
So, what is not consistent here would be me and my code.
I am focused today on my line of code that processes lines (missing from the source, remember...) "my $line = 0
This appears to be an error for it is not a numeric integer I am after in "$line". Isn't that correct?
It very well could be from what I read
Code:
my $line =~ /Failed;
which also runs but report is empty.
but from the Gotchas link (same section) it seems like "my $line = " should be more like
Code:
my $line = "Month: some month, Day: some day, Time: time stamp, Host: some host, Service: sshd, Failed: 's/Failed password for ', User: user, From: '/s::ffffff:'";
based on this expected line(s) content(s)...
Code:
Oct 16 13:22:46 hostname sshd[17289]: Failed password for root from ::ffff:217.18.242.235 port 48207 ssh2
I hope you know how to fix this and are allowing me the courtesy of finding it on my "own".
As you are on the path to enlightenment May I suggest that you start your regex at the beginning and build from there to see where the error lie?
Code:
$ cat Habitual.in
Oct 16 13:55:13 domain.com sshd[21141]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33279 ssh2
Oct 16 13:55:14 domain.com sshd[21149]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33894 ssh2
Oct 16 13:55:14 domain.com sshd[21153]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33406 ssh2
Oct 16 13:55:15 domain.com sshd[21168]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33965 ssh2
Oct 16 13:55:15 domain.com sshd[21169]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33427 ssh2
Oct 16 13:55:15 domain.com sshd[21189]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33475 ssh2
Oct 16 13:55:16 domain.com sshd[21188]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34058 ssh2
Oct 16 13:55:16 domain.com sshd[21195]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33494 ssh2
Oct 16 13:55:20 domain.com sshd[21205]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34328 ssh2
Oct 16 13:55:20 domain.com sshd[21209]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33670 ssh2
Oct 16 13:55:32 domain.com sshd[21221]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 35322 ssh2
Oct 16 13:55:34 domain.com sshd[21225]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 34595 ssh2
$ perl -ne '$line = $_;if($line =~ /[Ff]ailed/){print $_}' Habitual.in
Oct 16 13:55:13 domain.com sshd[21141]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33279 ssh2
Oct 16 13:55:14 domain.com sshd[21149]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33894 ssh2
Oct 16 13:55:14 domain.com sshd[21153]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33406 ssh2
Oct 16 13:55:15 domain.com sshd[21168]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33965 ssh2
Oct 16 13:55:15 domain.com sshd[21169]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33427 ssh2
Oct 16 13:55:15 domain.com sshd[21189]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33475 ssh2
Oct 16 13:55:16 domain.com sshd[21188]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34058 ssh2
Oct 16 13:55:16 domain.com sshd[21195]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33494 ssh2
Oct 16 13:55:20 domain.com sshd[21205]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34328 ssh2
Oct 16 13:55:20 domain.com sshd[21209]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33670 ssh2
Oct 16 13:55:32 domain.com sshd[21221]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 35322 ssh2
Oct 16 13:55:34 domain.com sshd[21225]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 34595 ssh2
$ perl -ne 'chomp;$line = $_;if($line =~ /[Ff]ailed\spassword.*:(\d+\.\d+\.\d+\.\d+)/){print $_," ",$1,"\n"}' Habitual.in
Oct 16 13:55:13 domain.com sshd[21141]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33279 ssh2 74.86.64.194
Oct 16 13:55:14 domain.com sshd[21149]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33894 ssh2 67.228.13.82
Oct 16 13:55:14 domain.com sshd[21153]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33406 ssh2 74.86.64.194
Oct 16 13:55:15 domain.com sshd[21168]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 33965 ssh2 67.228.13.82
Oct 16 13:55:15 domain.com sshd[21169]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33427 ssh2 74.86.64.194
Oct 16 13:55:15 domain.com sshd[21189]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33475 ssh2 74.86.64.194
Oct 16 13:55:16 domain.com sshd[21188]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34058 ssh2 67.228.13.82
Oct 16 13:55:16 domain.com sshd[21195]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33494 ssh2 74.86.64.194
Oct 16 13:55:20 domain.com sshd[21205]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 34328 ssh2 67.228.13.82
Oct 16 13:55:20 domain.com sshd[21209]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 33670 ssh2 74.86.64.194
Oct 16 13:55:32 domain.com sshd[21221]: Failed password for invalid user postgres from ::ffff:67.228.13.82 port 35322 ssh2 67.228.13.82
Oct 16 13:55:34 domain.com sshd[21225]: Failed password for invalid user postgres from ::ffff:74.86.64.194 port 34595 ssh2 74.86.64.194
So if you build it as you see fit you can experiment on where it may be going wrong for you
As you are on the path to enlightenment May I suggest that you start your regex at the beginning and build from there to see where the error lie?
...
God, I hope that is the case, Thanks grail.
However, I am trying to migrate away from the perl one-liner(s) that I have and know work and incorporate it into a proper perl.pl script.
Where I am getting burnt is...
These one-liners work (as does yours)
Yeah sorry for the confusion there, I was using the one-liner just to show the code. Simply place it into a file and run to see how you go.
Code:
#!/usr/bin/env perl
#
#
use strict;
use warnings;
my $line;
open(FILE, $ARGV[0]) or die "Can't open file: $!\n";
while (<FILE>){
chomp;
$line = $_;
if($line =~ /[Ff]ailed\spassword.*:(\d+\.\d+\.\d+\.\d+)/){
print "$line $1\n"
}
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.