diff --git a/misc/checkconfluent b/misc/checkconfluent new file mode 100644 index 00000000..a068c848 --- /dev/null +++ b/misc/checkconfluent @@ -0,0 +1,114 @@ +#!/usr/bin/python3 +# frequent problems to check/repair +# confluent_uuid mismatch from /var/lib/confluent/public/site +# repair would be to set the uuid global to match filesystem for least disruptive change +# local certificate is missing some addresses +# repair is osdeploy initialize -t + +# automation and/or ca certificates are somehow not viable +# This may be simple as file not exist or exist but can't be decrypted, or something about the ssh-agent in confluent isn't working + +# avoid regenerating ssh ca when not needed, people tend to repeat initialize and this needs to be made harmless. Instruct user to delete the file if they truly +#want to start over. +# +# +import os +import socket +import glob +import ssl +import sys +import confluent.certutil as certutil +import confluent.config.configmanager as configmanager + +def emprint(txt): + if sys.stdout.isatty(): + print('\x1b[1m\x1b[4m' + txt + '\x1b[0m') + else: + print(txt) + +def deployment_configured(): + return os.path.exists('/var/lib/confluent/public/site/confluent_uuid') + +def webserver_listening(): + try: + conn = socket.create_connection(('localhost', 443)) + return conn + except Exception: + return False + + +def certificates_missing_ips(conn): + # check if the tls can verify by the right CAs, then further + # check if all ip addresses are in the certificate offered + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + ctx.check_hostname = False + for cacert in glob.glob('/var/lib/confluent/public/site/tls/*.pem'): + ctx.load_verify_locations(cacert) + sock = ctx.wrap_socket(conn) + crt = sock.getpeercert() + sans = crt.get('subjectAltName', []) + ips = certutil.get_ip_addresses() + missing_ips = [] + for ip in ips: + for san in sans: + field, val = san + if val[-1] == '\n': + val = val[:-1] + if ':' in val: + # must normalize ipv6 to a sane value + val = socket.getaddrinfo(val, 443, type=socket.SOCK_STREAM)[0][-1][0] + if ip == 'val': + break + else: + missing_ips.append(ip) + return missing_ips + + + +def is_ipv6_enabled(): + # check for ability to create AF_INET6, for kernel disabled ipv6 + pass + # for every interface with an ipv4 address, check if there's an fe80 as well + # warn that os deployment and discovery services may be impacted for afflicted + # interface + +# check ssh sanity, are there automation keys and ca keys? can the configmanager +# keys unlock them? + +# check for pxe support, tftp transfer of ipxe file + +# check for http access to confluent-public, use site.cpio as file to check? + +# check for deployment.useinsecureprotocols=firmware + +def uuid_matches(): + with open('/var/lib/confluent/public/site/confluent_uuid', 'r') as uuidf: + fsuuid = uuidf.read() + dbuuid = configmanger.get_global('confluent_uuid') + return dbuuid == fsuuid: + + #TODO: osdeploy initialize needs to resync from filesystem at some point, + + #if not confluentuuid: + # confluentuuid = str(uuid.uuid4()) + # configmanager.set_global('confluent_uuid', confluentuuid) + +if __name__ == '__main__': + if deployment_configured(): + print("OS Deployment: Initialized") + if not uuid_matches(): + #TODO: need a resolution to suggest + emprint('UUID inconsistent between confluent database and /var/lib/confluent') + conn = webserver_listening() + if conn: + cert = certificates_missing_ips(conn) + if cert: + for addr in cert: + emprint('Address missing from certificate: {0}'.format(addr)) + emprint('Example resolution: osdeploy initialize -t') + else: + emprint("Web Server: Not Running") + emprint("Example resolution: systemctl enable httpd --now") + else: + print("OS Deployment: Uninitialized") + print()