# Step-by-Step: Kerberized Keystone

Authentication plugins in Keystoneclient have gotten to the point where they are sufficiently well deployed that we can start to do interesting additional forms of authentication. As Kerberos is a commonly requested authentication mechanism here is a simple, single domain keystone setup using Kerberos authentication. They are not necessarily how you would setup a production deployment, but should give you the information you need to configure that yourself.

They create:

• A FreeIPA server machine called ipa.test.jamielennox.net
• A Packstack all in one deployment of OpenStack called openstack.test.jamielennox.net

Notes:

• I use the realm TEST.JAMIELENNOX.NET. There is no meaning to this domain, it doesn’t exist or make any difference to the deployment.
• I am using a single domain deployment, so regular users and service users are intermingled. There is no great benefit to this because the Kerberos plugin only supports the Keystone v3 API (so you have to be domain aware), however it a couple of steps. Generally when doing a deployment like this I would put the IPA users in there own domain.

Disclaimer:

• The goal of Kerberos authentication is obviously to enable both the command line and horizon interfaces to use your existing Kerberos ticket. At the time of writing the openstackclient is really the only client capable of using plugins. I am also working on the patches required to enable horizon for SSO. There are obviously no promises that will be ready and accepted for the Kilo release, but I’m hoping so.

## Part 1 - Install FreeIPA

From a brand new centos 7 image:

Now install the FreeIPA server.

I’ve ignored the details here, generally having correctly set the hostname the defaults are correct for me, the only thing I generally do is opt to configuring bind for DNS. This is the reason for installing bind-dyndb-ldap and you can skip it if you don’t install bind, however you will need to edit your /etc/hosts file for the IPA server for the other machines as IPA relies on hostnames.

Pay particular attention to the username you give to the admin user as this user will be used from keystone later. If you are unfamiliar with FreeIPA I suggest you test out the web interface, this is where your users will be registered. As FreeIPA expects to be on a routable address you will need to add the hostname to /etc/hosts of the client machine to use the web service.

## Part 2 - Register as a FreeIPA Client

The first thing I like to do is register the machine as a FreeIPA client machine. After registering the machine comes available for us to fetch Kerberos tickets from (and SSL certs, etc).

Again, having correctly set a hostname and DNS server the default options are correct for me. You’ll need to provide the admin user and password from setting up the FreeIPA server.

## Part 3 - Install Packstack

Packstack is a series of wrappers around the upstream puppet scripts that integrates well with RHEL/Centos, it will deploy the latest packaged version which is currently Juno. You could use devstack or any alternative deployment here.

The --allinone option configures the entire OpenStack deployment on this machine, see the docs for more detailed deployments methods.

## Part 4 - Convert Keystone to Apache

To use kerberos authentication the keystone server uses the mod_auth_kerb Apache module. We therefore need to run the keystone server within Apache rather than from the script. Ideally here we would have generated an answer file and told Packstack to use the httpd deployment method (which it can do) however this never seems to work for me, so I’ll do it manually. YMMV.

Stop the existing keystone server and prevent it starting on boot:

There are many ways you could setup keystone within Apache. I don’t think the official docs explain this very well but you can deploy it as you would any other mod_wsgi python site.

This is the httpd config file I used initially:

If you restart Apache with this configuration you should see keystone start up and run with no apparent difference.

There has been a push recently to stop using ports 5000 and 35357 when using apache and run them off the /main and /admin paths. This will work just fine, however I’m trying to do this with as little overall change to the initial deployment, you may obviously set your deployment up to your own needs.

## Part 5 - Convert Keystone to LDAP:

First we create a keystone user. This isn’t required in a typical deployment, however we need to provide a user with which to connect to the ldap server.

--random sets a random password, you can omit it and set your own if you like.

Edit the /etc/keystone/keystone.conf file to use LDAP for the identity backend, and SQL for assignments. This is the preferred deployment so whilst the users are in LDAP, projects and the permissions a user has on a project are managed in SQL.

Still in /etc/keystone/keystone.conf we set the parameters for how to talk to the LDAP server that FreeIPA set up. The password used here is the random one generated above. You will need to replace the pattern dc=test,dc=jamielennox,dc=net with the similarly formatted realm that FreeIPA is configured for in your deployment. This is the complete (comments removed) [ldap] section of the keystone.conf file. This plus the [identity] block above are also exactly what would go into a domain specific backend configuration if you are deploying that way.

