Kerberos authentication for Keystone (OpenStack)

By Gauvain Pocentek, Cloud Consultant @Objectif Libre

This blogpost describes how you can improve OpenStack Keystone authentication security, thanks to Kerberos/

Intended audience: OpenStack administrators, already familiar with Keystone deployment and concepts.

Keystone is the OpenStack component responsible for user authentication on a cloud platform. Default and standard authentication requires sending login and password to Keystone, using an API call. User passwords are often stored in plain text in unencrypted authentication files. Which is not secure. Even if the password is prompted when sourcing an RC file (such as the one you can download from the Horizon GUI), it still resides in the shell environment.

Keystone can rely on external systems to validate user credentials. Once the user has been authenticated, Keystone generates a token as usual, and this token is used to communicate with all the OpenStack APIs.

Let’s see now how you can configure Keystone to allow users to authenticate with their Kerberos ticket instead of the usual login/password.

Pre-requisites

This blog assumes that you have a working Keystone installation, and a working LDAP-backed Kerberos server (this could be a manually installed server, a freeIPA server, an Active Directory server, or whatever tool provides both LDAP and Kerberos services). Installing and understanding these services is out of scope for this article.

We use the following information in the examples:

Kerberos realm: OL.CORP

Keystone domain name: olcorp

Kerberos admin and kdc servers: kerberos.ol.corp

Keystone base URL: https://ks-krb.ol.corp:5000

Test user login: user1

Let’s configure

The following steps are needed to make the Kerberos authentication work:

Add a kerberos principal and generate a keytab file for the httpd server exposing Keystone: the kerberos authentication is actually done by the web server, not Keystone itself

Configure httpd to support the kerberos authentication on a specific URL, to support both password and kerberos-based authentication

Enable LDAP domain support in Keystone

Configure Keystone’s [auth] section for kerberos

Kerberos setup

The httpd server running the Keystone WSGI script needs to be kerberized. This means creating a principal for the service, and an associated keytab file. How you do that depends on the Kerberos service you use.

The following example works with an MIT Kerberos server:

# kadmin.local kadmin.local: addprinc -randkey HTTP/ks-krb.ol.corp kadmin.local: ktadd -k /tmp/http.keytab HTTP/ks-krb.ol.corp

Upload the /tmp/http.keytab file to the Keystone server (in /etc/apache2 or /etc/httpd for example). It will be used later, in the httpd configuration file.

Enable LDAP authentication on Keystone

In this example we use a dedicated domain for LDAP authentication, for multiple reasons:

The default domain hosting the system users can stay unmodified

We can still use basic username/password authentication for the cloud admin

No need to add system users to the LDAP directory

It’s easy to add new domains, each connected to its own directory

To enable the multi-domain configuration, modify the following settings in keystone.conf :

[identity] domain_specific_drivers_enabled = True domain_config_dir = /etc/keystone/domains

The /etc/keystone/domains/ folder will contain the definition of authentication back-ends for the domains.

The olcorp domain settings are definied in /etc/keystone/domains/keystone.olcorp.conf . Make sure to respect the keystone.DOMAIN_NAME.conf format for the file name otherwise Keystone will not find the settings:

[identity] driver = ldap [ldap] url = ldaps://ldap.ol.corp suffix = dc=ol,dc=corp user = cn=keystone,ou=apps,dc=ol,dc=corp password = s3cr3t ...

You can refer to the Keystone documentation for a complete description of this configuration file.

Restart Keystone and make sure everything works:

$ sudo systemctl restart apache2 $ . adminrc $ openstack domain create olcorp $ PROJECT_ID = $( openstack project create --domain olcorp test -f value -c id ) $ USER_ID = $( openstack user show user1 -f value -c id ) $ openstack role add --user $USER_ID --project $PROJECT_ID _member_

You should be able to login as an LDAP user on Keystone (and horizon) in the olcorp domain.

Enable Kerberos authentication on httpd

The httpd / mod_wsgi setup for Keystone will be modified to expose 2 base URLs:

On / : standard login/password authentication

: standard login/password authentication On /krb/ : kerberos authentication

Only the /krb/v3/auth/tokens location needs to be kerberized, as this is the only authentication endpoint for Keystone.

Update the WSGI configuration file (for example /etc/apache2/sites-enabled/wsgi-keystone.conf ):

<VirtualHost *:5000> ... WSGIScriptAlias /krb /usr/bin/keystone-wsgi-public WSGIScriptAlias / /usr/bin/keystone-wsgi-public ... <Location "/krb/v3/auth/tokens"> LogLevel debug AuthType Kerberos AuthName "Kerberos Login" KrbMethodNegotiate On KrbMethodK5Passwd Off KrbServiceName HTTP KrbAuthRealms OL.CORP Krb5KeyTab /path/to/http.keytab KrbVerifyKDC Off KrbLocalUserMapping On KrbAuthoritative On Require valid-user SetEnv REMOTE_DOMAIN olcorp </Location> </VirtualHost>

When httpd validates a user’s credentials, a REMOTE_USER environment variable containing the user login is sent to Keystone. The additional REMOTE_DOMAIN variable is set to help Keystone find the user information in the correct domain.

Make sure that Keystone supports this behaviour by adding the kerberos auth method in keystone.conf :

[auth] methods = external,password,token,oauth1,kerberos

Restart httpd to apply all the changes:

$ sudo systemctl restart apache2

Test the authentication

You should still be able to authenticate using your login and password:

$ source keystonerc $ openstack token issue

But you can also use a kerberos authentication (note the OS_AUTH_URL variable):

$ kinit Password for user1@OL.CORP: $ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: user1@OL.CORP $ export OS_AUTH_URL = https://ks-krb.ol.corp:5000/krb/v3 $ export OS_AUTH_TYPE = v3kerberos $ export OS_PROJECT_DOMAIN_ID = 17957a91111c44378b08c1f0c58b9e60 $ export OS_PROJECT_NAME = test $ export OS_IDENTITY_API_VERSION = 3 $ openstack token issue -f value -c id gAAAAABahuuzhdSxSL2vgD99umDKU3Kd_6HQuoahfGm...

Conclusion

Kerberos authentication is common and secure, and setting up Keystone to use it is quite straightforward.

If you are already using Kerberos, you should consider it for you OpenStack users authentication as well.