Frankenkerberos - a quest to make a kerberos that understands LDAP aliases install cleanly on really old servers.
We have a boat load of servers that need to be gotten to. If you manage any
number of servers, you've more than likely looked at centralized
authentication.
We've been using LDAP to store account information, and kerberos for the
authentication bit. We ran into two problems with this. The first problem we
ran into is that we have servers still running that survived the jurrasic
period. This is a problem, because stable production type operating systems
from the jurassic period still run with a nice old verison of kerberos.
This brings us to the second problem. Our servers don't live in a magic happy
network where everything is proper and hosts live by one name with proper
reverse DNS. Our servers are loaded to the gills, and often serve more than
one thing under different names. We also use esoteric host names to identify
servers within the data center. Nobody like using these names, so they get
friendlier aliases...
Herin lies the problem with being old. Kerberos 1.7.x totally digs aliases
when used with LDAP. Old kerberos hates them and despises them. Say you have a
server named sf4n136.domain.com which also known as gateway23.domain.com.
Typically you would want to log into gateway23, so you'd type 'ssh
gateway23.domain.com'. If your ssh is sane, it will dutifully ask the kerberos
server for a service ticket for gateway23. The kerberos server will see that
and say, "huh, who?". It wants you to log in with the real host name of
sf4n136. To make this even more problematic, some old ssh versions
patronizingly do a reverse DNS lookup after resolving the IP, and will use
whatever it gets back as the hostname. Obviously that's what you really
wanted, you just didn't know any better!
So what do you do? You install a kerberos server that handles aliases. You
then put the aliases in the proper entry of your LDAP server database.
Kerberos up to very recently required the client to specifically ask the KDC
to check if the service you are requesting could be an alias. If you didn't
ask, it wouldn't bother returning aliases. The problem with this approach is
that old clients don't bother with all that new fangled alias garbage. They
don't even know what they are. Back when dinosaurs ruled the data center,
servers who called themselves by more than one name were eaten.
One option is to patch the KDC so it unconditionally returns canonicalized
service entries (fancy talk for resolving aliases). Ok, so now you ask for
gateway23, and the server sees that it is really sf4n136, so it just whips up
a ticket encrypted with sf4n236's password, winks at you and labels it
gateway23.
Here's the rub with that. The server you hand that ticket to has to figure out
what the heck you're trying to use, so it can check if you are allowed to use
it. It does this by looking at the service name on the ticket you handed it,
and tries to decrypt the ticket with the corresponding keytab entry for that
service. Unless you've setup keytab entries for every possible name that might
be used to get to that server, you're sunk. Then you might as well forget
aliases, and setup some insane system for keeping a jazillion keytabs up to
date.
New kerberos to the rescue! 1.7.blah knows that the KDC has been doing favors
for you, and doesn't really trust the name on the ticket. It knows that the
real KDC is trustworthy, so if you really do know the real KDC, the ticket you
gave it probably matches something in its keytab. If it can't find that
particular name, it just loops through everything it has, and tries to decrypt
the ticket. Once it finds something that works, it figures out what secret
arrangement you had with the KDC and lets you into the corresponding service.
Still, there's another problem. ARGG!! There's always another problem.
Kerberos has changed a lot since these servers where born. You can't just
update kerberos, since 3/4 of the entire freekin operating system seems to
depend on the old version. Here is where we are blessed. We don't use
kerberos4, and all that stuff depends on kerberos4. This means when we install
a newer kerberos, we can just leave bits of those old libraries laying around.
When those old programs dance with the linker, they won't know the difference,
maybe...
There is one bit in the kerberos5 API that changed. Fortunately, it was just
an initialization function that is no longer needed. That means we can just
write that function in, have it do nothing, and the program will be blissfully
unaware.
So that's what I did. I rolled an RPM that works on all our versions of Centos
by grabbing bits and pieces it needs from old kerberos and patching the
source. Then I compiled for i386 and x86_64, threw the RPMs in our custom repo,
and viola. The next day all the servers had new shiny Frankenkerberos. It's a
conglomeration of old and new parts, and it's alive! Didn't even have to
subject the servers to static shock.