diff --git a/puppet-manifests/src/modules/openstack/templates/lighttpd.conf.erb b/puppet-manifests/src/modules/openstack/templates/lighttpd.conf.erb index 6be64f0513..62f2be6265 100755 --- a/puppet-manifests/src/modules/openstack/templates/lighttpd.conf.erb +++ b/puppet-manifests/src/modules/openstack/templates/lighttpd.conf.erb @@ -245,6 +245,7 @@ $HTTP["url"] !~ "^/(rel-[^/]*|feed|updates|static)/" { # ".cgi" => "/usr/bin/perl" ) # +<% if @enable_https %> #### SSL engine $SERVER["socket"] == ":443" { ssl.engine = "enable" @@ -263,6 +264,11 @@ $SERVER["socket"] == "[::]:443" { ssl.use-sslv3 = "disable" ssl.cipher-list = "ALL:!aNULL:!eNULL:!EXPORT:!TLSv1:!DES:!MD5:!PSK:!RC4:!EDH-RSA-DES-CBC3-SHA:!EDH-DSS-DES-CBC3-SHA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA:!ECDHE-RSA-DES-CBC3-SHA:!ECDHE-RSA-AES128-SHA:!ECDHE-RSA-AES256-SHA:!DES-CBC3-SHA:!AES128-SHA:!AES256-SHA:!DHE-DSS-AES128-SHA:!DHE-DSS-AES256-SHA:!CAMELLIA128-SHA:!CAMELLIA256-SHA:!DHE-DSS-CAMELLIA128-SHA:!DHE-DSS-CAMELLIA256-SHA:!DHE-RSA-CAMELLIA128-SHA:!DHE-RSA-CAMELLIA256-SHA:!ECDHE-ECDSA-DES-CBC3-SHA:!ECDHE-ECDSA-AES128-SHA:!ECDHE-ECDSA-AES256-SHA" } +<% else %> +### +# HTTPS not enabled +### +<% end %> #### status module #status.status-url = "/server-status" diff --git a/sysinv/sysinv/sysinv/sysinv/agent/manager.py b/sysinv/sysinv/sysinv/sysinv/agent/manager.py index e8263ffb3e..1c1a91331d 100644 --- a/sysinv/sysinv/sysinv/sysinv/agent/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/agent/manager.py @@ -1290,6 +1290,7 @@ class AgentManager(service.PeriodicService): self._ihost_personality)) permissions = iconfig_dict.get('permissions') + nobackup = iconfig_dict.get('nobackup') if not permissions: permissions = constants.CONFIG_FILE_PERMISSION_DEFAULT @@ -1311,8 +1312,9 @@ class AgentManager(service.PeriodicService): iconfig_dict['file_content'])) if os.path.isfile(file_name): - if not os.path.isfile(file_name_sysinv): - shutil.copy2(file_name, file_name_sysinv) + if not nobackup: + if not os.path.isfile(file_name_sysinv): + shutil.copy2(file_name, file_name_sysinv) # Remove resolv.conf file. It may have been created as a # symlink by the volatile configuration scripts. @@ -1324,9 +1326,10 @@ class AgentManager(service.PeriodicService): f_content = file_content os.umask(0) - with os.fdopen(os.open(file_name, os.O_CREAT | os.O_WRONLY, + if f_content is not None: + with os.fdopen(os.open(file_name, os.O_CREAT | os.O_WRONLY, permissions), 'wb') as f: - f.write(f_content) + f.write(f_content) self._update_config_applied(iconfig_uuid) self._report_config_applied(context) diff --git a/sysinv/sysinv/sysinv/sysinv/common/constants.py b/sysinv/sysinv/sysinv/sysinv/common/constants.py index 53c6070ec2..c14148dc37 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/common/constants.py @@ -1142,11 +1142,14 @@ SYSINV_GRPNAME = "sysinv" CERT_TYPE_SSL = 'ssl' SSL_CERT_DIR = "/etc/ssl/private/" SSL_CERT_FILE = "server-cert.pem" # pem with PK and cert +# self signed pem to get started +SSL_CERT_SS_FILE = "self-signed-server-cert.pem" CERT_MURANO_DIR = "/etc/ssl/private/murano-rabbit" CERT_FILE = "cert.pem" CERT_KEY_FILE = "key.pem" CERT_CA_FILE = "ca-cert.pem" SSL_PEM_FILE = os.path.join(SSL_CERT_DIR, SSL_CERT_FILE) +SSL_PEM_SS_FILE = os.path.join(SSL_CERT_DIR, SSL_CERT_SS_FILE) SSL_PEM_FILE_SHARED = os.path.join(tsc.CONFIG_PATH, SSL_CERT_FILE) MURANO_CERT_KEY_FILE = os.path.join(CERT_MURANO_DIR, CERT_KEY_FILE) diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py index 72f613cd2f..8ca797550f 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py @@ -5199,7 +5199,10 @@ class ConductorManager(service.PeriodicService): :param context: an admin context. """ personalities = [constants.CONTROLLER] - config_uuid = self._config_update_hosts(context, personalities) + system = self.dbapi.isystem_get_one() + + if system.capabilities.get('https_enabled', False): + self._config_selfsigned_certificate(context) config_dict = { "personalities": personalities, @@ -5209,12 +5212,13 @@ class ConductorManager(service.PeriodicService): 'openstack::nova::api::runtime', 'openstack::heat::engine::runtime'] } + + config_uuid = self._config_update_hosts(context, personalities) self._config_apply_runtime_manifest(context, config_uuid, config_dict) - system = self.dbapi.isystem_get_one() if not system.capabilities.get('https_enabled', False): self._destroy_tpm_config(context) - self._destroy_certificates() + self._destroy_certificates(context) def update_oam_config(self, context): """Update the OAM network configuration""" @@ -9573,7 +9577,7 @@ class ConductorManager(service.PeriodicService): self._config_apply_runtime_manifest(context, config_uuid, config_dict) - def _destroy_certificates(self): + def _destroy_certificates(self, context): """Delete certificates.""" LOG.info("_destroy_certificates clear ssl/tpm certificates") @@ -9583,6 +9587,18 @@ class ConductorManager(service.PeriodicService): constants.CERT_MODE_SSL, constants.CERT_MODE_TPM]: self.dbapi.certificate_destroy(certificate.uuid) + personalities = [constants.CONTROLLER] + + config_uuid = self._config_update_hosts(context, personalities) + config_dict = { + 'personalities': personalities, + 'file_names': [constants.SSL_PEM_FILE], + 'file_content': None, + 'permissions': constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY, + 'nobackup': True, + } + self._config_update_file(context, config_uuid, config_dict) + def _destroy_tpm_config(self, context, tpm_obj=None): """Delete a tpmconfig.""" @@ -9771,6 +9787,7 @@ class ConductorManager(service.PeriodicService): 'personalities': personalities, 'file_names': [constants.SSL_PEM_FILE], 'file_content': file_content, + 'nobackup': True, 'permissions': constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY, } self._config_update_file(context, config_uuid, config_dict) @@ -9857,3 +9874,46 @@ class ConductorManager(service.PeriodicService): raise exception.SysinvException(_(msg)) return signature + + def _config_selfsigned_certificate(self, context): + """ + This code is invoked when https is enabled + to install a self signed certificate to get started + + :param context: an admin context. + + """ + + mode = constants.CERT_MODE_SSL + passphrase = None + certificate_file = constants.SSL_PEM_SS_FILE + + with open(certificate_file) as pemfile: + pem_contents = pemfile.read() + + LOG.info("_config_selfsigned_certificate mode=%s file=%s" % (mode, certificate_file)) + + private_bytes, public_bytes, signature = \ + self._extract_keys_from_pem(mode, pem_contents, passphrase) + + personalities = [constants.CONTROLLER] + + config_uuid = self._config_update_hosts(context, personalities) + file_content = private_bytes + public_bytes + config_dict = { + 'personalities': personalities, + 'file_names': [constants.SSL_PEM_FILE], + 'file_content': file_content, + 'permissions': constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY, + 'nobackup': True, + } + self._config_update_file(context, config_uuid, config_dict) + + # copy the certificate to shared directory + with os.fdopen(os.open(constants.SSL_PEM_FILE_SHARED, + os.O_CREAT | os.O_WRONLY, + constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY), + 'wb') as f: + f.write(file_content) + + return signature