Exemplo n.º 1
0
def _InitGanetiServerSetup(master_name, cfg):
    """Setup the necessary configuration for the initial node daemon.

  This creates the nodepass file containing the shared password for
  the cluster, generates the SSL certificate and starts the node daemon.

  @type master_name: str
  @param master_name: Name of the master node
  @type cfg: ConfigWriter
  @param cfg: the configuration writer

  """
    # Generate cluster secrets
    GenerateClusterCrypto(True, False, False, False, False, False, master_name)

    # Add the master's SSL certificate digest to the configuration.
    master_uuid = cfg.GetMasterNode()
    master_digest = utils.GetCertificateDigest()
    cfg.AddNodeToCandidateCerts(master_uuid, master_digest)
    cfg.Update(cfg.GetClusterInfo(), logging.error)
    ssconf.WriteSsconfFiles(cfg.GetSsconfValues())

    if not os.path.exists(
            os.path.join(
                pathutils.DATA_DIR, "%s%s" %
                (constants.SSCONF_FILEPREFIX,
                 constants.SS_MASTER_CANDIDATES_CERTS))):
        raise errors.OpExecError(
            "Ssconf file for master candidate certificates"
            " was not written.")

    if not os.path.exists(pathutils.NODED_CERT_FILE):
        raise errors.OpExecError(
            "The server certficate was not created properly.")

    if not os.path.exists(pathutils.NODED_CLIENT_CERT_FILE):
        raise errors.OpExecError("The client certificate was not created"
                                 " properly.")

    # set up the inter-node password and certificate
    result = utils.RunCmd([pathutils.DAEMON_UTIL, "start", constants.NODED])
    if result.failed:
        raise errors.OpExecError("Could not start the node daemon, command %s"
                                 " had exitcode %s and error %s" %
                                 (result.cmd, result.exit_code, result.output))

    _WaitForNodeDaemon(master_name)
Exemplo n.º 2
0
def SSLVerifyPeer(conn, cert, errnum, errdepth, ok):
    """Callback function to verify a peer against the candidate cert map.

  Note that we have a chicken-and-egg problem during cluster init and upgrade.
  This method checks whether the incoming connection comes from a master
  candidate by comparing it to the master certificate map in the cluster
  configuration. However, during cluster init and cluster upgrade there
  are various RPC calls done to the master node itself, before the candidate
  certificate list is established and the cluster configuration is written.
  In this case, we cannot check against the master candidate map.

  This problem is solved by checking whether the candidate map is empty. An
  initialized 2.11 or higher cluster has at least one entry for the master
  node in the candidate map. If the map is empty, we know that we are still
  in the bootstrap/upgrade phase. In this case, we read the server certificate
  digest and compare it to the incoming request.

  This means that after an upgrade of Ganeti, the system continues to operate
  like before, using server certificates only. After the client certificates
  are generated with ``gnt-cluster renew-crypto --new-node-certificates``,
  RPC communication is switched to using client certificates and the trick of
  using server certificates does not work anymore.

  @type conn: C{OpenSSL.SSL.Connection}
  @param conn: the OpenSSL connection object
  @type cert: C{OpenSSL.X509}
  @param cert: the peer's SSL certificate

  """
    # some parameters are unused, but this is the API
    # pylint: disable=W0613
    _BOOTSTRAP = "bootstrap"
    sstore = ssconf.SimpleStore()
    try:
        candidate_certs = sstore.GetMasterCandidatesCertMap()
    except errors.ConfigurationError:
        logging.info("No candidate certificates found. Switching to "
                     "bootstrap/update mode.")
        candidate_certs = None
    if not candidate_certs:
        candidate_certs = {
            _BOOTSTRAP:
            utils.GetCertificateDigest(cert_filename=pathutils.NODED_CERT_FILE)
        }
    return cert.digest("sha1") in candidate_certs.values()
Exemplo n.º 3
0
def SSLVerifyPeer(conn, cert, errnum, errdepth, ok):
    """Callback function to verify a peer against the candidate cert map.

  Note that we have a chicken-and-egg problem during cluster init and upgrade.
  This method checks whether the incoming connection comes from a master
  candidate by comparing it to the master certificate map in the cluster
  configuration. However, during cluster init and cluster upgrade there
  are various RPC calls done to the master node itself, before the candidate
  certificate list is established and the cluster configuration is written.
  In this case, we cannot check against the master candidate map.

  This problem is solved by checking whether the candidate map is empty. An
  initialized 2.11 or higher cluster has at least one entry for the master
  node in the candidate map. If the map is empty, we know that we are still
  in the bootstrap/upgrade phase. In this case, we read the server certificate
  digest and compare it to the incoming request.

  This means that after an upgrade of Ganeti, the system continues to operate
  like before, using server certificates only. After the client certificates
  are generated with ``gnt-cluster renew-crypto --new-node-certificates``,
  RPC communication is switched to using client certificates and the trick of
  using server certificates does not work anymore.

  @type conn: C{OpenSSL.SSL.Connection}
  @param conn: the OpenSSL connection object
  @type cert: C{OpenSSL.X509}
  @param cert: the peer's SSL certificate
  @type errdepth: integer
  @param errdepth: number of the step in the certificate chain starting at 0
                   for the actual client certificate.

  """
    # some parameters are unused, but this is the API
    # pylint: disable=W0613

    # If we receive a certificate from the certificate chain that is higher
    # than the lowest element of the chain, we have to check it against the
    # server certificate.
    if errdepth > 0:
        server_digest = utils.GetCertificateDigest(
            cert_filename=pathutils.NODED_CERT_FILE)
        match = cert.digest("sha1") == server_digest
        if not match:
            logging.debug(
                "Received certificate from the certificate chain, which"
                " does not match the server certficate. Digest of the"
                " received certificate: %s. Digest of the server"
                " certificate: %s.", cert.digest("sha1"), server_digest)
        return match
    elif errdepth == 0:
        sstore = ssconf.SimpleStore()
        try:
            candidate_certs = sstore.GetMasterCandidatesCertMap()
        except errors.ConfigurationError:
            logging.info("No candidate certificates found. Switching to "
                         "bootstrap/update mode.")
            candidate_certs = None
        if not candidate_certs:
            candidate_certs = {
                constants.CRYPTO_BOOTSTRAP:
                utils.GetCertificateDigest(
                    cert_filename=pathutils.NODED_CERT_FILE)
            }
        match = cert.digest("sha1") in candidate_certs.values()
        if not match:
            logging.debug(
                "Received certificate which is not a certificate of a"
                " master candidate. Certificate digest: %s. List of master"
                " candidate certificate digests: %s.", cert.digest("sha1"),
                str(candidate_certs))
        return match
    else:
        logging.error("Invalid errdepth value: %s.", errdepth)
        return False
Exemplo n.º 4
0
 def GetCertificateDigest(self):
     return utils.GetCertificateDigest(cert_filename=self.ssl_cert_path)