Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/tools/kdc-log-analyze.pl
34860 views
1
#! /usr/pkg/bin/perl
2
# -*- mode: perl; perl-indent-level: 8 -*-
3
#
4
# Copyright (c) 2003 Kungliga Tekniska Högskolan
5
# (Royal Institute of Technology, Stockholm, Sweden).
6
# All rights reserved.
7
#
8
# Redistribution and use in source and binary forms, with or without
9
# modification, are permitted provided that the following conditions
10
# are met:
11
#
12
# 1. Redistributions of source code must retain the above copyright
13
# notice, this list of conditions and the following disclaimer.
14
#
15
# 2. Redistributions in binary form must reproduce the above copyright
16
# notice, this list of conditions and the following disclaimer in the
17
# documentation and/or other materials provided with the distribution.
18
#
19
# 3. Neither the name of the Institute nor the names of its contributors
20
# may be used to endorse or promote products derived from this software
21
# without specific prior written permission.
22
#
23
# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
# SUCH DAMAGE.
34
#
35
# $Id$
36
#
37
# kdc-log-analyze - Analyze a KDC log file and give a report on the contents
38
#
39
# Note: The parts you want likely want to customize are the variable $notlocal,
40
# the array @local_network_re and the array @local_realms.
41
#
42
# Idea and implemetion for MIT Kerberos was done first by
43
# Ken Hornstein <[email protected]>, this program wouldn't exists
44
# without his help.
45
#
46
47
use strict;
48
use Sys::Hostname;
49
50
my $notlocal = 'not SU';
51
my @local_realms = ( "SU.SE" );
52
my @local_networks_re =
53
(
54
"130\.237",
55
"193\.11\.3[0-9]\.",
56
"130.242.128",
57
"2001:6b0:5:"
58
);
59
60
my $as_req = 0;
61
my %as_req_addr;
62
my %as_req_addr_nonlocal;
63
my %as_req_client;
64
my %as_req_server;
65
my %addr_uses_des;
66
my %princ_uses_des;
67
my $five24_req = 0;
68
my %five24_req_addr;
69
my %five24_req_addr_nonlocal;
70
my %five24_req_server;
71
my %five24_req_client;
72
my $as_req_successful = 0;
73
my $as_req_error = 0;
74
my $no_such_princ = 0;
75
my %no_such_princ_princ;
76
my %no_such_princ_addr;
77
my %no_such_princ_addr_nonlocal;
78
my $as_req_etype_odd = 0;
79
my %bw_addr;
80
my $pa_alt_princ_request = 0;
81
my $pa_alt_princ_verify = 0;
82
my $tgs_req = 0;
83
my %tgs_req_addr;
84
my %tgs_req_addr_nonlocal;
85
my %tgs_req_client;
86
my %tgs_req_server;
87
my $tgs_xrealm_out = 0;
88
my %tgs_xrealm_out_realm;
89
my %tgs_xrealm_out_princ;
90
my $tgs_xrealm_in = 0;
91
my %tgs_xrealm_in_realm;
92
my %tgs_xrealm_in_princ;
93
my %enctype_session;
94
my %enctype_ticket;
95
my $restarts = 0;
96
my $forward_non_forward = 0;
97
my $v4_req = 0;
98
my %v4_req_addr;
99
my %v4_req_addr_nonlocal;
100
my $v4_cross = 0;
101
my %v4_cross_realm;
102
my $v5_cross = 0;
103
my %v5_cross_realm;
104
my $referrals = 0;
105
my %referral_princ;
106
my %referral_realm;
107
my %strange_tcp_data;
108
my $http_malformed = 0;
109
my %http_malformed_addr;
110
my $http_non_kdc = 0;
111
my %http_non_kdc_addr;
112
my $tcp_conn_timeout = 0;
113
my %tcp_conn_timeout_addr;
114
my $failed_processing = 0;
115
my %failed_processing_addr;
116
my $connection_closed = 0;
117
my %connection_closed_addr;
118
my $pa_failed = 0;
119
my %pa_failed_princ;
120
my %pa_failed_addr;
121
my %ip;
122
123
$ip{'4'} = $ip{'6'} = 0;
124
125
while (<>) {
126
process_line($_);
127
}
128
129
print "Kerberos KDC Log Report for ",
130
hostname, " on ", scalar localtime, "\n\n";
131
132
print "General Statistics\n\n";
133
134
print "\tNumber of IPv4 requests: $ip{'4'}\n";
135
print "\tNumber of IPv6 requests: $ip{'6'}\n\n";
136
137
print "\tNumber of restarts: $restarts\n";
138
print "\tNumber of V4 requests: $v4_req\n";
139
if ($v4_req > 0) {
140
print "\tTop ten IP addresses performing V4 requests:\n";
141
topten(\%v4_req_addr);
142
}
143
if (int(keys %v4_req_addr_nonlocal) > 0) {
144
print "\tTop ten $notlocal IP addresses performing V4 requests:\n";
145
topten(\%v4_req_addr_nonlocal);
146
147
}
148
print "\n";
149
150
print "\tNumber of V4 cross realms (krb4 and 524) requests: $v4_cross\n";
151
if ($v4_cross > 0) {
152
print "\tTop ten realms performing V4 cross requests:\n";
153
topten(\%v4_cross_realm);
154
}
155
print "\n";
156
157
print "\tNumber of V45 cross realms requests: $v5_cross\n";
158
if ($v5_cross > 0) {
159
print "\tTop ten realms performing V4 cross requests:\n";
160
topten(\%v5_cross_realm);
161
}
162
print "\n";
163
164
print "\tNumber of failed lookups: $no_such_princ\n";
165
if ($no_such_princ > 0) {
166
print "\tTop ten IP addresses failing to find principal:\n";
167
topten(\%no_such_princ_addr);
168
print "\tTop ten $notlocal IP addresses failing find principal:\n";
169
topten(\%no_such_princ_addr_nonlocal);
170
print "\tTop ten failed to find principals\n";
171
topten(\%no_such_princ_princ);
172
}
173
print "\n";
174
175
print "\tBandwidth pigs:\n";
176
topten(\%bw_addr);
177
print "\n";
178
179
print "\tStrange TCP data clients: ", int(keys %strange_tcp_data),"\n";
180
topten(\%strange_tcp_data);
181
print "\n";
182
183
print "\tTimeout waiting on TCP requests: ", $tcp_conn_timeout,"\n";
184
if ($tcp_conn_timeout > 0) {
185
print "\tTop ten TCP timeout request clients\n";
186
topten(\%tcp_conn_timeout_addr);
187
}
188
print "\n";
189
190
print "\tFailed processing requests: ", $failed_processing,"\n";
191
if ($failed_processing > 0) {
192
print "\tTop ten failed processing request clients\n";
193
topten(\%failed_processing_addr);
194
}
195
print "\n";
196
197
print "\tConnection closed requests: ", $connection_closed,"\n";
198
if ($connection_closed > 0) {
199
print "\tTop ten connection closed request clients\n";
200
topten(\%connection_closed_addr);
201
}
202
print "\n";
203
204
print "\tMalformed HTTP requests: ", $http_malformed,"\n";
205
if ($http_malformed > 0) {
206
print "\tTop ten malformed HTTP request clients\n";
207
topten(\%http_malformed_addr);
208
}
209
print "\n";
210
211
print "\tHTTP non kdc requests: ", $http_non_kdc,"\n";
212
if ($http_non_kdc > 0) {
213
print "\tTop ten HTTP non KDC request clients\n";
214
topten(\%http_non_kdc_addr);
215
}
216
print "\n";
217
218
print "Report on AS_REQ requests\n\n";
219
print "Overall AS_REQ statistics\n\n";
220
221
print "\tTotal number: $as_req\n";
222
223
print "\nAS_REQ client/server statistics\n\n";
224
225
print "\tDistinct IP Addresses performing requests: ",
226
int(keys %as_req_addr),"\n";
227
print "\tOverall top ten IP addresses\n";
228
topten(\%as_req_addr);
229
230
print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
231
int(keys %as_req_addr_nonlocal), "\n";
232
print "\tTop ten non-local ($notlocal) IP address:\n";
233
topten(\%as_req_addr_nonlocal);
234
235
print "\n\tPreauth failed for for: ", $pa_failed, " requests\n";
236
if ($pa_failed) {
237
print "\tPreauth failed top ten IP addresses:\n";
238
topten(\%pa_failed_addr);
239
print "\tPreauth failed top ten principals:\n";
240
topten(\%pa_failed_princ);
241
}
242
243
print "\n\tDistinct clients performing requests: ",
244
int(keys %as_req_client), "\n";
245
print "\tTop ten clients:\n";
246
topten(\%as_req_client);
247
248
print "\tDistinct services requested: ", int(keys %as_req_server), "\n";
249
print "\tTop ten requested services:\n";
250
topten(\%as_req_server);
251
252
print "\n\n\nReport on TGS_REQ requests:\n\n";
253
print "Overall TGS_REQ statistics\n\n";
254
print "\tTotal number: $tgs_req\n";
255
256
print "\nTGS_REQ client/server statistics\n\n";
257
print "\tDistinct IP addresses performing requests: ",
258
int(keys %tgs_req_addr), "\n";
259
print "\tOverall top ten IP addresses\n";
260
topten(\%tgs_req_addr);
261
262
print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
263
int(keys %tgs_req_addr_nonlocal), "\n";
264
print "\tTop ten non-local ($notlocal) IP address:\n";
265
topten(\%tgs_req_addr_nonlocal);
266
267
print "\tDistinct clients performing requests: ",
268
int(keys %tgs_req_client), "\n";
269
print "\tTop ten clients:\n";
270
topten(\%tgs_req_client);
271
272
print "\tDistinct services requested: ", int(keys %tgs_req_server), "\n";
273
print "\tTop ten requested services:\n";
274
topten(\%tgs_req_server);
275
276
print "\n\n\nReport on 524_REQ requests:\n\n";
277
278
print "\t524_REQ client/server statistics\n\n";
279
280
print "\tDistinct IP Addresses performing requests: ",
281
int(keys %five24_req_addr),"\n";
282
print "\tOverall top ten IP addresses\n";
283
topten(\%five24_req_addr);
284
285
print "\tDistinct non-local ($notlocal) IP Addresses performing requests: ",
286
int(keys %five24_req_addr_nonlocal), "\n";
287
print "\tTop ten non-local ($notlocal) IP address:\n";
288
topten(\%five24_req_addr_nonlocal);
289
290
print "\tDistinct clients performing requests: ", int(keys %five24_req_client), "\n";
291
print "\tTop ten clients:\n";
292
topten(\%five24_req_client);
293
294
print "\tDistinct services requested: ", int(keys %five24_req_server), "\n";
295
print "\tTop ten requested services:\n";
296
topten(\%five24_req_server);
297
print "\n";
298
299
print "Cross realm statistics\n\n";
300
301
print "\tNumber of cross-realm tgs out: $tgs_xrealm_out\n";
302
if ($tgs_xrealm_out > 0) {
303
print "\tTop ten realms used for out cross-realm:\n";
304
topten(\%tgs_xrealm_out_realm);
305
print "\tTop ten principals use out cross-realm:\n";
306
topten(\%tgs_xrealm_out_princ);
307
}
308
print "\tNumber of cross-realm tgs in: $tgs_xrealm_in\n";
309
if ($tgs_xrealm_in > 0) {
310
print "\tTop ten realms used for in cross-realm:\n";
311
topten(\%tgs_xrealm_in_realm);
312
print "\tTop ten principals use in cross-realm:\n";
313
topten(\%tgs_xrealm_in_princ);
314
}
315
316
print "\n\nReport on referral:\n\n";
317
318
print "\tNumber of referrals: $referrals\n";
319
if ($referrals > 0) {
320
print "\tTop ten referral-ed principals:\n";
321
topten(\%referral_princ);
322
print "\tTop ten to realm referrals:\n";
323
topten(\%referral_realm);
324
}
325
326
print "\n\nEnctype Statistics:\n\n";
327
print "\tTop ten session enctypes:\n";
328
topten(\%enctype_session);
329
print "\tTop ten ticket enctypes:\n";
330
topten(\%enctype_ticket);
331
332
print "\tDistinct IP addresses using DES: ", int(keys %addr_uses_des), "\n";
333
print "\tTop IP addresses using DES:\n";
334
topten(\%addr_uses_des);
335
print "\tDistinct principals using DES: ", int(keys %princ_uses_des), "\n";
336
print "\tTop ten principals using DES:\n";
337
topten(\%princ_uses_des);
338
339
print "\n";
340
341
printf("Requests to forward non-forwardable ticket: $forward_non_forward\n");
342
343
344
exit 0;
345
346
my $last_addr = "";
347
my $last_principal = "";
348
349
sub process_line {
350
local($_) = @_;
351
#
352
# Eat these lines that are output as a result of startup (but
353
# log the number of restarts)
354
#
355
if (/AS-REQ \(krb4\) (.*) from IPv([46]):([0-9\.:a-fA-F]+) for krbtgt.*$/){
356
$v4_req++;
357
$v4_req_addr{$3}++;
358
$v4_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
359
$last_addr = $3;
360
$last_principal = $1;
361
$ip{$2}++;
362
} elsif (/AS-REQ (.*) from IPv([46]):([0-9\.:a-fA-F]+) for (.*)$/) {
363
$as_req++;
364
$as_req_client{$1}++;
365
$as_req_server{$4}++;
366
$as_req_addr{$3}++;
367
$as_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
368
$last_addr = $3;
369
$last_principal = $1;
370
$ip{$2}++;
371
} elsif (/TGS-REQ \(krb4\)/) {
372
#Nothing
373
} elsif (/TGS-REQ (.+) from IPv([46]):([0-9\.:a-fA-F]+) for (.*?)( \[.*\]){0,1}$/) {
374
$tgs_req++;
375
$tgs_req_client{$1}++;
376
$tgs_req_server{$4}++;
377
$tgs_req_addr{$3}++;
378
$tgs_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
379
$last_addr = $3;
380
$last_principal = $1;
381
$ip{$2}++;
382
383
my $source = $1;
384
my $dest = $4;
385
386
if (!islocalrealm($source)) {
387
$tgs_xrealm_in++;
388
$tgs_xrealm_in_princ{$source}++;
389
if ($source =~ /[^@]+@([^@]+)/ ) {
390
$tgs_xrealm_in_realm{$1}++;
391
}
392
}
393
if ($dest =~ /krbtgt\/([^@]+)@[^@]+/) {
394
if (!islocalrealm($1)) {
395
$tgs_xrealm_out++;
396
$tgs_xrealm_out_realm{$1}++;
397
$tgs_xrealm_out_princ{$source}++;
398
}
399
}
400
} elsif (/524-REQ (.*) from IPv([46]):([0-9\.:a-fA-F]+) for (.*)$/) {
401
$five24_req++;
402
$five24_req_client{$1}++;
403
$five24_req_server{$4}++;
404
$five24_req_addr{$3}++;
405
$five24_req_addr_nonlocal{$3}++ if (!islocaladdr($3));
406
$last_addr = $3;
407
$last_principal = $1;
408
$ip{$2}++;
409
} elsif (/TCP data of strange type from IPv[46]:([0-9\.:a-fA-F]+)/) {
410
$strange_tcp_data{$1}++;
411
} elsif (/Lookup (.*) failed: No such entry in the database/) {
412
$no_such_princ++;
413
$no_such_princ_addr{$last_addr}++;
414
$no_such_princ_addr_nonlocal{$last_addr}++ if (!islocaladdr($last_addr));
415
$no_such_princ_princ{$1}++;
416
} elsif (/Lookup .* succeeded$/) {
417
# Nothing
418
} elsif (/Malformed HTTP request from IPv[46]:([0-9\.:a-fA-F]+)$/) {
419
$http_malformed++;
420
$http_malformed_addr{$1}++;
421
} elsif (/TCP-connection from IPv[46]:([0-9\.:a-fA-F]+) expired after [0-9]+ bytes/) {
422
$tcp_conn_timeout++;
423
$tcp_conn_timeout_addr{$1}++;
424
} elsif (/Failed processing [0-9]+ byte request from IPv[46]:([0-9\.:a-fA-F]+)/) {
425
$failed_processing++;
426
$failed_processing_addr{$1}++;
427
} elsif (/connection closed before end of data after [0-9]+ bytes from IPv[46]:([0-9\.:a-fA-F]+)/) {
428
$connection_closed++;
429
$connection_closed_addr{$1}++;
430
} elsif (/HTTP request from IPv[46]:([0-9\.:a-fA-F]+) is non KDC request/) {
431
$http_non_kdc++;
432
$http_non_kdc_addr{$1}++;
433
} elsif (/returning a referral to realm (.*) for server (.*) that was not found/) {
434
$referrals++;
435
$referral_princ{$2}++;
436
$referral_realm{$1}++;
437
} elsif (/krb4 Cross-realm (.*) -> (.*) disabled/) {
438
$v4_cross++;
439
$v4_cross_realm{$1."->".$2}++;
440
} elsif (/524 cross-realm (.*) -> (.*) disabled/) {
441
$v4_cross++;
442
$v4_cross_realm{$1."->".$2}++;
443
} elsif (/cross-realm (.*) -> (.*): no transit through realm (.*)/) {
444
} elsif (/cross-realm (.*) -> (.*) via \[([^\]]+)\]/) {
445
$v5_cross++;
446
$v5_cross_realm{$1."->".$2}++;
447
} elsif (/cross-realm (.*) -> (.*)/) {
448
$v5_cross++;
449
$v5_cross_realm{$1."->".$2}++;
450
} elsif (/sending ([0-9]+) bytes to IPv[46]:([0-9\.:a-fA-F]+)/) {
451
$bw_addr{$2} += $1;
452
} elsif (/Using ([-a-z0-9]+)\/([-a-z0-9]+)/) {
453
$enctype_ticket{$1}++;
454
$enctype_session{$2}++;
455
456
my $ticket = $1;
457
my $session = $2;
458
459
if ($ticket =~ /des-cbc-(crc|md4|md5)/) {
460
$addr_uses_des{$last_addr}++;
461
$princ_uses_des{$last_principal}++;
462
}
463
464
} elsif (/Failed to decrypt PA-DATA -- (.+)$/) {
465
$pa_failed++;
466
$pa_failed_princ{$last_principal}++;
467
$pa_failed_addr{$last_addr}++;
468
469
} elsif (/Request to forward non-forwardable ticket/) {
470
$forward_non_forward++;
471
} elsif (/HTTP request:/) {
472
} elsif (/krb_rd_req: Incorrect network address/) {
473
} elsif (/krb_rd_req: Ticket expired \(krb_rd_req\)/) {
474
} elsif (/Ticket expired \(.*\)/) {
475
} elsif (/krb_rd_req: Can't decode authenticator \(krb_rd_req\)/) {
476
} elsif (/Request from wrong address/) {
477
# XXX
478
} elsif (/UNKNOWN --/) {
479
# XXX
480
} elsif (/Too large time skew -- (.*)$/) {
481
# XXX
482
} elsif (/No PA-ENC-TIMESTAMP --/) {
483
# XXX
484
} elsif (/Looking for pa-data --/) {
485
# XXX
486
} elsif (/Pre-authentication succeded -- (.+)$/) {
487
# XXX
488
} elsif (/Bad request for ([,a-zA-Z0-9]+) ticket/) {
489
# XXX
490
} elsif (/Failed to verify AP-REQ: Ticket expired/) {
491
# XXX
492
} elsif (/Client not found in database:/) {
493
# XXX
494
} elsif (/Server not found in database \(krb4\)/) {
495
} elsif (/Server not found in database:/) {
496
# XXX
497
} elsif (/newsyslog.*logfile turned over/) {
498
# Nothing
499
} elsif (/Requested flags:/) {
500
# Nothing
501
} elsif (/shutting down/) {
502
# Nothing
503
} elsif (/listening on IP/) {
504
# Nothing
505
} elsif (/commencing operation/) {
506
$restarts++;
507
}
508
#
509
# Log it if we didn't parse the line
510
#
511
else {
512
print "Unknown log file line: $_";
513
}
514
}
515
516
sub topten {
517
my ($list) = @_;
518
my @keys;
519
520
my $key;
521
522
@keys = (sort {$$list{$b} <=> $$list{$a}} (keys %{$list}));
523
splice @keys, 10;
524
525
foreach $key (@keys) {
526
print "\t\t$key - $$list{$key}\n";
527
}
528
}
529
530
sub islocaladdr (\$) {
531
my ($addr) = @_;
532
my $net;
533
534
foreach $net (@local_networks_re) {
535
return 1 if ($addr =~ /$net/);
536
}
537
return 0;
538
}
539
540
sub islocalrealm (\$) {
541
my ($princ) = @_;
542
my $realm;
543
544
foreach $realm (@local_realms) {
545
return 1 if ($princ eq $realm);
546
return 1 if ($princ =~ /[^@]+\@${realm}/);
547
}
548
return 0;
549
}
550
551