示例#1
0
    def remove_xcluster_root_cert(self, ssh_options, replication_config_name,
                                  producer_certs_dir):
        def check_rm_result(rm_result):
            if rm_result.exited and rm_result.stderr.find(
                    "No such file or directory") == -1:
                raise YBOpsRuntimeError(
                    "Remote shell command 'rm' failed with "
                    "return code '{}' and error '{}'".format(
                        rm_result.stderr.encode('utf-8'), rm_result.exited))

        if producer_certs_dir is None:
            producer_certs_dir = self.PRODUCER_CERTS_DIR_NAME
        remote_shell = RemoteShell(ssh_options)
        node_ip = ssh_options["ssh_host"]
        src_root_cert_dir_path = os.path.join(producer_certs_dir,
                                              replication_config_name)
        src_root_cert_path = os.path.join(src_root_cert_dir_path,
                                          self.ROOT_CERT_NAME)
        logging.info(
            "Removing server cert located at {} from server {}.".format(
                src_root_cert_dir_path, node_ip))

        remote_shell.run_command(
            'chmod -f 666 {}/* || true'.format(src_root_cert_dir_path))
        result = remote_shell.run_command_raw('rm ' + src_root_cert_path)
        check_rm_result(result)
        # Remove the directory only if it is empty.
        result = remote_shell.run_command_raw('rm -d ' +
                                              src_root_cert_dir_path)
        check_rm_result(result)
        # No need to check the result of this command.
        remote_shell.run_command_raw('rm -d ' + producer_certs_dir)
    def verify_certs(self,
                     root_crt_path,
                     node_crt_path,
                     ssh_options,
                     verify_hostname=False):
        remote_shell = RemoteShell(ssh_options)

        try:
            remote_shell.run_command('which openssl')
        except YBOpsRuntimeError:
            logging.debug(
                "Openssl not found, skipping certificate verification.")
            return

        # Verify if the node cert is not expired
        validity_verify = remote_shell.run_command_raw(
            "openssl x509 -noout -checkend 86400 -in {}".format(node_crt_path))
        if validity_verify.exited == 1:
            raise YBOpsRuntimeError(
                "Node cert: {} is expired or will expire in one day.".format(
                    node_crt_path))

        # Verify if node cert has valid signature
        signature_verify = remote_shell.run_command_raw(
            "openssl verify -CAfile {} {} | egrep error".format(
                root_crt_path, node_crt_path))
        if signature_verify.exited != 1:
            raise YBOpsRuntimeError(
                "Node cert: {} is not signed by the provided root cert: {}.".
                format(node_crt_path, root_crt_path))

        if verify_hostname:
            self.__verify_certs_hostname(node_crt_path, ssh_options)
示例#3
0
    def verify_certs(self,
                     root_crt_path,
                     node_crt_path,
                     ssh_options,
                     verify_hostname=False):
        remote_shell = RemoteShell(ssh_options)
        # Verify that both cert are present in FS and have read rights
        root_file_verify = remote_shell.run_command_raw(
            "test -r {}".format(root_crt_path))
        if root_file_verify.exited == 1:
            raise YBOpsRuntimeError(
                "Root cert: {} is absent or is not readable.".format(
                    root_crt_path))
        node_file_verify = remote_shell.run_command_raw(
            "test -r {}".format(node_crt_path))
        if node_file_verify.exited == 1:
            raise YBOpsRuntimeError(
                "Node cert: {} is absent or is not readable.".format(
                    node_crt_path))
        try:
            remote_shell.run_command('which openssl')
        except YBOpsRuntimeError:
            logging.debug(
                "Openssl not found, skipping certificate verification.")
            return

        # Verify if root and node certs are valid
        cert_verify = remote_shell.run_command_raw(
            ("openssl crl2pkcs7 -nocrl -certfile {} -certfile {} "
             "| openssl pkcs7 -print_certs -text -noout").format(
                 root_crt_path, node_crt_path))
        if cert_verify.exited == 1:
            raise YBOpsRuntimeError(
                "Provided certs ({}, {}) are not valid.".format(
                    root_crt_path, node_crt_path))

        # Verify if the node cert is not expired
        validity_verify = remote_shell.run_command_raw(
            "openssl x509 -noout -checkend 86400 -in {}".format(node_crt_path))
        if validity_verify.exited == 1:
            raise YBOpsRuntimeError(
                "Node cert: {} is expired or will expire in one day.".format(
                    node_crt_path))

        # Verify if node cert has valid signature
        signature_verify = remote_shell.run_command_raw(
            "openssl verify -CAfile {} {} | egrep error".format(
                root_crt_path, node_crt_path))
        if signature_verify.exited != 1:
            raise YBOpsRuntimeError(
                "Node cert: {} is not signed by the provided root cert: {}.".
                format(node_crt_path, root_crt_path))

        if verify_hostname:
            self.__verify_certs_hostname(node_crt_path, ssh_options)
