def cert_list(request): """ Page dedicated to show certificate list """ try: certs = SSLCertificate.objects(is_trusted_ca__ne=True) except DoesNotExist: certs = None try: trusted_ca_list = SSLCertificate.objects(is_trusted_ca=True) except DoesNotExist: trusted_ca_list = None return render_to_response('cert.html', {'certs': certs, 'trusted_ca_list': trusted_ca_list}, context_instance=RequestContext(request))
def remove_ca(request, cert_id): """ Function called when a Trusted CA certificate is deleted. It will erase-it on disk. :param request: Django request object :param cert_id: String id of certificate to erase :return: """ try: certificate = SSLCertificate(ObjectId(cert_id)) except Exception as e: logger.error( "API::remove_ca: CA Certificate '{}' not found : {}".format( cert_id, e)) return JsonResponse({ 'status': 0, 'error': "CA Certificate '{}' not found : {}".format(cert_id, str(e)) }) # Delete the certificate on disk certificate_path = "{}/{}.crt".format(certs_dir, str(cert_id)) try: os_remove(certificate_path) except Exception as e: logger.error( "API::remove_ca: Failed to delete certificate '{}' on disk : {}". format(certificate_path, str(e))) os_system("/usr/local/bin/c_rehash /home/vlt-sys/Engine/conf/certs") logger.info("API::remove_ca: Ca certificate successfully deleted on disk") return JsonResponse({'status': 1})
def remove_cert(request, cert_id): """ Function called when a certificate is deleted. It will erase-it on disk. :param request: Django request object :param cert_id: String id of certificate to erase :return: """ try: certificate = SSLCertificate(ObjectId(cert_id)) except Exception as e: logger.error( "API::delete_cert: SSL Certificate '{}' not found : {}".format( cert_id, e)) return JsonResponse({ 'status': 0, 'error': "SSL Certificate '{}' not found : {}".format(cert_id, str(e)) }) # Delete all the declinaisons of files of that certificate on disk if certificate.cert and certificate.key: certificate_path = "{}SSLProxyCertificateFile-{}.txt".format( settings.CONF_DIR, cert_id) try: os_remove(certificate_path) except Exception as e: logger.error( "API::remove_cert: Failed to delete file '{}' on disk : {}". format(certificate_path, str(e))) if certificate.cert: certificate_path = "{}SSLCertificateFile-{}.txt".format( settings.CONF_DIR, cert_id) try: os_remove(certificate_path) except Exception as e: logger.error( "API::remove_cert: Failed to delete file '{}' on disk : {}". format(certificate_path, str(e))) if certificate.key: certificate_path = "{}SSLCertificateKeyFile-{}.txt".format( settings.CONF_DIR, cert_id) try: os_remove(certificate_path) except Exception as e: logger.error( "API::remove_cert: Failed to delete file '{}' on disk : {}". format(certificate_path, str(e))) logger.info( "API::remove_cert: SSL certificate successfully deleted on disk") return JsonResponse({'status': 1})
def perform_cert_options(self, zabbix_options): certificate_files = { 'chain': "{}/pki/ca_cert.crt".format(self.config_path), 'cert': "{}/pki/cert.crt".format(self.config_path), 'key': "{}/pki/cert.key".format(self.config_path), 'crl': "{}/pki/cert.crl".format(self.config_path) } # Retrieve SSLCertificate object ssl_cert = SSLCertificate.objects(id=zabbix_options.get('tls_cert')).only(*certificate_files.keys()).first() for attribute_name in certificate_files.keys(): self.write_configuration_file(certificate_files[attribute_name], getattr(ssl_cert, attribute_name)) # If CRL is not present, set the crl empty if not ssl_cert.crl: certificate_files['crl'] = "" # Replace SSLCertificate object by dict for template use zabbix_options['tls_cert_file'] = certificate_files return zabbix_options
def import_certificate(conn): """ Import all SSL certificates :param: ssl_conf_id: ssl certificate id :param: ssl_conf_cert: ssl cert chain :param: ssl_conf_key: ssl key chain :param: ssl_conf_ca: ssl ca chain :param: ssl_conf_ssl_protocol: ssl protocols supported :param: ssl_conf_ssl_cipher_suite: ssl ciphers suite :return modssl_dict: dict to link sslprofile id in sqlite to object created in mongodb """ logger.info("Importing SSL profiles and certificates") ssl_conf = conn.cursor() ssl_conf.execute("SELECT * FROM ssl_conf") ssl_conf_sql = ssl_conf.fetchall() app = conn.cursor() app.execute("SELECT * FROM app") application_sql = app.fetchall() # Retrieve index in database of each name fields of "app" table col_name_list_app = [tuple[0] for tuple in app.description] ssl_configuration_id = col_name_list_app.index("ssl_configuration_id") auth_id = col_name_list_app.index("auth_id") # Retrieve index in database of each name fields of ""ssl_conf" table col_name_list_ssl_conf = [tuple[0] for tuple in ssl_conf.description] ssl_conf_id = col_name_list_ssl_conf.index("id") ssl_conf_cert = col_name_list_ssl_conf.index("cert") ssl_conf_key = col_name_list_ssl_conf.index("key") ssl_conf_ca = col_name_list_ssl_conf.index("ca") ssl_conf_ssl_protocol = col_name_list_ssl_conf.index("ssl_protocol") ssl_conf_ssl_cipher_suite = col_name_list_ssl_conf.index("ssl_cipher_suite") modssl_dict = dict() used_ssl_list = list() # Avoid unused ssl_profile for app in application_sql: used_ssl_list.append(app[ssl_configuration_id]) for i in ssl_conf_sql: # if ssl_profile id is in list of used ssl profile by application, we import it if i[ssl_conf_id] in used_ssl_list and i[ssl_conf_cert]: # then we create and populate the ssl profile verify_client = "none" modssl = ModSSL() modssl.name = "SSL_profile_" + str(i[ssl_conf_id]) if "+SSLv3" in i[ssl_conf_ssl_protocol]: modssl.protocols = "+SSLv3" if "+TLSv1" in i[ssl_conf_ssl_protocol]: modssl.protocols = "+TLSv1" if "+TLSv1.1" in i[ssl_conf_ssl_protocol]: modssl.protocols = "+TLSv1.1" if "+TLSv1.2" in i[ssl_conf_ssl_protocol]: modssl.protocols = "+TLSv1.2" modssl.ciphers = i[ssl_conf_ssl_cipher_suite] modssl.engine = "builtin" # if auth method is SSL or SSL|Kerberos, verify client certificate for app in application_sql: if app[auth_id] == "6" or app[auth_id] == "5": verify_client = "require" modssl.verifyclient = verify_client modssl.engine = "builtin" # then we create the linked certificate of this ssl profile cert = SSLCertificate() cert.cert = "" cert.key = "" cert.chain = "" certificate = "" # remove \r in string cert, key, ca for j in i[ssl_conf_cert].split("\r"): certificate = certificate + j cert.cert = str(i[ssl_conf_cert]) cert.key = str(i[ssl_conf_key]) cert.chain = str(i[ssl_conf_ca]) x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert.cert) # retrieve each fields of subject if it exists for j in x509.get_subject().get_components(): if j[0] == "CN": cert.cn = j[1] elif j[0] == "C": cert.c = j[1] elif j[0] == "ST": cert.st = j[1] elif j[0] == "L": cert.l = j[1] elif j[0] == "O": cert.o = j[1] elif j[0] == "OU": cert.ou = j[1] # retrieve issuer informations cert.issuer = str(x509.get_issuer()).split("<X509Name object '")[1].split("'>")[0] # parse date format cert.validfrom = str(x509.get_notBefore())[0:4]+"-"+str(x509.get_notBefore())[4:6]\ +"-"+str(x509.get_notBefore())[6:8]+" "+str(x509.get_notBefore())[8:10]\ +":"+str(x509.get_notBefore())[10:12]+":"+str(x509.get_notBefore())[12:14] cert.validtill = str(x509.get_notAfter())[0:4]+"-"+str(x509.get_notAfter())[4:6]\ +"-"+str(x509.get_notAfter())[6:8]+" "+str(x509.get_notAfter())[8:10]\ +":"+str(x509.get_notAfter())[10:12]+":"+str(x509.get_notAfter())[12:14] # name is issuer cert.name = str(x509.get_subject()).split("<X509Name object '")[1].split("'>")[0] cert.save() modssl.certificate = cert modssl.save() modssl_dict[i[ssl_conf_id]] = modssl logger.info("End of SSL profiles and certificates importing process") return modssl_dict
def create_certificate(self): """ Create Node certificate from Cluster CA authority """ if self.certificate is None: # Get PKI next serial number cluster = Cluster.objects.get() serial = cluster.ca_serial serial += 1 crt, key = ssl_utils.mk_signed_cert(ssl_utils.get_ca_cert_path(), ssl_utils.get_ca_key_path(), self.name, 'FR', '', '', '', '', serial) # TODO: Error handling # Save serial number cluster.ca_serial = serial cluster.save() # Store the certificate certificate = SSLCertificate() certificate.name = str(crt.get_subject()) certificate.cn = str(self.name) certificate.o = 'FR' certificate.cert = crt.as_pem().decode('utf8') certificate.key = key.as_pem(cipher=None).decode('utf8') certificate.status = 'V' certificate.issuer = str(crt.get_issuer()) certificate.validfrom = str(crt.get_not_before().get_datetime()) certificate.validtill = str(crt.get_not_after().get_datetime()) certificate.serial = str(serial) certificate.is_ca = False internal = cluster.ca_certificate certificate.chain = str(internal.cert) certificate.save() self.certificate = certificate self.save()
def __init__(self, *args, **kwargs): try: self.listeners = kwargs.pop('listeners') except KeyError: pass super(ApplicationForm, self).__init__(*args, **kwargs) self = bootstrap_tooltips(self) repo_lst = BaseAbstractRepository.get_auth_repositories() auth_repo_lst = list() for rep in repo_lst: auth_repo_lst.append(( ObjectId(rep.id), rep.repo_name, )) mod_sec_choices = list() for rule in ModSecRulesSet.objects(type_rule__nin=('wlbl', )): mod_sec_choices.append((ObjectId(rule.id), rule.name)) dataset_list = list() dataset_list.append(((None), "------------------------------")) for dataset in Dataset.objects(svm_built=True).only('name', 'id'): dataset_list.append((ObjectId(dataset.id), dataset.name)) client_certificate = [('', '---------')] for cert in SSLCertificate.objects(is_trusted_ca__ne=True).only( 'id', 'cn'): client_certificate.append(("%sSSLProxyCertificateFile-%s.txt" % (settings.CONF_DIR, cert.id), cert.cn)) COOCKIE_CIPHER = ( ('rc4', 'RC4 (128 bits)'), ('aes128', 'AES 128 (128 bits)'), ('aes256', 'AES 256 (256 bits)'), ) IP_REPUTATION = [] loganalyser_rules = Cluster.objects.get( ).system_settings.loganalyser_settings.loganalyser_rules for rule in loganalyser_rules: tags = rule.tags.split(',') for tag in tags: IP_REPUTATION.append((tag, tag.capitalize())) GEOIP = [] for tag in [ "AF", "AX", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW" ]: GEOIP.append((tag, tag)) self.fields['block_reputation'] = MultipleChoiceField( required=False, choices=set(IP_REPUTATION), widget=SelectMultiple(attrs={'class': 'form-control select2'})) self.fields['block_geoip'] = MultipleChoiceField( required=False, choices=set(GEOIP), widget=SelectMultiple(attrs={'class': 'form-control select2'})) self.fields['allow_geoip'] = MultipleChoiceField( required=False, choices=set(GEOIP), widget=SelectMultiple(attrs={'class': 'form-control select2'})) self.fields['template'].queryset = portalTemplate.objects.filter() self.fields['auth_backend'] = ChoiceField( choices=auth_repo_lst, required=False, widget=Select(attrs={'class': 'form-control'})) self.fields['auth_backend_fallbacks'] = MultipleChoiceField( choices=auth_repo_lst, required=False, widget=SelectMultiple(attrs={'class': 'form-control select2'})) self.fields['redirect_uri'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 80, 'rows': 1, 'class': 'form-control' })) self.fields['sso_capture_content'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 80, 'rows': 2, 'class': 'form-control' })) self.fields['sso_replace_pattern'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 40, 'rows': 2, 'class': 'form-control' })) self.fields['sso_replace_content'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 40, 'rows': 2, 'class': 'form-control' })) self.fields['sso_after_post_request'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 80, 'rows': 2, 'class': 'form-control' })) self.fields['rules_set'] = MultipleChoiceField( choices=mod_sec_choices, required=False, widget=SelectMultiple(attrs={'class': 'form-control'})) self.fields['datasets'] = ChoiceField( choices=dataset_list, required=False, widget=Select(attrs={'class': 'form-control'})) self.fields['ssl_protocol'] = ChoiceField( choices=SSL_PROTOCOLS, required=False, widget=Select(attrs={'class': 'form-control'})) self.fields['ssl_client_certificate'] = ChoiceField( choices=client_certificate, required=False, widget=Select(attrs={'class': 'form-control'})) self.fields['custom_vhost'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 80, 'rows': 15, 'class': 'form-control' })) self.fields['custom_location'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 80, 'rows': 15, 'class': 'form-control' })) self.fields['custom_proxy'] = CharField( required=False, widget=Textarea(attrs={ 'cols': 80, 'rows': 15, 'class': 'form-control' })) self.fields['cookie_cipher'] = ChoiceField( choices=COOCKIE_CIPHER, required=False, widget=Select(attrs={'class': 'form-control'})) if self.initial.get("auth_backend"): repo = BaseAbstractRepository.search_repository( self.initial.get('auth_backend')) if isinstance(repo, LDAPRepository): try: groups = [(x, x) for x in repo.get_backend().enumerate_groups()] except: groups = [] finally: self.fields['group_registration'] = ChoiceField( choices=groups, required=False, widget=Select(attrs={'class': 'form-control'}))
import os import sys sys.path.append('/home/vlt-gui/vulture') os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'vulture.settings') import django django.setup() from gui.models.ssl_certificate import SSLCertificate from M2Crypto import X509 import subprocess if __name__ == '__main__': for cert in SSLCertificate.objects(issuer="LET'S ENCRYPT", status__ne="R"): print "Updating certificate {}".format(cert.cn) # Call acme-client to generate the Let's Encrypt challenge proc = subprocess.Popen( [ '/usr/local/sbin/acme.sh', '--issue', '-d', cert.cn, '--webroot', '/home/vlt-sys/Engine/conf', '--cert-home', '/usr/local/etc/ssl/acme' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={ 'PATH': "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" })
def write_ca(request, cert_id): """ Function called when a new Trusted CA certificate is imported. It will write-it on disk. :param request: Django request object :param cert_id: String id of certificate to write on disk :return: """ try: certificate = SSLCertificate(ObjectId(cert_id)) except Exception as e: logger.error( "API::write_ca: CA Certificate '{}' not found : {}".format( cert_id, e)) return JsonResponse({ 'status': 0, 'error': "CA Certificate '{}' not found : {}".format(cert_id, str(e)) }) try: cert_content = json_loads(request.body)['certificate'] except Exception as e: logger.error( "API::write_ca: CA certificate content not found in api request : {}" .format(str(e))) return JsonResponse({ 'status': 0, 'error': "CA certificate content null : {}".format(str(e)) }) # Write the certificate on disk certificate_path = "{}/{}.crt".format(certs_dir, str(cert_id)) try: with open(certificate_path, "w") as certificate_fd: certificate_fd.write(str(cert_content)) except Exception as e: logger.error( "API::write_ca: Cannot write CA certificate '{}' on disk : {}". format(certificate_path, e)) return JsonResponse({ 'status': 0, 'error': "Cannot write CA certificate '{}' on disk : {}".format( certificate_path, str(e)) }) # Set permissions try: os_chmod(certificate_path, 664) os_system("/usr/bin/chgrp vlt-web {}".format(certificate_path)) except Exception as e: logger.error( "API::write_ca: Failed to set permissions on '{}' file : {}". format(certificate_path, str(e))) os_system("/usr/local/bin/c_rehash /home/vlt-sys/Engine/conf/certs") logger.info("API::write_ca: Ca certificate successfully written on disk") return JsonResponse({'status': 1})
def conf_has_changed(self, parameters, service_settings=None, conf_django=None): """ Test if configuration into system configuration file is same that configuration in database (from parameters var) :param parameters: A dict containing configuration parameters :param service_settings: A dict containing configuration parameters, sent to tempale.render as 'conf_service' :param conf_django: A dict containing configuration parameters, sent to template.render as 'conf_django' """ # Modify parameters according to tls/psk options if parameters.get('tls_accept') == 'cert' or parameters.get('tls_connect') == 'cert': certificate_files = { 'chain': "{}/pki/ca_cert.crt".format(self.config_path), 'cert': "{}/pki/cert.crt".format(self.config_path), 'key': "{}/pki/cert.key".format(self.config_path), 'crl': "{}/pki/cert.crl".format(self.config_path) } ssl_cert = SSLCertificate.objects(id=parameters.get('tls_cert')).only(*certificate_files.keys()).first() if not ssl_cert.crl: certificate_files['crl'] = "" parameters['tls_cert_file'] = certificate_files if parameters.get('tls_accept') == 'psk' or parameters.get('tls_connect') == 'psk': parameters['psk_file'] = "{}/pki/psk.key".format(self.config_path) global_conf_has_changed = super(ZABBIX, self).conf_has_changed(parameters, service_settings, conf_django) if global_conf_has_changed.startswith("Unable to check if conf has changed"): raise ServiceConfigError(global_conf_has_changed) # If the configuration file hasn't changed, check if certificate/psk files has changed if not global_conf_has_changed: if parameters.get('tls_accept') == 'cert' or parameters.get('tls_connect') == 'cert': for attribute_name, filename in certificate_files.items(): if not filename: continue try: with open(filename, 'r') as fd: orig_conf = fd.read() if orig_conf != getattr(ssl_cert, attribute_name): logger.info("[ZABBIX] Configuration file '{}' differs on disk".format(filename)) return True except Exception as e: # FIXME : raise Exception to say the admin "Hey, cannot read conf!" in the GUI ? logger.error("[ZABBIX] Cannot check configuration on '{}' file: ".format(filename)) logger.exception(e) # We can't read the file, but it may have been modified return True if parameters.get('tls_accept') == 'psk' or parameters.get('tls_connect') == 'psk': psk_key_path = "{}/pki/psk.key".format(self.config_path) try: with open(psk_key_path, 'r') as fd: orig_conf = fd.read() if orig_conf != parameters.get('psk_key'): logger.info("[ZABBIX] Configuration file '{}' differs on disk".format(psk_key_path)) return True except Exception as e: logger.error("[ZABBIX] Cannot check configuration on '{}' file: ".format(psk_key_path)) logger.exception(e) # We can't read the file, but it may have been modified return True # If none of the files has changed: return False return False # If the configuration file has changed, return True logger.info("[ZABBIX] Global configuration file '/usr/local/etc/zabbix4/zabbix_agentd.conf' differs on disk.") return True
__license__ = "GPLv3" __version__ = "3.0.0" __maintainer__ = "Vulture Project" __email__ = "*****@*****.**" __doc__ = """This migration script rewrite HAProxy certificates on disk """ import os import sys sys.path.append('/home/vlt-gui/vulture') os.environ.setdefault("DJANGO_SETTINGS_MODULE", 'vulture.settings') import django django.setup() from gui.models.network_settings import Loadbalancer from gui.models.ssl_certificate import SSLCertificate if __name__ == '__main__': # If HAProxy used if Loadbalancer.objects.count() == 0: print("No load-balancer configured.") sys.exit(0) for cert in SSLCertificate.objects(): cert.write_certificate() print("Cert {} reloaded".format(cert.name)) print("Certificates reloaded")
def check_status(): """ Check if rc.conf.local need updates. Update file if needed :return: True if rc.conf.local was updated, False otherwise """ listeners = [] devices = {} haproxy = False reg = re.compile("^ifconfig_([^ ]+)_alias\{\}.*") cluster = Cluster.objects.get() node = cluster.get_current_node() # We add alias number (by device) for listener in node.get_listeners(): if reg.match(listener.rc_conf): dev = reg.match(listener.rc_conf).groups()[0] if not devices.get(dev): devices[dev] = 0 cpt = devices.get(dev) rc_conf = listener.rc_conf.format(cpt) devices[dev] += 1 else: rc_conf = listener.rc_conf listeners.append(rc_conf) """ GUI-0.3 Upgrade system_settings.pf_settings may not exists in GUI-0.3 upgraded from GUI-0.2 In this case we need to initialize it with default VALUES """ system_settings = node.system_settings if system_settings.pf_settings is None: system_settings.pf_settings = PFSettings() if system_settings.ipsec_settings is None: system_settings.ipsec_settings = IPSECSettings() loadbalancers = [] for loadbalancer in Loadbalancer.objects.all(): if loadbalancer.ssl_profile and loadbalancer.ssl_profile.hpkp_enable: loadbalancer.ssl_profile.pkp = PKP.getSPKIFingerpring( loadbalancer.ssl_profile.certificate.cert) if loadbalancer.incoming_listener.is_carp: for l in loadbalancer.incoming_listener.get_related_carp_inets(): if l.get_related_node() == node: haproxy = True if loadbalancer not in loadbalancers: loadbalancers.append(loadbalancer) elif loadbalancer.incoming_listener.get_related_node() == node: if loadbalancer not in loadbalancers: loadbalancers.append(loadbalancer) haproxy = True try: pf_logs = True if system_settings.pf_settings.repository_type == 'data' else False except KeyError: pf_logs = False parameters = { 'default_ipv4_gw': node.default_ipv4_gw, 'default_ipv6_gw': node.default_ipv6_gw, 'static_route': node.static_route, 'listeners': listeners, 'pf_logs': pf_logs, 'haproxy': haproxy, 'strongswan': system_settings.ipsec_settings.enabled } # Checking if rc.conf.local differs. tpl, path_rc = tpl_utils.get_template('rc.conf.local') conf_rc = tpl.render(conf=parameters) try: with open(path_rc, 'r') as f: orig_conf = f.read() except IOError: orig_conf = "" # rc.conf.local and/or pf.conf differs => writing new version if orig_conf != conf_rc: write_in_file(path_rc, conf_rc) if node.default_ipv4_gw or node.default_ipv6_gw: proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'service', 'routing', 'restart' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() #### HAPROXY Configuration #### parameters = {'haproxy': loadbalancers} tpl, path_haproxy = tpl_utils.get_template('vlthaproxy') conf_haproxy = tpl.render(conf=parameters) if not len(loadbalancers): conf_haproxy = "" try: with open(path_haproxy, 'r') as f: orig_conf = f.read() except IOError: orig_conf = "" ## Check diff in haproxy.conf proc = subprocess.Popen([ "/usr/local/bin/sudo", "-u", "vlt-sys", "/usr/local/bin/sudo", "service", "vlthaproxy", "status" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) res, errors = proc.communicate() haproxy_need_start = "haproxy not running" in errors.decode('utf8') if haproxy and orig_conf != conf_haproxy: write_in_file(path_haproxy, conf_haproxy) """ Delete all certificates in /home/vlt-sys/Engine/conf/haproxy """ os.system("/bin/rm %shaproxy/*" % settings.CONF_DIR) """ Write SSL-Profile certificates """ for loadbalancer in loadbalancers: if loadbalancer.enable_tls and loadbalancer.ssl_profile: loadbalancer.ssl_profile.write_HAProxy_conf() """ Store certificates so that HA-PROXY may use them """ for cert in SSLCertificate.objects(): cert.write_certificate() if not haproxy_need_start: proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'service', 'vlthaproxy', 'restart' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() else: proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'service', 'vlthaproxy', 'start' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() elif haproxy and haproxy_need_start: proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'service', 'vlthaproxy', 'start' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() elif not haproxy: write_in_file(path_haproxy, conf_haproxy) proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'service', 'vlthaproxy', 'stop' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() cluster = Cluster.objects.get() node = cluster.get_current_node() ## CHECK Vulture Cluster Whitelist for Packet Filter ips = [] for listener in Listener.objects.all(): ips.append(listener.ip) ips = set(ips) proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'pfctl', '-t', 'vulture_cluster', '-T', 'show' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) res, errors = proc.communicate() if res is False: return False res = res.decode('utf8') for ip in ips: if ip not in node.system_settings.pf_settings.pf_whitelist: node.system_settings.pf_settings.pf_whitelist = node.system_settings.pf_settings.pf_whitelist + '\n' + str( ip) node.save(bootstrap=True) res = [r.strip() for r in res.split('\n') if r != ""] for ip in ips: if ip not in res: proc = subprocess.Popen([ '/usr/local/bin/sudo', '-u', 'vlt-sys', '/usr/local/bin/sudo', 'pfctl', '-t', 'vulture_cluster', '-T', 'add', ip ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) res2, errors = proc.communicate() if res2 is False: return False return True
def sign(request): """ method dedicated to sign an external certificate request :param request: Django POST request object :param POST['csr']: The PEM certificate request """ cert = SSLCertificate() cert.cert = "" cert.key = "" cert.chain = "" cert.csr = "" if request.method == 'POST': dataPosted = request.POST error = dict() err = None try: cert.csr = str(dataPosted['csr']) except: err = True error['csr'] = "PEM Certificate request required" pass if err: return render_to_response('cert_sign.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Check the request try: x509Request = X509.load_request_string(cert.csr) except: error['csr'] = "Invalid PEM Certificate Request" return render_to_response('cert_sign.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Get cluster cluster = Cluster.objects.get() # Find the internal CA's certificate and private key internal = cluster.ca_certificate ca_key = RSA.load_key_string(internal.key.encode('utf8')) ca_cert = X509.load_cert_string(internal.cert.encode('utf8')) # Get PKI next serial number serial = cluster.ca_serial serial += 1 # Create a certificate from the request crt = mk_cert(serial) crt.set_pubkey(x509Request.get_pubkey()) pk = EVP.PKey() pk.assign_rsa(ca_key) issuer = X509.X509_Name() subject = X509.X509_Name() fields = str(x509Request.get_subject()).split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": subject.CN = tmp[1] cert.cn = tmp[1] elif str(tmp[0]) == "C": subject.C = tmp[1] cert.c = tmp[1] elif str(tmp[0]) == "ST": subject.ST = tmp[1] cert.st = tmp[1] elif str(tmp[0]) == "L": subject.L = tmp[1] cert.l = tmp[1] elif str(tmp[0]) == "O": subject.O = tmp[1] cert.o = tmp[1] elif str(tmp[0]) == "OU": subject.OU = tmp[1] cert.ou = tmp[1] fields = str(ca_cert.get_subject()).split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": issuer.CN = tmp[1] elif str(tmp[0]) == "C": issuer.C = tmp[1] elif str(tmp[0]) == "ST": issuer.ST = tmp[1] elif str(tmp[0]) == "L": issuer.L = tmp[1] elif str(tmp[0]) == "O": issuer.O = tmp[1] elif str(tmp[0]) == "OU": issuer.OU = tmp[1] crt.set_subject(subject) crt.set_issuer(issuer) crt.add_ext(X509.new_extension('basicConstraints', 'CA:FALSE')) crt.add_ext( X509.new_extension('subjectKeyIdentifier', str(crt.get_fingerprint()))) try: crt.sign(pk, 'sha256') except Exception as e: print(e) # Save serial number cluster.ca_serial = serial cluster.save() # Store the certificate cert.cert = crt.as_pem().decode('utf8') cert.name = str(crt.get_subject()) cert.status = 'V' cert.issuer = str(internal.issuer) cert.validfrom = str(crt.get_not_before().get_datetime()) cert.validtill = str(crt.get_not_after().get_datetime()) cert.is_ca = False cert.chain = str(internal.cert) cert.serial = str(serial) cert.save() return HttpResponseRedirect('/system/cert/') return render_to_response('cert_sign.html', { 'cert': cert, }, context_instance=RequestContext(request))
def load_ca(request): """ method dedicated to certificate importation :param request: Django POST request object :param POST['cert']: The PEM X509 trusted CA """ # Used to api_request the write of the new certificates cluster = Cluster.objects.get() cert = SSLCertificate() str_cert_list = "" if request.method == 'POST': dataPosted = request.POST users_cn = "" error = dict() err = None try: str_cert_list = str(dataPosted['cert']) except: err = True error['cert'] = "X509 PEM trusted CA required" pass try: users_cn = str(dataPosted['cn']) except: pass if err: return render_to_response('cert_import_ca.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # If the user provide CN, split them users_cn = users_cn.replace(' ', '') users_cn_list = filter(lambda x: x, users_cn.split(";")) # Create a list with the certificates the user imported cert_list = filter(lambda x: x, str_cert_list.split("-----BEGIN CERTIFICATE-----")) # Create the CAs in Mongo ca_count = 0 for cer_pem, users_cn in zip_longest(cert_list, users_cn_list): if not cer_pem: break if "-----BEGIN CERTIFICATE-----" not in cer_pem: cer_pem = "-----BEGIN CERTIFICATE-----" + cer_pem cert = SSLCertificate() cert.cert = cer_pem cert.key = "" cert.chain = "" cert.is_trusted_ca = True # Check the certificate try: x509Cert = X509.load_cert_string(cert.cert) except: error['cert'] = "Invalid X509 PEM trusted CA: " + str( ca_count) + " CA saved" return render_to_response( 'cert_import_ca.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Store certificate details cert.name = str(x509Cert.get_subject()) cert.status = 'V' cert.issuer = str(x509Cert.get_issuer()) try: cert.validfrom = str(x509Cert.get_not_before().get_datetime()) except Exception as e: logger.error( "Exception while retrieving validation date 'before' of certificates : " ) logger.exception(e) try: cert.validtill = str(x509Cert.get_not_after().get_datetime()) except Exception as e: logger.error( "Exception while retrieving validation date 'after' dates of certificates : " ) logger.exception(e) # Find certificate fields fields = cert.name.split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": cert.cn = tmp[1] elif str(tmp[0]) == "C": cert.c = tmp[1] elif str(tmp[0]) == "ST": cert.st = tmp[1] elif str(tmp[0]) == "L": cert.l = tmp[1] elif str(tmp[0]) == "O": cert.o = tmp[1] elif str(tmp[0]) == "OU": cert.ou = tmp[1] # If the CA doesn't provide a CN, use the user's one if not cert.cn and not users_cn: error['cn'] = "No CN provided by the user or the CA: " + str( ca_count) + " CA saved" return render_to_response( 'cert_import_ca.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) elif not cert.cn: cert.cn = users_cn # Save the CA in Mongo cert.save() # Write the certificate on disk on all nodes response = cluster.api_request( "/api/certs/write_ca/{}".format(str(cert.id)), {'certificate': cert.cert}) for node_name in response.keys(): if response[node_name].get('status') != 1: logger.error(response[node_name].get('error')) # Add the saved CA to the count ca_count += 1 os.system("/usr/local/bin/c_rehash /home/vlt-sys/Engine/conf/certs") return HttpResponseRedirect('/system/cert/') return render_to_response('cert_import_ca.html', { 'cert': cert, }, context_instance=RequestContext(request))
def load(request): """ method dedicated to certificate importation :param request: Django POST request object :param POST['cert']: The PEM X509 certificate :param POST['key']: The PEM X509 key :param POST['chain']: The PEM X509 certificate chain """ cert = SSLCertificate() cert.cert = "" cert.key = "" cert.chain = "" if request.method == 'POST': dataPosted = request.POST error = dict() err = None try: cert_cert = dataPosted['cert'] except: err = True error['cert'] = "X509 PEM Certificate required" pass try: cert_key = dataPosted['key'] except: err = True error['key'] = "X509 PEM Key required" pass try: cert.chain = str(dataPosted['chain']) except: pass if err: return render_to_response('cert_import.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Check the certificate try: x509Cert = X509.load_cert_string(bytes(cert_cert, 'utf8')) cert.cert = str(cert_cert) except: error['cert'] = "Invalid X509 PEM Certificate" return render_to_response('cert_import.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) global keypass try: keypass = str(dataPosted['keypass']) except: pass # Check the private key try: bio = BIO.MemoryBuffer(bytes(cert_key, 'utf8')) RSA.load_key_bio(bio, callback=read_pass_from_POST) cert.key = str(cert_key) except RSA.RSAError: try: bio = BIO.MemoryBuffer(bytes(cert_key, 'utf8')) EC.load_key_bio(bio, callback=read_pass_from_POST) cert.key = str(cert_key) except RSA.RSAError: error['keypass'] = "******" except Exception as e: logger.exception(e) error['key'] = "Invalid PEM KEY" except Exception as e: logger.exception(e) error['key'] = "Invalid PEM KEY" if error: return render_to_response('cert_import.html', { 'cert': cert, 'error': error }, context_instance=RequestContext(request)) # Store certificate details cert.name = str(x509Cert.get_subject()) cert.status = 'V' cert.issuer = str(x509Cert.get_issuer()) try: cert.validfrom = str(x509Cert.get_not_before().get_datetime()) except Exception as e: logger.error( "Exception while retrieving validation date 'before' of certificates : " ) logger.exception(e) try: cert.validtill = str(x509Cert.get_not_after().get_datetime()) except Exception as e: logger.error( "Exception while retrieving validation date 'after' of certificates : " ) logger.exception(e) if x509Cert.check_ca(): cert.is_ca = True else: cert.is_ca = False # Find certificate fields fields = cert.name.split('/') for field in fields: tmp = field.split('=') if str(tmp[0]) == "CN": cert.cn = tmp[1] elif str(tmp[0]) == "C": cert.c = tmp[1] elif str(tmp[0]) == "ST": cert.st = tmp[1] elif str(tmp[0]) == "L": cert.l = tmp[1] elif str(tmp[0]) == "O": cert.o = tmp[1] elif str(tmp[0]) == "OU": cert.ou = tmp[1] # if cert.cn is empty check if subjectAltName is set en use it if (not cert.cn): alt_name = x509Cert.get_ext('subjectAltName').get_value() if (alt_name): cert.cn = alt_name cert.save() return HttpResponseRedirect('/system/cert/') return render_to_response('cert_import.html', { 'cert': cert, }, context_instance=RequestContext(request))