Simple usage of Kerberos for SSH authentication on FreeBSD
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:
- Interactive login to systems (locally as well as via SSH)
- Mail services (IMAP, SMTP)
- NFSv4
- LDAP
- ā¦
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.
Requirements
- A secure host to be used as KDC. This should really be used only as
Kerberos key distribution center to minimize the attack surface. If LDAP
is used as additional metadata directory service one might at most
run the LDAP server on the same machine if itās seen as equally dangerous.
No other services should run on your KDC if possible.
- Kerberos highly depends on correctly setup DNS. This means that all your
machines should have a fully qualified domain name (FQDN) assigned
as well as the presence of a correctly configured reverse DNS zone that
is mapping IP addresses back to the FQDN. This is heavily used during a
canonicalization process. One could - in theory - disable hostname
canonicalization but itās way better to configure oneās DNS properly. If
oneās using DHCP one can dynamically update oneās DNS zones (forward and
reverse) too. One shouldnāt use stuff like wildcard DNS for that purposes.
Key distribution center setup
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:
- The host record and reverse record for the
KDC
itself.
- An record that assigns an realm name to the domain name. This is
done using an
TXT
record for a hostname _kerberos
(i.e.
an record of the form _kerberos IN TXT "EXAMPLE.COM"
)
- SRV records for all services supplied by the KDC:
_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:
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
:
Adding an server / host
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
.
SSHD configuration
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:
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.
Adding an client
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: