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 # or httpd $ . adminrc # login as cloud admin $ 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 - 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 # or httpd
Test the authentication
You should still be able to authenticate using your login and password:
$ source keystonerc # downloaded from horizon for example $ 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.