ping for kdc utility?
Russ Allbery
eagle at eyrie.org
Wed Apr 2 16:33:38 EDT 2014
Wang Shouhua <shouhuaw at gmail.com> writes:
> To see if the KDC is still 'alive and kicking'. Apparently some
> students-as-admins here spend the night trying to find a problem in our
> Kerberos setup the whole night and they are very exhausted. The problem
> turned out to be a switch/firewall problem which caused the KDC to stop
> processing requests after some time, something which could have been
> diagnosed much earlier using a dedicated utility.
I would just authenticate using a keytab and ensure that you can get
tickets. Here's the script we use for that purpose. Note that this is
something of a hack and does things like use predictable files in /tmp by
default, so use with caution. It uses k5start, but you could easily
modify it to use kinit instead.
#!/usr/bin/perl
#
# kdc-check -- Check a Kerberos KDC for correct operation.
#
# Written by R.L. "Bob" Morgan
# Updated by Russ Allbery <rra at stanford.edu>
# Copyright 1994, 2003, 2011
# The Board of Trustees of the Leland Stanford Junior University
##############################################################################
# Site configuration
##############################################################################
# The location of Kerberos v5 files and programs. The keytab locaction should
# contain host/<hostname> and the k5start program must support -q, -f, and -u.
our $KRB5_CONF = '/etc/krb5.conf';
our $KRB_KEYTAB = '/etc/krb5.keytab';
our $K5START = '/usr/bin/k5start';
# Path to klist that supports the -5 option.
our $KLIST = '/usr/bin/klist';
##############################################################################
# Modules and declarations
##############################################################################
require 5.003;
use strict;
use Getopt::Long qw(GetOptions);
use Fcntl qw(O_CREAT O_EXCL O_WRONLY);
use Net::Domain qw(hostfqdn);
use Sys::Hostname qw(hostname);
our $USAGE = <<'EOU';
Usage: kdc-check [-5dv] [-c <conf>] [-f <keytab>] [-p <user>] [-r <realm>]
[-s <server>]
Checks a Kerberos server by attempting to obtain a ticket. By default, it
obtains a TGT for host/<hostname> for the local fully qualified system
name, using the keytab in /etc/krb5.keytab and the Kerberos KDCs defined
in the default krb5.conf.
Options:
-5 Ignored for backward compatibility
-c <conf> Use <conf> instead of the default krb5.conf
-d Enable debugging (don't delete temporary files)
-f <keytab> Use <keytab> instead of /etc/krb5.keytab
-p <user> Obtain tickets for <user> instead of host/<hostname>
-r <realm> Use the realm <realm>, requires -s be given
-s <server> Use the KDC <server>, writing out a temporary krb5.conf
-v Be verbose
Exit status:
0 if server is up and returns proper response
1 otherwise
EOU
#'# for cperl-mode
##############################################################################
# Kerberos handling
##############################################################################
# Create a temporary file name and return it. This is a really bad function
# for this and should be replaced with a standard tmp file creation call.
sub tmp_file_name {
my $program = $0;
$program =~ s%.*/%%;
my $tmp = $ENV{TMPDIR} || '/tmp';
return "$tmp/$program.$$";
}
# Create a krb5.conf file limited to the particular server. Takes the realm
# name, the server, and optionally the file name into which to put the new
# krb5.conf file, and returns the file name used. Ideally more of the
# libdefaults section should come from the current configuration file.
sub create_krb5_conf {
my ($realm, $server, $file) = @_;
$file = tmp_file_name unless $file;
sysopen (CONF, $file, O_WRONLY | O_CREAT | O_EXCL)
or die "$0: cannot create $file: $!\n";
print CONF <<"EOC";
[libdefaults]
default_realm = $realm
ticket_lifetime = 25hrs
[realms]
$realm = {
kdc = $server:88
}
EOC
close CONF or die "$0: cannot flush $file: $!\n";
return $file;
}
# Given the path to the krb5.conf file, determine the default realm name and
# return it.
sub get_realm {
my ($conf) = @_;
open (CONF, $conf) or die "$0: cannot open $conf: $!\n";
my $realm;
while (<CONF>) {
if (/^\s*default_realm\s*=\s*(\S+)/) {
$realm = $1;
last;
}
}
return $realm;
}
# Obtain a ticket using k5start. Takes the ticket file into which it should
# be put, the path to the keytab file, the principal, and a flag saying
# whether to be verbose. Returns true on success, false on failure.
sub get_ticket {
my ($cache, $srvtab, $principal, $verbose) = @_;
unlink $cache;
$ENV{KRB5CCNAME} = $cache;
die "$0: unsafe ticket cache name: $cache\n" if $cache =~ /[\'\\\s]/;
my @args = ('-f', $srvtab, '-u', $principal);
unshift (@args, '-q') unless $verbose;
return (system ($K5START, @args) == 0);
}
# Check a Kerberos ticket cache to make sure that it contains the right
# principal. Takes the cache to check and the principal we're looking for and
# runs klist on the file.
sub check_ticket {
my ($cache, $principal) = @_;
my $output = `$KLIST -5 '$cache'`;
return ($output =~ /\nDefault principal: $principal(\@|\s)/);
}
##############################################################################
# Implementation
##############################################################################
# Trim $0 for error messages.
my $fullname = $0;
$0 =~ s%.*/%%;
# Parse the command line options.
my ($config, $debug, $dummy, $principal, $realm, $server, $keytab,
$verbose, $help, $version);
Getopt::Long::Configure ('bundling');
GetOptions ('5|krb5' => \$dummy,
'c|config=s' => \$config,
'd|debug' => \$debug,
'f|keytab=s' => \$keytab,
'h|help' => \$help,
'p|principal=s' => \$principal,
'r|realm=s' => \$realm,
's|server=s' => \$server,
'v|verbose' => \$verbose) or exit 1;
# Act on some standard options.
if ($help) {
print $USAGE;
exit 0;
}
# Determine the principal and keytab.
my $hostname = hostfqdn;
$principal = 'host/' . $hostname unless $principal;
$keytab = $KRB_KEYTAB unless $keytab;
# Check the command-line options for consistency and set some defaults.
die "$0: -c cannot be given if -s is given\n" if $config && $server;
die "$0: -r <realm> requires -s <server>\n" if $realm && !$server;
$verbose = 1 if $debug;
if ($server && !$realm) {
$realm = get_realm ($KRB5_CONF)
or die "$0: cannot obtain Kerberos realm from $KRB5_CONF\n";
}
$config = create_krb5_conf ($realm, $server) if $server;
$ENV{KRB5_CONFIG} = $config if $config;
my $cache = ($ENV{TMPDIR} || '/tmp') . "/kdc-check.tk$$";
# Print out debugging information if desired.
if ($debug) {
print "server = $server\n";
print "realm = $realm\n";
print "principal = $principal\n";
print "keytab = $keytab\n";
print "cache = $cache\n";
print "config = $config\n";
print "\nWill run the command:\n\n";
print " $K5START " . ($verbose ? '' : "-q ")
. "-f $keytab -u $principal\n\n";
}
# Now, do the actual work.
my $status;
$status = get_ticket ($cache, $keytab, $principal, $verbose);
$status = check_ticket ($cache, $principal) if $status;
unless ($debug) {
unlink $cache;
unlink $config if $server;
}
exit ($status ? 0 : 1);
##############################################################################
# Documentation
##############################################################################
=head1 NAME
kdc-check - Check a Kerberos KDC for correct operation
=head1 SYNOPSIS
B<kdc-check> [B<-5dhv>] [B<--version>] [B<-c> I<config>] [B<-f> I<srvtab>]
S<[B<-p> I<principal>]> [B<-r> I<realm>] [B<-s> I<server>]
=head1 DESCRIPTION
B<kdc-check> checks the operation of a Kerberos KDC by attempting to
obtain a ticket from it. It depends on B<k5start> to actually obtain the
ticket. Use the "kstart" Debian package.
It obtains the default realm from F</etc/krb5.conf> and then attempts to
obtain a Kerberos TGT for host/<hostname> in that realm using
F</etc/krb5.keytab>, where <hostname> is the fully-qualified name of the
local system. Various options can change that behavior.
B<kdc-check> exits with status 0 if the KDC hands back the appropriate
ticket, and with status 1 otherwise.
=head1 OPTIONS
=over 4
=item B<-5>, B<--krb5>
Ignored for backward compatibility.
=item B<-c> I<config>, B<--config>=I<config>
Use I<config> as the krb5.conf file rather than F</etc/krb5.conf>. This
option cannot be used in combination with the B<-s> option. It sets the
environment variable KRB5_CONFIG to point the Kerberos libraries at a
different configuration file.
=item B<-d>, B<--debug>
Do not delete the temporary files and print out the values of all internal
variables. This flag implies B<-v>.
=item B<-f> I<keytab>, B<--keytab>=I<keytab>
Use I<keytab> as the keytab for authentication rather than the default of
F</etc/krb5.keytab>.
=item B<-h>, B<--help>
Print out usage information.
=item B<-p> I<principal>, B<--principal>=I<principal>
Authenticate as I<principal> rather than as the default of host/<host>
where <host> is the fully-qualified local hostname.
=item B<-r> I<realm>, B<--realm>=I<realm>
Obtain a ticket in I<realm> rather than the default Kerberos realm (as
determined by looking in F</etc/krb5.conf>). This option can only be used
in combination with B<-s>.
=item B<-s> I<server>, B<--server>=I<server>
Obtain tickets specifically from I<server> rather than using the system
default krb5.conf. This is done by writing out a one-time krb5.conf file
and then setting the environment variable KRB5_CONFIG to point to it. The
realm can be specified with B<-r>, and if not specified is taken from the
system krb5.conf. This option cannot be used with B<-c> (for obvious
reasons).
=item B<-v>, B<--verbose>
Do not pass the B<-q> flag to B<k5start>, allowing B<k5start> to be more
verbose about what it's doing. This flag is implied by B<-d>.
=back
=head1 EXAMPLES
Check default operations by obtaining a TGT for host/<host> using
F</etc/krb5.keytab> from whatever servers are listed in the system default
krb5.conf file (F</etc/krb5.conf>):
kdc-check
Specifically test that kerberos1.stanford.edu returns a TGT for the
stanford.edu realm, using the default principal and keytab:
kdc-check -s kerberos1.stanford.edu -r stanford.edu
Test that kerberos1.stanford.edu returns a TGT for the default realm, as
determined from the system krb5.conf file (F</etc/krb5.conf>), for the
principal service/monitoring, using the keytab in
F</etc/keytabs/service.monitoring> for authentication.
kdc-check -s kerberos1.stanford.edu -p service/monitoring \
-f /etc/keytabs/service.monitoring
=head1 SEE ALSO
k5start(1)
=head1 AUTHORS
Original version written by R.L. "Bob" Morgan. Updated and reorganized by
Russ Allbery <rra at stanford.edu>, who also added Kerberos v5 support.
=cut
--
Russ Allbery (eagle at eyrie.org) <http://www.eyrie.org/~eagle/>
More information about the Kerberos
mailing list