From 167d75572436d1bc17bd574ea5cb6be21b6dad10 Mon Sep 17 00:00:00 2001 From: Egon Rijpkema Date: Fri, 10 Aug 2018 16:15:48 +0200 Subject: [PATCH] Imported all shibboleth stuff from openstack-test05 --- keystone/.gitignore | 8 - keystone/Dockerfile | 22 ++- keystone/apache-keystone.conf | 126 ++++++++++++++ keystone/attribute-map.xml | 30 ++++ keystone/attribute-policy.xml | 71 ++++++++ keystone/keystone.conf | 11 ++ keystone/routers.py | 252 ++++++++++++++++++++++++++++ keystone/rules.json | 20 +++ keystone/run.sh | 20 +++ keystone/shibboleth2.xml | 114 +++++++++++++ keystone/sso_callback_template.html | 22 +++ keystone/test.php | 4 + 12 files changed, 691 insertions(+), 9 deletions(-) delete mode 100644 keystone/.gitignore create mode 100644 keystone/apache-keystone.conf create mode 100644 keystone/attribute-map.xml create mode 100644 keystone/attribute-policy.xml create mode 100644 keystone/routers.py create mode 100644 keystone/rules.json create mode 100755 keystone/run.sh create mode 100644 keystone/shibboleth2.xml create mode 100644 keystone/sso_callback_template.html create mode 100644 keystone/test.php diff --git a/keystone/.gitignore b/keystone/.gitignore deleted file mode 100644 index f432e90..0000000 --- a/keystone/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# ---> Vim -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -*.un~ -Session.vim -.netrwhist -*~ - diff --git a/keystone/Dockerfile b/keystone/Dockerfile index d757a54..1634dee 100644 --- a/keystone/Dockerfile +++ b/keystone/Dockerfile @@ -13,16 +13,36 @@ RUN set -x \ && apt-get -y update \ && apt-get -y install \ && apt-get -y install keystone python-openstackclient \ + && apt-get -y install libapache2-mod-shib2 \ && apt-get -y clean # set admin token TODO: make this a secret # in volume of met env COPY keystone.conf /etc/keystone/keystone.conf +COPY apache-keystone.conf /etc/apache2/sites-available/keystone.conf + +COPY shibboleth2.xml /etc/shibboleth/shibboleth2.xml +COPY attribute-map.xml /etc/shibboleth/attribute-map.xml +COPY attribute-policy.xml /etc/shibboleth/attribute-policy.xml + +COPY sso_callback_template.html /etc/keystone/sso_callback_template.html + +RUN mkdir /var/run/shibboleth + +COPY run.sh /etc/run.sh + RUN mkdir /etc/keystone/fernet-keys RUN chown keystone: /etc/keystone/fernet-keys +RUN a2enmod shib2 + COPY bootstrap.sh /etc/bootstrap.sh -CMD apachectl -DFOREGROUND +# Testing only!!! +RUN mkdir -p /var/www/html/secure +RUN apt-get -y install php libapache2-mod-php +COPY test.php /var/www/html/secure/test.php + +CMD /etc/run.sh diff --git a/keystone/apache-keystone.conf b/keystone/apache-keystone.conf new file mode 100644 index 0000000..99e0111 --- /dev/null +++ b/keystone/apache-keystone.conf @@ -0,0 +1,126 @@ +LoadModule ssl_module modules/mod_ssl.so + +Listen 5000 +Listen 35357 + + + AuthType shibboleth + ShibRequestSetting requireSession 1 + require valid-user + + +Alias "/secure" "/var/www/html/secure" + + + ServerName https://merlin.hpc.rug.nl:5000 + SSLEngine on + SSLCertificateFile "/certs/merlin.hpc.rug.nl.crt" + SSLCertificateKeyFile "/certs/merlin.hpc.rug.nl.key" + UseCanonicalName On + WSGIScriptAlias / /usr/bin/keystone-wsgi-public + WSGIDaemonProcess keystone-public processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP} + WSGIProcessGroup keystone-public + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + LimitRequestBody 114688 + + # Added for federation. + WSGIScriptAliasMatch ^(/v3/OS-FEDERATION/identity_providers/.*?/protocols/.*?/auth)$ /usr/local/bin/keystone-wsgi-public/$1 + + = 2.4> + ErrorLogFormat "%{cu}t %M" + + + ErrorLog /var/log/apache2/keystone.log + CustomLog /var/log/apache2/keystone_access.log combined + + + = 2.4> + Require all granted + + + Order allow,deny + Allow from all + + + + + SetHandler shib + + + + ShibRequestSetting requireSession 1 + AuthType shibboleth + ShibExportAssertion Off + Require valid-user + + + ShibRequireSession On + ShibRequireAll On + + + + + AuthType shibboleth + Require valid-user + ShibRequestSetting requireSession 1 + ShibRequireSession On + ShibExportAssertion Off + + + AuthType shibboleth + Require valid-user + + + + + + ServerName https://merlin.hpc.rug.nl:35357 + SSLEngine on + SSLCertificateFile "/certs/merlin.hpc.rug.nl.crt" + SSLCertificateKeyFile "/certs/merlin.hpc.rug.nl.key" + UseCanonicalName On + WSGIScriptAlias / /usr/bin/keystone-wsgi-admin + WSGIDaemonProcess keystone-admin processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP} + WSGIProcessGroup keystone-admin + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + LimitRequestBody 114688 + + = 2.4> + ErrorLogFormat "%{cu}t %M" + + + ErrorLog /var/log/apache2/keystone.log + CustomLog /var/log/apache2/keystone_access.log combined + + + = 2.4> + Require all granted + + + Order allow,deny + Allow from all + + + + +Alias /identity /usr/bin/keystone-wsgi-public + + SetHandler wsgi-script + Options +ExecCGI + + WSGIProcessGroup keystone-public + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + + +Alias /identity_admin /usr/bin/keystone-wsgi-admin + + SetHandler wsgi-script + Options +ExecCGI + + WSGIProcessGroup keystone-admin + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + diff --git a/keystone/attribute-map.xml b/keystone/attribute-map.xml new file mode 100644 index 0000000..c641cca --- /dev/null +++ b/keystone/attribute-map.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/keystone/attribute-policy.xml b/keystone/attribute-policy.xml new file mode 100644 index 0000000..055567d --- /dev/null +++ b/keystone/attribute-policy.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/keystone/keystone.conf b/keystone/keystone.conf index ae08a24..2e85c6a 100644 --- a/keystone/keystone.conf +++ b/keystone/keystone.conf @@ -1,6 +1,7 @@ [DEFAULT] verbose = true +log_file = /var/log/keystone/keystone.log [database] connection = mysql+pymysql://keystone:keystone@mariadb/keystone @@ -8,5 +9,15 @@ connection = mysql+pymysql://keystone:keystone@mariadb/keystone [token] provider = fernet +[auth] +methods = password,token,mapped,openid,saml2 + +[federation] +trusted_dashboard = http://merlin.hpc.rug.nl/horizon/auth/websso/ +sso_calback_template = /etc/keystone/sso_calback_template.html + +[mapped] +remote_id_attribute = Shib-Identity-Provider + [identity] default_domain_id = default diff --git a/keystone/routers.py b/keystone/routers.py new file mode 100644 index 0000000..419dd4e --- /dev/null +++ b/keystone/routers.py @@ -0,0 +1,252 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import functools + +from keystone.common import json_home +from keystone.common import wsgi +from keystone.federation import controllers + + +build_resource_relation = functools.partial( + json_home.build_v3_extension_resource_relation, + extension_name='OS-FEDERATION', extension_version='1.0') + +build_parameter_relation = functools.partial( + json_home.build_v3_extension_parameter_relation, + extension_name='OS-FEDERATION', extension_version='1.0') + +IDP_ID_PARAMETER_RELATION = build_parameter_relation(parameter_name='idp_id') +PROTOCOL_ID_PARAMETER_RELATION = build_parameter_relation( + parameter_name='protocol_id') +SP_ID_PARAMETER_RELATION = build_parameter_relation(parameter_name='sp_id') + + +class Routers(wsgi.RoutersBase): + """API Endpoints for the Federation extension. + + The API looks like:: + + PUT /OS-FEDERATION/identity_providers/{idp_id} + GET /OS-FEDERATION/identity_providers + GET /OS-FEDERATION/identity_providers/{idp_id} + DELETE /OS-FEDERATION/identity_providers/{idp_id} + PATCH /OS-FEDERATION/identity_providers/{idp_id} + + PUT /OS-FEDERATION/identity_providers/ + {idp_id}/protocols/{protocol_id} + GET /OS-FEDERATION/identity_providers/ + {idp_id}/protocols + GET /OS-FEDERATION/identity_providers/ + {idp_id}/protocols/{protocol_id} + PATCH /OS-FEDERATION/identity_providers/ + {idp_id}/protocols/{protocol_id} + DELETE /OS-FEDERATION/identity_providers/ + {idp_id}/protocols/{protocol_id} + + PUT /OS-FEDERATION/mappings + GET /OS-FEDERATION/mappings + PATCH /OS-FEDERATION/mappings/{mapping_id} + GET /OS-FEDERATION/mappings/{mapping_id} + DELETE /OS-FEDERATION/mappings/{mapping_id} + + GET /OS-FEDERATION/projects + GET /OS-FEDERATION/domains + + PUT /OS-FEDERATION/service_providers/{sp_id} + GET /OS-FEDERATION/service_providers + GET /OS-FEDERATION/service_providers/{sp_id} + DELETE /OS-FEDERATION/service_providers/{sp_id} + PATCH /OS-FEDERATION/service_providers/{sp_id} + + GET /OS-FEDERATION/identity_providers/{idp_id}/ + protocols/{protocol_id}/auth + POST /OS-FEDERATION/identity_providers/{idp_id}/ + protocols/{protocol_id}/auth + GET /auth/OS-FEDERATION/identity_providers/ + {idp_id}/protocols/{protocol_id}/websso + ?origin=https%3A//horizon.example.com + POST /auth/OS-FEDERATION/identity_providers/ + {idp_id}/protocols/{protocol_id}/websso + ?origin=https%3A//horizon.example.com + + + POST /auth/OS-FEDERATION/saml2 + POST /auth/OS-FEDERATION/saml2/ecp + GET /OS-FEDERATION/saml2/metadata + + GET /auth/OS-FEDERATION/websso/{protocol_id} + ?origin=https%3A//horizon.example.com + + POST /auth/OS-FEDERATION/websso/{protocol_id} + ?origin=https%3A//horizon.example.com + + """ + + def _construct_url(self, suffix): + return "/OS-FEDERATION/%s" % suffix + + def append_v3_routers(self, mapper, routers): + auth_controller = controllers.Auth() + idp_controller = controllers.IdentityProvider() + protocol_controller = controllers.FederationProtocol() + mapping_controller = controllers.MappingController() + project_controller = controllers.ProjectAssignmentV3() + domain_controller = controllers.DomainV3() + saml_metadata_controller = controllers.SAMLMetadataV3() + sp_controller = controllers.ServiceProvider() + + # Identity Provider CRUD operations + + self._add_resource( + mapper, idp_controller, + path=self._construct_url('identity_providers/{idp_id}'), + get_action='get_identity_provider', + put_action='create_identity_provider', + patch_action='update_identity_provider', + delete_action='delete_identity_provider', + rel=build_resource_relation(resource_name='identity_provider'), + path_vars={ + 'idp_id': IDP_ID_PARAMETER_RELATION, + }) + self._add_resource( + mapper, idp_controller, + path=self._construct_url('identity_providers'), + get_action='list_identity_providers', + rel=build_resource_relation(resource_name='identity_providers')) + + # Protocol CRUD operations + + self._add_resource( + mapper, protocol_controller, + path=self._construct_url('identity_providers/{idp_id}/protocols/' + '{protocol_id}'), + get_action='get_protocol', + put_action='create_protocol', + patch_action='update_protocol', + delete_action='delete_protocol', + rel=build_resource_relation( + resource_name='identity_provider_protocol'), + path_vars={ + 'idp_id': IDP_ID_PARAMETER_RELATION, + 'protocol_id': PROTOCOL_ID_PARAMETER_RELATION, + }) + self._add_resource( + mapper, protocol_controller, + path=self._construct_url('identity_providers/{idp_id}/protocols'), + get_action='list_protocols', + rel=build_resource_relation( + resource_name='identity_provider_protocols'), + path_vars={ + 'idp_id': IDP_ID_PARAMETER_RELATION, + }) + + # Mapping CRUD operations + + self._add_resource( + mapper, mapping_controller, + path=self._construct_url('mappings/{mapping_id}'), + get_action='get_mapping', + put_action='create_mapping', + patch_action='update_mapping', + delete_action='delete_mapping', + rel=build_resource_relation(resource_name='mapping'), + path_vars={ + 'mapping_id': build_parameter_relation( + parameter_name='mapping_id'), + }) + self._add_resource( + mapper, mapping_controller, + path=self._construct_url('mappings'), + get_action='list_mappings', + rel=build_resource_relation(resource_name='mappings')) + + # Service Providers CRUD operations + + self._add_resource( + mapper, sp_controller, + path=self._construct_url('service_providers/{sp_id}'), + get_action='get_service_provider', + put_action='create_service_provider', + patch_action='update_service_provider', + delete_action='delete_service_provider', + rel=build_resource_relation(resource_name='service_provider'), + path_vars={ + 'sp_id': SP_ID_PARAMETER_RELATION, + }) + + self._add_resource( + mapper, sp_controller, + path=self._construct_url('service_providers'), + get_action='list_service_providers', + rel=build_resource_relation(resource_name='service_providers')) + + self._add_resource( + mapper, domain_controller, + path=self._construct_url('domains'), + new_path='/auth/domains', + get_action='list_domains_for_user', + rel=build_resource_relation(resource_name='domains')) + self._add_resource( + mapper, project_controller, + path=self._construct_url('projects'), + new_path='/auth/projects', + get_action='list_projects_for_user', + rel=build_resource_relation(resource_name='projects')) + + # Auth operations + self._add_resource( + mapper, auth_controller, + path=self._construct_url('identity_providers/{idp_id}/' + 'protocols/{protocol_id}/auth'), + get_post_action='federated_authentication', + rel=build_resource_relation( + resource_name='identity_provider_protocol_auth'), + path_vars={ + 'idp_id': IDP_ID_PARAMETER_RELATION, + 'protocol_id': PROTOCOL_ID_PARAMETER_RELATION, + }) + self._add_resource( + mapper, auth_controller, + path='/auth' + self._construct_url('saml2'), + post_action='create_saml_assertion', + rel=build_resource_relation(resource_name='saml2')) + self._add_resource( + mapper, auth_controller, + path='/auth' + self._construct_url('saml2/ecp'), + post_action='create_ecp_assertion', + rel=build_resource_relation(resource_name='ecp')) + self._add_resource( + mapper, auth_controller, + path='/auth' + self._construct_url('websso/{protocol_id}'), + get_post_action='federated_sso_auth', + rel=build_resource_relation(resource_name='websso'), + path_vars={ + 'protocol_id': PROTOCOL_ID_PARAMETER_RELATION, + }) + self._add_resource( + mapper, auth_controller, + path='/auth' + self._construct_url( + 'identity_providers/{idp_id}/protocols/{protocol_id}/websso'), + get_post_action='federated_idp_specific_sso_auth', + rel=build_resource_relation(resource_name='identity_providers'), + path_vars={ + 'idp_id': IDP_ID_PARAMETER_RELATION, + 'protocol_id': PROTOCOL_ID_PARAMETER_RELATION, + }) + + # Keystone-Identity-Provider metadata endpoint + self._add_resource( + mapper, saml_metadata_controller, + path=self._construct_url('saml2/metadata'), + get_action='get_metadata', + rel=build_resource_relation(resource_name='metadata')) diff --git a/keystone/rules.json b/keystone/rules.json new file mode 100644 index 0000000..0e406a6 --- /dev/null +++ b/keystone/rules.json @@ -0,0 +1,20 @@ +[ + { + "local": [ + { + "group_ids": "{1}", + "user": { + "name": "{0}" + } + } + ], + "remote": [ + { + "type": "REMOTE_USER" + }, + { + "type": "openstackGroupEntitlements" + } + ] + } +] diff --git a/keystone/run.sh b/keystone/run.sh new file mode 100755 index 0000000..593b3d5 --- /dev/null +++ b/keystone/run.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# start nova compute service + +chown keystone: /etc/keystone/fernet-keys +chmod 700 /etc/keystone/fernet-keys + +# Start apache +a2enmod ssl +apachectl -DFOREGROUND & + +chown _shibd: /etc/shibboleth/sp*.pem + +shibd -f -F & + +# If any process fails, kill the rest. +# This insures the container stops and systemd will restart it. + +wait -n +pkill -P $$ + diff --git a/keystone/shibboleth2.xml b/keystone/shibboleth2.xml new file mode 100644 index 0000000..908dfd1 --- /dev/null +++ b/keystone/shibboleth2.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + SAML2 + + + + SAML2 Local + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/keystone/sso_callback_template.html b/keystone/sso_callback_template.html new file mode 100644 index 0000000..c6997dc --- /dev/null +++ b/keystone/sso_callback_template.html @@ -0,0 +1,22 @@ + + + + Keystone WebSSO redirect + + +
+ Please wait... +
+ + +
+ + + \ No newline at end of file diff --git a/keystone/test.php b/keystone/test.php new file mode 100644 index 0000000..28cd932 --- /dev/null +++ b/keystone/test.php @@ -0,0 +1,4 @@ + +Shibboleth test +
+