"Update SSL certificate generation process"

This commit is contained in:
Till Tomczak 2025-05-26 10:48:36 +02:00
parent 0d7264524f
commit f063d07232
4 changed files with 74 additions and 54 deletions

View File

@ -18,7 +18,8 @@ from flask_wtf.csrf import CSRFProtect
from config.settings import (
SECRET_KEY, TAPO_USERNAME, TAPO_PASSWORD, PRINTERS,
FLASK_HOST, FLASK_PORT, FLASK_DEBUG, SESSION_LIFETIME,
SCHEDULER_INTERVAL, SCHEDULER_ENABLED, get_ssl_context, FLASK_FALLBACK_PORT
SCHEDULER_INTERVAL, SCHEDULER_ENABLED, get_ssl_context, FLASK_FALLBACK_PORT,
SSL_ENABLED, SSL_CERT_PATH, SSL_KEY_PATH
)
from utils.logging_config import setup_logging, get_logger, log_startup_info
from models import User, Printer, Job, Stats, get_db_session, init_database, create_initial_admin
@ -1396,6 +1397,9 @@ def check_jobs():
if __name__ == "__main__":
import argparse
import threading
import ssl
import socket
import logging
# Kommandozeilenargumente parsen
parser = argparse.ArgumentParser(description='MYP Platform - 3D-Drucker Reservierungssystem')
@ -1411,56 +1415,64 @@ if __name__ == "__main__":
port = args.port if args.port else FLASK_PORT
# SSL-Kontext abrufen
ssl_context = None if args.no_ssl else get_ssl_context()
# Funktion zum Starten des Servers
def start_server(use_ssl=True, server_port=None):
if server_port is None:
server_port = port
ssl_context = None
if SSL_ENABLED and not args.no_ssl:
try:
if use_ssl and ssl_context:
protocol = "HTTPS"
app_logger.info(f"{protocol}-Server wird auf Port {server_port} gestartet...")
app.run(host=FLASK_HOST, port=server_port, debug=FLASK_DEBUG, ssl_context=ssl_context)
if SSL_CERT_PATH and SSL_KEY_PATH:
ssl_context = (SSL_CERT_PATH, SSL_KEY_PATH)
logging.info(f"SSL aktiviert mit Zertifikat: {SSL_CERT_PATH}")
else:
protocol = "HTTP"
app_logger.info(f"{protocol}-Server wird auf Port {server_port} gestartet...")
app.run(host=FLASK_HOST, port=server_port, debug=FLASK_DEBUG)
ssl_context = 'adhoc'
logging.info("SSL aktiviert mit selbstsigniertem Ad-hoc-Zertifikat")
except Exception as e:
app_logger.error(f"Fehler beim Starten des {protocol}-Servers auf Port {server_port}: {str(e)}")
if server_port == FLASK_PORT:
fallback_port = FLASK_FALLBACK_PORT
app_logger.info(f"Versuche auf Fallback-Port {fallback_port} zu starten...")
try:
if use_ssl and ssl_context:
app.run(host=FLASK_HOST, port=fallback_port, debug=FLASK_DEBUG, ssl_context=ssl_context)
else:
app.run(host=FLASK_HOST, port=fallback_port, debug=FLASK_DEBUG)
except Exception as e2:
app_logger.error(f"Auch Fallback-Port fehlgeschlagen: {str(e2)}")
app_logger.info("Versuche auf Standard-Port 5000 zu starten...")
if use_ssl and ssl_context:
app.run(host=FLASK_HOST, port=5000, debug=FLASK_DEBUG, ssl_context=ssl_context)
else:
app.run(host=FLASK_HOST, port=5000, debug=FLASK_DEBUG)
logging.error(f"Fehler beim Laden des SSL-Kontexts: {e}")
ssl_context = None
# Dual-Protokoll-Modus: HTTP und HTTPS parallel starten
# Dual-Protokoll-Modus: HTTP und HTTPS gleichzeitig
if args.dual_protocol:
app_logger.info("Starte Server im Dual-Protokoll-Modus (HTTP und HTTPS)...")
# Funktion zum Starten des HTTP-Servers
def start_http_server():
try:
logging.info(f"Starte HTTP-Server auf Port 80...")
# Kopie der App erstellen
from werkzeug.serving import run_simple
run_simple('0.0.0.0', 80, app, threaded=True)
except socket.error as e:
logging.error(f"Konnte HTTP-Server nicht starten: {e}")
# HTTPS auf Hauptport (443)
https_thread = threading.Thread(target=start_server, kwargs={"use_ssl": True, "server_port": port})
# Funktion zum Starten des HTTPS-Servers
def start_https_server():
try:
if ssl_context:
logging.info(f"Starte HTTPS-Server auf Port {port}...")
app.run(host='0.0.0.0', port=port, ssl_context=ssl_context, threaded=True)
else:
logging.warning("HTTPS deaktiviert aufgrund fehlender Zertifikate")
app.run(host='0.0.0.0', port=port, threaded=True)
except socket.error as e:
logging.error(f"Konnte HTTPS-Server nicht starten: {e}")
# Beide Server in separaten Threads starten
http_thread = threading.Thread(target=start_http_server)
https_thread = threading.Thread(target=start_https_server)
http_thread.daemon = True
https_thread.daemon = True
http_thread.start()
https_thread.start()
# HTTP auf Alternativport (80)
http_port = FLASK_FALLBACK_PORT
start_server(use_ssl=False, server_port=http_port)
# Warten, bis beide Threads beendet sind (was sie normalerweise nicht sein sollten)
http_thread.join()
https_thread.join()
else:
# Normaler Start mit einem Protokoll
app_logger.info(f"Server wird auf Port {port} mit {'HTTPS' if ssl_context else 'HTTP'} gestartet...")
start_server(use_ssl=bool(ssl_context))
# Normaler Modus - entweder HTTP oder HTTPS
if ssl_context:
logging.info(f"Starte HTTPS-Server auf Port {port}...")
app.run(host='0.0.0.0', port=port, ssl_context=ssl_context, threaded=True)
else:
logging.info(f"Starte HTTP-Server auf Port {port}...")
app.run(host='0.0.0.0', port=port, threaded=True)
# Content Security Policy anpassen
@app.after_request

