parse kdc log
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12937 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
439
tools/kdc-log-analyze.pl
Executable file
439
tools/kdc-log-analyze.pl
Executable file
@@ -0,0 +1,439 @@
|
||||
#! /usr/pkg/bin/perl
|
||||
# -*- mode: perl; perl-indent-level: 8 -*-
|
||||
#
|
||||
# Copyright (c) 2003 Kungliga Tekniska H<>gskolan
|
||||
# (Royal Institute of Technology, Stockholm, Sweden).
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the Institute nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# kdc-log-analyze - Analyze a KDC log file and give a report on the contents
|
||||
#
|
||||
# Note: The parts you want likely want to customize are the variable $notlocal,
|
||||
# the array @local_network_re and the array @local_realms.
|
||||
#
|
||||
# Idea and implemetion for MIT Kerberos was done first by
|
||||
# Ken Hornstein <kenh@cmf.nrl.navy.mil>, this program wouldn't exists
|
||||
# without his help.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use Sys::Hostname;
|
||||
|
||||
my $notlocal = 'not SU';
|
||||
my @local_realms = ( "SU.SE" );
|
||||
my @local_networks_re = ( "130.237" );
|
||||
|
||||
my $as_req = 0;
|
||||
my %as_req_addr;
|
||||
my %as_req_addr_nonlocal;
|
||||
my %as_req_client;
|
||||
my %as_req_server;
|
||||
my $five24_req = 0;
|
||||
my %five24_req_addr;
|
||||
my %five24_req_addr_nonlocal;
|
||||
my %five24_req_server;
|
||||
my %five24_req_client;
|
||||
my $as_req_successful = 0;
|
||||
my $as_req_error = 0;
|
||||
my $as_req_no_such_princ = 0;
|
||||
my $as_req_etype_odd = 0;
|
||||
my %bw_addr;
|
||||
my $pa_alt_princ_request = 0;
|
||||
my $pa_alt_princ_verify = 0;
|
||||
my $tgs_req = 0;
|
||||
my %tgs_req_addr;
|
||||
my %tgs_req_addr_nonlocal;
|
||||
my %tgs_req_client;
|
||||
my %tgs_req_server;
|
||||
my $tgs_xrealm_out = 0;
|
||||
my %tgs_xrealm_out_realm;
|
||||
my %tgs_xrealm_out_princ;
|
||||
my $tgs_xrealm_in = 0;
|
||||
my %tgs_xrealm_in_realm;
|
||||
my %tgs_xrealm_in_princ;
|
||||
my %enctype_session;
|
||||
my %enctype_ticket;
|
||||
my $restarts = 0;
|
||||
my $v4_req = 0;
|
||||
my %v4_req_addr;
|
||||
my %v4_req_addr_nonlocal;
|
||||
my $v4_cross;
|
||||
my %v4_cross_realm;
|
||||
my $referrals = 0;
|
||||
my %referral_princ;
|
||||
my %referral_realm;
|
||||
my %strange_tcp_data;
|
||||
my $http_malformed = 0;
|
||||
my %http_malformed_addr;
|
||||
my $http_non_kdc = 0;
|
||||
my %http_non_kdc_addr;
|
||||
my $tcp_conn_timeout = 0;
|
||||
my %tcp_conn_timeout_addr;
|
||||
|
||||
my %enctype;
|
||||
|
||||
$enctype{25} = 'AES256-CTS';
|
||||
$enctype{24} = 'AES128-CTS';
|
||||
$enctype{23} = 'RC4-HMAC';
|
||||
$enctype{16} = '3DES-CBC-SHA1';
|
||||
$enctype{5} = '3DES-CBC-MD5';
|
||||
$enctype{3} = 'DES-CBC-MD5';
|
||||
$enctype{2} = 'DES-CBC-MD4';
|
||||
$enctype{1} = 'DES-CBC-CRC';
|
||||
|
||||
while (<>) {
|
||||
process_line($_);
|
||||
}
|
||||
|
||||
print "Kerberos KDC Log Report for ",
|
||||
hostname, " on ", scalar localtime, "\n\n";
|
||||
|
||||
print "General Statistics\n\n";
|
||||
|
||||
print "\tNumber of restarts: $restarts\n";
|
||||
print "\tNumber of V4 requests: $v4_req\n";
|
||||
if ($v4_req > 0) {
|
||||
print "\tTop ten IP addresses performing V4 requests:\n";
|
||||
topten(\%v4_req_addr);
|
||||
}
|
||||
if (int(keys %v4_req_addr_nonlocal) > 0) {
|
||||
print "\tTop ten $notlocal IP addresses performing V4 requests:\n";
|
||||
topten(\%v4_req_addr_nonlocal);
|
||||
|
||||
}
|
||||
print "\n";
|
||||
|
||||
print "\tNumber of V4 cross realms (krb4 and 524) requests: $v4_cross\n";
|
||||
if ($v4_cross > 0) {
|
||||
print "\tTop ten realms performing V4 cross requests:\n";
|
||||
topten(\%v4_cross_realm);
|
||||
}
|
||||
print "\n";
|
||||
|
||||
print "\tNumber of failed lookups: $as_req_no_such_princ\n\n";
|
||||
|
||||
print "\tBandwidth pigs:\n";
|
||||
topten(\%bw_addr);
|
||||
print "\n";
|
||||
|
||||
print "\tStrange TCP data clients: ", int(keys %strange_tcp_data),"\n";
|
||||
topten(\%strange_tcp_data);
|
||||
print "\n";
|
||||
|
||||
print "\tTimeout waiting on TCP requests: ", $tcp_conn_timeout,"\n";
|
||||
if ($tcp_conn_timeout > 0) {
|
||||
print "\tTop ten TCP timeout request clients\n";
|
||||
topten(\%tcp_conn_timeout_addr);
|
||||
}
|
||||
print "\n";
|
||||
|
||||
print "\tMalformed HTTP requests: ", $http_malformed,"\n";
|
||||
if ($http_malformed > 0) {
|
||||
print "\tTop ten malformed HTTP request clients\n";
|
||||
topten(\%http_malformed_addr);
|
||||
}
|
||||
print "\n";
|
||||
|
||||
print "\tHTTP non kdc requests: ", $http_non_kdc,"\n";
|
||||
if ($http_non_kdc > 0) {
|
||||
print "\tTop ten HTTP non KDC request clients\n";
|
||||
topten(\%http_non_kdc_addr);
|
||||
}
|
||||
print "\n";
|
||||
|
||||
print "Report on AS_REQ requests\n\n";
|
||||
print "Overall AS_REQ statistics\n\n";
|
||||
|
||||
print "\tTotal number: $as_req\n";
|
||||
|
||||
print "\nAS_REQ client/server statistics\n\n";
|
||||
|
||||
print "\tDistinct IP Addresses performing requests: ",
|
||||
int(keys %as_req_addr),"\n";
|
||||
print "\tOverall top ten IP addresses\n";
|
||||
topten(\%as_req_addr);
|
||||
|
||||
print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
|
||||
int(keys %as_req_addr_nonlocal), "\n";
|
||||
print "\tTop ten non-local ($notlocal) IP address:\n";
|
||||
topten(\%as_req_addr_nonlocal);
|
||||
|
||||
print "\tDistinct clients performing requests: ", int(keys %as_req_client), "\n";
|
||||
print "\tTop ten clients:\n";
|
||||
topten(\%as_req_client);
|
||||
|
||||
print "\tDistinct services requested: ", int(keys %as_req_server), "\n";
|
||||
print "\tTop ten requested services:\n";
|
||||
topten(\%as_req_server);
|
||||
|
||||
print "\n\n\nReport on TGS_REQ requests:\n\n";
|
||||
print "Overall TGS_REQ statistics\n\n";
|
||||
print "\tTotal number: $tgs_req\n";
|
||||
|
||||
print "\nTGS_REQ client/server statistics\n\n";
|
||||
print "\tDistinct IP addresses performing requests: ",
|
||||
int(keys %tgs_req_addr), "\n";
|
||||
print "\tOverall top ten IP addresses\n";
|
||||
topten(\%tgs_req_addr);
|
||||
|
||||
print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
|
||||
int(keys %tgs_req_addr_nonlocal), "\n";
|
||||
print "\tTop ten non-local ($notlocal) IP address:\n";
|
||||
topten(\%tgs_req_addr_nonlocal);
|
||||
|
||||
print "\tDistinct clients performing requests: ",
|
||||
int(keys %tgs_req_client), "\n";
|
||||
print "\tTop ten clients:\n";
|
||||
topten(\%tgs_req_client);
|
||||
|
||||
print "\tDistinct services requested: ", int(keys %tgs_req_server), "\n";
|
||||
print "\tTop ten requested services:\n";
|
||||
topten(\%tgs_req_server);
|
||||
print "\n";
|
||||
|
||||
print "\t524_REQ client/server statistics\n\n";
|
||||
|
||||
print "\tDistinct IP Addresses performing requests: ",
|
||||
int(keys %five24_req_addr),"\n";
|
||||
print "\tOverall top ten IP addresses\n";
|
||||
topten(\%five24_req_addr);
|
||||
|
||||
print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
|
||||
int(keys %five24_req_addr_nonlocal), "\n";
|
||||
print "\tTop ten non-local ($notlocal) IP address:\n";
|
||||
topten(\%five24_req_addr_nonlocal);
|
||||
|
||||
print "\tDistinct clients performing requests: ", int(keys %five24_req_client), "\n";
|
||||
print "\tTop ten clients:\n";
|
||||
topten(\%five24_req_client);
|
||||
|
||||
print "\tDistinct services requested: ", int(keys %five24_req_server), "\n";
|
||||
print "\tTop ten requested services:\n";
|
||||
topten(\%five24_req_server);
|
||||
print "\n";
|
||||
|
||||
print "\tNumber of cross-realm tgs out: $tgs_xrealm_out\n";
|
||||
if ($tgs_xrealm_out > 0) {
|
||||
print "\tTop ten realms used for out cross-realm:\n";
|
||||
topten(\%tgs_xrealm_out_realm);
|
||||
print "\tTop ten principals use out cross-realm:\n";
|
||||
topten(\%tgs_xrealm_out_princ);
|
||||
}
|
||||
print "\tNumber of cross-realm tgs in: $tgs_xrealm_in\n";
|
||||
if ($tgs_xrealm_in > 0) {
|
||||
print "\tTop ten realms used for in cross-realm:\n";
|
||||
topten(\%tgs_xrealm_in_realm);
|
||||
print "\tTop ten principals use in cross-realm:\n";
|
||||
topten(\%tgs_xrealm_in_princ);
|
||||
}
|
||||
|
||||
print "\n\n\nReport on referral:\n\n";
|
||||
|
||||
print "\tNumber of referrals: $referrals\n";
|
||||
if ($referrals > 0) {
|
||||
print "\tTop ten referral-ed principals:\n";
|
||||
topten(\%referral_princ);
|
||||
print "\tTop ten to realm referrals:\n";
|
||||
topten(\%referral_realm);
|
||||
}
|
||||
|
||||
print "\n\n\tEnctype Stats:\n";
|
||||
print "\tTop ten session enctypes:\n";
|
||||
topten(\%enctype_session);
|
||||
print "\tTop ten ticket enctypes:\n";
|
||||
topten(\%enctype_ticket);
|
||||
|
||||
print "\t";
|
||||
|
||||
|
||||
exit 0;
|
||||
|
||||
sub process_line {
|
||||
local($_) = @_;
|
||||
#
|
||||
# Eat these lines that are output as a result of startup (but
|
||||
# log the number of restarts)
|
||||
#
|
||||
if (/AS-REQ \(krb4\) (.*) from IPv[46]:([0-9\.:a-fA-F]+) for krbtgt.*$/){
|
||||
$v4_req++;
|
||||
$v4_req_addr{$2}++;
|
||||
$v4_req_addr_nonlocal{$2}++ if (!islocaladdr($2));
|
||||
} elsif (/AS-REQ (.*) from IPv[46]:([0-9\.:a-fA-F]+) for (.*)$/) {
|
||||
$as_req++;
|
||||
$as_req_client{$1}++;
|
||||
$as_req_server{$3}++;
|
||||
$as_req_addr{$2}++;
|
||||
$as_req_addr_nonlocal{$2}++ if (!islocaladdr($2));
|
||||
} elsif (/TGS-REQ \(krb4\)/) {
|
||||
#Nothing
|
||||
} elsif (/TGS-REQ (.+) from IPv[46]:([0-9\.:a-fA-F]+) for (.*?)( \[.*\]){0,1}$/) {
|
||||
$tgs_req++;
|
||||
$tgs_req_client{$1}++;
|
||||
$tgs_req_server{$3}++;
|
||||
$tgs_req_addr{$2}++;
|
||||
$tgs_req_addr_nonlocal{$2}++ if (!islocaladdr($2));
|
||||
|
||||
my $source = $1;
|
||||
my $dest = $3;
|
||||
|
||||
if (!islocalrealm($source)) {
|
||||
$tgs_xrealm_in++;
|
||||
$tgs_xrealm_in_princ{$source}++;
|
||||
if ($source =~ /[^@]+@([^@]+)/ ) {
|
||||
$tgs_xrealm_in_realm{$1}++;
|
||||
}
|
||||
}
|
||||
if ($dest =~ /krbtgt\/([^@]+)@[^@]+/) {
|
||||
if (!islocalrealm($1)) {
|
||||
$tgs_xrealm_out++;
|
||||
$tgs_xrealm_out_realm{$1}++;
|
||||
$tgs_xrealm_out_princ{$source}++;
|
||||
}
|
||||
}
|
||||
} elsif (/524-REQ (.*) from IPv[46]:([0-9\.:a-fA-F]+) for (.*)$/) {
|
||||
$five24_req++;
|
||||
$five24_req_addr{$2}++;
|
||||
$five24_req_addr_nonlocal{$2}++ if (!islocaladdr($2));
|
||||
$five24_req_client{$1}++;
|
||||
$five24_req_server{$3}++;
|
||||
} elsif (/TCP data of strange type from IPv[46]:([0-9\.:a-fA-F]+)/) {
|
||||
$strange_tcp_data{$1}++;
|
||||
} elsif (/Lookup (.*) failed: No such entry in the database/) {
|
||||
$as_req_no_such_princ++;
|
||||
} elsif (/Lookup .* succeeded$/) {
|
||||
# Nothing
|
||||
} elsif (/Malformed HTTP request from IPv[46]:([0-9\.:a-fA-F]+)$/) {
|
||||
$http_malformed++;
|
||||
$http_malformed_addr{$1}++;
|
||||
} elsif (/TCP-connection from IPv[46]:([0-9\.:a-fA-F]+) expired after [0-9]+ bytes/) {
|
||||
$tcp_conn_timeout++;
|
||||
$tcp_conn_timeout_addr{$1}++;
|
||||
} elsif (/HTTP request from IPv[46]:([0-9\.:a-fA-F]+) is non KDC request/) {
|
||||
$http_non_kdc++;
|
||||
$http_non_kdc_addr{$1}++;
|
||||
} elsif (/returning a referral to realm (.*) for server (.*) that was not found/) {
|
||||
$referrals++;
|
||||
$referral_princ{$2}++;
|
||||
$referral_realm{$1}++;
|
||||
} elsif (/krb4 Cross-realm (.*) -> (.*) disabled/) {
|
||||
$v4_cross++;
|
||||
$v4_cross_realm{$1."->".$2}++;
|
||||
} elsif (/524 cross-realm (.*) -> (.*) disabled/) {
|
||||
$v4_cross++;
|
||||
$v4_cross_realm{$1."->".$2}++;
|
||||
} elsif (/Server not found in database \(krb4\)/) {
|
||||
} elsif (/krb_rd_req: Incorrect network address/) {
|
||||
} elsif (/krb_rd_req: Ticket expired \(krb_rd_req\)/) {
|
||||
} elsif (/krb_rd_req: Can't decode authenticator \(krb_rd_req\)/) {
|
||||
} elsif (/Request from wrong address/) {
|
||||
# XXX
|
||||
} elsif (/UNKNOWN --/) {
|
||||
# XXX
|
||||
} elsif (/Too large time skew -- (.*)$/) {
|
||||
# XXX
|
||||
} elsif (/No PA-ENC-TIMESTAMP --/) {
|
||||
# XXX
|
||||
} elsif (/Failed to decrypt PA-DATA -- (.+)$/) {
|
||||
} elsif (/Looking for pa-data --/) {
|
||||
# XXX
|
||||
} elsif (/Pre-authentication succeded -- (.+)$/) {
|
||||
# XXX
|
||||
} elsif (/Bad request for ([,a-zA-Z0-9]+) ticket/) {
|
||||
# XXX
|
||||
} elsif (/Failed to verify AP-REQ: Ticket expired/) {
|
||||
# XXX
|
||||
} elsif (/newsyslog.*logfile turned over/) {
|
||||
# Nothing
|
||||
} elsif (/Using ([-a-z0-9]+)\/([-a-z0-9]+)/) {
|
||||
$enctype_ticket{$1}++;
|
||||
$enctype_session{$2}++;
|
||||
} elsif (/Client not found in database:/) {
|
||||
# Nothing
|
||||
} elsif (/Server not found in database:/) {
|
||||
# Nothing
|
||||
} elsif (/sending ([0-9]+) bytes to IPv[46]:([0-9\.:a-fA-F]+)/) {
|
||||
$bw_addr{$2} += $1;
|
||||
} elsif (/Requested flags:/) {
|
||||
# Nothing
|
||||
} elsif (/shutting down/) {
|
||||
# Nothing
|
||||
} elsif (/listening on IP/) {
|
||||
# Nothing
|
||||
} elsif (/commencing operation/) {
|
||||
$restarts++;
|
||||
}
|
||||
#
|
||||
# Log it if we didn't parse the line
|
||||
#
|
||||
else {
|
||||
print "Unknown log file line: $_";
|
||||
}
|
||||
}
|
||||
|
||||
sub topten {
|
||||
my ($list, $map) = @_;
|
||||
my (@keys);
|
||||
|
||||
my $key;
|
||||
|
||||
@keys = (sort {$$list{$b} <=> $$list{$a}} (keys %{$list}));
|
||||
splice @keys, 10;
|
||||
|
||||
if (defined $map) {
|
||||
foreach $key (@keys) {
|
||||
print "\t\t$$map{$key} - $$list{$key}\n";
|
||||
}
|
||||
} else {
|
||||
foreach $key (@keys) {
|
||||
print "\t\t$key - $$list{$key}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub islocaladdr (\$) {
|
||||
my ($addr) = @_;
|
||||
my $net;
|
||||
|
||||
foreach $net (@local_networks_re) {
|
||||
return 1 if ($addr =~ /$net/);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub islocalrealm (\$) {
|
||||
my ($princ) = @_;
|
||||
my $realm;
|
||||
|
||||
foreach $realm (@local_realms) {
|
||||
return 1 if ($princ =~ /[^@]+\@${realm}/);
|
||||
}
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user