Path: blob/main/crypto/heimdal/tools/kdc-log-analyze.pl
34860 views
#! /usr/pkg/bin/perl1# -*- mode: perl; perl-indent-level: 8 -*-2#3# Copyright (c) 2003 Kungliga Tekniska Högskolan4# (Royal Institute of Technology, Stockholm, Sweden).5# All rights reserved.6#7# Redistribution and use in source and binary forms, with or without8# modification, are permitted provided that the following conditions9# are met:10#11# 1. Redistributions of source code must retain the above copyright12# notice, this list of conditions and the following disclaimer.13#14# 2. Redistributions in binary form must reproduce the above copyright15# notice, this list of conditions and the following disclaimer in the16# documentation and/or other materials provided with the distribution.17#18# 3. Neither the name of the Institute nor the names of its contributors19# may be used to endorse or promote products derived from this software20# without specific prior written permission.21#22# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND23# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE25# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE26# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL27# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS28# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)29# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT30# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY31# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF32# SUCH DAMAGE.33#34# $Id$35#36# kdc-log-analyze - Analyze a KDC log file and give a report on the contents37#38# Note: The parts you want likely want to customize are the variable $notlocal,39# the array @local_network_re and the array @local_realms.40#41# Idea and implemetion for MIT Kerberos was done first by42# Ken Hornstein <[email protected]>, this program wouldn't exists43# without his help.44#4546use strict;47use Sys::Hostname;4849my $notlocal = 'not SU';50my @local_realms = ( "SU.SE" );51my @local_networks_re =52(53"130\.237",54"193\.11\.3[0-9]\.",55"130.242.128",56"2001:6b0:5:"57);5859my $as_req = 0;60my %as_req_addr;61my %as_req_addr_nonlocal;62my %as_req_client;63my %as_req_server;64my %addr_uses_des;65my %princ_uses_des;66my $five24_req = 0;67my %five24_req_addr;68my %five24_req_addr_nonlocal;69my %five24_req_server;70my %five24_req_client;71my $as_req_successful = 0;72my $as_req_error = 0;73my $no_such_princ = 0;74my %no_such_princ_princ;75my %no_such_princ_addr;76my %no_such_princ_addr_nonlocal;77my $as_req_etype_odd = 0;78my %bw_addr;79my $pa_alt_princ_request = 0;80my $pa_alt_princ_verify = 0;81my $tgs_req = 0;82my %tgs_req_addr;83my %tgs_req_addr_nonlocal;84my %tgs_req_client;85my %tgs_req_server;86my $tgs_xrealm_out = 0;87my %tgs_xrealm_out_realm;88my %tgs_xrealm_out_princ;89my $tgs_xrealm_in = 0;90my %tgs_xrealm_in_realm;91my %tgs_xrealm_in_princ;92my %enctype_session;93my %enctype_ticket;94my $restarts = 0;95my $forward_non_forward = 0;96my $v4_req = 0;97my %v4_req_addr;98my %v4_req_addr_nonlocal;99my $v4_cross = 0;100my %v4_cross_realm;101my $v5_cross = 0;102my %v5_cross_realm;103my $referrals = 0;104my %referral_princ;105my %referral_realm;106my %strange_tcp_data;107my $http_malformed = 0;108my %http_malformed_addr;109my $http_non_kdc = 0;110my %http_non_kdc_addr;111my $tcp_conn_timeout = 0;112my %tcp_conn_timeout_addr;113my $failed_processing = 0;114my %failed_processing_addr;115my $connection_closed = 0;116my %connection_closed_addr;117my $pa_failed = 0;118my %pa_failed_princ;119my %pa_failed_addr;120my %ip;121122$ip{'4'} = $ip{'6'} = 0;123124while (<>) {125process_line($_);126}127128print "Kerberos KDC Log Report for ",129hostname, " on ", scalar localtime, "\n\n";130131print "General Statistics\n\n";132133print "\tNumber of IPv4 requests: $ip{'4'}\n";134print "\tNumber of IPv6 requests: $ip{'6'}\n\n";135136print "\tNumber of restarts: $restarts\n";137print "\tNumber of V4 requests: $v4_req\n";138if ($v4_req > 0) {139print "\tTop ten IP addresses performing V4 requests:\n";140topten(\%v4_req_addr);141}142if (int(keys %v4_req_addr_nonlocal) > 0) {143print "\tTop ten $notlocal IP addresses performing V4 requests:\n";144topten(\%v4_req_addr_nonlocal);145146}147print "\n";148149print "\tNumber of V4 cross realms (krb4 and 524) requests: $v4_cross\n";150if ($v4_cross > 0) {151print "\tTop ten realms performing V4 cross requests:\n";152topten(\%v4_cross_realm);153}154print "\n";155156print "\tNumber of V45 cross realms requests: $v5_cross\n";157if ($v5_cross > 0) {158print "\tTop ten realms performing V4 cross requests:\n";159topten(\%v5_cross_realm);160}161print "\n";162163print "\tNumber of failed lookups: $no_such_princ\n";164if ($no_such_princ > 0) {165print "\tTop ten IP addresses failing to find principal:\n";166topten(\%no_such_princ_addr);167print "\tTop ten $notlocal IP addresses failing find principal:\n";168topten(\%no_such_princ_addr_nonlocal);169print "\tTop ten failed to find principals\n";170topten(\%no_such_princ_princ);171}172print "\n";173174print "\tBandwidth pigs:\n";175topten(\%bw_addr);176print "\n";177178print "\tStrange TCP data clients: ", int(keys %strange_tcp_data),"\n";179topten(\%strange_tcp_data);180print "\n";181182print "\tTimeout waiting on TCP requests: ", $tcp_conn_timeout,"\n";183if ($tcp_conn_timeout > 0) {184print "\tTop ten TCP timeout request clients\n";185topten(\%tcp_conn_timeout_addr);186}187print "\n";188189print "\tFailed processing requests: ", $failed_processing,"\n";190if ($failed_processing > 0) {191print "\tTop ten failed processing request clients\n";192topten(\%failed_processing_addr);193}194print "\n";195196print "\tConnection closed requests: ", $connection_closed,"\n";197if ($connection_closed > 0) {198print "\tTop ten connection closed request clients\n";199topten(\%connection_closed_addr);200}201print "\n";202203print "\tMalformed HTTP requests: ", $http_malformed,"\n";204if ($http_malformed > 0) {205print "\tTop ten malformed HTTP request clients\n";206topten(\%http_malformed_addr);207}208print "\n";209210print "\tHTTP non kdc requests: ", $http_non_kdc,"\n";211if ($http_non_kdc > 0) {212print "\tTop ten HTTP non KDC request clients\n";213topten(\%http_non_kdc_addr);214}215print "\n";216217print "Report on AS_REQ requests\n\n";218print "Overall AS_REQ statistics\n\n";219220print "\tTotal number: $as_req\n";221222print "\nAS_REQ client/server statistics\n\n";223224print "\tDistinct IP Addresses performing requests: ",225int(keys %as_req_addr),"\n";226print "\tOverall top ten IP addresses\n";227topten(\%as_req_addr);228229print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",230int(keys %as_req_addr_nonlocal), "\n";231print "\tTop ten non-local ($notlocal) IP address:\n";232topten(\%as_req_addr_nonlocal);233234print "\n\tPreauth failed for for: ", $pa_failed, " requests\n";235if ($pa_failed) {236print "\tPreauth failed top ten IP addresses:\n";237topten(\%pa_failed_addr);238print "\tPreauth failed top ten principals:\n";239topten(\%pa_failed_princ);240}241242print "\n\tDistinct clients performing requests: ",243int(keys %as_req_client), "\n";244print "\tTop ten clients:\n";245topten(\%as_req_client);246247print "\tDistinct services requested: ", int(keys %as_req_server), "\n";248print "\tTop ten requested services:\n";249topten(\%as_req_server);250251print "\n\n\nReport on TGS_REQ requests:\n\n";252print "Overall TGS_REQ statistics\n\n";253print "\tTotal number: $tgs_req\n";254255print "\nTGS_REQ client/server statistics\n\n";256print "\tDistinct IP addresses performing requests: ",257int(keys %tgs_req_addr), "\n";258print "\tOverall top ten IP addresses\n";259topten(\%tgs_req_addr);260261print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",262int(keys %tgs_req_addr_nonlocal), "\n";263print "\tTop ten non-local ($notlocal) IP address:\n";264topten(\%tgs_req_addr_nonlocal);265266print "\tDistinct clients performing requests: ",267int(keys %tgs_req_client), "\n";268print "\tTop ten clients:\n";269topten(\%tgs_req_client);270271print "\tDistinct services requested: ", int(keys %tgs_req_server), "\n";272print "\tTop ten requested services:\n";273topten(\%tgs_req_server);274275print "\n\n\nReport on 524_REQ requests:\n\n";276277print "\t524_REQ client/server statistics\n\n";278279print "\tDistinct IP Addresses performing requests: ",280int(keys %five24_req_addr),"\n";281print "\tOverall top ten IP addresses\n";282topten(\%five24_req_addr);283284print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",285int(keys %five24_req_addr_nonlocal), "\n";286print "\tTop ten non-local ($notlocal) IP address:\n";287topten(\%five24_req_addr_nonlocal);288289print "\tDistinct clients performing requests: ", int(keys %five24_req_client), "\n";290print "\tTop ten clients:\n";291topten(\%five24_req_client);292293print "\tDistinct services requested: ", int(keys %five24_req_server), "\n";294print "\tTop ten requested services:\n";295topten(\%five24_req_server);296print "\n";297298print "Cross realm statistics\n\n";299300print "\tNumber of cross-realm tgs out: $tgs_xrealm_out\n";301if ($tgs_xrealm_out > 0) {302print "\tTop ten realms used for out cross-realm:\n";303topten(\%tgs_xrealm_out_realm);304print "\tTop ten principals use out cross-realm:\n";305topten(\%tgs_xrealm_out_princ);306}307print "\tNumber of cross-realm tgs in: $tgs_xrealm_in\n";308if ($tgs_xrealm_in > 0) {309print "\tTop ten realms used for in cross-realm:\n";310topten(\%tgs_xrealm_in_realm);311print "\tTop ten principals use in cross-realm:\n";312topten(\%tgs_xrealm_in_princ);313}314315print "\n\nReport on referral:\n\n";316317print "\tNumber of referrals: $referrals\n";318if ($referrals > 0) {319print "\tTop ten referral-ed principals:\n";320topten(\%referral_princ);321print "\tTop ten to realm referrals:\n";322topten(\%referral_realm);323}324325print "\n\nEnctype Statistics:\n\n";326print "\tTop ten session enctypes:\n";327topten(\%enctype_session);328print "\tTop ten ticket enctypes:\n";329topten(\%enctype_ticket);330331print "\tDistinct IP addresses using DES: ", int(keys %addr_uses_des), "\n";332print "\tTop IP addresses using DES:\n";333topten(\%addr_uses_des);334print "\tDistinct principals using DES: ", int(keys %princ_uses_des), "\n";335print "\tTop ten principals using DES:\n";336topten(\%princ_uses_des);337338print "\n";339340printf("Requests to forward non-forwardable ticket: $forward_non_forward\n");341342343exit 0;344345my $last_addr = "";346my $last_principal = "";347348sub process_line {349local($_) = @_;350#351# Eat these lines that are output as a result of startup (but352# log the number of restarts)353#354if (/AS-REQ \(krb4\) (.*) from IPv([46]):([0-9\.:a-fA-F]+) for krbtgt.*$/){355$v4_req++;356$v4_req_addr{$3}++;357$v4_req_addr_nonlocal{$3}++ if (!islocaladdr($3));358$last_addr = $3;359$last_principal = $1;360$ip{$2}++;361} elsif (/AS-REQ (.*) from IPv([46]):([0-9\.:a-fA-F]+) for (.*)$/) {362$as_req++;363$as_req_client{$1}++;364$as_req_server{$4}++;365$as_req_addr{$3}++;366$as_req_addr_nonlocal{$3}++ if (!islocaladdr($3));367$last_addr = $3;368$last_principal = $1;369$ip{$2}++;370} elsif (/TGS-REQ \(krb4\)/) {371#Nothing372} elsif (/TGS-REQ (.+) from IPv([46]):([0-9\.:a-fA-F]+) for (.*?)( \[.*\]){0,1}$/) {373$tgs_req++;374$tgs_req_client{$1}++;375$tgs_req_server{$4}++;376$tgs_req_addr{$3}++;377$tgs_req_addr_nonlocal{$3}++ if (!islocaladdr($3));378$last_addr = $3;379$last_principal = $1;380$ip{$2}++;381382my $source = $1;383my $dest = $4;384385if (!islocalrealm($source)) {386$tgs_xrealm_in++;387$tgs_xrealm_in_princ{$source}++;388if ($source =~ /[^@]+@([^@]+)/ ) {389$tgs_xrealm_in_realm{$1}++;390}391}392if ($dest =~ /krbtgt\/([^@]+)@[^@]+/) {393if (!islocalrealm($1)) {394$tgs_xrealm_out++;395$tgs_xrealm_out_realm{$1}++;396$tgs_xrealm_out_princ{$source}++;397}398}399} elsif (/524-REQ (.*) from IPv([46]):([0-9\.:a-fA-F]+) for (.*)$/) {400$five24_req++;401$five24_req_client{$1}++;402$five24_req_server{$4}++;403$five24_req_addr{$3}++;404$five24_req_addr_nonlocal{$3}++ if (!islocaladdr($3));405$last_addr = $3;406$last_principal = $1;407$ip{$2}++;408} elsif (/TCP data of strange type from IPv[46]:([0-9\.:a-fA-F]+)/) {409$strange_tcp_data{$1}++;410} elsif (/Lookup (.*) failed: No such entry in the database/) {411$no_such_princ++;412$no_such_princ_addr{$last_addr}++;413$no_such_princ_addr_nonlocal{$last_addr}++ if (!islocaladdr($last_addr));414$no_such_princ_princ{$1}++;415} elsif (/Lookup .* succeeded$/) {416# Nothing417} elsif (/Malformed HTTP request from IPv[46]:([0-9\.:a-fA-F]+)$/) {418$http_malformed++;419$http_malformed_addr{$1}++;420} elsif (/TCP-connection from IPv[46]:([0-9\.:a-fA-F]+) expired after [0-9]+ bytes/) {421$tcp_conn_timeout++;422$tcp_conn_timeout_addr{$1}++;423} elsif (/Failed processing [0-9]+ byte request from IPv[46]:([0-9\.:a-fA-F]+)/) {424$failed_processing++;425$failed_processing_addr{$1}++;426} elsif (/connection closed before end of data after [0-9]+ bytes from IPv[46]:([0-9\.:a-fA-F]+)/) {427$connection_closed++;428$connection_closed_addr{$1}++;429} elsif (/HTTP request from IPv[46]:([0-9\.:a-fA-F]+) is non KDC request/) {430$http_non_kdc++;431$http_non_kdc_addr{$1}++;432} elsif (/returning a referral to realm (.*) for server (.*) that was not found/) {433$referrals++;434$referral_princ{$2}++;435$referral_realm{$1}++;436} elsif (/krb4 Cross-realm (.*) -> (.*) disabled/) {437$v4_cross++;438$v4_cross_realm{$1."->".$2}++;439} elsif (/524 cross-realm (.*) -> (.*) disabled/) {440$v4_cross++;441$v4_cross_realm{$1."->".$2}++;442} elsif (/cross-realm (.*) -> (.*): no transit through realm (.*)/) {443} elsif (/cross-realm (.*) -> (.*) via \[([^\]]+)\]/) {444$v5_cross++;445$v5_cross_realm{$1."->".$2}++;446} elsif (/cross-realm (.*) -> (.*)/) {447$v5_cross++;448$v5_cross_realm{$1."->".$2}++;449} elsif (/sending ([0-9]+) bytes to IPv[46]:([0-9\.:a-fA-F]+)/) {450$bw_addr{$2} += $1;451} elsif (/Using ([-a-z0-9]+)\/([-a-z0-9]+)/) {452$enctype_ticket{$1}++;453$enctype_session{$2}++;454455my $ticket = $1;456my $session = $2;457458if ($ticket =~ /des-cbc-(crc|md4|md5)/) {459$addr_uses_des{$last_addr}++;460$princ_uses_des{$last_principal}++;461}462463} elsif (/Failed to decrypt PA-DATA -- (.+)$/) {464$pa_failed++;465$pa_failed_princ{$last_principal}++;466$pa_failed_addr{$last_addr}++;467468} elsif (/Request to forward non-forwardable ticket/) {469$forward_non_forward++;470} elsif (/HTTP request:/) {471} elsif (/krb_rd_req: Incorrect network address/) {472} elsif (/krb_rd_req: Ticket expired \(krb_rd_req\)/) {473} elsif (/Ticket expired \(.*\)/) {474} elsif (/krb_rd_req: Can't decode authenticator \(krb_rd_req\)/) {475} elsif (/Request from wrong address/) {476# XXX477} elsif (/UNKNOWN --/) {478# XXX479} elsif (/Too large time skew -- (.*)$/) {480# XXX481} elsif (/No PA-ENC-TIMESTAMP --/) {482# XXX483} elsif (/Looking for pa-data --/) {484# XXX485} elsif (/Pre-authentication succeded -- (.+)$/) {486# XXX487} elsif (/Bad request for ([,a-zA-Z0-9]+) ticket/) {488# XXX489} elsif (/Failed to verify AP-REQ: Ticket expired/) {490# XXX491} elsif (/Client not found in database:/) {492# XXX493} elsif (/Server not found in database \(krb4\)/) {494} elsif (/Server not found in database:/) {495# XXX496} elsif (/newsyslog.*logfile turned over/) {497# Nothing498} elsif (/Requested flags:/) {499# Nothing500} elsif (/shutting down/) {501# Nothing502} elsif (/listening on IP/) {503# Nothing504} elsif (/commencing operation/) {505$restarts++;506}507#508# Log it if we didn't parse the line509#510else {511print "Unknown log file line: $_";512}513}514515sub topten {516my ($list) = @_;517my @keys;518519my $key;520521@keys = (sort {$$list{$b} <=> $$list{$a}} (keys %{$list}));522splice @keys, 10;523524foreach $key (@keys) {525print "\t\t$key - $$list{$key}\n";526}527}528529sub islocaladdr (\$) {530my ($addr) = @_;531my $net;532533foreach $net (@local_networks_re) {534return 1 if ($addr =~ /$net/);535}536return 0;537}538539sub islocalrealm (\$) {540my ($princ) = @_;541my $realm;542543foreach $realm (@local_realms) {544return 1 if ($princ eq $realm);545return 1 if ($princ =~ /[^@]+\@${realm}/);546}547return 0;548}549550551