Use standalone httpd role

In order to unify approach for managing Apache Web server, we migrate
to usage of standalone `httpd` role instead of managing apache
separately inside service roles.

Change-Id: I5be9be18ec0b61a4c24f4ac670cf195db0a65dc8
This commit is contained in:
Dmitriy Rabotyagov
2025-04-28 18:10:02 +02:00
parent a6b4f71010
commit 4a58212a5e
15 changed files with 198 additions and 465 deletions

View File

@@ -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('') }}"

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -1,10 +0,0 @@
<IfModule mpm_{{ keystone_httpd_mpm_backend }}_module>
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 }}
</IfModule>

View File

@@ -1,147 +0,0 @@
# {{ ansible_managed }}
Listen {{ keystone_web_server_bind_address }}:{{ keystone_service_port }}
<VirtualHost {{ keystone_web_server_bind_address }}:{{ keystone_service_port }}>
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
</IfVersion>
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 %}
<Location {{ keystone_sp.trusted_idp_list.0.oidc_redirect_path | default('/oidc_redirect') }}>
Require valid-user
AuthType openid-connect
</Location>
<Location /v3/OS-FEDERATION/identity_providers/{{ keystone_sp.trusted_idp_list.0.name }}/protocols/openid/auth>
Require valid-user
AuthType auth-openidc
</Location>
<Location /v3/auth/OS-FEDERATION/websso/openid>
Require valid-user
AuthType openid-connect
</Location>
<Location /v3/auth/OS-FEDERATION/identity_providers/{{ keystone_sp.trusted_idp_list.0.name }}/protocols/openid/websso>
Require valid-user
AuthType openid-connect
</Location>
{% endif %}
{%- if keystone_sp_apache_mod_shib -%}
ShibURLScheme {{ keystone_service_publicuri_proto }}
<Location /Shibboleth.sso>
SetHandler shib
</Location>
<Location /v3/auth/OS-FEDERATION/websso/saml2>
AuthType shibboleth
ShibRequestSetting requireSession 1
ShibRequestSetting exportAssertion 1
ShibRequireSession On
ShibExportAssertion On
Require valid-user
</Location>
<LocationMatch /v3/OS-FEDERATION/identity_providers/.*?/protocols/saml2/auth>
ShibRequestSetting requireSession 1
AuthType shibboleth
ShibExportAssertion Off
Require valid-user
</LocationMatch>
{% endif %}
{% if keystone_sp != {} -%}
<Directory /var/www/cgi-bin/keystone>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
{% endif %}
{% if keystone_sp_apache_mod_shib -%}
ProxyPass /Shibboleth.sso !
{% endif -%}
ProxyPass / uwsgi://127.0.0.1:{{ keystone_uwsgi_ports['keystone-wsgi-public']['socket'] }}/
</VirtualHost>

View File

@@ -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.

View File

@@ -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

View File

@@ -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 %}

View File

@@ -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 !"
- "<LocationMatch /v3/OS-FEDERATION/identity_providers/.*?/protocols/saml2/auth>"
- " ShibRequestSetting requireSession 1"
- " AuthType shibboleth"
- " ShibExportAssertion Off"
- " Require valid-user"
- "</LocationMatch>"
_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

View File

@@ -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"

View File

@@ -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 %}