示例#4
0
 def remove_old_root_cert(self, ssh_options, certs_dir):
     remote_shell = RemoteShell(ssh_options)
     yb_root_cert_path = os.path.join(certs_dir, self.ROOT_CERT_NAME)
     yb_root_cert_new_path = os.path.join(certs_dir, self.ROOT_CERT_NEW_NAME)
     # Check if ca_new.crt is present, it will be present if
     # APPEND_NEW_ROOT_CERT action was performed before
     file_verify = remote_shell.run_command_raw(
         "test -f '{}'".format(yb_root_cert_new_path))
     # No action needed if ca_new.crt is not present
     if not file_verify.exited:
         # Give write permissions to cert directory
         remote_shell.run_command(
             'chmod -f 666 {}/* || true'.format(certs_dir))
         # Remove ca.crt and rename ca_new.crt to ca.crt
         remote_shell.run_command("mv '{}' '{}'".format(
             yb_root_cert_new_path, yb_root_cert_path))
         # Reset the write permissions
         remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))
示例#5
0
    def copy_server_certs(self, ssh_options, root_cert_path, server_cert_path,
                          server_key_path, certs_location, certs_dir,
                          rotate_certs, skip_cert_validation):
        remote_shell = RemoteShell(ssh_options)
        node_ip = ssh_options["ssh_host"]
        cert_file = 'node.{}.crt'.format(node_ip)
        key_file = 'node.{}.key'.format(node_ip)
        yb_root_cert_path = os.path.join(certs_dir, self.ROOT_CERT_NAME)
        yb_server_cert_path = os.path.join(certs_dir, cert_file)
        yb_server_key_path = os.path.join(certs_dir, key_file)

        copy_root = True
        if rotate_certs:
            root_cert_command = remote_shell.run_command_raw(
                "cat '{}'".format(yb_root_cert_path))
            # In case of tls toggle root cert might not be present
            if not root_cert_command.exited:
                root_cert = root_cert_command.stdout
                root_cert_new = None
                if certs_location == self.CERT_LOCATION_NODE:
                    root_cert_new = remote_shell.run_command(
                        "cat '{}'".format(root_cert_path)).stdout
                if certs_location == self.CERT_LOCATION_PLATFORM:
                    with open(root_cert_path) as file:
                        root_cert_new = file.read()
                if root_cert is not None and root_cert_new is not None:
                    compare_result = self.compare_certs(
                        root_cert_new, root_cert)
                    if compare_result == 0 or compare_result == 1:
                        # Don't copy root certs if the new root cert is
                        # same or subset of the existing root cert
                        copy_root = False
                else:
                    raise YBOpsRuntimeError(
                        "Unable to fetch the certificate {}".format(
                            root_cert_path))

        logging.info("Moving server certs located at {}, {}, {}.".format(
            root_cert_path, server_cert_path, server_key_path))

        remote_shell.run_command('mkdir -p ' + certs_dir)
        # Give write permissions. If the command fails, ignore.
        remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_dir))

        if certs_location == self.CERT_LOCATION_NODE:
            if skip_cert_validation == 'ALL':
                logging.info(
                    "Skipping all validations for certs for node {}".format(
                        node_ip))
            else:
                verify_hostname = True
                if skip_cert_validation == 'HOSTNAME':
                    logging.info(
                        "Skipping host name validation for certs for node {}".
                        format(node_ip))
                    verify_hostname = False
                self.verify_certs(root_cert_path, server_cert_path,
                                  ssh_options, verify_hostname)
            if copy_root:
                remote_shell.run_command("cp '{}' '{}'".format(
                    root_cert_path, yb_root_cert_path))
            remote_shell.run_command("cp '{}' '{}'".format(
                server_cert_path, yb_server_cert_path))
            remote_shell.run_command("cp '{}' '{}'".format(
                server_key_path, yb_server_key_path))
        if certs_location == self.CERT_LOCATION_PLATFORM:
            if copy_root:
                remote_shell.put_file(root_cert_path, yb_root_cert_path)
            remote_shell.put_file(server_cert_path, yb_server_cert_path)
            remote_shell.put_file(server_key_path, yb_server_key_path)

        # Reset the write permission as a sanity check.
        remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))