Configure sssd for subcloud to access central openldap

This change updated sssd and ldap sysinv puppet plugin to generate
proper hieradata for puppet to create sssd configuration and
openldap clients' configuration (ldap.conf, ldapscripts.conf) for
subcloud. With these configuration, sssd and openldap clients on
subcloud can access secure openldap running on System Controller.

Test Plan:
PASS: DC system controller and subcloud deployment.
PASS: On subcloud, verify openldap users are accessible by
      ldapsearch -xH ldaps://<System Controller mgmt floating IP>
      -b "ou=People,dc=cgcs,dc=local"
PASS: On subcloud, verify openldap users are accessible by
      ldapfinger
PASS: On subcloud, verify default openldap users (admin, operator)
      can login on console.
PASS: On subcloud, verify openldap users are cached by:
      getent passwd <openldap username>
PASS: On system controller, create new openldap user, verify the new
      user can login to subcloud on console and by ssh.
PASS: On system controller, verify openldap users are cached by:
      getent passwd <openldap username>
PASS: AIO-SX deploymnet, verify bootstrap and unlock succeeds.
PASS: AIO-SX system lock/unlock, verify system boots up into normal
      condition, and openldap functions as expected.

Story: 2009834
Task: 46600
Depends-On: https://review.opendev.org/c/starlingx/ansible-playbooks/+/861782
Signed-off-by: Andy Ning <andy.ning@windriver.com>
Change-Id: I831aef7896bf16d67cef9dee7d4590c393fd1792
This commit is contained in:
Andy Ning 2022-09-22 13:21:24 -04:00
parent 37bdbc0342
commit 2b5e706fe3
3 changed files with 87 additions and 19 deletions

View File

@ -3350,6 +3350,36 @@ def get_certificate_from_secret(secret_name, secret_ns):
return tls_crt, tls_key
def get_ca_certificate_from_opaque_secret(secret_name, secret_ns):
"""
Get a CA certificate from a k8s opaque secret (tls secret requires
both tls.crt and tls.key present, a CA certificate alone can be stored
as an opaque secret ca.crt)
:param secret_name: the name of the secret
:param secret_ns: the namespace of the secret
:return: ca_crt: the CA certificate.
raise Exception for kubernetes data errors
"""
kube = kubernetes.KubeOperator()
secret = kube.kube_get_secret(secret_name, secret_ns)
if not hasattr(secret, 'data'):
raise Exception('Invalid secret %s\\%s' % (secret_ns, secret_name))
data = secret.data
if 'ca.crt' not in data:
raise Exception('Invalid CA certificate data from secret %s\\%s' %
(secret_ns, secret_name))
try:
ca_crt = base64.decode_as_text(data['ca.crt'])
except TypeError:
raise Exception('CA certificate secret data is invalid %s\\%s' %
(secret_ns, secret_name))
return ca_crt
def verify_ca_crt(crt):
cmd = ['openssl', 'verify']
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE,

View File

