Fix issues when switch between HTTP and HTTPS

Issues:
1- wrs-ssl.rpm installs a key file that is expected to be modified by
user. Updating, patching or removing this RPM can potentially change the
user file.
2- Going back to HTTP after going to HTTPS fails
3- Going back to HTTPS again after going back to HTTP, access fails
until a new key is installed
4- key files under /etc/ssl/private are required to be removed when
going back to HTTP
5- sysinv creates backup copies of key (.pem) files

Fixes:
1- renaming the self signed certificate installed by wrs-ssl.rpm so
that:
- the key file is not installed in place
- the self-signed certificate remains available to reinstall when going
back and forth between HTTP and HTTPS
2- updating the lighttpd.conf manifest so that the daemon does not look
for pem files in HTTP mode
3- modifying sysinv so that the pem files are removed from both
controllers when going back to HTTP
4- modifying sysinv so that the tool does not create a backup copy of
the pem file.

Story: 2002894
Task: 22857

Change-Id: Ibd0958e910a8914a3c65d3504ff82ebbef24c6c5
Signed-off-by: Jack Ding <jack.ding@windriver.com>
This commit is contained in:
Paul-Emile Element 2018-06-12 14:32:25 -04:00 committed by Jack Ding
parent 5f6ba4f658
commit 885a23ef09
4 changed files with 80 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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