====== AAI integrations in Openstack Mitaka ======
Authors: Paolo Andreetto (INFN Padova)
==== Requirements ====
* CentOS Linux release 7.1
* Openstack from "Kilo" to "Mikata" release
==== Shibboleth installation ====
=== Installing repositories ===
wget -O /etc/yum.repos.d/EGI-trustanchors.repo http://repository.egi.eu/sw/production/cas/1/current/repo-files/EGI-trustanchors.repo
wget -O /etc/yum.repos.d/shibboleth.repo http://download.opensuse.org/repositories/security://shibboleth/CentOS_7/security:shibboleth.repo
=== Installing required modules ===
yum -y install ca-policy-egi-core fetch-crl shibboleth httpd mod_ssl
=== Starting cron service "fetch-crl-cron" ===
systemctl enable fetch-crl-cron && systemctl start fetch-crl-cron
=== Installing certificate - key and setting their permissions ===
Deploy the service certificate file in ///etc/shibboleth/sp-cert.pem// and the related service key file in ///etc/shibboleth/sp-key.pem//.
Change the ownership and permissions for those files:
chmod 400 /etc/shibboleth/sp-key.pem
chmod 600 /etc/shibboleth/sp-cert.pem
chown shibd.shibd /etc/shibboleth/sp-key.pem
chown shibd.shibd /etc/shibboleth/sp-cert.pem
==== Shibboleth service’s configuration ====
=== Downloading the attribute-map file ===
wget -O /etc/shibboleth/attribute-map.xml http://wiki.infn.it/_media/cn/ccr/aai/howto/attribute-map.xml
=== Configuring the shibboleth daemon ===
The file ///etc/shibboleth/shibboleth2.xml// must contain the following definitions:
SAML2 SAML1
SAML2 Local
/etc/shibboleth/sp-key.pem
/etc/shibboleth/sp-cert.pem
/etc/grid-security/certificates/INFN-CA-2015.pem
/etc/grid-security/certificates/49f18420.r0
=== Verifying the configuration procedure ===
Use the command:
LD_LIBRARY_PATH=/opt/shibboleth/lib64 runuser -s /bin/bash -c 'shibd -t' -- shibd
(see note below)
=== Starting the shibboleth daemon ===
systemctl enable shibd && systemctl start shibd
^ Troubleshooting ^ ^
| | if the command above reports the error: CRIT Shibboleth.Application : error building CredentialResolver: Unable to load CRL(s) from file
then it is necessary to run the fetch-crl command manually: cd /etc/grid-security/certificates && fetch-crl -v
|
| | if the command above reports the errors: CRIT XMLTooling.Config : libcurl lacks OpenSSL-specific options,
this will greatly limit functionality
ERROR XMLTooling.libcurl.InputStream : error while fetching
https://www.idem.garr.it/docs/conf/idem-metadata.xml: (59) Unknown cipher in list
ERROR XMLTooling.libcurl.InputStream : on Red Hat 6+, make sure libcurl used is built with OpenSSL
ERROR XMLTooling.ParserPool : fatal error on line 0, column 0, message: internal error in NetAccessor
ERROR OpenSAML.MetadataProvider.XML : error while loading resource
(https://www.idem.garr.it/docs/conf/idem-metadata.xml): XML error(s) during parsing
ERROR OpenSAML.MetadataProvider.XML : metadata instance was invalid at time of acquisition
CRIT OpenSAML.Metadata.Chaining : failure initializing MetadataProvider:
Metadata instance was invalid at time of acquisition.
even if the message is marked as critical, those errors can be ignored. On many RedHat/Fedora installation a different version of libcurl is required, the library is located in ///opt/shibboleth/lib64//. The shibboleth daemon calls the configuration script ///etc/sysconfig/shibd// in order to overwrite the system library. In case it is possible to remove the error running the command LD_LIBRARY_PATH=/opt/shibboleth/lib64 shibd -t
|
==== HTTP service’s configuration ====
=== Configuration of the module "apache-ssl" ===
if the module isn't already configured, define the following attributes:
SSLCertificateFile /etc/grid-security/hostcert.pem
SSLCertificateKeyFile /etc/grid-security/hostkey.pem
in the configuration file for SSL apache plugin. In general the file is ''/etc/httpd/conf.d/ssl.conf''. If the dashboard has been deployed using packstack the file is ''/etc/httpd/conf.d/15-horizon_ssl_vhost.conf''
=== Configuration of the service “shibbolet” for the Openstack-Dashboard ===
In the file ''/etc/httpd/conf.d/shib.conf'' insert the following section:
AuthType shibboleth
ShibRequestSetting requireSession 1
require shib-session
=== Configuration file of the Dashboard ===
Add the following instructions, if not already present, in the file ///etc/httpd/conf.d/openstack-dashboard.conf// (or ///etc/httpd/conf.d/15-horizon_ssl_vhost.conf// if packstack have been used):
WSGIScriptAlias /dashboard-shib /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
In order to avoid [[https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPApacheConfig|security holes]] it is necessary to activate the [[http://httpd.apache.org/docs/2.4/mod/core.html#usecanonicalname|UseCanonicalName]] option for any virtual host or location protected by shibboleth
ServerName https://cloud-areapd.pd.infn.it
UseCanonicalName On
=== Restarting of the service ''httpd'' ===
systemctl restart httpd
==== Installation of the AAI integration ====
=== Download the repository containing the integration packages ===
Repository for Kilo:
wget -O /etc/yum.repos.d/openstack-security-integrations.repo http://igi-01.pd.infn.it/mrepo/CAP/openstack-security-integrations_centos7_kilo.repo
Repository for Mitaka:
wget -O /etc/yum.repos.d/openstack-security-integrations.repo http://igi-01.pd.infn.it/mrepo/CAP/openstack-security-integrations_centos7_mitaka.repo
=== Installation of the keystone plugin ===
yum -y install keystone-skey-auth
=== Installation of the dashboard wrappers ===
For the project Cloud Area Padovana:
yum -y install openstack-auth-cap
For the project Cloud Veneto:
yum -y install openstack-auth-cedc
=== Generating the secret key ===
The secret key is the shared secret between Horizon and Keystone.
It must be deployed by hand on both side and it can be generated with the following command:
python -c "from horizon.utils import secret_key; print secret_key.generate_key(32)"
The generated key must be specified, between double quotes, as the parameter "KEYSTONE_SECRET_KEY" in the file ///etc/openstack-dashboard/local_settings//:
KEYSTONE_SECRET_KEY = "PeYjxbEzJZ4ZLj1AJCBvUar5fSfJOAkq"
=== Setting up the database ===
In the file ///etc/openstack-dashboard/local_settings// define the parameter for the database
according to the [[https://docs.djangoproject.com/en/1.4/ref/databases/|Django requirements]].
This snippet is an example for a mysql based installation:
DATABASES = {
'default': {
'ENGINE' : 'django.db.backends.mysql',
'NAME' : 'horizon_aai',
'USER' : 'horizonaai',
'PASSWORD' : '*********',
'HOST' : 'cloud-areapd.pd.infn.it',
'PORT' : '3306'
}
}
The database must be created manually and all permissions granted before performing any further action:
create database horizon_aai;
grant all on horizon_aai.* to 'horizonaai'@'cloud-areapd.pd.infn.it' identified by '*********';
grant all on horizon_aai.* to 'horizonaai'@'localhost' identified by '*********';
The database can be populated with the command:
runuser -s /bin/bash -c 'python /usr/share/openstack-dashboard/manage.py migrate' -- apache
The creation of an admin user in the database is not required.
=== Setting up the notication system ===
The notification system must be configured according to [[https://docs.djangoproject.com/en/1.4/topics/email/|Django requirements]].
The file to be modified is ///etc/openstack-dashboard/local_settings//.
Several notifications are sent directly to site administrators, their addresses must be defined in variable **MANAGERS**
This snippet is an example of configuration for accessing a protected SMTP server:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = '****.pd.infn.it'
EMAIL_PORT = 587
EMAIL_HOST_USER = '******'
EMAIL_HOST_PASSWORD = '******'
SERVER_EMAIL = 'cloud@lists.pd.infn.it'
MANAGERS = (('Cloud Support', 'cloud-support@lists.pd.infn.it'),)
=== Install notification templates ===
In the file ///etc/openstack-dashboard/local_settings// the following definition must be defined:
NOTIFICATION_TEMPLATE_DIR = '/etc/openstack-auth-shib/notifications'
=== Other changes ===
It is necessary to force the version 3 for keystone API.
In the file ///etc/openstack-dashboard/local_settings// the following definitions must be present
OPENSTACK_API_VERSIONS = {
"identity": 3
}
OPENSTACK_HOST = "cloud-areapd.pd.infn.it"
# Keystone accessible in plaintext
#OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST
# Keystone protected with SSL/TLS
OPENSTACK_KEYSTONE_URL = "https://%s:5000/v3" % OPENSTACK_HOST
OPENSTACK_SSL_CACERT = "/etc/grid-security/certificates/INFN-CA-2006.pem"
In the configuration file ///etc/openstack-dashboard/local_settings// the URL for help must be defined.
For the project Cloud Area Padovana:
HORIZON_CONFIG = {
#other definitions
'help_url': "http://www.pd.infn.it/cloud/Users_Guide/html-desktop/",
}
For the project Cloud Veneto:
HORIZON_CONFIG = {
#other definitions
'help_url': "https://cloud.cedc.csia.unipd.it/User_Guide/index.html",
}
Since the configuration file of the dashboard contains sensitive parameters it is necessary to change its permissions:
chmod 640 /etc/openstack-dashboard/local_settings && chown root.apache /etc/openstack-dashboard/local_settings
=== Restarting of the service "httpd" ===
systemctl restart httpd
^ Troubleshooting ^ ^
| | If the log in the file ///var/log/horizon/horizon.log// reports the error: ''You have offline compression enabled but key "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" is missing from offline manifest. You may need to run "python manage.py compress"'' it is necessary to run the stylesheet compression utility manually:
yum -y install python-lesscpy
cd /usr/share/openstack-dashboard/ && python manage.py compress
systemctl restart httpd
|
^ Tips ^ ^
| | The log for Horizon can be enabled defining a new handler, a new formatter and a new logger in the LOGGING table of the file ///etc/openstack-dashboard/local_settings//:LOGGING = {
'formatters': {
'verbose': {
'format': '%(asctime)s %(process)d %(levelname)s %(name)s '
'%(message)s'
},
},
# other definitions
'handlers': {
# other definitions
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/horizon/horizon.log',
'formatter': 'verbose',
},
}
'loggers': {
# other definitions
'openstack_auth_shib': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': False,
},
}
then the handler //file// can be used in the loggers such as 'horizon': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': False,
}
. For further details about logging see the [[https://docs.python.org/2.7/library/logging.html| python documentation]] |
| | If you're configuring SSL support for connections between Horizon and Keystone don't use the IP address for OPENSTACK_HOST, use the fully qualified name as reported in the host certificate |
| | It's strongly recommanded to use memcached for storing session attributes, instead of signed cookies. Login cannot be correctly performed if too many data are stored in a cookie. The cache definition is specified into the file ///etc/openstack-dashboard/local_settings//:SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
The memcache daemon must be running systemctl status memcached
For further details refer to the [[https://docs.djangoproject.com/en/1.4/topics/http/sessions/|django session guide]] |
| | It is possible to restore manually the standard Openstack logos with the following commands: cp /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/logo-orig.png \
/usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/logo.png
cp /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/logo-splash-orig.png \
/usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/logo-splash.png
cp /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/favicon-orig.ico \
/usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/favicon.ico
|
| | If necessary the service metadata (service description, information URLs, etc.) can be customized editing the file ///etc/openstack-auth-shib/idem-template-metadata.xml// |
==== Configuration of the Keystone service ====
=== Configuration of the authentication plugin "skey" ===
Change the "auth" section in the file ///etc/keystone/keystone.conf// in the following way:
[auth]
methods=sKey,password,token
password=keystone.auth.plugins.password.Password
token=keystone.auth.plugins.token.Token
sKey = keystone_skey_auth.skey.SecretKeyAuth
Create a new section in the file ///etc/keystone/keystone.conf//:
[skey]
secret_key = "PeYjxbEzJZ4ZLj1AJCBvUar5fSfJOAkq"
The secret key defined in the keystone configuration file is the same key specified by the parameter "KEYSTONE_SECRET_KEY" in the file ///etc/openstack-dashboard/local_settings//
Configure fernet tokens support in the service with the following definitions in ///etc/keystone/keystone.conf//:
[token]
provider = keystone.token.providers.fernet.Provider
[fernet_tokens]
key_repository = /etc/keystone/fernet-keys
Create the fernet key repository:
mkdir -p /etc/keystone/fernet-keys && chown keystone.keystone /etc/keystone/fernet-keys && chmod 750 /etc/keystone/fernet-keys
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
=== Restarting the keystone service ===
If the keystone service is running in stand-alone mode:
systemctl restart openstack-keystone
If the keystone service is running as a WSGI application in Apache:
systemctl restart httpd
==== Configuration of the cron scripts ====
Create the configuration file ///etc/openstack-auth-shib/actions.conf// with the following definitions:
USERNAME=admin
TENANTNAME=admin
PASSWD=****
AUTHURL=https://cloud-areapd.pd.infn.it:35357/v3/
CAFILE=/etc/grid-security/certificates/INFN-CA-2015.pem
NOTIFICATION_PLAN=5,10,20
The configuration file must be readable only by root:
chmod 600 /etc/openstack-auth-shib/actions.conf
Create the cron file ///etc/cron.d/openstack-auth-shib-cron// with the following content:
5 0 * * * root python /usr/share/openstack-dashboard/manage.py checkexpiration --config /etc/openstack-auth-shib/actions.conf --logconf /etc/openstack-auth-shib/logging.conf 2>/dev/null
10 0 * * * root python /usr/share/openstack-dashboard/manage.py notifyexpiration --config /etc/openstack-auth-shib/actions.conf --logconf /etc/openstack-auth-shib/logging.conf 2>/dev/null
0 9 * * 1 root python /usr/share/openstack-dashboard/manage.py pendingsubscr --config /etc/openstack-auth-shib/actions.conf --logconf /etc/openstack-auth-shib/logging.conf 2>/dev/null
^ Tips ^ ^
| | Since the script accesses the database, for installations on multiple nodes which share the same backend, it's recommanded to have different crontab configurations for different nodes |
| | The configuration file for the logging system of all the scripts is ///etc/openstack-auth-shib/logging.conf// |
==== The guest project ====
The guest project can be created by the cloud administrator directly with the dashboard.
From the "Projects" page create a new project and set the "Guest Project" flag.
Only one guest project can be created.
==== Setup for INFN-AAI testing ====
In the file ///etc/shibboleth/shibboleth2.xml// a new metadata provider in the chain must be defined:
and the entityID must point to the corresponding URL
SAML2 SAML1
==== Setup for UniPD-IdP (production) ====
In the file ///etc/httpd/conf.d/shib.conf// a new location must be added:
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibRequestSetting applicationId default
ShibRequestSetting target https://cloud-areapd.pd.infn.it/dashboard-unipd/auth/login/
ShibRequestSetting entityID https://shibidp.cca.unipd.it/idp/shibboleth
require shib-session
A new alias must be created in the file ///etc/httpd/conf.d/openstack-dashboard.conf// (or ///etc/httpd/conf.d/15-horizon_ssl_vhost.conf// if packstack have been used):
WSGIScriptAlias /dashboard-unipd /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
In the file ///etc/openstack-dashboard/local_settings// the following parameter must be defined:
HORIZON_CONFIG['identity_providers'] = [
{'id' : 'unipd', 'type' : 'production', 'path' : '/dashboard-unipd/auth/login/', 'description' : 'UniPD IdP', 'logo' : '/dashboard/static/dashboard/img/logoUniPD.png'}
]
Restart the daemons:
systemctl restart shibd
systemctl restart httpd
==== Setup for IDEM (testing) ====
The public key must be downloaded from IDEM site:
wget https://www.idem.garr.it/documenti/doc_download/321-idem-metadata-signer-2019 -O /etc/shibboleth/idem_signer_2019.pem
chmod 444 /etc/shibboleth/idem_signer_2019.pem
In the file ///etc/shibboleth/shibboleth2.xml// the following definitions must be specified:
SAML2 SAML1
In the file ///etc/httpd/conf.d/shib.conf// a new location must be added:
AuthType shibboleth
ShibRequestSetting requireSession 1
require shib-session
A new alias must be created in the file ///etc/httpd/conf.d/openstack-dashboard.conf// (or ///etc/httpd/conf.d/15-horizon_ssl_vhost.conf// if packstack have been used):
WSGIScriptAlias /dashboard-idem /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
In the file ///etc/openstack-dashboard/local_settings// the following parameter must be defined:
HORIZON_CONFIG['identity_providers'] = [
{'id' : 'idem', 'type' : 'experimental', 'path' : '/dashboard-idem/auth/login/', 'description' : 'IDEM federation', 'logo' : '/dashboard/static/dashboard/img/logoIDEM.png'}
]
==== References ====
* INFN AAI Support: aai-support@lists.infn.it
* UniPD SSO Support : supporto.sso@unipd.it