Make sure to restart keystone (via apache) to set this configuration.

## Part 6 - Recreate the LDAP users:

This is particularly hacky. For my single domain deployment when I switch Keystone over to using the LDAP source it will loose access to the users that were set up via Packstack so I will need to recreate these users. If you are using multiple domains you can skip this, leave the service users in the default domain and use your FreeIPA users via an alternative domain.

The easiest way I’ve found to do this is to remove the [general] tag at the top of the Packstack answers file that was created and then source it as bash environment variables. This answers file is generally found in /root/ and will be appended with a timestamp.

Then install the admin tools to allow you to add users via command line and kinit as the admin user to have permission to add users.

Then recreate those users, I’ll omit the shell prompt here so that it’s easier to copy and paste, but you could script this fairly easily. We are creating a FreeIPA user for each of the services, setting a password for the user, and then assigning the user a role on the services project.

I’m using the admin token to assign the roles as there are no longer any valid users that I can use to assign these roles.

NOTE: This is a fairly unsafe way of creating these users in IPA as they are given full home and login permissions to any IPA machines. In a real deployment these should be system users and ensure they aren’t able to login.

I add the keystone user to the services project as well - though in this case it won’t really matter.

Create the demo user and add the default roles to admin and demo so the keystonerc_admin and keystonerc_demo files still work as expected.

## Part 7 - Kerberos:

Now we look to add Kerberos authentication. First we have to register the service that you want to use on the IPA server. For the current Kerberos plugin this must be the HTTP service or the plugin won’t catch it. Then we fetch the keytab and put it somewhere apache can access it.

Install the mod_auth_kerb apache module which handles Kerberos Authentication, and enable it. (Generally you don’t have to enable module, this looks like a pattern that packstack has established)

Add the following snippet to both the vhosts we created earlier, adjusting /main to /admin for the admin port. The WSGIScriptAlias / "/var/www/keystone/main" is already present from the initial setup, this just shows that you need to insert the /krb reference above it to make it take precedence.

This is creating a new route to the Keystone server code through which every access is Kerberos protected. We will use this address later as our authentication URL.

The SetEnv directive there is not required as we are deploying into the Default domain, however if you are deploying into a different domain you should set REMOTE_DOMAIN to the name of the user’s domain.

Restart Apache.

## Part 8 - Client:

Obviously you don’t have to run the client on the same machine as the server. You can start up another machine here and do an ipa-client-install to initialize it for testing if you like, or put it on your own desktop (you can add your kerberos server to /etc/krb5.conf to not register it as a FreeIPA client).

Install the openstack command line tool

We also want to install the Kerberos client plugin from source. This plugin is imminently due for its first release on PyPI however it will take a while to get to packages.

Now kinit as the demo user to get a Kerberos ticket to test with.

Finally, for the dramatic finale, let’s get a token. I’m putting the authentication parameters on the command line however they all exist as environment variables to create your own keystonerc file.

Notice the main authentication differences (and I’ll use the CLI equivalent for demonstration):

• --os-auth-url http://openstack.test.jamielennox.net:5000/krb/v3 we need to specify the v3 auth-url and include the /krb path so that the authentication request goes to the Kerberos route. Also because of the way your Kerberos ticket will be validated you have to use the full hostname as the url, even if you are calling from that box.
• --os-auth-type v3kerberos which tells the CLI to use the kerberos plugin appropriate for the v3 API.
• --os-project-domain-id because we are in the V3 API now so you need to specify the domain-id if you use --os-project-name

# Finish

Getting to the point where we can support the openstack command line tool has taken a lot of foundational work, and due to the independence of the clients it may be some time before the existing CLIs come to accept an authentication plugin parameter. However now the foundation is in place I hope to see Kerberos becoming a more widely deployed authentication mechanism for OpenStack.

# Thanks

Special thanks have to go to:

• Jose Castro Leon and Marek Dennis from CERN who did the initial Kerberos implementation and have been pushing the approach.
• Nathan Kinder who scripted a setup that is more advanced and production worthy that I cheated off for a number of settings.
• Adam Young who started this whole Kerberos quest and who has stepped me through most of the above at least once.

full history here