-
Notifications
You must be signed in to change notification settings - Fork 269
Implement all Keycloak settings #1203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -158,128 +158,161 @@ | |
| $listen_socket = '/run/foreman.sock' | ||
|
|
||
| class { 'foreman::config::apache': | ||
| app_root => $foreman::app_root, | ||
| priority => $foreman::vhost_priority, | ||
| servername => $foreman::servername, | ||
| serveraliases => $foreman::serveraliases, | ||
| server_port => $foreman::server_port, | ||
| server_ssl_port => $foreman::server_ssl_port, | ||
| proxy_backend => "unix://${listen_socket}", | ||
| ssl => $foreman::ssl, | ||
| ssl_ca => $foreman::server_ssl_ca, | ||
| ssl_chain => $foreman::server_ssl_chain, | ||
| ssl_cert => $foreman::server_ssl_cert, | ||
| ssl_key => $foreman::server_ssl_key, | ||
| ssl_crl => $foreman::server_ssl_crl, | ||
| ssl_protocol => $foreman::server_ssl_protocol, | ||
| ssl_verify_client => $foreman::server_ssl_verify_client, | ||
| user => $foreman::user, | ||
| foreman_url => $foreman::foreman_url, | ||
| ipa_authentication => $foreman::ipa_authentication, | ||
| keycloak => $foreman::keycloak, | ||
| keycloak_app_name => $foreman::keycloak_app_name, | ||
| keycloak_realm => $foreman::keycloak_realm, | ||
| app_root => $foreman::app_root, | ||
| priority => $foreman::vhost_priority, | ||
| servername => $foreman::servername, | ||
| serveraliases => $foreman::serveraliases, | ||
| server_port => $foreman::server_port, | ||
| server_ssl_port => $foreman::server_ssl_port, | ||
| proxy_backend => "unix://${listen_socket}", | ||
| ssl => $foreman::ssl, | ||
| ssl_ca => $foreman::server_ssl_ca, | ||
| ssl_chain => $foreman::server_ssl_chain, | ||
| ssl_cert => $foreman::server_ssl_cert, | ||
| ssl_key => $foreman::server_ssl_key, | ||
| ssl_crl => $foreman::server_ssl_crl, | ||
| ssl_protocol => $foreman::server_ssl_protocol, | ||
| ssl_verify_client => $foreman::server_ssl_verify_client, | ||
| user => $foreman::user, | ||
| foreman_url => $foreman::foreman_url, | ||
| external_authentication => $external_foreman::authentication, | ||
| keycloak => $foreman::keycloak, | ||
| keycloak_app_name => $foreman::keycloak_app_name, | ||
| keycloak_realm => $foreman::keycloak_realm, | ||
| } | ||
|
|
||
| contain foreman::config::apache | ||
|
|
||
| $foreman_socket_override = template('foreman/foreman.socket-overrides.erb') | ||
|
|
||
| if $foreman::ipa_authentication { | ||
| if $facts['os']['selinux']['enabled'] { | ||
| selboolean { ['allow_httpd_mod_auth_pam', 'httpd_dbus_sssd']: | ||
| persistent => true, | ||
| value => 'on', | ||
| case $foreman::external_authentication { | ||
| 'ipa', 'ipa_with_api': { | ||
| if $facts['os']['selinux']['enabled'] { | ||
| selboolean { ['allow_httpd_mod_auth_pam', 'httpd_dbus_sssd']: | ||
| persistent => true, | ||
| value => 'on', | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if $foreman::ipa_manage_sssd { | ||
| service { 'sssd': | ||
| ensure => running, | ||
| enable => true, | ||
| require => Package['sssd-dbus'], | ||
| if $foreman::ipa_manage_sssd { | ||
| service { 'sssd': | ||
| ensure => running, | ||
| enable => true, | ||
| require => Package['sssd-dbus'], | ||
| } | ||
| } | ||
| } | ||
|
|
||
| file { "/etc/pam.d/${foreman::pam_service}": | ||
| ensure => file, | ||
| owner => root, | ||
| group => root, | ||
| mode => '0644', | ||
| content => template('foreman/pam_service.erb'), | ||
| } | ||
| file { "/etc/pam.d/${foreman::pam_service}": | ||
| ensure => file, | ||
| owner => root, | ||
| group => root, | ||
| mode => '0644', | ||
| content => template('foreman/pam_service.erb'), | ||
| } | ||
|
|
||
| $http_keytab = pick($foreman::http_keytab, "${apache::conf_dir}/http.keytab") | ||
| $http_keytab = pick($foreman::http_keytab, "${apache::conf_dir}/http.keytab") | ||
|
|
||
| exec { 'ipa-getkeytab': | ||
| command => "/bin/echo Get keytab \ | ||
| && KRB5CCNAME=KEYRING:session:get-http-service-keytab kinit -k \ | ||
| && KRB5CCNAME=KEYRING:session:get-http-service-keytab /usr/sbin/ipa-getkeytab -k ${http_keytab} -p HTTP/${facts['networking']['fqdn']} \ | ||
| && kdestroy -c KEYRING:session:get-http-service-keytab", | ||
| creates => $http_keytab, | ||
| } | ||
| -> file { $http_keytab: | ||
| ensure => file, | ||
| owner => $apache::user, | ||
| mode => '0600', | ||
| } | ||
| exec { 'ipa-getkeytab': | ||
| command => "/bin/echo Get keytab \ | ||
| && KRB5CCNAME=KEYRING:session:get-http-service-keytab kinit -k \ | ||
| && KRB5CCNAME=KEYRING:session:get-http-service-keytab /usr/sbin/ipa-getkeytab -k ${http_keytab} -p HTTP/${facts['networking']['fqdn']} \ | ||
| && kdestroy -c KEYRING:session:get-http-service-keytab", | ||
| creates => $http_keytab, | ||
| } | ||
| -> file { $http_keytab: | ||
| ensure => file, | ||
| owner => $apache::user, | ||
| mode => '0600', | ||
| } | ||
|
|
||
| $gssapi_local_name = bool2str($foreman::gssapi_local_name, 'On', 'Off') | ||
| $gssapi_local_name = bool2str($foreman::gssapi_local_name, 'On', 'Off') | ||
|
|
||
| foreman::config::apache::fragment { 'intercept_form_submit': | ||
| ssl_content => template('foreman/intercept_form_submit.conf.erb'), | ||
| } | ||
| foreman::config::apache::fragment { 'intercept_form_submit': | ||
| ssl_content => template('foreman/intercept_form_submit.conf.erb'), | ||
| } | ||
|
|
||
| foreman::config::apache::fragment { 'lookup_identity': | ||
| ssl_content => template('foreman/lookup_identity.conf.erb'), | ||
| } | ||
| foreman::config::apache::fragment { 'lookup_identity': | ||
| ssl_content => template('foreman/lookup_identity.conf.erb'), | ||
| } | ||
|
|
||
| foreman::config::apache::fragment { 'auth_gssapi': | ||
| ssl_content => template('foreman/auth_gssapi.conf.erb'), | ||
| } | ||
| foreman::config::apache::fragment { 'auth_gssapi': | ||
| ssl_content => template('foreman/auth_gssapi.conf.erb'), | ||
| } | ||
|
|
||
| foreman::config::apache::fragment { 'external_auth_api': | ||
| ssl_content => template('foreman/external_auth_api.conf.erb'), | ||
| } | ||
| foreman::config::apache::fragment { 'external_auth_api': | ||
| ssl_content => template('foreman/external_auth_api.conf.erb'), | ||
| } | ||
|
|
||
| if $foreman::ipa_manage_sssd { | ||
| $sssd = pick(fact('foreman_sssd'), {}) | ||
| $sssd_services = join(unique(pick($sssd['services'], []) + ['ifp']), ', ') | ||
| $sssd_ldap_user_extra_attrs = join(unique(pick($sssd['ldap_user_extra_attrs'], []) + ['email:mail', 'lastname:sn', 'firstname:givenname']), ', ') | ||
| $sssd_allowed_uids = join(unique(pick($sssd['allowed_uids'], []) + [$apache::user, 'root']), ', ') | ||
| $sssd_user_attributes = join(unique(pick($sssd['user_attributes'], []) + ['+email', '+firstname', '+lastname']), ', ') | ||
| $sssd_ifp_extra_attributes = [ | ||
| "set target[.=~regexp('domain/.*')]/ldap_user_extra_attrs '${sssd_ldap_user_extra_attrs}'", | ||
| "set target[.='sssd']/services '${sssd_services}'", | ||
| 'set target[.=\'ifp\'] \'ifp\'', | ||
| "set target[.='ifp']/allowed_uids '${sssd_allowed_uids}'", | ||
| "set target[.='ifp']/user_attributes '${sssd_user_attributes}'", | ||
| ] | ||
|
|
||
| $sssd_changes = $sssd_ifp_extra_attributes + ($foreman::ipa_sssd_default_realm ? { | ||
| undef => [], | ||
| default => ["set target[.='sssd']/default_domain_suffix '${$foreman::ipa_sssd_default_realm}'"], | ||
| }) | ||
|
|
||
| augeas { 'sssd-ifp-extra-attributes': | ||
| context => '/files/etc/sssd/sssd.conf', | ||
| changes => $sssd_changes, | ||
| notify => Service['sssd'], | ||
| if $foreman::ipa_manage_sssd { | ||
| $sssd = pick(fact('foreman_sssd'), {}) | ||
| $sssd_services = join(unique(pick($sssd['services'], []) + ['ifp']), ', ') | ||
| $sssd_ldap_user_extra_attrs = join(unique(pick($sssd['ldap_user_extra_attrs'], []) + ['email:mail', 'lastname:sn', 'firstname:givenname']), ', ') | ||
| $sssd_allowed_uids = join(unique(pick($sssd['allowed_uids'], []) + [$apache::user, 'root']), ', ') | ||
| $sssd_user_attributes = join(unique(pick($sssd['user_attributes'], []) + ['+email', '+firstname', '+lastname']), ', ') | ||
| $sssd_ifp_extra_attributes = [ | ||
| "set target[.=~regexp('domain/.*')]/ldap_user_extra_attrs '${sssd_ldap_user_extra_attrs}'", | ||
| "set target[.='sssd']/services '${sssd_services}'", | ||
| 'set target[.=\'ifp\'] \'ifp\'', | ||
| "set target[.='ifp']/allowed_uids '${sssd_allowed_uids}'", | ||
| "set target[.='ifp']/user_attributes '${sssd_user_attributes}'", | ||
| ] | ||
|
|
||
| $sssd_changes = $sssd_ifp_extra_attributes + ($foreman::ipa_sssd_default_realm ? { | ||
| undef => [], | ||
| default => ["set target[.='sssd']/default_domain_suffix '${$foreman::ipa_sssd_default_realm}'"], | ||
| }) | ||
|
|
||
| augeas { 'sssd-ifp-extra-attributes': | ||
| context => '/files/etc/sssd/sssd.conf', | ||
| changes => $sssd_changes, | ||
| notify => Service['sssd'], | ||
| } | ||
| } | ||
|
|
||
| foreman::settings_fragment { 'authorize_login_delegation.yaml': | ||
| content => template('foreman/settings-external-auth.yaml.erb'), | ||
| order => '02', | ||
| } | ||
| } | ||
|
|
||
| foreman::settings_fragment { 'authorize_login_delegation.yaml': | ||
| content => template('foreman/settings-external-auth.yaml.erb'), | ||
| order => '02', | ||
| foreman::settings_fragment { 'authorize_login_delegation_api.yaml': | ||
| content => template('foreman/settings-external-auth-api.yaml.erb'), | ||
| order => '03', | ||
| } | ||
| } | ||
| 'keycloak': { | ||
| $foreman_socket_override = undef | ||
|
|
||
| unless $foreman::ssl { | ||
| fail('Keycloak requires HTTPS') | ||
| } | ||
|
|
||
| foreman::settings_fragment { 'authorize_login_delegation_api.yaml': | ||
| content => template('foreman/settings-external-auth-api.yaml.erb'), | ||
| order => '03', | ||
| foreman::settings_fragment { 'authorize_login_delegation.yaml': | ||
| content => template('foreman/settings-external-auth.yaml.erb'), | ||
| order => '02', | ||
| } | ||
|
|
||
| # TODO: parameter | ||
| $keycloak_url = 'https://keycloak.example.com' | ||
| $oidc_issuer = "${keycloak_url}/auth/realms/${foreman::keycloak_realm}" | ||
| $keycloak_settings = { | ||
| ':login_delegation_logout_url' => "${foreman::foreman_url}/users/extlogout", | ||
| # TODO: parameters or obtain from ${oidc_issuer}/.well-known/openid-configuration | ||
| ':oidc_algorithm' => 'RS256', | ||
| ':oidc_audience' => ["${foreman::servername}-foreman-openidc"], | ||
| ':oidc_issuer' => $oidc_issuer, | ||
| ':oidc_jwks_url' => "${oidc_issuer}/protocol/openid-connect/certs", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would also parameterize
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was still wondering how to best deal with this. IMHO this is also covered by the TODO above it that this isn't the final form. One thought I had was to have Note that the OIDC standard says there should be a
In particular, it should have the
That only leaves Now I wonder what should read these values. Should we modify Foreman itself to do this? That feels more correct than having the installer retrieve these values and store it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
With keycloak being "just" a preset for the generic oidc one?
Would that mean not relying on apache's mod_auth_oidc at all?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, something like that.
Disclaimer: I only just looked this up. It probably still should depend on mod_auth_oidc because we would get a good integration with various providers (https://github.com/OpenIDC/mod_auth_openidc?tab=readme-ov-file#quickstart-for-specific-providers) But I was wondering how we could get rid of those settings or at least minimize what we need to manage. https://github.com/OpenIDC/mod_auth_openidc/wiki#12-how-can-i-customize-the-idp-discovery-or-initial-login-page mentions reading the mod_auth_oidc metadata cache directly, which feels very ugly. I also see mentions that mod_auth_oidc sends This would make it a lot more like the regular external authentication (like with LDAP) where we pass HTTP headers with the values. |
||
| } | ||
|
|
||
| foreman::settings_fragment { 'authorize_login_delegation-keycloak.yaml': | ||
| # TODO: does this include the document marker? | ||
| content => stdlib::to_yaml($keycloak_settings), | ||
| order => '04', | ||
| } | ||
| } | ||
| default: { | ||
| $foreman_socket_override = undef | ||
| } | ||
| } | ||
| } else { | ||
| $foreman_socket_override = undef | ||
| } | ||
|
|
||
| systemd::dropin_file { 'foreman-socket': | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would parameterize
oidc_audienceso that the value can be overwritten. This allows people who have a certain naming standards for their keycloak clients to keep using them.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, which is why there's a TODO above it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies! Completely over looked those