Пример #1
0
def send_data():
    # Send the data that is required to create a server certificate for
    # this server.
    config = hookenv.config()
    server_crt_path = crtPath('server')
    client_crt_path = crtPath('client')
    server_key_path = keyPath('server')
    client_key_path = keyPath('client')
    ca_crt_path = caPath()
    # Use the private ip of this unit as the Common Name for the certificate.
    if config['ssl_cert']:
        for certs_path in ('server_crt_path', 'client_crt_path'):
            with open(certs_path, "wb") as fs:
                os.chmod(
                    certs_path,
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
                fs.write(base64.b64decode(config['ssl_cert']))
            if config['ssl_key']:
                with open(certs_path, "wb") as fks:
                    os.chmod(certs_path, stat.S_IWUSR | stat.S_IWUSR)
                    fks.write(base64.b64decode(config['ssl_key']))
        import_srv_crt_to_keystore()
        if config['ssl_ca']:
            with open(ca_crt_path, "wb") as fca:
                os.chmod(
                    ca_crt_path,
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
                fca.write(base64.b64decode(config['ssl_ca']))
        import_ca_crt_to_keystore()
    else:
        common_name = hookenv.unit_private_ip()
        common_public_name = hookenv.unit_public_ip()
        sans = [
            common_name,
            common_public_name,
            hookenv.unit_public_ip(),
            socket.gethostname(),
            socket.getfqdn(),
        ]

        # maybe they have extra names they want as SANs
        extra_sans = hookenv.config('subject_alt_names')
        if extra_sans and not extra_sans == "":
            sans.extend(extra_sans.split())

        # Request a server cert with this information.
        tls_client.request_server_cert(common_name,
                                       sans,
                                       crt_path=server_crt_path,
                                       key_path=server_key_path)

        # Request a client cert with this information.
        tls_client.request_client_cert(common_name,
                                       sans,
                                       crt_path=client_crt_path,
                                       key_path=client_key_path)
Пример #2
0
def clear_certificates():
    ca_path = caPath()
    ca_keystore = caKeystore()
    ca_keystore_secret = keystoreSecret()
    if os.path.exists(ca_path):
        os.remove(ca_path)
    if os.path.exists(ca_keystore):
        os.remove(ca_keystore)
    if os.path.exists(ca_keystore_secret):
        os.remove(ca_keystore_secret)

    certs_paths = unitdata.kv().get('layer.tls-client.cert-paths', {})
    for cert_type in ('server', 'client'):
        crt_path = crtPath(cert_type)
        key_path = keyPath(cert_type)
        keystore_path = keystore(cert_type)
        if os.path.exists(crt_path):
            os.remove(crt_path)
        if os.path.exists(key_path):
            os.remove(key_path)
        if os.path.exists(keystore_path):
            os.remove(keystore_path)
        remove_state('kafka.{}.keystore.saved'.format(cert_type))
        data_changed('kafka_{}_certificate'.format(cert_type), {})

        for common_name, paths in certs_paths.get(cert_type, {}).items():
            data_changed(
                'layer.tls-client.'
                '{}.{}'.format(cert_type, common_name), {})

    # We need to clean up data because the underlying layer
    # failes to clear flags and data_changed states when
    # we remove {charm}-easyrsa relation.
    unitdata_keys = ('reactive.tls_client',
                     'reactive.data_changed.endpoint.certificates',
                     'reactive.data_changed.ca_certificate',
                     'reactive.data_changed.certificate',
                     'reactive.data_changed.client',
                     'reactive.data_changed.server',
                     'reactive.data_changed.kafka_client_certificate',
                     'reactive.data_changed.kafka_server_certificate',
                     'reactive.states.endpoint.certificates',
                     'reactive.states.tls_client')

    for k in unitdata_keys:
        unitdata.kv().unsetrange(None, k)

    cleanup_states = ('kafka.ca.keystore.saved', 'tls_client.ca.saved',
                      'tls_client.server.certificate.saved',
                      'tls_client.server.key.saved',
                      'tls_client.client.certificate.saved',
                      'tls_client.client.key.saved', 'kafka.started')
    for s in cleanup_states:
        remove_state(s)
Пример #3
0
def send_data():
    # Send the data that is required to create a server certificate for
    # this server.

    # Use the private ip of this unit as the Common Name for the certificate.
    common_name = hookenv.unit_private_ip()

    # Create SANs that the tls layer will add to the server cert.
    sans = [
        common_name,
        socket.gethostname(),
    ]
    extra_names = hookenv.config().get('subject_alt_names', '')
    sans.extend([n.strip() for n in extra_names.split(',') if n])

    # Request a server cert with this information.
    tls_client.request_server_cert(common_name,
                                   sans,
                                   crt_path=crtPath('server'),
                                   key_path=keyPath('server'))
    tls_client.request_client_cert('system:snap-kafka',
                                   crt_path=crtPath('client'),
                                   key_path=keyPath('client'))
Пример #4
0
def import_srv_crt_to_keystore():
    for cert_type in ('server', 'client'):
        password = keystore_password()
        crt_path = crtPath(cert_type)
        key_path = keyPath(cert_type)

        if os.path.isfile(crt_path) and os.path.isfile(key_path):
            with open(crt_path, 'rt') as f:
                cert = f.read()
                loaded_cert = crypto.load_certificate(crypto.FILETYPE_PEM,
                                                      cert)
                if not data_changed('kafka_{}_certificate'.format(cert_type),
                                    cert):
                    log('server certificate of key file missing')
                    return

            with open(key_path, 'rt') as f:
                loaded_key = crypto.load_privatekey(crypto.FILETYPE_PEM,
                                                    f.read())

            with tempfile.NamedTemporaryFile() as tmp:
                log('server certificate changed')

                keystore_path = keystore(cert_type)

                pkcs12 = crypto.PKCS12Type()
                pkcs12.set_certificate(loaded_cert)
                pkcs12.set_privatekey(loaded_key)
                pkcs12_data = pkcs12.export(password)
                log('opening tmp file {}'.format(tmp.name))

                # write cert and private key to the pkcs12 file
                tmp.write(pkcs12_data)
                tmp.flush()

                log('importing pkcs12')
                # import the pkcs12 into the keystore
                check_call([
                    'keytool', '-v', '-importkeystore', '-srckeystore',
                    str(tmp.name), '-srcstorepass', password, '-srcstoretype',
                    'PKCS12', '-destkeystore', keystore_path, '-deststoretype',
                    'JKS', '-deststorepass', password, '--noprompt'
                ])
                os.chmod(keystore_path, 0o440)

                remove_state('tls_client.certs.changed')
                set_state('kafka.{}.keystore.saved'.format(cert_type))
                remove_state('kafka.started')