Authors: Paolo Andreetto (INFN Padova)
Install the EUGridPMA packages
wget -O /etc/yum.repos.d/EGI-trustanchors.repo http://repository.egi.eu/sw/production/cas/1/current/repo-files/EGI-trustanchors.repo yum -y install ca-policy-egi-core fetch-crl
Start the cron service:
systemctl enable fetch-crl-cron && systemctl start fetch-crl-cron
Install the required modules
wget -O /etc/yum.repos.d/shibboleth.repo http://download.opensuse.org/repositories/security://shibboleth/CentOS_7/security:shibboleth.repo yum -y install shibboleth
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
The file /etc/shibboleth/shibboleth2.xml must contain the following definitions:
<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config" xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" clockSkew="180"> <ApplicationDefaults id="default" entityID="https://cloud-areapd.pd.infn.it/dashboard-shib" REMOTE_USER="eppn persistent-id targeted-id"> <Sessions lifetime="28800" timeout="3600" relayState="ss:mem" checkAddress="false" handlerSSL="true" cookieProps="https"> <SSO>SAML2 SAML1</SSO> <Logout>SAML2 Local</Logout> <Handler type="MetadataGenerator" Location="/Metadata" template="/etc/openstack-auth-shib/idem-template-metadata.xml" signing="true"/> <Handler type="Status" Location="/Status" acl="127.0.0.1 ::1"/> <Handler type="Session" Location="/Session" showAttributeValues="false"/> <Handler type="DiscoveryFeed" Location="/DiscoFeed"/> </Sessions> <Errors redirectErrors="https://cloud-areapd.pd.infn.it/dashboard/auth/auth_error/"/> <MetadataProvider type="Chaining"> <MetadataProvider type="XML" uri="https://www.garr.it/idem-metadata/idem-metadata-sha256.xml" backingFilePath="/var/cache/shibboleth/idem-metadata.xml" reloadInterval="7200"/> </MetadataProvider> <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="/usr/share/openstack-auth-shib/attribute-map.xml"/> <AttributeResolver type="Query" subjectMatch="true"/> <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/> <CredentialResolver type="File"> <Key><Path>/etc/shibboleth/sp-key.pem</Path></Key> <Certificate> <Path>/etc/shibboleth/sp-cert.pem</Path> <Path>/etc/grid-security/certificates/INFN-CA-2015.pem</Path> </Certificate> <CRL> <Path>/etc/grid-security/certificates/49f18420.r0</Path> </CRL> </CredentialResolver> </ApplicationDefaults> <SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/> <ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/> </SPConfig>
Install the Apache plugin for OpenID:
yum -y install mod_auth_openidc
Create the configuration file /etc/httpd/conf.d/auth_openidc.conf containing the definitions:
OIDCClaimPrefix "OIDC-" OIDCMetadataDir /var/cache/httpd/mod_auth_openidc/metadata OIDCCryptoPassphrase ******** OIDCRedirectURI https://cloud-areapd.pd.infn.it/dashboard-openidc/redirect-uri
if the module "apache-ssl" 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
In order to avoid security holes it is necessary to activate the UseCanonicalName option for any virtual host or location protected by shibboleth
ServerName https://cloud-areapd.pd.infn.it
UseCanonicalName On
The repository for Ocata can be downloaded with the command:
wget -O /etc/yum.repos.d/openstack-security-integrations.repo http://igi-01.pd.infn.it/mrepo/CAP/openstack-security-integrations_centos7_ocata.repo
The integration for the project Cloud Area Padovana can be installed with the command:
yum -y install openstack-auth-cap keystone-skey-auth
The integration for the project Cloud Veneto can be installed with the following command:
yum -y install openstack-auth-cedc keystone-skey-auth
In the file /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.d/_1000_local_settings.py define the parameter for the database according to the 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.
The notification system must be configured according to 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'),)
In the virtual host section of the dashboard the following definitions must be declared
WSGIScriptAlias /dashboard-infn "/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi" <Location /dashboard-infn> AuthType shibboleth ShibRequestSetting requireSession 1 require shib-session ShibRequestSetting applicationId default ShibRequestSetting entityID https://idp.infn.it/saml2/idp/metadata.php </Location>
In the virtual host section of the Keystone service (main) the following definitions must be declared
<Location ~ "/v3/auth/OS-FEDERATION/identity_providers/infnaai/protocols/mapped/websso"> AuthType shibboleth Require shib-session ShibRequestSetting requireSession 1 ShibRequestSetting applicationId default ShibRequestSetting entityID https://idp.infn.it/saml2/idp/metadata.php ShibRequireSession On ShibExportAssertion Off </Location>
If the testing IdP has to be used in the file /etc/shibboleth/shibboleth2.xml a new metadata provider in the chain must be defined:
<MetadataProvider type="Chaining"> <MetadataProvider type="XML" uri="https://idp.infn.it/testing/saml2/idp/metadata.php" backingFilePath="/var/cache/shibboleth/idp.infn.it-testing-metadata.xml"/> </MetadataProvider>
and the entityID is https://idp.infn.it/testing/saml2/idp/metadata.php
In the virtual host section of the dashboard the following definitions must be declared
WSGIScriptAlias /dashboard-unipd /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi <Location /dashboard-unipd> AuthType shibboleth ShibRequestSetting requireSession 1 ShibRequestSetting applicationId default ShibRequestSetting entityID https://shibidp.cca.unipd.it/idp/shibboleth require shib-session </Location>
In the virtual host section of the Keystone service (main) the following definitions must be declared
<Location ~ "/v3/auth/OS-FEDERATION/identity_providers/unipdaai/protocols/mapped/websso"> AuthType shibboleth Require shib-session ShibRequestSetting requireSession 1 ShibRequestSetting applicationId default ShibRequestSetting entityID https://shibidp.cca.unipd.it/idp/shibboleth ShibRequireSession On ShibExportAssertion Off </Location>
In the virtual host section of the dashboard the following definitions must be declared
WSGIScriptAlias /dashboard-openidc "/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi" <Location /dashboard-openidc> AuthType openid-connect Require claim iss:https://iam-test.indigo-datacloud.eu/ LogLevel debug </Location>
In the virtual host section of the Keystone service (main) the following definitions must be declared
<Location ~ "/v3/auth/OS-FEDERATION/identity_providers/indigoaai/protocols/openid/websso"> AuthType openid-connect Require claim iss:https://iam-test.indigo-datacloud.eu/ LogLevel debug </Location>
In the file /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.d/_1001_indigo_settings.py it is necessary to register the INDIGO IAM
HORIZON_CONFIG['identity_providers']['indigo_sso'] = { 'context' : '/dashboard-openidc', 'path' : '/dashboard-openidc/auth/register/', 'description' : 'INDIGO IAM', 'logo' : '/dashboard/static/dashboard/img/logoINDIGO.png', 'uid_tag' : 'OIDC-preferred_username', 'org_tag' : 'OIDC-organisation_name' }
Download the metadata from INDIGO IAM:
wget -O /var/cache/httpd/mod_auth_openidc/metadata/iam-test.indigo-datacloud.eu.provider https://iam-test.indigo-datacloud.eu/.well-known/openid-configuration
Create the client configuration file for INDIGO IAM /var/cache/httpd/mod_auth_openidc/metadata/iam-test.indigo-datacloud.eu.client with the following definitions:
{ "client_id" : "**********************", "client_secret" : "*******************************************************" }
Create the service configuration file for INDIGO IAM /var/cache/httpd/mod_auth_openidc/metadata/iam-test.indigo-datacloud.eu.conf with the following definitions:
{ "scope" : "openid profile email", "token_endpoint_auth" : "client_secret_basic", "response_type" : "code" }
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"
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 django session guide
Since the configuration file of the dashboard contains sensitive parameters it is necessary to change its permissions:
chown root.apache /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.d/_1000_local_settings.py chmod 640 /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.d/_1000_local_settings.py
It is strongly recommended to verify the configuration of the shibboleth service with the command:
LD_LIBRARY_PATH=/opt/shibboleth/lib64 runuser -s /bin/bash -c 'shibd -t' -- shibd
before starting the service:
systemctl enable shibd && systemctl start shibd
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, }, } For further details about logging see the python documentation |
|
If necessary the service metadata (service description, information URLs, etc.) can be customized editing the file /etc/openstack-auth-shib/idem-template-metadata.xml |
Change the following sections in the file /etc/keystone/keystone.conf:
[federation] trusted_dashboard = https://cloud-areapd.pd.infn.it/dashboard/auth/websso/ [mapped] remote_id_attribute = Shib-Identity-Provider [auth] methods = password,token,mapped,openid
Restart the keystone service :
systemctl restart httpd
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
Tips | |
---|---|
The crontab configuration file is located at /etc/cron.d/openstack-auth-shib-cron | |
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 |