From 49df34a4f4284a87c303ea7ccaf460b82d5a8e67 Mon Sep 17 00:00:00 2001 From: Leonardo Mendes Date: Wed, 3 Apr 2024 10:39:13 -0300 Subject: [PATCH] Add Intermediate CA support to IPsec configuration The current implementation of IPsec configuration by IPsec server/client supports Root CA only. This commit adds support for Intermediate CA. Now, IPSec Auth Server send both certificates to IPSec Auth client to store. If it's a self-signed certificate, the same certificate is send as Root CA. Test plan: PASS: In a DX system with available enabled active status with IPsec server being executed from controller-0 and a self-signed CA installed. Run "ipsec-client pxecontroller --opcode 1" in controller-1. Observe that 4 CAs certificates are created, but they are the same certificate. Observe that a security association is established between the hosts via "swanctl --list-sas" command. PASS: In a DX system with available enabled active status with IPsec server being executed from controller-0 and a self-signed CA installed. Run "ipsec-client pxecontroller --opcode 2" in controller-1. Observe the previously created CertificateRequest was deleted and generated a new one for controller-1's node. The new certificate is sent to IPsec Client with Root and Intermediate CA, which is the same, to be stored and the swanctl rekey command executed successfully. PASS: In a DX system with available enabled active status with IPsec server being executed from controller-0 and an intermediate CA installed. Run "ipsec-client pxecontroller --opcode 1" in worker-0. Observe that 4 CAs certificates are created, including Root and Intermediate CA. Observe that a security association is established between the hosts via "swanctl --list-sas" command. PASS: In a DX system with available enabled active status with IPsec server being executed from controller-0 and an Intermediate CA installed. Run "ipsec-client pxecontroller --opcode 2" in worker-0. Observe the previously created CertificateRequest was deleted and generated a new one for worker-0's node. The new certificate is sent to IPsec Client with Root and Intermediate CA to be stored and the swanctl rekey command executed successfully. PASS: In a DX system, simulate the IPsec cert is about to expire, run the script, verify IPsec cert, private key and trusted CA cert are renewed. Story: 2010940 Task: 49825 Change-Id: I25c973350c4f460233a4e6e5ddda8366b948d120 Signed-off-by: Leonardo Mendes --- sysinv/sysinv/sysinv/sysinv/ipsec_auth/client/client.py | 3 +++ sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/constants.py | 4 ++++ sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py | 5 ++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/client/client.py b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/client/client.py index 64fdd1ba4b..c89ab36114 100644 --- a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/client/client.py +++ b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/client/client.py @@ -144,6 +144,7 @@ class Client(object): self.ots_token = msg['token'] self.hostname = msg['hostname'] key = base64.b64decode(msg['pub_key']) + root_ca_cert = base64.b64decode(msg['root_ca_cert']) ca_cert = base64.b64decode(msg['ca_cert']) digest = base64.b64decode(msg['hash']) @@ -154,8 +155,10 @@ class Client(object): return False utils.save_data(constants.TMP_PUK1_FILE, key) + utils.save_data(constants.TRUSTED_ROOT_CA_CERT_1_PATH, root_ca_cert) utils.save_data(constants.TRUSTED_CA_CERT_1_PATH, ca_cert) if self.op_code == constants.OP_CODE_INITIAL_AUTH: + utils.save_data(constants.TRUSTED_ROOT_CA_CERT_0_PATH, root_ca_cert) utils.save_data(constants.TRUSTED_CA_CERT_0_PATH, ca_cert) if self.state == State.STAGE_4: diff --git a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/constants.py b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/constants.py index abc6a5b65d..629aae1165 100644 --- a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/constants.py @@ -29,10 +29,14 @@ SECRET_SYSTEM_LOCAL_CA = 'system-local-ca' # the last tls certificate associated with system-local-ca, # while system-local-ca-1.crt file is the current certificate # associated with system-local-ca. +TRUSTED_ROOT_CA_CERT_FILE_0 = 'system-root-ca-0.crt' +TRUSTED_ROOT_CA_CERT_FILE_1 = 'system-root-ca-1.crt' TRUSTED_CA_CERT_FILE_0 = 'system-local-ca-0.crt' TRUSTED_CA_CERT_FILE_1 = 'system-local-ca-1.crt' TRUSTED_CA_CERT_FILES = TRUSTED_CA_CERT_FILE_0 + ',' + TRUSTED_CA_CERT_FILE_1 TRUSTED_CA_CERT_DIR = '/etc/swanctl/x509ca/' +TRUSTED_ROOT_CA_CERT_0_PATH = TRUSTED_CA_CERT_DIR + TRUSTED_ROOT_CA_CERT_FILE_0 +TRUSTED_ROOT_CA_CERT_1_PATH = TRUSTED_CA_CERT_DIR + TRUSTED_ROOT_CA_CERT_FILE_1 TRUSTED_CA_CERT_0_PATH = TRUSTED_CA_CERT_DIR + TRUSTED_CA_CERT_FILE_0 TRUSTED_CA_CERT_1_PATH = TRUSTED_CA_CERT_DIR + TRUSTED_CA_CERT_FILE_1 diff --git a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py index bda8020813..ebcc9459c7 100644 --- a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py +++ b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py @@ -88,6 +88,7 @@ class IPsecConnection(object): kubeapi = kubernetes.KubeOperator() CA_KEY = 'tls.key' CA_CRT = 'tls.crt' + ROOT_CA_CRT = 'ca.crt' def __init__(self): self.op_code = None @@ -102,6 +103,7 @@ class IPsecConnection(object): self.ots_token = Token() self.ca_key = self._get_system_local_ca_secret_info(self.CA_KEY) self.ca_crt = self._get_system_local_ca_secret_info(self.CA_CRT) + self.root_ca_crt = self._get_system_local_ca_secret_info(self.ROOT_CA_CRT) self.state = State.STAGE_1 def handle_messaging(self, sock, sel): @@ -144,7 +146,7 @@ class IPsecConnection(object): data = json.loads(recv_message.decode('utf-8')) payload = {} - if not self.ca_key or not self.ca_crt: + if not self.ca_key or not self.ca_crt or not self.root_ca_crt: raise ValueError('Failed to retrieve system-local-ca information') if self.state == State.STAGE_2: @@ -169,6 +171,7 @@ class IPsecConnection(object): payload["hostname"] = self.hostname payload["pub_key"] = pub_key.decode("utf-8") payload["ca_cert"] = self.ca_crt.decode("utf-8") + payload["root_ca_cert"] = self.root_ca_crt.decode("utf-8") payload["hash"] = hash_payload.decode("utf-8") LOG.info("Sending IPSec Auth Response")