@ -52,24 +52,37 @@ class LdapPuppet(base.BasePuppet):
def get_secure_system_config(self):
config = {}
is_subcloud = \
self._distributed_cloud_role() == constants.DISTRIBUTED_CLOUD_ROLE_SUBCLOUD
# Retrieve openldap CA certificate, and server certificate/key
if self._is_openldap_certificate_created() and not is_subcloud:
ldap_ca_cert, _ = utils.get_certificate_from_secret(
constants.OPENLDAP_CA_CERT_SECRET_NAME,
constants.CERT_NAMESPACE_PLATFORM_CA_CERTS)
# Retrieve openldap CA certificate, and server certificate/key.
# For subcloud, only CA certificate is needed.
if self._is_openldap_certificate_created():
is_subcloud = \
self._distributed_cloud_role() == \
constants.DISTRIBUTED_CLOUD_ROLE_SUBCLOUD
ldap_cert, ldap_key = utils.get_certificate_from_secret(
constants.OPENLDAP_CERT_SECRET_NAME,
constants.CERT_NAMESPACE_PLATFORM_CERTS)
if is_subcloud:
ldap_ca_cert = utils.get_ca_certificate_from_opaque_secret(
constants.OPENLDAP_CA_CERT_SECRET_NAME,
constants.CERT_NAMESPACE_PLATFORM_CA_CERTS)
config.update({
'platform::ldap::params::secure_cert': ldap_cert,
'platform::ldap::params::secure_key': ldap_key,
'platform::ldap::params::ca_cert': ldap_ca_cert,
})
config.update({
'platform::ldap::params::ca_cert': ldap_ca_cert,
})
else:
ldap_ca_cert, _ = utils.get_certificate_from_secret(
constants.OPENLDAP_CA_CERT_SECRET_NAME,
constants.CERT_NAMESPACE_PLATFORM_CA_CERTS)
ldap_cert, ldap_key = utils.get_certificate_from_secret(
constants.OPENLDAP_CERT_SECRET_NAME,
constants.CERT_NAMESPACE_PLATFORM_CERTS)
config.update({
'platform::ldap::params::secure_cert': ldap_cert,
'platform::ldap::params::secure_key': ldap_key,
'platform::ldap::params::ca_cert': ldap_ca_cert,
})
return config

View File

@ -154,6 +154,7 @@ class SssdPuppet(base.BasePuppet):
def _get_local_domain(self):
binding_pass = self._get_keyring_password(self.SERVICE_NAME,
self.SERVICE_USER)
ldap_uri = self._get_local_domain_uri()
# sssd supports the debug levels (from sssd.conf manual page):
# 0, 0x0010: Fatal failures. Anything that would prevent SSSD
@ -178,6 +179,8 @@ class SssdPuppet(base.BasePuppet):
#
# Debug level: 0x0270, includes fatal failures, critical failures,
# serious failures and function data.
# Default is to bind anonymously.
domain_parameters = {
'cache_credentials': 'true',
'debug_level': '0x0270',
@ -187,14 +190,21 @@ class SssdPuppet(base.BasePuppet):
'ldap_search_base': 'dc=cgcs,dc=local',
'ldap_user_home_directory': '/home/$cn',
'ldap_user_shell': '/bin/bash',
'ldap_uri': 'ldaps://controller/',
'ldap_uri': ldap_uri,
'ldap_tls_cacert': '/etc/ssl/certs/ca-certificates.crt',
'ldap_default_bind_dn': 'CN=ldapadmin,DC=cgcs,DC=local',
'ldap_default_authtok_type': 'password',
'ldap_default_authtok': binding_pass,
'fallback_homedir': '/home/%u',
}
# bind to 'CN=ldapadmin,DC=cgcs,DC=local' using password if
# this is not a DC Subcloud.
if self._distributed_cloud_role() != \
constants.DISTRIBUTED_CLOUD_ROLE_SUBCLOUD:
domain_parameters.update({
'ldap_default_bind_dn': 'CN=ldapadmin,DC=cgcs,DC=local',
'ldap_default_authtok_type': 'password',
'ldap_default_authtok': binding_pass,
})
return domain_parameters
def _get_ldap_domain(self, domain):
@ -290,3 +300,18 @@ class SssdPuppet(base.BasePuppet):
}
return pam_parameters
def _get_local_domain_uri(self):
ldapserver_host = constants.CONTROLLER
if self._distributed_cloud_role() == \
constants.DISTRIBUTED_CLOUD_ROLE_SUBCLOUD:
sys_controller_network = self.dbapi.network_get_by_type(
constants.NETWORK_TYPE_SYSTEM_CONTROLLER)
sys_controller_network_addr_pool = self.dbapi.address_pool_get(
sys_controller_network.pool_uuid)
ldapserver_addr = sys_controller_network_addr_pool.floating_address
ldapserver_host = self._format_url_address(ldapserver_addr)
ldapserver_uri = 'ldaps://%s' % ldapserver_host
return ldapserver_uri