View File

@ -34,9 +34,9 @@ SESSION_LIFETIME = timedelta(days=7)
# SSL-Konfiguration
SSL_ENABLED = True
SSL_CERT_PATH = "instance/ssl/myp.crt"
SSL_KEY_PATH = "instance/ssl/myp.key"
SSL_HOSTNAME = "localhost"
SSL_CERT_PATH = "app/instance/ssl/myp.crt"
SSL_KEY_PATH = "app/instance/ssl/myp.key"
SSL_HOSTNAME = "raspberrypi"
# Scheduler-Konfiguration
SCHEDULER_INTERVAL = 60 # Sekunden

Binary file not shown.

View File

@ -8,6 +8,8 @@ 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
import ipaddress
import argparse
def generate_ssl_certificate():
"""
@ -65,9 +67,8 @@ def generate_ssl_certificate():
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)))
san_list.append(x509.IPAddress(ipaddress.IPv4Address(ip)))
# Zertifikat erstellen
cert = x509.CertificateBuilder().subject_name(
@ -221,20 +222,27 @@ def copy_to_raspberry():
if __name__ == "__main__":
print("=== MYP SSL-Zertifikatsgenerator ===")
# Kommandozeilenargumente parsen
parser = argparse.ArgumentParser(description='MYP SSL-Zertifikatsgenerator')
parser.add_argument('--no-install', action='store_true', help='Zertifikat nicht im System installieren')
parser.add_argument('--no-raspberry', action='store_true', help='Zertifikat nicht auf den Raspberry Pi kopieren')
parser.add_argument('--quiet', action='store_true', help='Keine Benutzerinteraktion')
args = parser.parse_args()
# 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:
# System-Installation des Zertifikats
if not args.no_install:
if args.quiet or input("Möchten Sie das Zertifikat im System-Zertifikatsspeicher installieren? (j/n): ").lower() == 'j':
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:
# Kopieren auf Raspberry Pi
if not args.no_raspberry:
if args.quiet or input("Möchten Sie das Zertifikat auf den Raspberry Pi kopieren? (j/n): ").lower() == 'j':
copy_to_raspberry()
print("Vorgang abgeschlossen.")