diff --git a/defaults/main.yml b/defaults/main.yml index 7b725084..7961b0ef 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -224,19 +224,6 @@ keystone_web_server_bind_address: "{{ openstack_service_bind_address | default(' ## Apache setup keystone_apache_log_level: info keystone_apache_custom_log_format: combined -keystone_apache_servertokens: "Prod" -keystone_apache_serversignature: "Off" - -## Apache MPM tunables -keystone_httpd_mpm_backend: "{{ openstack_apache_mpm_backend | default('event') }}" -keystone_httpd_mpm_server_limit: "{{ keystone_wsgi_processes }}" -keystone_httpd_mpm_start_servers: 2 -keystone_httpd_mpm_min_spare_threads: 25 -keystone_httpd_mpm_max_spare_threads: 75 -keystone_httpd_mpm_thread_limit: 64 -keystone_httpd_mpm_thread_child: 25 -keystone_httpd_mpm_max_requests: "{{ keystone_httpd_mpm_server_limit | int * keystone_httpd_mpm_thread_child | int }}" -keystone_httpd_mpm_max_conn_child: 0 ## uWSGI setup keystone_wsgi_threads: 1 @@ -276,6 +263,8 @@ keystone_pki_regen_cert: "" # By default, CA creation is controlled using the CA 'condition' field keystone_pki_create_ca: true +# SAN which will be used by HTTP role to generate certificatess +keystone_pki_san: "{{ openstack_pki_san | default('DNS:' ~ ansible_facts['hostname'] ~ ',IP:' ~ keystone_node_address) }}" # An optional private certificate authority for when Keystone is an IDP keystone_idp_authority_name: "KeystoneIDPAuthority" keystone_pki_authorities: @@ -293,46 +282,11 @@ keystone_pki_authorities: not_after: "+3650d" condition: "{{ (keystone_idp['certfile'] is defined) and _keystone_is_first_play_host }}" -# By default, certificate creation is controlled using the certificates 'condition' field -keystone_pki_create_certificates: true -# Server certificate for Apache -keystone_pki_certificates: - - name: "keystone_{{ ansible_facts['hostname'] }}" - provider: ownca - cn: "{{ ansible_facts['hostname'] }}" - san: "{{ 'DNS:' ~ ansible_facts['hostname'] ~ ',IP:' ~ keystone_node_address }}" - signed_by: "{{ keystone_pki_intermediate_cert_name }}" - condition: "{{ keystone_backend_ssl }}" - # Set to the value of keystone_idp_authority_name to regenerate the IDP CA keystone_pki_regen_ca: "" -# keystone destination files for Apache SSL certificates -keystone_ssl_cert: /etc/ssl/certs/keystone.pem -keystone_ssl_key: /etc/ssl/private/keystone.key -keystone_ssl_ca_cert: /etc/ssl/certs/keystone-ca.pem - # Installation details for SSL certificates keystone_pki_install_certificates: - # Apache certificates - - src: "{{ keystone_user_ssl_cert | default(keystone_pki_certs_path ~ 'keystone_' ~ ansible_facts['hostname'] ~ '-chain.crt') }}" - dest: "{{ keystone_ssl_cert }}" - owner: "{{ keystone_system_user_name }}" - group: "{{ keystone_system_group_name }}" - mode: "0644" - condition: "{{ keystone_backend_ssl }}" - - src: "{{ keystone_user_ssl_key | default(keystone_pki_keys_path ~ 'keystone_' ~ ansible_facts['hostname'] ~ '.key.pem') }}" - dest: "{{ keystone_ssl_key }}" - owner: "{{ keystone_system_user_name }}" - group: "{{ keystone_system_group_name }}" - mode: "0600" - condition: "{{ keystone_backend_ssl }}" - - src: "{{ keystone_user_ssl_ca_cert | default(keystone_pki_intermediate_cert_path) }}" - dest: "{{ keystone_ssl_ca_cert }}" - owner: "{{ keystone_system_user_name }}" - group: "{{ keystone_system_group_name }}" - mode: "0644" - condition: "{{ keystone_user_ssl_ca_cert is defined }}" # IDP certificates - src: "{{ keystone_pki_dir ~ '/roots/' ~ keystone_idp_authority_name ~ '/certs/' ~ keystone_idp_authority_name ~ '.crt' }}" dest: "{{ keystone_idp['certfile'] | default('') }}" diff --git a/handlers/main.yml b/handlers/main.yml index 2a441bde..2be7c6c7 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -13,33 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# NOTE(noonedeadpunk): Handler with the same name is triggered from the http role - name: Restart web server - ansible.builtin.service: - name: "{{ keystone_system_service_name }}" - enabled: true - state: restarted - daemon_reload: "{{ (ansible_facts['service_mgr'] == 'systemd') | ternary('yes', omit) }}" - register: _restart - until: _restart is success - retries: 5 - delay: 2 - listen: - - "venv changed" - -- name: Wait for web server to complete starting - ansible.builtin.wait_for: - host: "{{ keystone_web_server_bind_address }}" - port: "{{ item }}" - timeout: 25 - delay: 10 - with_items: - - "{{ keystone_service_port }}" - register: _wait_check - until: _wait_check is success - retries: 5 - listen: - - "venv changed" - - "Restart web server" + ansible.builtin.meta: noop + when: false - name: Stop uWSGI ansible.builtin.service: @@ -82,6 +59,7 @@ listen: - "venv changed" - "Restart uWSGI" + - "Start uWSGI" - name: Restart Shibd ansible.builtin.service: diff --git a/tasks/keystone_apache.yml b/tasks/keystone_apache.yml index 18027aff..462cf9a6 100644 --- a/tasks/keystone_apache.yml +++ b/tasks/keystone_apache.yml @@ -13,143 +13,62 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Create apache nogroup group - ansible.builtin.group: - name: "nogroup" - system: "yes" - -- name: Create apache nogroup user - ansible.builtin.user: - name: "nogroup" - group: "nogroup" - system: "yes" - shell: "/bin/false" - -- name: Ensure apache log folder exists - ansible.builtin.file: - dest: "{{ keystone_apache_default_log_folder }}" - state: directory - owner: "{{ keystone_apache_default_log_owner }}" - group: "{{ keystone_apache_default_log_grp }}" - mode: "0755" - -- name: Ensure apache2 MPM for Debian/Ubuntu - community.general.apache2_module: - name: "{{ item.name }}" - state: "{{ item.state }}" - warn_mpm_absent: false - with_items: "{{ keystone_apache_mpms | sort(attribute='state') }}" - when: - - ansible_facts['pkg_mgr'] == 'apt' - notify: Restart web server - -- name: Ensure apache2 MPM for EL - ansible.builtin.copy: - content: | - LoadModule mpm_{{ keystone_httpd_mpm_backend }}_module modules/mod_mpm_{{ keystone_httpd_mpm_backend }}.so - - dest: /etc/httpd/conf.modules.d/00-mpm.conf - mode: "0644" - when: - - ansible_facts['pkg_mgr'] == 'dnf' - notify: Restart web server - -## NOTE(cloudnull): -## Module enable/disable process is only functional on Debian -- name: Enable apache2 modules - community.general.apache2_module: - name: "{{ item.name }}" - state: "{{ item.state }}" - with_items: "{{ keystone_apache_modules }}" - when: - - ansible_facts['pkg_mgr'] == 'apt' - - item.state == 'present' - notify: - - Restart web server - -- name: Place apache2 config files - ansible.builtin.template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: "root" - group: "root" - mode: "0644" - with_items: "{{ keystone_apache_configs }}" - notify: - - Restart web server - -## NOTE(cloudnull): -## Module enable/disable process is only functional on Debian -- name: Disable apache2 modules - community.general.apache2_module: - name: "{{ item.name }}" - state: "{{ item.state }}" - with_items: "{{ keystone_apache_modules }}" - when: - - ansible_facts['pkg_mgr'] == 'apt' - - item.state == 'absent' - notify: - - Restart web server - -## NOTE(andymccr): -## We need to enable a module for httpd on RedHat/CentOS using LoadModule inside conf files -- name: Enable/disable proxy_uwsgi_module - ansible.builtin.lineinfile: - dest: "/etc/httpd/conf.modules.d/00-proxy.conf" - line: "LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so" - state: "present" - when: - - ansible_facts['pkg_mgr'] == 'dnf' - notify: - - Restart web server - -- name: Disable default apache site +- name: Clean-up old vhost files ansible.builtin.file: path: "{{ item }}" - state: "absent" - with_items: "{{ keystone_apache_default_sites }}" - notify: - - Restart web server + state: absent + loop: "{{ keystone_deprecated_apache_configs }}" -- name: Enabled keystone vhost - ansible.builtin.file: - src: "{{ keystone_apache_site_available }}" - dest: "{{ keystone_apache_site_enabled }}" - state: "link" - when: - - keystone_apache_site_available is defined - - keystone_apache_site_enabled is defined - notify: - - Restart web server - -- name: Ensure Apache ServerName - ansible.builtin.lineinfile: - dest: "{{ keystone_apache_conf }}" - line: "ServerName {{ ansible_facts['hostname'] }}" - notify: - - Restart web server - -- name: Ensure Apache ServerTokens - ansible.builtin.lineinfile: - dest: "{{ keystone_apache_security_conf }}" - regexp: "^ServerTokens" - line: "ServerTokens {{ keystone_apache_servertokens }}" - notify: - - Restart web server - -- name: Ensure Apache ServerSignature - ansible.builtin.lineinfile: - dest: "{{ keystone_apache_security_conf }}" - regexp: "^ServerSignature" - line: "ServerSignature {{ keystone_apache_serversignature }}" - notify: - - Restart web server - -- name: Remove Listen from Apache config - ansible.builtin.lineinfile: - dest: "{{ keystone_apache_conf }}" - regexp: "^(Listen.*)" - backrefs: true - line: "#\\1" - notify: - - Restart web server +- name: Including HTTPD role + ansible.builtin.import_role: + name: httpd + vars: + httpd_pki_dir: "{{ keystone_pki_dir }}" + httpd_pki_setup_host: "{{ keystone_pki_setup_host }}" + httpd_ssl_protocol: "{{ keystone_ssl_protocol }}" + httpd_ssl_cipher_suite_tls12: "{{ keystone_ssl_cipher_suite_tls12 }}" + httpd_ssl_cipher_suite_tls13: "{{ keystone_ssl_cipher_suite_tls13 }}" + httpd_pki_regen_cert: "{{ keystone_pki_regen_cert }}" + httpd_extra_packages: "{{ keystone_sp_apache_mod_packages | selectattr('state', 'eq', 'present') | map(attribute='name') }}" + httpd_extra_modules: "{{ keystone_apache_modules }}" + httpd_vhosts: + - name: openstack_keystone + address: "{{ keystone_web_server_bind_address }}" + port: "{{ keystone_service_port }}" + log_level: "{{ keystone_apache_log_level }}" + log_format: "{{ keystone_apache_custom_log_format }}" + server_name: "{{ ansible_facts['hostname'] }}" + headers: + - 'Header set X-Content-Type-Options "nosniff"' + - 'Header set X-XSS-Protection "1; mode=block"' + - >- + Header set Content-Security-Policy "default-src 'self' https: wss:;" + - >- + {% set scp_script_src = "script-src 'sha256-oBahlBFQem+nMs1JwgcBB03Hy8nRh5e8qEGTOcxmAuM=';" -%} + {{ (keystone_sp != {}) | ternary('Header set Content-Security-Policy "' ~ scp_script_src ~ '"', '') }} + - "Header set X-Frame-Options {{ keystone_x_frame_options | default('DENY') }}" + options: |- + {% set options = _keystone_httpd_base_options %} + {% if keystone_sp_apache_mod_auth_openidc %} + {% set _ = options.extend(_keystone_httpd_openidc_options) %} + {% endif %} + {% if keystone_sp_apache_mod_shib %} + {% set _ = options.extend(_keystone_httpd_shib_options) %} + {% endif %} + {% set _ = options.append('ProxyPass / uwsgi://127.0.0.1:' ~ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] ~ '/') %} + {{ options }} + locations: |- + {% set locations = [] %} + {% if keystone_sp_apache_mod_auth_openidc %} + {% set _ = locations.extend(_keystone_httpd_openidc_locations) %} + {% endif %} + {% if keystone_sp_apache_mod_shib %} + {% set _ = locations.extend(_keystone_httpd_shib_locations) %} + {% endif %} + {{ locations }} + directories: "{{ (keystone_sp != {}) | ternary(_keystone_httpd_sp_directories, []) }}" + ssl: "{{ keystone_backend_ssl | ternary(_keystone_httpd_vhost_ssl, false) }}" + tags: + - horizon-install + - horizon-config + - httpd diff --git a/tasks/keystone_install.yml b/tasks/keystone_install.yml index d149a65e..49264c06 100644 --- a/tasks/keystone_install.yml +++ b/tasks/keystone_install.yml @@ -22,7 +22,6 @@ mode: "{{ item.mode | default('0755') }}" with_items: - { path: "/var/lock/keystone", mode: "2755" } - - { path: "/var/log/httpd", mode: "2755" } when: - ansible_facts['pkg_mgr'] == 'dnf' @@ -58,15 +57,8 @@ retries: 5 delay: 2 notify: - - Restart web server - Restart uWSGI -- name: Install/remove apache mod packages for federated authentication - ansible.builtin.package: - name: "{{ item.name }}" - state: "{{ item.state }}" - with_items: "{{ keystone_sp_apache_mod_packages }}" - - name: Install the python venv ansible.builtin.import_role: name: "python_venv_build" @@ -145,5 +137,3 @@ dest: "/var/www/cgi-bin/keystone/main" state: link force: true - notify: - - Restart web server diff --git a/tasks/keystone_ldap_setup.yml b/tasks/keystone_ldap_setup.yml index 504421de..6a4d523b 100644 --- a/tasks/keystone_ldap_setup.yml +++ b/tasks/keystone_ldap_setup.yml @@ -43,7 +43,6 @@ no_log: true notify: - Restart uWSGI - - Restart web server # Bug 1547542 - Older versions of the keystone role would deploy a blank # keystone.Default.conf and this will cause errors when adding LDAP-backed @@ -55,4 +54,3 @@ when: keystone_ldap.Default is not defined notify: - Restart uWSGI - - Restart web server diff --git a/tasks/keystone_post_install.yml b/tasks/keystone_post_install.yml index 50ddcd21..80b014c9 100644 --- a/tasks/keystone_post_install.yml +++ b/tasks/keystone_post_install.yml @@ -38,7 +38,6 @@ config_type: "ini" notify: - Restart uWSGI - - Restart web server - name: Implement policy.yaml if there are overrides configured openstack.config_template.config_template: @@ -92,7 +91,6 @@ with_items: "{{ keystone_core_files }}" notify: - Restart uWSGI - - Restart web server - name: Cleanup fetched temp files ansible.builtin.file: diff --git a/tasks/main.yml b/tasks/main.yml index 95e6d200..72fdc7f9 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -120,6 +120,21 @@ tags: - always +- name: Importing keystone_federation_sp_shib_setup tasks + ansible.builtin.import_tasks: keystone_federation_sp_shib_setup.yml + when: + - keystone_sp_apache_mod_shib + - not (keystone_use_uwsgi | bool) + tags: + - keystone-config + +- name: Importing keystone_apache tasks + ansible.builtin.import_tasks: "keystone_apache.yml" + when: + - not (keystone_use_uwsgi | bool) + tags: + - keystone-config + - name: Importing keystone_install tasks ansible.builtin.import_tasks: keystone_install.yml tags: @@ -159,14 +174,6 @@ tags: - keystone-config -- name: Importing keystone_federation_sp_shib_setup tasks - ansible.builtin.import_tasks: keystone_federation_sp_shib_setup.yml - when: - - keystone_sp_apache_mod_shib - - not (keystone_use_uwsgi | bool) - tags: - - keystone-config - - name: Create and install SSL certificates ansible.builtin.include_role: name: pki @@ -177,19 +184,9 @@ pki_create_ca: "{{ keystone_pki_create_ca }}" pki_authorities: "{{ keystone_pki_ca_certificates }}" pki_regen_ca: "{{ keystone_pki_regen_ca }}" - pki_create_certificates: "{{ keystone_pki_create_certificates }}" - pki_regen_cert: "{{ keystone_pki_regen_cert }}" - pki_certificates: "{{ keystone_pki_certificates }}" pki_install_certificates: "{{ keystone_pki_install_certificates }}" when: - - (keystone_backend_ssl | bool) or (keystone_idp['certfile'] is defined) - tags: - - keystone-config - -- name: Importing keystone_apache tasks - ansible.builtin.import_tasks: "keystone_apache.yml" - when: - - not (keystone_use_uwsgi | bool) + - keystone_idp['certfile'] is defined tags: - keystone-config diff --git a/templates/keystone-httpd-mpm.conf.j2 b/templates/keystone-httpd-mpm.conf.j2 deleted file mode 100644 index 17ba32de..00000000 --- a/templates/keystone-httpd-mpm.conf.j2 +++ /dev/null @@ -1,10 +0,0 @@ - - ServerLimit {{ keystone_httpd_mpm_server_limit }} - StartServers {{ keystone_httpd_mpm_start_servers }} - MinSpareThreads {{ keystone_httpd_mpm_min_spare_threads }} - MaxSpareThreads {{ keystone_httpd_mpm_max_spare_threads }} - ThreadLimit {{ keystone_httpd_mpm_thread_limit }} - ThreadsPerChild {{ keystone_httpd_mpm_thread_child }} - MaxRequestWorkers {{ keystone_httpd_mpm_max_requests }} - MaxConnectionsPerChild {{ keystone_httpd_mpm_max_conn_child }} - diff --git a/templates/keystone-httpd.conf.j2 b/templates/keystone-httpd.conf.j2 deleted file mode 100644 index 6421514a..00000000 --- a/templates/keystone-httpd.conf.j2 +++ /dev/null @@ -1,147 +0,0 @@ -# {{ ansible_managed }} - -Listen {{ keystone_web_server_bind_address }}:{{ keystone_service_port }} - - - = 2.4> - ErrorLogFormat "%{cu}t %M" - - - LogLevel {{ keystone_apache_log_level }} - ErrorLog syslog:daemon - CustomLog "|/usr/bin/env logger -p daemon.info -t {{ keystone_system_service_name }}" {{ keystone_apache_custom_log_format }} - Options +FollowSymLinks - - Header set X-Content-Type-Options "nosniff" - Header set X-XSS-Protection "1; mode=block" - Header set Content-Security-Policy "default-src 'self' https: wss:;" - {% if keystone_sp != {} -%} - Header set Content-Security-Policy "script-src 'sha256-oBahlBFQem+nMs1JwgcBB03Hy8nRh5e8qEGTOcxmAuM=';" - {% endif -%} - Header set X-Frame-Options "{{ keystone_x_frame_options | default ('DENY') }}" - - {% if keystone_backend_ssl | bool -%} - SSLEngine on - SSLCertificateFile {{ keystone_ssl_cert }} - SSLCertificateKeyFile {{ keystone_ssl_key }} - {% if keystone_user_ssl_ca_cert is defined -%} - SSLCACertificateFile {{ keystone_ssl_ca_cert }} - {% endif -%} - SSLCompression Off - SSLProtocol {{ keystone_ssl_protocol }} - SSLHonorCipherOrder On - {% if keystone_ssl_cipher_suite_tls12 != "" -%} - SSLCipherSuite {{ keystone_ssl_cipher_suite_tls12 }} - {% endif -%} - {% if keystone_ssl_cipher_suite_tls13 != "" -%} - SSLCipherSuite TLSv1.3 {{ keystone_ssl_cipher_suite_tls13 }} - {% endif -%} - SSLOptions +StdEnvVars +ExportCertData - {% endif -%} - {% if keystone_sp_apache_mod_auth_openidc -%} - OIDCClaimPrefix "{{ keystone_sp.trusted_idp_list.0.oidc_claim_prefix | default('OIDC-') }}" - OIDCResponseType "{{ keystone_sp.trusted_idp_list.0.oidc_resp_type | default('id_token') }}" - OIDCScope "{{ keystone_sp.trusted_idp_list.0.oidc_scope | default('openid email profile') }}" - OIDCProviderMetadataURL {{ keystone_sp.trusted_idp_list.0.oidc_provider_metadata_url }} - OIDCClientID {{ keystone_sp.trusted_idp_list.0.oidc_client_id }} - OIDCClientSecret {{ keystone_sp.trusted_idp_list.0.oidc_client_secret }} - OIDCCryptoPassphrase {{ keystone_sp.trusted_idp_list.0.oidc_crypto_passphrase }} - OIDCRedirectURI {{ keystone_service_publicuri }}{{ keystone_sp.trusted_idp_list.0.oidc_redirect_path | default('/oidc_redirect') }} - {% if _keystone_sp_apache_mod_auth_openidc_gte_2_4_11 is defined and _keystone_sp_apache_mod_auth_openidc_gte_2_4_11 -%} - OIDCXForwardedHeaders {{ keystone_secure_proxy_ssl_header }} - {% endif -%} - {% if keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri is defined -%} - OIDCOAuthVerifyJwksUri {{ keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri }} - {% endif -%} - {% if keystone_sp.trusted_idp_list.0.oidc_outgoing_proxy is defined -%} - OIDCOutgoingProxy {{ keystone_sp.trusted_idp_list.0.oidc_outgoing_proxy }} - {% endif -%} - {% if keystone_sp.trusted_idp_list.0.oidc_oauth_introspection_endpoint is defined -%} - OIDCOAuthIntrospectionEndpoint {{ keystone_sp.trusted_idp_list.0.oidc_oauth_introspection_endpoint }} - {% endif -%} - {% if keystone_sp.trusted_idp_list.0.oidc_oauth_client_id is defined -%} - OIDCOAuthClientID {{ keystone_sp.trusted_idp_list.0.oidc_oauth_client_id }} - {% endif -%} - {% if keystone_sp.trusted_idp_list.0.oidc_oauth_client_secret is defined -%} - OIDCOAuthClientSecret {{ keystone_sp.trusted_idp_list.0.oidc_oauth_client_secret }} - {% endif -%} - {% if keystone_sp.trusted_idp_list.0.oidc_pkce_method is defined -%} - OIDCPKCEMethod {{ keystone_sp.trusted_idp_list.0.oidc_pkce_method }} - {% endif -%} - {% if keystone_cache_servers | length > 0 -%} - OIDCCacheType memcache - OIDCMemCacheServers "{{ keystone_cache_servers | join(' ') }}" - {% endif %} - {% if keystone_sp.trusted_idp_list.0.oidc_auth_request_params is defined -%} - OIDCAuthRequestParams {{ keystone_sp.trusted_idp_list.0.oidc_auth_request_params }} - {% endif %} - {% if keystone_sp.trusted_idp_list.0.oidc_state_max_number_of_cookies is defined -%} - OIDCStateMaxNumberOfCookies {{ keystone_sp.trusted_idp_list.0.oidc_state_max_number_of_cookies }} - {% endif %} - {% if keystone_sp.trusted_idp_list.0.oidc_default_url is defined -%} - OIDCDefaultURL {{ keystone_sp.trusted_idp_list.0.oidc_default_url }} - {% endif %} - {% if keystone_sp.trusted_idp_list.0.oidc_claim_delimiter is defined -%} - OIDCClaimDelimiter "{{ keystone_sp.trusted_idp_list.0.oidc_claim_delimiter }}" - {% endif %} - - - Require valid-user - AuthType openid-connect - - - - Require valid-user - AuthType auth-openidc - - - - Require valid-user - AuthType openid-connect - - - - Require valid-user - AuthType openid-connect - - {% endif %} - {%- if keystone_sp_apache_mod_shib -%} - ShibURLScheme {{ keystone_service_publicuri_proto }} - - - SetHandler shib - - - - AuthType shibboleth - ShibRequestSetting requireSession 1 - ShibRequestSetting exportAssertion 1 - ShibRequireSession On - ShibExportAssertion On - Require valid-user - - - - ShibRequestSetting requireSession 1 - AuthType shibboleth - ShibExportAssertion Off - Require valid-user - - {% endif %} - - {% if keystone_sp != {} -%} - - Options Indexes FollowSymLinks MultiViews - AllowOverride All - Order allow,deny - allow from all - - {% endif %} - - {% if keystone_sp_apache_mod_shib -%} - ProxyPass /Shibboleth.sso ! - {% endif -%} - - ProxyPass / uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] }}/ - - diff --git a/templates/keystone-ports.conf.j2 b/templates/keystone-ports.conf.j2 deleted file mode 100644 index 3c32de37..00000000 --- a/templates/keystone-ports.conf.j2 +++ /dev/null @@ -1,6 +0,0 @@ -# {{ ansible_managed }} - -# We place a blank file here -# Listen commands happen inside the individual VHost files -# This allows for multiple services VHosts to exist without -# overwriting Listen lines. diff --git a/vars/debian.yml b/vars/debian.yml index 5157c029..5aae3f3f 100644 --- a/vars/debian.yml +++ b/vars/debian.yml @@ -41,11 +41,6 @@ keystone_service_distro_packages: - python3-keystone - python3-systemd -keystone_apache_distro_packages: - - apache2 - - apache2-utils - - libapache2-mod-proxy-uwsgi - keystone_idp_distro_packages: - ssl-cert - xmlsec1 @@ -62,47 +57,21 @@ keystone_sp_apache_mod_packages: keystone_developer_mode_distro_packages: - build-essential -keystone_apache_default_sites: - - "/etc/apache2/sites-enabled/000-default.conf" - -keystone_apache_site_available: "/etc/apache2/sites-available/keystone-httpd.conf" -keystone_apache_site_enabled: "/etc/apache2/sites-enabled/keystone-httpd.conf" -keystone_apache_conf: "/etc/apache2/apache2.conf" -keystone_apache_default_log_folder: "/var/log/apache2" -keystone_apache_default_log_owner: "root" -keystone_apache_default_log_grp: "adm" -keystone_apache_security_conf: "/etc/apache2/conf-available/security.conf" - -keystone_apache_configs: - - { src: "keystone-ports.conf.j2", dest: "/etc/apache2/ports.conf" } - - { src: "keystone-httpd.conf.j2", dest: "/etc/apache2/sites-available/keystone-httpd.conf" } - - { src: "keystone-httpd-mpm.conf.j2", dest: "/etc/apache2/mods-available/mpm_{{ keystone_httpd_mpm_backend }}.conf" } - -keystone_apache_mpms: - - name: "mpm_event" - state: "{{ (keystone_httpd_mpm_backend == 'event') | ternary('present', 'absent') }}" - - name: "mpm_worker" - state: "{{ (keystone_httpd_mpm_backend == 'worker') | ternary('present', 'absent') }}" - - name: "mpm_prefork" - state: "{{ (keystone_httpd_mpm_backend == 'prefork') | ternary('present', 'absent') }}" +keystone_deprecated_apache_configs: + - /etc/apache2/sites-available/keystone-httpd.conf + - /etc/apache2/sites-enabled/keystone-httpd.conf keystone_apache_modules: - - name: "ssl" - state: "{{ (keystone_backend_ssl | bool) | ternary('present', 'absent') }}" - name: "shib" state: "{{ keystone_sp_apache_mod_shib | ternary('present', 'absent') }}" - name: "auth_openidc" state: "{{ keystone_sp_apache_mod_auth_openidc | ternary('present', 'absent') }}" - name: "proxy_uwsgi" state: "present" - - name: "headers" - state: "present" # This can be enabled when Apache2.5+ is available # - name: "mod_journald" # state: "present -keystone_system_service_name: "{{ (keystone_use_uwsgi | bool) | ternary('keystone-wsgi-public', 'apache2') }}" - keystone_uwsgi_bin: "/usr/bin" keystone_sshd: ssh diff --git a/vars/distro_install.yml b/vars/distro_install.yml index c43d8363..7953f210 100644 --- a/vars/distro_install.yml +++ b/vars/distro_install.yml @@ -19,7 +19,7 @@ # enabled. # keystone_package_list: |- - {% set packages = keystone_distro_packages | union((keystone_use_uwsgi | bool) | ternary([], keystone_apache_distro_packages)) %} + {% set packages = keystone_distro_packages %} {% if keystone_idp != {} %} {% set _ = packages.extend(keystone_idp_distro_packages) %} {% endif %} diff --git a/vars/main.yml b/vars/main.yml index b71c47d9..7022c21e 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -77,3 +77,116 @@ _keystone_cache_backend_package: |- {%- endif %} {%- endfor %} oslo.cache[{{ oslo.backend }}] + +_keystone_httpd_vhost_ssl: |- + {% set ssl_options = {} %} + {% if (keystone_user_ssl_cert is defined and keystone_user_ssl_cert) and (keystone_user_ssl_key is defined and keystone_user_ssl_key) %} + {% set _ = ssl_options.update({'cert': keystone_user_ssl_cert, 'key': keystone_user_ssl_key}) %} + {% if keystone_user_ssl_ca_cert is defined and keystone_user_ssl_ca_cert %} + {% set _ = ssl_options.update({'ca': keystone_user_ssl_ca_cert}) %} + {% endif %} + {% else %} + {% set _ = ssl_options.update({'san': keystone_pki_san}) %} + {% endif %} + {{ ssl_options }} + +_keystone_httpd_base_options: + - Options +FollowSymLinks + +_keystone_httpd_shib_options: + - "ShibURLScheme {{ keystone_service_publicuri_proto }}" + - "ProxyPass /Shibboleth.sso !" + - "" + - " ShibRequestSetting requireSession 1" + - " AuthType shibboleth" + - " ShibExportAssertion Off" + - " Require valid-user" + - "" + +_keystone_httpd_openidc_base_options: + - "OIDCClaimPrefix \"{{ keystone_sp.trusted_idp_list.0.oidc_claim_prefix | default('OIDC-') }}\"" + - "OIDCResponseType \"{{ keystone_sp.trusted_idp_list.0.oidc_resp_type | default('id_token') }}\"" + - "OIDCScope \"{{ keystone_sp.trusted_idp_list.0.oidc_scope | default('openid email profile') }}\"" + - "OIDCProviderMetadataURL {{ keystone_sp.trusted_idp_list.0.oidc_provider_metadata_url }}" + - "OIDCClientID {{ keystone_sp.trusted_idp_list.0.oidc_client_id }}" + - "OIDCClientSecret {{ keystone_sp.trusted_idp_list.0.oidc_client_secret }}" + - "OIDCCryptoPassphrase {{ keystone_sp.trusted_idp_list.0.oidc_crypto_passphrase }}" + - "OIDCRedirectURI {{ keystone_service_publicuri }}{{ keystone_sp.trusted_idp_list.0.oidc_redirect_path | default('/oidc_redirect') }}" + +_keystone_httpd_openidc_options: |- + {% set openidc_options = _keystone_httpd_openidc_base_options %} + {% if _keystone_sp_apache_mod_auth_openidc_gte_2_4_11 is defined and _keystone_sp_apache_mod_auth_openidc_gte_2_4_11 %} + {% set _ = openidc_options.append('OIDCXForwardedHeaders ' ~ keystone_secure_proxy_ssl_header) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri is defined %} + {% set _ = openidc_options.append('OIDCOAuthVerifyJwksUri ' ~ keystone_sp.trusted_idp_list.0.oidc_auth_verify_jwks_uri) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_outgoing_proxy is defined %} + {% set _ = openidc_options.append('OIDCOutgoingProxy ' ~ keystone_sp.trusted_idp_list.0.oidc_outgoing_proxy) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_oauth_introspection_endpoint is defined %} + {% set _ = openidc_options.append('OIDCOAuthIntrospectionEndpoint ' ~ keystone_sp.trusted_idp_list.0.oidc_oauth_introspection_endpoint) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_oauth_client_id is defined %} + {% set _ = openidc_options.append('OIDCOAuthClientID ' ~ keystone_sp.trusted_idp_list.0.oidc_oauth_client_id) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_oauth_client_secret is defined %} + {% set _ = openidc_options.append('OIDCOAuthClientSecret ' ~ keystone_sp.trusted_idp_list.0.oidc_oauth_client_secret) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_pkce_method is defined %} + {% set _ = openidc_options.append('OIDCPKCEMethod ' ~ keystone_sp.trusted_idp_list.0.oidc_pkce_method) %} + {% endif %} + {% if keystone_cache_servers | length > 0 -%} + {% set _ = openidc_options.append('OIDCCacheType memcache') %} + {% set _ = openidc_options.append('OIDCMemCacheServers "' ~ keystone_cache_servers | join(' ') ~ '"') %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_auth_request_params is defined %} + {% set _ = openidc_options.append('OIDCAuthRequestParams ' ~ keystone_sp.trusted_idp_list.0.oidc_auth_request_params) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_state_max_number_of_cookies is defined -%} + {% set _ = openidc_options.append('OIDCStateMaxNumberOfCookies ' ~ keystone_sp.trusted_idp_list.0.oidc_state_max_number_of_cookies) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_default_url is defined %} + {% set _ = openidc_options.append('OIDCDefaultURL ' ~ keystone_sp.trusted_idp_list.0.oidc_default_url) %} + {% endif %} + {% if keystone_sp.trusted_idp_list.0.oidc_claim_delimiter is defined %} + {% set _ = openidc_options.append('OIDCClaimDelimiter ' ~ keystone_sp.trusted_idp_list.0.oidc_claim_delimiter) %} + {% endif %} + {{ openidc_options }} + +_keystone_httpd_openidc_location_options: + - Require valid-user + - AuthType openid-connect + +_keystone_httpd_openidc_locations: + - path: "{{ keystone_sp.trusted_idp_list.0.oidc_redirect_path | default('/oidc_redirect') }}" + options: "{{ _keystone_httpd_openidc_location_options }}" + - path: "/v3/OS-FEDERATION/identity_providers/{{ keystone_sp.trusted_idp_list.0.name }}/protocols/openid/auth" + options: + - Require valid-user + - AuthType auth-openidc + - path: /v3/auth/OS-FEDERATION/websso/openid + options: "{{ _keystone_httpd_openidc_location_options }}" + - path: /v3/auth/OS-FEDERATION/identity_providers/{{ keystone_sp.trusted_idp_list.0.name }}/protocols/openid/websso + options: "{{ _keystone_httpd_openidc_location_options }}" + +_keystone_httpd_shib_locations: + - path: /CShibboleth.sso + options: + - SetHandler shib + - path: /v3/auth/OS-FEDERATION/websso/saml2\ + options: + - AuthType shibboleth + - ShibRequestSetting requireSession 1 + - ShibRequestSetting exportAssertion 1 + - ShibRequireSession On + - ShibExportAssertion On + - Require valid-user + +_keystone_httpd_sp_directories: + - path: /var/www/cgi-bin/keystone + options: + - Options Indexes FollowSymLinks MultiViews + - AllowOverride All + - Order allow,deny + - allow from all diff --git a/vars/redhat.yml b/vars/redhat.yml index d967207a..263098b2 100644 --- a/vars/redhat.yml +++ b/vars/redhat.yml @@ -35,11 +35,6 @@ keystone_service_distro_packages: - openstack-keystone - python3-systemd -keystone_apache_distro_packages: - - httpd - - httpd-tools - - mod_ssl - keystone_idp_distro_packages: - xmlsec1 @@ -55,23 +50,8 @@ keystone_sp_apache_mod_packages: keystone_developer_mode_distro_packages: - gcc -keystone_apache_default_sites: - - "/etc/httpd/conf.d/userdir.conf" - - "/etc/httpd/conf.d/welcome.conf" - - "/etc/httpd/conf.d/ssl.conf" - -keystone_apache_conf: "/etc/httpd/conf/httpd.conf" -keystone_apache_default_log_folder: "/var/log/httpd" -keystone_apache_default_log_owner: "root" -keystone_apache_default_log_grp: "root" -keystone_apache_security_conf: "{{ keystone_apache_conf }}" - -keystone_apache_configs: - - { src: "keystone-ports.conf.j2", dest: "/etc/httpd/conf.d/ports.conf" } - - { src: "keystone-httpd.conf.j2", dest: "/etc/httpd/conf.d/keystone-httpd.conf" } - - { src: "keystone-httpd-mpm.conf.j2", dest: "/etc/httpd/conf.modules.d/mpm_{{ keystone_httpd_mpm_backend }}.conf" } - -keystone_system_service_name: "{{ (keystone_use_uwsgi | bool) | ternary('keystone-wsgi-public', 'httpd') }}" +keystone_deprecated_apache_configs: + - /etc/httpd/conf.d/keystone-httpd.conf keystone_uwsgi_bin: "/usr/sbin" diff --git a/vars/source_install.yml b/vars/source_install.yml index 92292aef..d5a17c40 100644 --- a/vars/source_install.yml +++ b/vars/source_install.yml @@ -19,7 +19,7 @@ # enabled. # keystone_package_list: |- - {% set packages = keystone_distro_packages | union((keystone_use_uwsgi | bool) | ternary([], keystone_apache_distro_packages)) %} + {% set packages = keystone_distro_packages %} {% if keystone_idp != {} %} {% set _ = packages.extend(keystone_idp_distro_packages) %} {% endif %}