17 Feb 2020 - tsp
Last update 17 Feb 2020
9 mins
This article should provide a short introduction on how to setup Kerberos
based authentication inside on owns network. Kerberos is one of the most
used single sign on solutions used today (it’s also used behind the
surface for Windows Domains) an provides authentication over insecure
networks like the Internet - of course that means it’s also suited for
authentication inside a corporate or home network. Basically it provides
authentication using tickets - users authenticate against the ticket
authentication server (using kinit
or - most of the time - embedded
in one own’s login procedure). This authentication might happen (as in this
tutorial) using passwords but it may also happen using certificates or other
mechanisms. After the user has authenticated itself against the KDC an
ticket granting ticket is issued and stored at the users maching. This
can be listed using klist
. For every service that a user wants to access
the client (transparently) asks the ticket granting service for an ticket
to access the given service - using the ticket granting ticket for one owns
authentication. The ticket granting service then issues an session ticket
which is then used to authenticate against the service itself.
Note that authentication is not done crossing domain (administrative) boundaries. All services that one authenticates have to be situated inside the same domain as the user. Kerberos identifies domains using strings similar to domains known from the DNS system - but keep in mind that they basically live in a different namespace (although they are normally overlapping and some autodiscovery methods to detect the KDC are using that identity).
Kerberos provides single sign on when one has kerberized all key services. Most services used today support this including:
For web applications there are some different methods to kerberize intranet
applications (like SPNEGO). They do work - but there are some formal
problems since they violate the strict rules defined by the HTTP
specification when it comes to the Authorization
header. One should
note that one cannot easily mix Kerberos and other authentication mechanisms
on a webpage.
Single sign on in this context means that the user is only required to authenticate one, the Kerberos service is then providing authentication information to the services in a transparent way.
Most of the time Kerberos authentication is accompanied by an metadata
distribution system like LDAP
to provide properties to name services
like providing Unix user IDs, group memberships, mailadresses, home directories,
locations of mail directories, properties for XACML policy information points,
etc. This will not be handeled in this blog post.
Basically all tools required to setup a KDC are part of the base system.
One can simply enable the kdc
(the key distribution center) as
well as the kerberos administration system which provides a way to
add users, set passwords, etc. (kadmind
) inside one’s /etc/rc.conf
kdc_enable="YES"
kadmind_enable="YES"
Then one should configure one’s /etc/krb5.conf
. Basically this
would not be required but it makes live somewhat easier:
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_kdc = yes
dns_lookup_realm = yes
One should also add some records into the DNS zone:
KDC
itself.TXT
record for a hostname _kerberos
(i.e.
an record of the form _kerberos IN TXT "EXAMPLE.COM"
)_kerberos._udp IN SRV 10 0 88 kerberoskdc
_kerberos._tcp IN SRV 10 0 88 kerberoskdc
_kpasswd._udp IN SRV 10 0 464 kerberoskdc
_kerberos-adm._tcp IN SRV 10 0 749 kerberoskdc
_kerberos-iv._udp IN SRV 10 0 88 kerberoskdc
In this case the hostname of the KDC an administrative server is
assumed to be kerberoskdc
.
Now one should initialize the Kerberos database. This is done using
the kstash
database. The password one supplies is used to encrypt
the database. One should use a rather long (64 or more) characters random
password. There is no need to remember that password besides for having
to enter (or pasting) it two times since it’s stored on the KDC machine to
allow automatic booting an access to the database.
root@kdc# kstash
Master key: **********
Verifying password - Master key: **********
Now one can connect to the local KDC and initialize the database for the given realm:
root@kdc# kadmin -l
kadmin> init EXAMPLE.COM
Realm max ticket life [unlimited]:
After that one can start to add initial users:
kadmin> add testuser
Max ticket life [unlimited]:
Max renewable life [unlimited]:
Attributes []:
Password: ********
Verifying password - Password: ********
Now one can start the services
root@kdc# /etc/rc.d/kdc start
root@kdc# /etc/rc.d/kadmind start
and test the service by requesting a ticket:
kdc$ kinit testuser
If that was successful one can list all tickets present in ones credential cache:
kdc$ klist
Credentials cache: FILE:/tmp/krb5cc_1001
Principal: testuser@EXAMPLE.COM
Issued Expires Principal
Feb 17 01:45:33 2020 Feb 17 11:45:33 2020 krbtgt/EXAMPLE.COM@EXAMPLE.COM
To remove all tickets from the local cache on uses kdestroy
:
kdc$ kdestroy
One should add a /etc/krb5.conf
to provide an default realm and enable
DNS lookup for realm and KDC:
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_kdc = yes
dns_lookup_realm = yes
After that one should create an host principal and export the given key into the hosts keytab. One can do this from the root user:
root@newhost# kinit [User that has permissions]
root@newhost # kadmin
kadmin> add --random-key host/hostname.example.com
kadmin> ext_keytab host/hostname.example.com
kadmin> exit
root@newhost # kdestroy
Of course one can also do any step except the ext_keytab
command on
any other host on the network that one’s trusting. Note that the
supplied hostname.example.com
hostname should be the canonicalized
hostname. This is the hostname that one get’s when one first resolves the
hostname that one’s connecting to using DNS and then re-resolving the
IP address using the reverse DNS zone. This has the effect of giving an host
that’s aliased using multiple CNAME
records an unique name.
If one - for example - has the following records in DNS:
$ORIGIN example.com.
hostA IN A 10.0.0.1
aliasA IN CNAME hostA
aliasB IN CNAME hostB
and the reverse DNS zone entry
$ORIGIN in-addr.arpa.
1.0.0.10 IN PTR hostA.example.com.
one might access the same host using either hostA.example.com
or
one of aliasA.example.com
and aliasB.example.com
. When one accesses
the host using aliasA.example.com
the DNS system resolves that name
to 10.0.0.1
. The reverse DNS lookup yields the PTR
record
to hostA.example.com
. This is what’s used to build the host principal
name host/hostA.example.com@EXAMPLE.COM
.
Now one can configure sshd
to allow authentication using Kerberos.
This is done inside /etc/ssh/sshd_config
. To allow login using Kerberos
using the internal authentication mechanism of sshd
(not using PAM)
one can enable GSSAPI authentication:
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
If one really trusts one’s kerberos setup one might permit root
login
using Kerberos and/or disable usage of PAM and password authentication. The latter
one should always be done when one allows root login using ssh:
UsePAM no
PasswordAuthentication no
and to allow root login:
PermitRootLogin yes
One might restrict login using ssh further using
AllowGroups GROUP1 GROUP2 GROUP3
For example to permit login for wheel
users and mqadmin
users
one would set
AllowGroups wheel mqadmin
After that one has to add a list of users allowed to login into a given
user account to the ${HOME}/.k5login
file. To allow the users with
the names sample@EXAMPLE.COM
and sample2@EXAMPLE.COM
to login
for root one would write the following file into /root/.k5login
:
sample@EXAMPLE.COM
sample2@EXAMPLE.COM
Any user listed inside the .k5login
inside a users home directory might
login using the UID of the user to whom the home directory belongs.
Basically a client wouldn’t need any configuration. One might enable
GSSAPI authentication for ssh
when connecting to a specific set
of hosts or to hosts under a given domain. One shouldn’t enable that
as a wildcard. To do so one might edit /etc/ssh/ssh_config
and
add an per host configuration:
Host host1.example.com
GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes
One might also do this (when one really trusts all hosts to not steal forwardable tickets) under a given domain:
Host *.example.com
GSSAPIAuthentication yes
GSSAPIDelegateCredentials yes
This configuration also automatically forwards one own’s tickets to the
given host (this is what the GSSAPIDelegateCredentials
option does)
and tries authentication (using the GSSAPIAuthentication
option).
This article is tagged:
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/