Openstack Keystone VOMS module¶
This module is intended to provide VOMS authentication to an OpenStack Keystone. It is designed to be integrated as an external authentication plugin, so that Keystone will preserve its original features and users will still be able to authenticate using any of the Keystone native mechanisms.
This documentation is based on a Keystone 8 (Liberty) installation.
Attention
If you are upgrading from any priorversion, check the Upgrade nodes before proceeding.
- Only V2 authentication is supported in Liberty so far.
- If you are using the 2014.1 (Icehouse) version, please check the Icehouse Documentation. Note that support in Icehouse is only for V2 authentication.
- If you are using the 2014.2 (Juno) version, please check the Juno Documentation. Note that support in Icehouse is only for V2 authentication.
- If you are using the 2015.1 (Kilo) version, please check the Kilo Documentation. Note that support in Kilo is only for V2 authentication.
User documentation¶
If you do not intend to install it, but rather authenticate against a VOMS service that is VOMS enabled, check the following link.
VOMS authentication client plugin¶
In order to facilitate the usage of the VOMS authentication with an OpenStack installation an authentication plugin for the nova client has been created. Please follow its instructions in order to use it.
Manual Usage¶
In order to get a token, you must post a JSON request in the body containing the following:
{
"auth": {
"voms": "true"
}
}
In order to get a scoped token, use the following JSON document:
{
"auth": {
"voms": "true",
"tenantNane": "TenantForTheVo",
}
}
Deploying a VOMS Authentication in Keystone¶
If you are a resource provider willing to deploy a VOMS-enabled keystone service, check the following documentation.
Attention
If you are upgrading from any priorversion, check the Upgrade nodes before proceeding.
Note
Default configuration files vary by distribution. You might need to add these sections and options rather than modifying existing sections and options. Also, an ellipsis (...) in the configuration snippets indicates potential default configuration options that you should retain.
VOMS Overview¶
The VOMS service can issue x509 proxies based on RFC 3820
(https://www.ietf.org/rfc/rfc3820.txt) by using the -rfc
option in
the comandline. Instead of using plain X.509 certificates this proxy can
be used to authenticate against a properly configured Keystone server.
Keystone VOMS Overview¶
Follow this guide to enable your Keystone to be used with VOMS authentication. No modifications in the DB are needed, since it will be installed as an external plugin. Therefore, your Keystone will be usable with any other authentication mechanism that you had implemented (such as the native Keystone authentication).
This VOMS authentication module assumes that Keystone is working behind an http server as a WSGI application. SSL must be enabled in the http server.
Currently it only works with the V2 API of Keystone, a module compatible with the V3 API a work in progress.
How does it work?¶
SSL info is obtained from the request environment. The authentication module uses the VOMS library to check if the VOMS proxy is valid and if it is allowed in this server. The mapping between a VO, VO group and a keystone tenant is made in a configurable JSON file. For the moment there is no mapping for the Roles and/or Capabilities incoming from the VOMS credentials.
The mapped local tenant must exist in advance for a user to be authenticated.
If the mapped tenant doest not exist, the authentication will fail. The same
applies for the user, with the particularity that the backend is able to
autocreate new incoming users if the autocreate_users
is enabled in the
configuration file and the authentication is sucessful (i.e. the proxy is
accepted and it is valid). This option is disabled by default, but if you want
to let all the users from a VO to get into your infrastructure you should consider
enabling it. Once a user has been granted access, you can manage it as you will
do with any other user in keystone (e.g. disable/enable, grant/revoke roles,
etc.).
In order to get an unscoped token, you must POST to /tokens
, with the
following JSON document document in the request:
{
"auth": {
"voms": "true"
}
}
This request should return you your an unscoped token. Next step is the
discovery of your tenant (that may differ from the VO name). You have to use a
GET request to /tenants
passing the ID of your unscoped token (that you
obtained before) in the X-Auth-Token
header.
For further details, check the Test it! section.
Requirements¶
The Keystone VOMS authentication module requires some additional packages to be installed. Moreover, it requires that you run Keystone as a WSGI application behind an HTTP server (Apache will be used in this documentation, but any webserver could make it). Keystone project has deprecated eventlet, so you should be already running Keystone in such way.
- Keystone Liberty.
- EUgridPMA CA certificates at the latest version.
- fetch-crl package.
- VOMS libraries.
- HTTP server with WSGI enabled.
EUgridPMA CA certificates and fetch-crl¶
You must have EUgridPMA certificates installed
on its standard location (/etc/grid-security/certificates
) and the
fetch-crl
package properly working so as have the CRLs up to date.
Ubuntu 14.04¶
Use these commands to install on Ubuntu:
# wget -q -O - https://dist.eugridpma.info/distribution/igtf/current/GPG-KEY-EUGridPMA-RPM-3 | apt-key add -
# echo "deb http://repository.egi.eu/sw/production/cas/1/current egi-igtf core" \
| tee --append /etc/apt/sources.list.d/egi-cas.list
# apt-get update
# apt-get install ca-policy-egi-core fetch-crl
# fetch-crl
CentOS 7¶
Install CAs and fetch-crl with:
curl -L http://repository.egi.eu/sw/production/cas/1/current/repo-files/EGI-trustanchors.repo | sudo tee /etc/yum.repos.d/EGI-trustanchors.repo
sudo yum install ca-policy-egi-core fetch-crl
VOMS libraries¶
You must install the VOMS libraries. Please install the libvomsapi1
package in Debian/Ubuntu or
voms
package in RedHat/Fedora/ScientificLinux/etc:
# apt-get install libvomsapi1
Note
Since Kilo, the keystone project deprecates Eventlet in favor of a WSGI server. This guide uses the Apache HTTP server with mod_wsgi to serve keystone requests on ports 5000 and 35357. By default, the keystone service still listens on ports 5000 and 35357. Therefore, this guide disables the keystone service.
Disable keystone from starting automatically:
# service keystone stop
# echo "manual" > /etc/init/keystone.override
You need keystone working under Apache WSGI with mod_ssl
enabled. To do so,
install the packages, and enable the relevant modules.
- Ubuntu::
- # apt-get install apache2 libapache2-mod-wsgi # a2enmod ssl
- CentOS::
- # yum install mod_ssl
Then add to your Apache Keystone WSGI configuration the SSL options as shown below.
We assume that you have the CA certificates installed in the default location,
otherwise you should adapt it to your needs, also check that the paths of the wsgi
script are correct for your installation. The location of the configuration file
for the keystone service under Apache depends on your distribution (e.g. in Ubuntu is
/etc/apache2/sites-available/wsgi-keystone.conf
, in CentOS 7 is
/etc/httpd/conf.d/wsgi-keystone.conf
). Note that you need a valid certificate
for the http server (SSLCertificateFile
and SSLCertificateKeyFile
):
Listen 5000
WSGIDaemonProcess keystone user=keystone group=nogroup processes=8 threads=1
<VirtualHost _default_:5000>
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/hostcert.pem
SSLCertificateKeyFile /etc/ssl/private/hostkey.pem
SSLCACertificatePath /etc/grid-security/certificates
SSLCARevocationPath /etc/grid-security/certificates
SSLVerifyClient optional
SSLVerifyDepth 10
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLOptions +StdEnvVars +ExportCertData
WSGIScriptAlias / /var/www/cgi-bin/keystone/main
WSGIProcessGroup keystone
</VirtualHost>
Listen 35357
WSGIDaemonProcess keystoneapi user=keystone group=nogroup processes=8 threads=1
<VirtualHost _default_:35357>
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/hostcert.pem
SSLCertificateKeyFile /etc/ssl/private/hostkey.pem
SSLCACertificatePath /etc/grid-security/certificates
SSLCARevocationPath /etc/grid-security/certificates
SSLVerifyClient optional
SSLVerifyDepth 10
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLOptions +StdEnvVars +ExportCertData
WSGIScriptAlias / /var/www/cgi-bin/keystone/admin
WSGIProcessGroup keystoneapi
</VirtualHost>
As you can see, the SSLVerifyClient
is set to optional
, so that people
without a VOMS proxy can authenticate using their Keystone credentials.
If you do not have Keystone running already as WSGI application, you must
create a WSGI script as the one already included in the Github Keystone repository.
Copy this script to /var/www/cgi-bin/keystone/keystone.py
, create the
following links and restart apache:
# rm -Rf /usr/lib/cgi-bin/keystone
# mkdir -p /var/www/cgi-bin/keystone
# curl http://git.openstack.org/cgit/openstack/keystone/plain/httpd/keystone.py?h=stable/kilo \
| tee /var/www/cgi-bin/keystone/keystone.py
# ln /var/www/cgi-bin/keystone/keystone.py /var/www/cgi-bin/keystone/main
# ln /var/www/cgi-bin/keystone/keystone.py /var/www/cgi-bin/keystone/admin
# chown -R keystone:keystone /var/www/cgi-bin/keystone
Also, do not forget to set the variable OPENSSL_ALLOW_PROXY_CERTS
to
1
in your Apache environment (/etc/apache2/envvars
in Debian/Ubuntu,
/etc/sysconfig/httpd
in CentOS) so that X.509 proxy certificates are accepted
by OpenSSL. This is an important thing, so please double check that you have
really enabled it.
- Ubuntu::
- # echo “export OPENSSL_ALLOW_PROXY_CERTS=1” >> /etc/apache2/envvars
- CentOS::
- # echo “OPENSSL_ALLOW_PROXY_CERTS=1” >> /etc/sysconfig/httpd
With the above configuration, and assuming that the Keystone host is
keystone.example.org
the endpoints will be as follow:
https://keystone.example.org:5000/
will be public and private endpoints, thus the Keystone URL will behttps://keystone.example.org:5000/v2.0
https://keystone.example.org:35357/
will be administration endpoint, thus the Keystone URL will behttps://keystone.example.org:35357/v2.0
DB Backend¶
You should take into account that the default SQL backend used by keystone is SQLite, which does not support multithreading. You should switch to any other backend, such as MySQL.
SQL Token driver¶
Since you are running Keystone as a WSGI service, you have to ensure that you
are using the SQL backend for the token storage, so as to make it possible to
share them between the diferent WSGI processes. Check that the keystone conf
file /etc/keystone/keystone.conf
contains a [token]
section as
follows:
[token]
(...)
driver = keystone.token.backends.sql.Token
Catalog¶
Your have to adjust your keystone catalog so that the identity backend points to to the correct URLS as explained above. With the above configuration, these URLs will be:
- public URL:
https://keystone.example.org:5000/v2.0
- admin URL:
https://keystone.example.org:35357/v2.0
- internal URL:
https://keystone.example.org:5000/v2.0
If you are using the SQL backend for storing your catalog, you should adjust it manually to reflect the new endpoints. Also, the rest of the OpenStack configuration should be adjusted.
PKI Tokens¶
In order for the PKI tokens to work, you have to ensure that the keystone
WSGI processes, that will run as the user keystone
in the example above,
have access to the configuration files. If you get this error:
[error] ERROR:root:Command 'openssl' returned non-zero exit status 3
[error] Traceback (most recent call last):
[error] File "/usr/lib/python2.7/dist-packages/keystone/common/wsgi.py", line 229, in __call__
[error] result = method(context, **params)
[error] File "/usr/lib/python2.7/dist-packages/keystone/token/controllers.py", line 151, in authenticate
[error] CONF.signing.keyfile)
[error] File "/usr/lib/python2.7/dist-packages/keystone/common/cms.py", line 140, in cms_sign_token
[error] output = cms_sign_text(text, signing_cert_file_name, signing_key_file_name)
[error] File "/usr/lib/python2.7/dist-packages/keystone/common/cms.py", line 135, in cms_sign_text
[error] raise subprocess.CalledProcessError(retcode, "openssl")
[error] CalledProcessError: Command 'openssl' returned non-zero exit status 3
This may be that your keystone process cannot access the following file:
/etc/keystone/ssl/private/signing_key.pem
so please ensure that the keystone
user can access that file.
Upgrade notes¶
Upgrading to 2014.2 (Juno)¶
If you are upgrading from any prior version to the 2014.2 (juno) version, the
VOMS filter in the API paste file (/etc/keystone/keystone-paste.ini
) has
changed from:
[filter:voms]
paste.filter_factory = keystone_voms:VomsAuthNMiddleware.factory
to:
[filter:voms]
paste.filter_factory = keystone_voms.core:VomsAuthNMiddleware.factory
VOMS module Installation¶
This module assumes that you are running the Keystone 8 (Liberty) version.
Install the Keystone VOMS module¶
Install from Repositories¶
You can install Keystone VOMS from any of the following repositories. If you plan to install it like this, remove any prior version installed via pip. And check that you are removing the old versions. If you did not install this module using pip, just ignore this step:
# pip uninstall python-keystone-voms keystone-voms
Ubuntu 14.04¶
First of all, install the repository key into the APT list of trusted keys:
# curl http://download.opensuse.org/repositories/home:/aloga:/cloud-integration:/liberty/xUbuntu_14.04/Release.key | apt-key add -
Make sure that you don’t have any other cloud integration repo for an old
release, and add the repository to your sources.list.d
directory:
# echo "deb http://download.opensuse.org/repositories/home:/aloga:/cloud-integration:/liberty/xUbuntu_14.04/ ./" \
| tee /etc/apt/sources.list.d/aloga-cloud-integration-liberty.list
# apt-get update
# apt-get install python-keystone-voms
CentOS 7¶
Add the repository to yum and install:
# curl -L http://download.opensuse.org/repositories/home:aloga:cloud-integration:liberty/CentOS_7/home:aloga:cloud-integration:liberty.repo > /etc/yum.repos.d/home:aloga:cloud-integration:liberty.repo
# yum install python-keystone-voms
Install from pip¶
Before the PyPi package was called python-keystone-voms
. You should remove
if before installing it:
# pip uninstall python-keystone-voms
With a running Keystone you can install the VOMS module with the following command (note the version range):
# pip install 'keystone-voms>=8.0.0,<9.0.0'
Install from source¶
First, uninstall any old python-keystone-voms
installation. This was the
old name of the package and should be removed:
# pip uninstall python-keystone-voms
With a running Keystone, simply install this egg. In the upper-level
directory run python setup.py install
:
# git clone git://github.com/IFCA/keystone-voms.git -b stable/liberty
# cd keystone-voms
# pip install .
Enable the Keystone VOMS module¶
The authentication module is a WSGI middleware that performs the authentication
and passes the authenticated user down to keystone. Add the VOMS filter to your
paste configuration file (/etc/keystone/keystone-paste.ini
is the default one
in Ubuntu, /usr/share/keystone/keystone-dist-paste.ini
in CentOS). First,
add the VOMS filter as follows:
[filter:voms]
paste.filter_factory = keystone_voms.core:VomsAuthNMiddleware.factory
Then add this filter to the public_api
pipeline for the version V2 of your
API. Probably, you should add it before the debug
, ec2_extension
,
user_crud_extension
and public_service
components:
[pipeline:public_api]
(...)
pipeline = sizelimit url_normalize build_auth_context token_auth admin_token_auth xml_body_v2 json_body ec2_extension voms user_crud_extension public_service
Note that you may have a different pipeline. You don’t need to replace your
pipeline with the above, but just add the voms
filter in the correct place.
VOMS module Configuration¶
VOMS configuration options¶
There are several new options in /etc/keystone/keystone.conf
that are used
to configure the VOMS identity behaviour. The default values should be OK for
most installations, except the autocreate_users
option. These optiones are
under the [voms]
section:
[voms]
vomsdir_path = /etc/grid-security/vomsdir
ca_path = /etc/grid-security/certificates
voms_policy = /etc/keystone/voms.json
vomsapi_lib = libvomsapi.so.1
autocreate_users = False
add_roles = False
user_roles = _member_
vomsdir_path
: Path storing the.lsc
files.ca_path
: Path where the CAs and CRLs are stored.voms_policy
: JSON file containing the VO/tenant/role mapping.vomsapi_lib
: Path to the voms library to use.autocreate_users
: Whether a user should be autocreated if it does not exist.add_roles
: Whether roles should be added to users or not.user_roles
: list of role names to add to the users (ifadd_roles
isTrue
).
Allowed VOs¶
For each allowed VO, you need a subdirectory in /etc/grid-security/vomsdir/
that contains the .lsc
files of all truted VOMS servers for the given VO.
The LSC files must be named as the fully qualified host name of the
VOMS server with an .lsc
extension, and they contain:
- First line: subject DN of the VOMS server host certificate.
- Second line: subject DN of the CA that issued the VOMS server host certificate.
So, for example, for the dteam VO the first should be:
$ cat /etc/grid-security/vomsdir/dteam/voms.hellasgrid.gr.lsc
/C=GR/O=HellasGrid/OU=hellasgrid.gr/CN=voms.hellasgrid.gr
/C=GR/O=HellasGrid/OU=Certification Authorities/CN=HellasGrid CA 2006
The dteam VO has two VOMS servers (see link above) so another file for the second server needs to be present as well:
$ cat /etc/grid-security/vomsdir/dteam/voms2.hellasgrid.gr.lsc
/C=GR/O=HellasGrid/OU=hellasgrid.gr/CN=voms2.hellasgrid.gr
/C=GR/O=HellasGrid/OU=Certification Authorities/CN=HellasGrid CA 2006
For more details, please check the following page How to configure VOMS LSC
files.
Note that you do not need to install the .pem
certificate, just the .lsc
file.
VO to local tenant mapping¶
The VO and VO group mapping to the local tenants is made in the JSON
file /etc/keystone/voms.json
. It is based on the VO name and VOMS
proxy fqan:
{
"voname": {
"tenant": "local_tenant"
}
}
For example for the dteam VO, it could be configured as:
{
"dteam": {
"tenant": "dteam"
},
"/dteam/NGI_IBERGRID": {
"tenant": "dteam_ibergrid"
}
}
If there are no matching FQANS but there is a VO name definition, the user will authenticate, therefore, a user making the following request:
{
"auth": {
"voms": "true",
"tenantNane": "/dteam/NGI_IBERGRID",
}
}
against the following configuration:
{
"dteam": {
"tenant": "dteam"
}
}
will be sucessfully authenticated, because no FQAN matched, but the VO did.
Test it!¶
Once you have everything configured you can test it requesting a token using a valid VOMS proxy.
First get a valid VOMS proxy:
$ voms-proxy-init -voms <VOMS> -rfc
Then, get a unscoped token from the keystone server:
$ curl --cert $X509_USER_PROXY -d '{"auth":{"voms": true}}' \
-H "Content-type: application/json" \
https://<keystone_host>:5000/v2.0/tokens
This will give you something like:
{
"access": {
"token": {
"expires": "2011-08-10T17:45:22.838440",
"id": "0eed0ced-4667-4221-a0b2-24c91f242b0b"
}
}
}
Use the token ID that you obtained, to get a list of the tenants that you are allowed to access:
$ curl -H "X-Auth-Token:0eed0ced-4667-4221-a0b2-24c91f242b0b" \
http://<keystone_host>:5000/v2.0/tenants
If this is sucessful, you should get something like:
{
"tenants_links": [],
"tenants": [
{
"description": "Some Tenant",
"enabled": true,
"id": "999f045cb1ff4684a15ebb334af61461",
"name": "TenantName"
}
]
}
Identify the tenant, and request a scoped token:
$ curl --cert $X509_USER_PROXY \
-d '{"auth":{"voms": true, "tenantName": "TenantName"}}' \
-H "Content-type: application/json" \
https://<keystone_host>:5000/v2.0/tokens
Finally, you should obtain your token:
{
"access": {
(...)
},
"serviceCatalog": [
(...)
],
"token": {
"expires": "2013-07-30T12:16:23Z",
"id": "ccb739df861e76a5a9039d21ec040a91",
"issued_at": "2013-07-29T12:16:23.625426",
"tenant": {
"description": "Some Tenant",
"enabled": true,
"id": "999f045cb1ff4684a15ebb334af61461",
"name": "TenantName"
}
},
"user": {
(...)
}
}
}
If everything is OK, you should be able to start using it.
Troubleshooting¶
Apache complains about issuer of certificate¶
You get something like:
Certificate Verification: Error (20): unable to get local issuer certificate
You probably missed to set the OPENSSL_ALLOW_PROXY_CERTS
variable on the
Apache environment
Error 14: Signature error¶
You have to double check that the vomsdir_path
and ca_path
configuration options (that default to /etc/grid-security/vomsdir
and
/etc/grid-security/certificates
respectively) point to the correct path.
Also ensure that the .lsc
files have the right contents and that the CLRs
are up to date.