#!/usr/bin/env python # -*- coding: utf-8 -*- import os import datetime from cryptography import x509 from cryptography.x509.oid import NameOID from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption def generate_ssl_certificate(): """ Generiert ein verbessertes SSL-Zertifikat für die MYP-Anwendung mit korrekten Metadaten und alternativen Namen. """ print("Generiere verbessertes SSL-Zertifikat für die MYP-Anwendung...") # Verzeichnispfade definieren ssl_dir = "app/instance/ssl" ssl_cert_path = os.path.join(ssl_dir, "myp.crt") ssl_key_path = os.path.join(ssl_dir, "myp.key") # Verzeichnis erstellen, falls es nicht existiert os.makedirs(ssl_dir, exist_ok=True) try: # Privaten Schlüssel mit 4096 Bit generieren (sicherer) private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, ) # Aktuelles Datum und Ablaufdatum (1 Jahr gültig) now = datetime.datetime.now() valid_until = now + datetime.timedelta(days=365) # Liste aller möglichen Hostnamen/IPs hostnames = [ "localhost", "raspberrypi", "m040tbaraspi001", "m040tbaraspi001.de040.corpintra.net" ] # IP-Adressen (als String, werden später konvertiert) ip_addresses = [ "127.0.0.1", "192.168.0.105" ] # Erweiterte Zertifikatsattribute subject = issuer = x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "raspberrypi"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz AG"), x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Werk 040 Berlin"), x509.NameAttribute(NameOID.COUNTRY_NAME, "DE"), x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Berlin"), x509.NameAttribute(NameOID.LOCALITY_NAME, "Berlin") ]) # Subject Alternative Names (SAN) erstellen san_list = [] for hostname in hostnames: san_list.append(x509.DNSName(hostname)) # IP-Adressen hinzufügen import socket for ip in ip_addresses: san_list.append(x509.IPAddress(socket.inet_aton(ip))) # Zertifikat erstellen cert = x509.CertificateBuilder().subject_name( subject ).issuer_name( issuer ).public_key( private_key.public_key() ).serial_number( x509.random_serial_number() ).not_valid_before( now ).not_valid_after( valid_until ).add_extension( x509.SubjectAlternativeName(san_list), critical=False, ).add_extension( x509.BasicConstraints(ca=True, path_length=None), critical=True ).add_extension( x509.KeyUsage( digital_signature=True, content_commitment=False, key_encipherment=True, data_encipherment=False, key_agreement=False, key_cert_sign=True, crl_sign=True, encipher_only=False, decipher_only=False ), critical=True ).add_extension( x509.ExtendedKeyUsage([ x509.oid.ExtendedKeyUsageOID.SERVER_AUTH, x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH ]), critical=False ).sign(private_key, hashes.SHA256()) # Zertifikat und Schlüssel speichern with open(ssl_key_path, "wb") as f: f.write(private_key.private_bytes( encoding=Encoding.PEM, format=PrivateFormat.TraditionalOpenSSL, encryption_algorithm=NoEncryption() )) with open(ssl_cert_path, "wb") as f: f.write(cert.public_bytes(Encoding.PEM)) # Kopieren des Zertifikats in das Frontend-Verzeichnis frontend_ssl_dir = "../frontend/ssl" os.makedirs(frontend_ssl_dir, exist_ok=True) import shutil shutil.copy2(ssl_cert_path, os.path.join(frontend_ssl_dir, "myp.crt")) shutil.copy2(ssl_key_path, os.path.join(frontend_ssl_dir, "myp.key")) print(f"SSL-Zertifikat wurde erstellt:") print(f"- Zertifikat: {ssl_cert_path}") print(f"- Schlüssel: {ssl_key_path}") print(f"- Kopiert nach: {frontend_ssl_dir}") print(f"- Gültig bis: {valid_until.strftime('%d.%m.%Y')}") print(f"- Hostnamen: {', '.join(hostnames)}") print(f"- IP-Adressen: {', '.join(ip_addresses)}") return True except Exception as e: print(f"Fehler beim Erstellen des SSL-Zertifikats: {e}") return False def install_certificate_system(): """ Installiert das Zertifikat im System-Zertifikatsspeicher (Windows). Nur für Windows-Systeme. """ import platform if platform.system() != "Windows": print("Diese Funktion ist nur unter Windows verfügbar.") return False try: import subprocess ssl_cert_path = os.path.abspath("app/instance/ssl/myp.crt") # Befehle zum Installieren des Zertifikats im Windows-Zertifikatsspeicher commands = [ ["certutil", "-addstore", "-f", "ROOT", ssl_cert_path], ["certutil", "-addstore", "-f", "CA", ssl_cert_path], ["certutil", "-addstore", "-f", "MY", ssl_cert_path] ] for cmd in commands: subprocess.run(cmd, check=True, capture_output=True) print("Zertifikat wurde erfolgreich im System-Zertifikatsspeicher installiert.") return True except Exception as e: print(f"Fehler bei der Installation des Zertifikats im System: {e}") return False def copy_to_raspberry(): """ Kopiert das Zertifikat auf den Raspberry Pi. Erfordert SSH-Zugriff auf den Raspberry Pi. """ try: import subprocess ssl_cert_path = os.path.abspath("app/instance/ssl/myp.crt") ssl_key_path = os.path.abspath("app/instance/ssl/myp.key") # Raspberry Pi-Zugangsdaten raspberry_host = "raspberrypi" raspberry_user = "pi" raspberry_dest = "/home/pi/myp/ssl" # Befehle zum Kopieren der Dateien auf den Raspberry Pi scp_commands = [ ["scp", ssl_cert_path, f"{raspberry_user}@{raspberry_host}:{raspberry_dest}/myp.crt"], ["scp", ssl_key_path, f"{raspberry_user}@{raspberry_host}:{raspberry_dest}/myp.key"] ] # SSH-Befehl zum Erstellen des Verzeichnisses auf dem Raspberry Pi ssh_command = ["ssh", f"{raspberry_user}@{raspberry_host}", f"mkdir -p {raspberry_dest}"] # Verzeichnis auf dem Raspberry Pi erstellen print(f"Erstelle Verzeichnis auf dem Raspberry Pi: {raspberry_dest}") subprocess.run(ssh_command, check=True) # Dateien kopieren for cmd in scp_commands: print(f"Kopiere {cmd[1]} nach {cmd[2]}") subprocess.run(cmd, check=True) print(f"Zertifikate wurden erfolgreich auf den Raspberry Pi kopiert nach {raspberry_dest}") # Berechtigungen setzen chmod_command = ["ssh", f"{raspberry_user}@{raspberry_host}", f"chmod 600 {raspberry_dest}/myp.key"] subprocess.run(chmod_command, check=True) # Zertifikat im System-Zertifikatsspeicher installieren install_command = ["ssh", f"{raspberry_user}@{raspberry_host}", f"sudo cp {raspberry_dest}/myp.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates"] subprocess.run(install_command, check=True) print("Zertifikat wurde erfolgreich auf dem Raspberry Pi installiert und registriert.") return True except Exception as e: print(f"Fehler beim Kopieren des Zertifikats auf den Raspberry Pi: {e}") return False if __name__ == "__main__": print("=== MYP SSL-Zertifikatsgenerator ===") # Zertifikat generieren cert_generated = generate_ssl_certificate() if not cert_generated: print("Generierung des Zertifikats fehlgeschlagen.") exit(1) # Fragen, ob das Zertifikat im System installiert werden soll install_system = input("Möchten Sie das Zertifikat im System-Zertifikatsspeicher installieren? (j/n): ").lower() == 'j' if install_system: install_certificate_system() # Fragen, ob das Zertifikat auf den Raspberry Pi kopiert werden soll copy_raspberry = input("Möchten Sie das Zertifikat auf den Raspberry Pi kopieren? (j/n): ").lower() == 'j' if copy_raspberry: copy_to_raspberry() print("Vorgang abgeschlossen.")