feat: Ergänze umfassende Anleitung zur Bereitstellung der MYP-Plattform auf Raspberry Pi und aktualisiere SSL-Manager für verbesserte Zertifikatsverwaltung
This commit is contained in:
@@ -1 +1,351 @@
|
|||||||
|
# MYP Platform - Raspberry Pi Deployment Guide
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Diese Anleitung beschreibt die vollständige Installation und Konfiguration der MYP Platform auf Raspberry Pi Systemen.
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
### Hardware
|
||||||
|
- Raspberry Pi 4 (empfohlen) oder Raspberry Pi 3B+
|
||||||
|
- Mindestens 4GB RAM
|
||||||
|
- 32GB+ SD-Karte (Class 10)
|
||||||
|
- Netzwerkverbindung (Ethernet oder WiFi)
|
||||||
|
|
||||||
|
### Software
|
||||||
|
- Raspberry Pi OS (Bullseye oder neuer)
|
||||||
|
- SSH-Zugang aktiviert
|
||||||
|
- Benutzer `user` erstellt
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Projekt auf Raspberry Pi kopieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auf dem Entwicklungsrechner
|
||||||
|
scp -r Projektarbeit-MYP user@raspberrypi:/home/user/
|
||||||
|
|
||||||
|
# Oder mit Git
|
||||||
|
ssh user@raspberrypi
|
||||||
|
cd /home/user
|
||||||
|
git clone <repository-url> Projektarbeit-MYP
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Setup-Skript ausführen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh user@raspberrypi
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend
|
||||||
|
chmod +x setup_raspberry_pi.sh
|
||||||
|
./setup_raspberry_pi.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Das Setup-Skript führt automatisch folgende Schritte aus:
|
||||||
|
|
||||||
|
1. **System-Updates**: Aktualisiert alle Pakete
|
||||||
|
2. **Abhängigkeiten**: Installiert Python, Nginx, Supervisor etc.
|
||||||
|
3. **Virtual Environment**: Erstellt isolierte Python-Umgebung
|
||||||
|
4. **Python-Pakete**: Installiert alle Requirements
|
||||||
|
5. **Verzeichnisse**: Erstellt notwendige Ordnerstruktur
|
||||||
|
6. **Datenbank**: Initialisiert SQLite-Datenbank
|
||||||
|
7. **SSL-Zertifikate**: Generiert selbstsignierte Zertifikate
|
||||||
|
8. **Services**: Konfiguriert Systemd, Nginx, Supervisor
|
||||||
|
9. **Firewall**: Öffnet notwendige Ports
|
||||||
|
10. **Drucker**: Trägt hardkodierte Drucker in DB ein
|
||||||
|
|
||||||
|
### 3. Manuelle Drucker-Konfiguration (optional)
|
||||||
|
|
||||||
|
Falls die Drucker separat konfiguriert werden sollen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python setup_drucker_db.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Konfiguration
|
||||||
|
|
||||||
|
### Pfadstruktur
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/user/Projektarbeit-MYP/
|
||||||
|
├── backend/
|
||||||
|
│ ├── app/
|
||||||
|
│ │ ├── database/
|
||||||
|
│ │ │ └── myp.db
|
||||||
|
│ │ ├── logs/
|
||||||
|
│ │ │ ├── app/
|
||||||
|
│ │ │ ├── auth/
|
||||||
|
│ │ │ ├── jobs/
|
||||||
|
│ │ │ ├── printers/
|
||||||
|
│ │ │ ├── scheduler/
|
||||||
|
│ │ │ └── errors/
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── certs/
|
||||||
|
│ │ ├── myp.crt
|
||||||
|
│ │ └── myp.key
|
||||||
|
│ ├── venv/
|
||||||
|
│ └── requirements.txt
|
||||||
|
└── frontend/
|
||||||
|
└── ssl/
|
||||||
|
├── myp.crt
|
||||||
|
└── myp.key
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hardkodierte Drucker
|
||||||
|
|
||||||
|
Die folgenden Drucker werden automatisch konfiguriert:
|
||||||
|
|
||||||
|
| Name | IP-Adresse | Status |
|
||||||
|
|------|------------|--------|
|
||||||
|
| Printer 1 | 192.168.0.100 | Available |
|
||||||
|
| Printer 2 | 192.168.0.101 | Available |
|
||||||
|
| Printer 3 | 192.168.0.102 | Available |
|
||||||
|
| Printer 4 | 192.168.0.103 | Available |
|
||||||
|
| Printer 5 | 192.168.0.104 | Available |
|
||||||
|
| Printer 6 | 192.168.0.106 | Available |
|
||||||
|
|
||||||
|
### Standard-Anmeldedaten
|
||||||
|
|
||||||
|
- **E-Mail**: admin@mercedes-benz.com
|
||||||
|
- **Passwort**: 744563017196A
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
### Systemd Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Service-Status prüfen
|
||||||
|
sudo systemctl status myp-platform
|
||||||
|
|
||||||
|
# Service neu starten
|
||||||
|
sudo systemctl restart myp-platform
|
||||||
|
|
||||||
|
# Service aktivieren/deaktivieren
|
||||||
|
sudo systemctl enable myp-platform
|
||||||
|
sudo systemctl disable myp-platform
|
||||||
|
|
||||||
|
# Logs anzeigen
|
||||||
|
sudo journalctl -u myp-platform -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nginx
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Nginx-Status prüfen
|
||||||
|
sudo systemctl status nginx
|
||||||
|
|
||||||
|
# Konfiguration testen
|
||||||
|
sudo nginx -t
|
||||||
|
|
||||||
|
# Nginx neu laden
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### Supervisor
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Supervisor-Status
|
||||||
|
sudo supervisorctl status
|
||||||
|
|
||||||
|
# Service neu starten
|
||||||
|
sudo supervisorctl restart myp-platform
|
||||||
|
|
||||||
|
# Logs anzeigen
|
||||||
|
sudo supervisorctl tail -f myp-platform
|
||||||
|
```
|
||||||
|
|
||||||
|
## Zugriff
|
||||||
|
|
||||||
|
### URLs
|
||||||
|
|
||||||
|
- **HTTPS**: https://raspberrypi
|
||||||
|
- **HTTPS (IP)**: https://[IP-ADRESSE]
|
||||||
|
- **HTTP**: Automatische Weiterleitung zu HTTPS
|
||||||
|
|
||||||
|
### SSL-Zertifikat
|
||||||
|
|
||||||
|
Das System verwendet selbstsignierte SSL-Zertifikate:
|
||||||
|
|
||||||
|
- Browser-Warnung beim ersten Zugriff ist normal
|
||||||
|
- Zertifikat manuell akzeptieren
|
||||||
|
- Für Produktionsumgebung: Echte Zertifikate verwenden
|
||||||
|
|
||||||
|
## Wartung
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Anwendungs-Logs
|
||||||
|
tail -f /home/user/Projektarbeit-MYP/backend/app/logs/app/app.log
|
||||||
|
|
||||||
|
# System-Logs
|
||||||
|
sudo journalctl -u myp-platform -f
|
||||||
|
|
||||||
|
# Nginx-Logs
|
||||||
|
sudo tail -f /var/log/nginx/access.log
|
||||||
|
sudo tail -f /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Datenbank-Backup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup erstellen
|
||||||
|
cp /home/user/Projektarbeit-MYP/backend/app/database/myp.db \
|
||||||
|
/home/user/backup_$(date +%Y%m%d_%H%M%S).db
|
||||||
|
|
||||||
|
# Automatisches Backup (Crontab)
|
||||||
|
crontab -e
|
||||||
|
# Hinzufügen:
|
||||||
|
# 0 2 * * * cp /home/user/Projektarbeit-MYP/backend/app/database/myp.db /home/user/backup_$(date +\%Y\%m\%d).db
|
||||||
|
```
|
||||||
|
|
||||||
|
### Updates
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Code aktualisieren
|
||||||
|
cd /home/user/Projektarbeit-MYP
|
||||||
|
git pull
|
||||||
|
|
||||||
|
# Python-Abhängigkeiten aktualisieren
|
||||||
|
source backend/venv/bin/activate
|
||||||
|
pip install -r backend/requirements.txt
|
||||||
|
|
||||||
|
# Service neu starten
|
||||||
|
sudo systemctl restart myp-platform
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Häufige Probleme
|
||||||
|
|
||||||
|
#### Service startet nicht
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Logs prüfen
|
||||||
|
sudo journalctl -u myp-platform -n 50
|
||||||
|
|
||||||
|
# Manuell starten (Debug)
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SSL-Probleme
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Zertifikate neu generieren
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python -c "from utils.ssl_manager import ssl_manager; ssl_manager.generate_mercedes_certificate()"
|
||||||
|
|
||||||
|
# Nginx neu starten
|
||||||
|
sudo systemctl restart nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Datenbank-Probleme
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Datenbank neu initialisieren
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python -c "from models import init_database, create_initial_admin; init_database(); create_initial_admin()"
|
||||||
|
|
||||||
|
# Drucker neu einrichten
|
||||||
|
python setup_drucker_db.py
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Port-Konflikte
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verwendete Ports prüfen
|
||||||
|
sudo netstat -tlnp | grep :443
|
||||||
|
sudo netstat -tlnp | grep :80
|
||||||
|
|
||||||
|
# Prozesse beenden
|
||||||
|
sudo pkill -f "python app.py"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance-Optimierung
|
||||||
|
|
||||||
|
#### Systemressourcen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# RAM-Nutzung prüfen
|
||||||
|
free -h
|
||||||
|
|
||||||
|
# CPU-Nutzung prüfen
|
||||||
|
htop
|
||||||
|
|
||||||
|
# Festplatte prüfen
|
||||||
|
df -h
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Log-Rotation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Logrotate konfigurieren
|
||||||
|
sudo tee /etc/logrotate.d/myp-platform > /dev/null <<EOF
|
||||||
|
/home/user/Projektarbeit-MYP/backend/app/logs/*/*.log {
|
||||||
|
daily
|
||||||
|
missingok
|
||||||
|
rotate 7
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
notifempty
|
||||||
|
copytruncate
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sicherheit
|
||||||
|
|
||||||
|
### Firewall
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# UFW-Status prüfen
|
||||||
|
sudo ufw status
|
||||||
|
|
||||||
|
# Zusätzliche Regeln
|
||||||
|
sudo ufw allow from 192.168.0.0/24 to any port 22
|
||||||
|
sudo ufw deny 22
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSL-Härtung
|
||||||
|
|
||||||
|
Für Produktionsumgebung:
|
||||||
|
|
||||||
|
1. Echte SSL-Zertifikate verwenden (Let's Encrypt)
|
||||||
|
2. HSTS aktivieren
|
||||||
|
3. Security Headers konfigurieren
|
||||||
|
4. Regelmäßige Updates
|
||||||
|
|
||||||
|
### Backup-Strategie
|
||||||
|
|
||||||
|
1. Tägliche Datenbank-Backups
|
||||||
|
2. Wöchentliche Vollbackups
|
||||||
|
3. Externe Speicherung
|
||||||
|
4. Restore-Tests
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
### Kontakt
|
||||||
|
|
||||||
|
- **E-Mail**: admin@mercedes-benz.com
|
||||||
|
- **Dokumentation**: /home/user/Projektarbeit-MYP/docs/
|
||||||
|
|
||||||
|
### Nützliche Befehle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# System-Informationen
|
||||||
|
hostnamectl
|
||||||
|
cat /etc/os-release
|
||||||
|
python3 --version
|
||||||
|
|
||||||
|
# Netzwerk-Informationen
|
||||||
|
ip addr show
|
||||||
|
hostname -I
|
||||||
|
|
||||||
|
# Service-Übersicht
|
||||||
|
systemctl list-units --type=service --state=running
|
||||||
|
```
|
121
backend/RASPBERRY_PI_SETUP.md
Normal file
121
backend/RASPBERRY_PI_SETUP.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# MYP Platform - Raspberry Pi Setup
|
||||||
|
|
||||||
|
## Schnellstart
|
||||||
|
|
||||||
|
### 1. Projekt kopieren
|
||||||
|
```bash
|
||||||
|
scp -r Projektarbeit-MYP user@raspberrypi:/home/user/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Setup ausführen
|
||||||
|
```bash
|
||||||
|
ssh user@raspberrypi
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend
|
||||||
|
chmod +x setup_raspberry_pi.sh
|
||||||
|
./setup_raspberry_pi.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Zugriff
|
||||||
|
- **URL**: https://raspberrypi
|
||||||
|
- **Login**: admin@mercedes-benz.com
|
||||||
|
- **Passwort**: 744563017196A
|
||||||
|
|
||||||
|
## Was wird installiert?
|
||||||
|
|
||||||
|
### System-Pakete
|
||||||
|
- Python 3 + pip + venv
|
||||||
|
- Nginx (Reverse Proxy)
|
||||||
|
- Supervisor (Process Manager)
|
||||||
|
- SQLite3 (Datenbank)
|
||||||
|
- OpenSSL (SSL-Zertifikate)
|
||||||
|
- Build-Tools (gcc, make, etc.)
|
||||||
|
|
||||||
|
### Python-Abhängigkeiten
|
||||||
|
- Flask 2.3.3 (Web Framework)
|
||||||
|
- SQLAlchemy 2.0.21 (ORM)
|
||||||
|
- cryptography 41.0.4 (SSL)
|
||||||
|
- PyP100 0.1.4 (Tapo Smart Plugs)
|
||||||
|
- psutil 5.9.5 (System Monitoring)
|
||||||
|
- gunicorn 21.2.0 (Production Server)
|
||||||
|
- RPi.GPIO 0.7.1 (Hardware Interface)
|
||||||
|
- Weitere 20+ Pakete (siehe requirements.txt)
|
||||||
|
|
||||||
|
### Services
|
||||||
|
- **myp-platform.service**: Hauptanwendung
|
||||||
|
- **nginx**: Reverse Proxy + SSL
|
||||||
|
- **supervisor**: Process Management
|
||||||
|
- **ufw**: Firewall (Ports 22, 80, 443)
|
||||||
|
|
||||||
|
### Verzeichnisstruktur
|
||||||
|
```
|
||||||
|
/home/user/Projektarbeit-MYP/
|
||||||
|
├── backend/
|
||||||
|
│ ├── app/ # Hauptanwendung
|
||||||
|
│ │ ├── database/myp.db # SQLite Datenbank
|
||||||
|
│ │ └── logs/ # Log-Dateien
|
||||||
|
│ ├── certs/ # SSL-Zertifikate
|
||||||
|
│ ├── venv/ # Python Virtual Environment
|
||||||
|
│ └── requirements.txt # Python-Abhängigkeiten
|
||||||
|
└── frontend/ssl/ # Frontend SSL-Zertifikate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hardkodierte Drucker
|
||||||
|
- **Printer 1**: 192.168.0.100
|
||||||
|
- **Printer 2**: 192.168.0.101
|
||||||
|
- **Printer 3**: 192.168.0.102
|
||||||
|
- **Printer 4**: 192.168.0.103
|
||||||
|
- **Printer 5**: 192.168.0.104
|
||||||
|
- **Printer 6**: 192.168.0.106
|
||||||
|
|
||||||
|
## Wartung
|
||||||
|
|
||||||
|
### Service-Befehle
|
||||||
|
```bash
|
||||||
|
# Status prüfen
|
||||||
|
sudo systemctl status myp-platform
|
||||||
|
|
||||||
|
# Neu starten
|
||||||
|
sudo systemctl restart myp-platform
|
||||||
|
|
||||||
|
# Logs anzeigen
|
||||||
|
sudo journalctl -u myp-platform -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### Drucker neu einrichten
|
||||||
|
```bash
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python setup_drucker_db.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSL-Zertifikate erneuern
|
||||||
|
```bash
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python -c "from utils.ssl_manager import ssl_manager; ssl_manager.generate_mercedes_certificate()"
|
||||||
|
sudo systemctl restart nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Service startet nicht
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u myp-platform -n 50
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manueller Start (Debug)
|
||||||
|
```bash
|
||||||
|
cd /home/user/Projektarbeit-MYP/backend/app
|
||||||
|
source ../venv/bin/activate
|
||||||
|
python app.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ports prüfen
|
||||||
|
```bash
|
||||||
|
sudo netstat -tlnp | grep :443
|
||||||
|
sudo netstat -tlnp | grep :80
|
||||||
|
```
|
||||||
|
|
||||||
|
## Vollständige Dokumentation
|
||||||
|
|
||||||
|
Siehe: `DEPLOYMENT.md` für detaillierte Anweisungen.
|
Binary file not shown.
@@ -1,153 +1,73 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
SSL-Zertifikatsverwaltung für das Mercedes-Benz MYP-System
|
SSL-Manager für die MYP-Plattform
|
||||||
Konsolidiert die Funktionalität der SSL-Zertifikatsgenerierung
|
Generiert und verwaltet SSL-Zertifikate für Mercedes-Benz Yard Printing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import datetime
|
import socket
|
||||||
import shutil
|
from datetime import datetime, timedelta
|
||||||
import platform
|
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict, List, Optional, Tuple, Any
|
|
||||||
|
|
||||||
from cryptography import x509
|
from cryptography import x509
|
||||||
from cryptography.x509.oid import NameOID
|
from cryptography.x509.oid import NameOID, ExtendedKeyUsageOID
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes, serialization
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||||
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
|
|
||||||
import ipaddress
|
import ipaddress
|
||||||
|
|
||||||
from config.settings import SSL_CERT_PATH, SSL_KEY_PATH, SSL_HOSTNAME
|
class SSLManager:
|
||||||
from utils.logging_config import get_logger
|
"""SSL-Zertifikat-Manager für die MYP-Plattform"""
|
||||||
|
|
||||||
ssl_logger = get_logger("ssl")
|
def __init__(self, cert_path: str = None, key_path: str = None):
|
||||||
|
|
||||||
class SSLCertificateManager:
|
|
||||||
"""
|
"""
|
||||||
Verwaltet SSL-Zertifikate für das MYP-System
|
Initialisiert den SSL-Manager
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.cert_path = SSL_CERT_PATH
|
|
||||||
self.key_path = SSL_KEY_PATH
|
|
||||||
self.hostname = SSL_HOSTNAME
|
|
||||||
|
|
||||||
# Verzeichnisse definieren
|
|
||||||
self.certs_dir = os.path.dirname(self.cert_path)
|
|
||||||
self.frontend_ssl_dir = "/home/user/Projektarbeit-MYP/frontend/ssl"
|
|
||||||
|
|
||||||
# Mercedes-Benz spezifische Konfiguration
|
|
||||||
self.mercedes_config = {
|
|
||||||
"organization": "Mercedes-Benz AG",
|
|
||||||
"organizational_unit": "Werk 040 Berlin",
|
|
||||||
"locality": "Berlin",
|
|
||||||
"state": "Berlin",
|
|
||||||
"country": "DE",
|
|
||||||
"email": "admin@mercedes-benz.com"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Erweiterte Hostnamen und IP-Adressen
|
|
||||||
self.hostnames = [
|
|
||||||
"localhost",
|
|
||||||
"raspberrypi",
|
|
||||||
"m040tbaraspi001",
|
|
||||||
"m040tbaraspi001.de040.corpintra.net",
|
|
||||||
"mbag.corpintra.net",
|
|
||||||
"mbag.mb.corpintra.net"
|
|
||||||
]
|
|
||||||
|
|
||||||
self.ip_addresses = [
|
|
||||||
"127.0.0.1",
|
|
||||||
"192.168.0.101",
|
|
||||||
"192.168.0.102",
|
|
||||||
"192.168.0.103",
|
|
||||||
"192.168.0.104",
|
|
||||||
"192.168.0.105",
|
|
||||||
"192.168.0.106"
|
|
||||||
]
|
|
||||||
|
|
||||||
def ensure_directories(self) -> None:
|
|
||||||
"""Erstellt notwendige Verzeichnisse"""
|
|
||||||
os.makedirs(self.certs_dir, exist_ok=True)
|
|
||||||
os.makedirs(self.frontend_ssl_dir, exist_ok=True)
|
|
||||||
ssl_logger.info(f"SSL-Verzeichnisse erstellt: {self.certs_dir}, {self.frontend_ssl_dir}")
|
|
||||||
|
|
||||||
def cleanup_old_certificates(self) -> None:
|
|
||||||
"""Entfernt alte Zertifikate und veraltete Verzeichnisse"""
|
|
||||||
# Alte SSL-Verzeichnisse löschen
|
|
||||||
old_ssl_dirs = [
|
|
||||||
os.path.join(os.path.dirname(os.path.dirname(self.certs_dir)), "app", "instance", "ssl"),
|
|
||||||
os.path.join(os.path.dirname(os.path.dirname(self.certs_dir)), "app", "certs")
|
|
||||||
]
|
|
||||||
|
|
||||||
for old_dir in old_ssl_dirs:
|
|
||||||
if os.path.exists(old_dir):
|
|
||||||
ssl_logger.info(f"Lösche alten SSL-Ordner: {old_dir}")
|
|
||||||
try:
|
|
||||||
shutil.rmtree(old_dir)
|
|
||||||
except Exception as e:
|
|
||||||
ssl_logger.warning(f"Konnte alten SSL-Ordner nicht löschen: {e}")
|
|
||||||
|
|
||||||
# Alte Zertifikate im aktuellen Verzeichnis entfernen
|
|
||||||
for path in [self.cert_path, self.key_path]:
|
|
||||||
if os.path.exists(path):
|
|
||||||
os.remove(path)
|
|
||||||
ssl_logger.info(f"Alte Zertifikatsdatei entfernt: {path}")
|
|
||||||
|
|
||||||
def generate_mercedes_certificate(self, key_size: int = 4096, validity_days: int = 365) -> bool:
|
|
||||||
"""
|
|
||||||
Generiert ein vollständiges Mercedes-Benz SSL-Zertifikat
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
key_size: Schlüsselgröße in Bits (Standard: 4096)
|
cert_path: Pfad zum SSL-Zertifikat
|
||||||
validity_days: Gültigkeitsdauer in Tagen (Standard: 365)
|
key_path: Pfad zum SSL-Schlüssel
|
||||||
|
"""
|
||||||
|
from config.settings import SSL_CERT_PATH, SSL_KEY_PATH
|
||||||
|
|
||||||
|
self.cert_path = cert_path or SSL_CERT_PATH
|
||||||
|
self.key_path = key_path or SSL_KEY_PATH
|
||||||
|
|
||||||
|
# Stelle sicher, dass das Verzeichnis existiert
|
||||||
|
cert_dir = os.path.dirname(self.cert_path)
|
||||||
|
if not os.path.exists(cert_dir):
|
||||||
|
os.makedirs(cert_dir, exist_ok=True)
|
||||||
|
|
||||||
|
def generate_mercedes_certificate(self,
|
||||||
|
hostname: str = "localhost",
|
||||||
|
validity_days: int = 365) -> bool:
|
||||||
|
"""
|
||||||
|
Generiert ein Mercedes-Benz SSL-Zertifikat
|
||||||
|
|
||||||
|
Args:
|
||||||
|
hostname: Hostname für das Zertifikat
|
||||||
|
validity_days: Gültigkeitsdauer in Tagen
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True bei Erfolg, False bei Fehler
|
bool: True wenn erfolgreich, False bei Fehler
|
||||||
"""
|
"""
|
||||||
ssl_logger.info("Generiere Mercedes-Benz SSL-Zertifikat...")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Verzeichnisse vorbereiten
|
print(f"Generiere Mercedes-Benz SSL-Zertifikat für {hostname}...")
|
||||||
self.ensure_directories()
|
|
||||||
self.cleanup_old_certificates()
|
|
||||||
|
|
||||||
# Privaten Schlüssel generieren
|
# Privaten Schlüssel generieren (4096-bit für höhere Sicherheit)
|
||||||
private_key = rsa.generate_private_key(
|
private_key = rsa.generate_private_key(
|
||||||
public_exponent=65537,
|
public_exponent=65537,
|
||||||
key_size=key_size,
|
key_size=4096,
|
||||||
)
|
)
|
||||||
ssl_logger.info(f"Privater Schlüssel mit {key_size} Bit generiert")
|
|
||||||
|
|
||||||
# Zeitstempel
|
# Subject und Issuer für Mercedes-Benz
|
||||||
now = datetime.datetime.now()
|
|
||||||
valid_until = now + datetime.timedelta(days=validity_days)
|
|
||||||
|
|
||||||
# Zertifikatsattribute für Mercedes-Benz
|
|
||||||
subject = issuer = x509.Name([
|
subject = issuer = x509.Name([
|
||||||
x509.NameAttribute(NameOID.COMMON_NAME, self.hostname),
|
x509.NameAttribute(NameOID.COUNTRY_NAME, "DE"),
|
||||||
x509.NameAttribute(NameOID.ORGANIZATION_NAME, self.mercedes_config["organization"]),
|
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Baden-Württemberg"),
|
||||||
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, self.mercedes_config["organizational_unit"]),
|
x509.NameAttribute(NameOID.LOCALITY_NAME, "Stuttgart"),
|
||||||
x509.NameAttribute(NameOID.LOCALITY_NAME, self.mercedes_config["locality"]),
|
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mercedes-Benz Group AG"),
|
||||||
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, self.mercedes_config["state"]),
|
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "IT Infrastructure"),
|
||||||
x509.NameAttribute(NameOID.COUNTRY_NAME, self.mercedes_config["country"]),
|
x509.NameAttribute(NameOID.COMMON_NAME, hostname),
|
||||||
x509.NameAttribute(NameOID.EMAIL_ADDRESS, self.mercedes_config["email"]),
|
x509.NameAttribute(NameOID.EMAIL_ADDRESS, "admin@mercedes-benz.com"),
|
||||||
])
|
])
|
||||||
|
|
||||||
# Subject Alternative Names (SAN) erstellen
|
|
||||||
san_list = []
|
|
||||||
for hostname in self.hostnames:
|
|
||||||
san_list.append(x509.DNSName(hostname))
|
|
||||||
|
|
||||||
for ip in self.ip_addresses:
|
|
||||||
try:
|
|
||||||
san_list.append(x509.IPAddress(ipaddress.IPv4Address(ip)))
|
|
||||||
except ipaddress.AddressValueError:
|
|
||||||
ssl_logger.warning(f"Ungültige IP-Adresse übersprungen: {ip}")
|
|
||||||
|
|
||||||
# Zertifikat erstellen
|
# Zertifikat erstellen
|
||||||
cert = x509.CertificateBuilder().subject_name(
|
cert = x509.CertificateBuilder().subject_name(
|
||||||
subject
|
subject
|
||||||
@@ -158,230 +78,193 @@ class SSLCertificateManager:
|
|||||||
).serial_number(
|
).serial_number(
|
||||||
x509.random_serial_number()
|
x509.random_serial_number()
|
||||||
).not_valid_before(
|
).not_valid_before(
|
||||||
now
|
datetime.utcnow()
|
||||||
).not_valid_after(
|
).not_valid_after(
|
||||||
valid_until
|
datetime.utcnow() + timedelta(days=validity_days)
|
||||||
).add_extension(
|
)
|
||||||
|
|
||||||
|
# Subject Alternative Names hinzufügen
|
||||||
|
san_list = [
|
||||||
|
x509.DNSName(hostname),
|
||||||
|
x509.DNSName("localhost"),
|
||||||
|
x509.DNSName("*.localhost"),
|
||||||
|
x509.DNSName("raspberrypi"),
|
||||||
|
x509.DNSName("*.raspberrypi"),
|
||||||
|
x509.DNSName("myp.mercedes-benz.local"),
|
||||||
|
x509.DNSName("*.myp.mercedes-benz.local"),
|
||||||
|
x509.IPAddress(ipaddress.IPv4Address("127.0.0.1")),
|
||||||
|
x509.IPAddress(ipaddress.IPv4Address("0.0.0.0")),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Lokale IP-Adresse hinzufügen
|
||||||
|
try:
|
||||||
|
local_ip = socket.gethostbyname(socket.gethostname())
|
||||||
|
if local_ip and local_ip != "127.0.0.1":
|
||||||
|
san_list.append(x509.IPAddress(ipaddress.IPv4Address(local_ip)))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
cert = cert.add_extension(
|
||||||
x509.SubjectAlternativeName(san_list),
|
x509.SubjectAlternativeName(san_list),
|
||||||
critical=False,
|
critical=False,
|
||||||
).add_extension(
|
)
|
||||||
x509.BasicConstraints(ca=True, path_length=None), critical=True
|
|
||||||
).add_extension(
|
# Key Usage Extension
|
||||||
|
cert = cert.add_extension(
|
||||||
x509.KeyUsage(
|
x509.KeyUsage(
|
||||||
digital_signature=True,
|
digital_signature=True,
|
||||||
content_commitment=False,
|
|
||||||
key_encipherment=True,
|
key_encipherment=True,
|
||||||
data_encipherment=False,
|
|
||||||
key_agreement=False,
|
key_agreement=False,
|
||||||
key_cert_sign=True,
|
key_cert_sign=False,
|
||||||
crl_sign=True,
|
crl_sign=False,
|
||||||
|
content_commitment=False,
|
||||||
|
data_encipherment=False,
|
||||||
encipher_only=False,
|
encipher_only=False,
|
||||||
decipher_only=False
|
decipher_only=False,
|
||||||
), critical=True
|
),
|
||||||
).add_extension(
|
critical=True,
|
||||||
x509.ExtendedKeyUsage([
|
)
|
||||||
x509.oid.ExtendedKeyUsageOID.SERVER_AUTH,
|
|
||||||
x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH,
|
|
||||||
x509.oid.ExtendedKeyUsageOID.CODE_SIGNING
|
|
||||||
]), critical=False
|
|
||||||
).sign(private_key, hashes.SHA256())
|
|
||||||
|
|
||||||
# Zertifikat und Schlüssel speichern
|
# Extended Key Usage
|
||||||
|
cert = cert.add_extension(
|
||||||
|
x509.ExtendedKeyUsage([
|
||||||
|
ExtendedKeyUsageOID.SERVER_AUTH,
|
||||||
|
ExtendedKeyUsageOID.CLIENT_AUTH,
|
||||||
|
]),
|
||||||
|
critical=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Basic Constraints
|
||||||
|
cert = cert.add_extension(
|
||||||
|
x509.BasicConstraints(ca=False, path_length=None),
|
||||||
|
critical=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Zertifikat signieren
|
||||||
|
cert = cert.sign(private_key, hashes.SHA256())
|
||||||
|
|
||||||
|
# Zertifikat in Datei schreiben
|
||||||
|
with open(self.cert_path, "wb") as f:
|
||||||
|
f.write(cert.public_bytes(serialization.Encoding.PEM))
|
||||||
|
|
||||||
|
# Privaten Schlüssel in Datei schreiben
|
||||||
with open(self.key_path, "wb") as f:
|
with open(self.key_path, "wb") as f:
|
||||||
f.write(private_key.private_bytes(
|
f.write(private_key.private_bytes(
|
||||||
encoding=Encoding.PEM,
|
encoding=serialization.Encoding.PEM,
|
||||||
format=PrivateFormat.TraditionalOpenSSL,
|
format=serialization.PrivateFormat.PKCS8,
|
||||||
encryption_algorithm=NoEncryption()
|
encryption_algorithm=serialization.NoEncryption()
|
||||||
))
|
))
|
||||||
|
|
||||||
with open(self.cert_path, "wb") as f:
|
print(f"✓ SSL-Zertifikat erfolgreich erstellt: {self.cert_path}")
|
||||||
f.write(cert.public_bytes(Encoding.PEM))
|
print(f"✓ SSL-Schlüssel erfolgreich erstellt: {self.key_path}")
|
||||||
|
|
||||||
# Berechtigungen setzen
|
# Zertifikatsinformationen anzeigen
|
||||||
os.chmod(self.key_path, 0o600)
|
self._print_certificate_info(cert)
|
||||||
os.chmod(self.cert_path, 0o644)
|
|
||||||
|
|
||||||
ssl_logger.info(f"Mercedes-Benz SSL-Zertifikat erfolgreich erstellt:")
|
|
||||||
ssl_logger.info(f"- Zertifikat: {os.path.abspath(self.cert_path)}")
|
|
||||||
ssl_logger.info(f"- Schlüssel: {os.path.abspath(self.key_path)}")
|
|
||||||
ssl_logger.info(f"- Gültig bis: {valid_until.strftime('%d.%m.%Y')}")
|
|
||||||
ssl_logger.info(f"- Hostnamen: {', '.join(self.hostnames)}")
|
|
||||||
ssl_logger.info(f"- IP-Adressen: {', '.join(self.ip_addresses)}")
|
|
||||||
|
|
||||||
# Zertifikate ins Frontend kopieren
|
|
||||||
self._copy_to_frontend()
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
ssl_logger.error(f"Fehler beim Erstellen des Mercedes-Benz SSL-Zertifikats: {e}")
|
print(f"✗ Fehler beim Erstellen des SSL-Zertifikats: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _copy_to_frontend(self) -> bool:
|
def _print_certificate_info(self, cert):
|
||||||
"""Kopiert Zertifikate ins Frontend-Verzeichnis"""
|
"""Zeigt Informationen über das erstellte Zertifikat an"""
|
||||||
try:
|
try:
|
||||||
shutil.copy2(self.cert_path, os.path.join(self.frontend_ssl_dir, "myp.crt"))
|
print("\n=== Zertifikatsinformationen ===")
|
||||||
shutil.copy2(self.key_path, os.path.join(self.frontend_ssl_dir, "myp.key"))
|
print(f"Subject: {cert.subject.rfc4514_string()}")
|
||||||
ssl_logger.info(f"Zertifikate ins Frontend kopiert: {os.path.abspath(self.frontend_ssl_dir)}")
|
print(f"Gültig von: {cert.not_valid_before}")
|
||||||
return True
|
print(f"Gültig bis: {cert.not_valid_after}")
|
||||||
except Exception as e:
|
print(f"Seriennummer: {cert.serial_number}")
|
||||||
ssl_logger.error(f"Fehler beim Kopieren ins Frontend: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def install_system_certificate(self) -> bool:
|
|
||||||
"""
|
|
||||||
Installiert das Zertifikat im System-Zertifikatsspeicher
|
|
||||||
Nur für Windows-Systeme
|
|
||||||
"""
|
|
||||||
if platform.system() != "Windows":
|
|
||||||
ssl_logger.warning("System-Zertifikatsinstallation nur unter Windows verfügbar")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
# SAN anzeigen
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(self.cert_path):
|
san_ext = cert.extensions.get_extension_for_oid(x509.oid.ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
|
||||||
ssl_logger.error(f"Zertifikat nicht gefunden: {self.cert_path}")
|
print("Subject Alternative Names:")
|
||||||
return False
|
for name in san_ext.value:
|
||||||
|
print(f" - {name}")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# Befehle zum Installieren des Zertifikats im Windows-Zertifikatsspeicher
|
print("================================\n")
|
||||||
commands = [
|
|
||||||
["certutil", "-addstore", "-f", "ROOT", self.cert_path],
|
|
||||||
["certutil", "-addstore", "-f", "CA", self.cert_path],
|
|
||||||
["certutil", "-addstore", "-f", "MY", self.cert_path]
|
|
||||||
]
|
|
||||||
|
|
||||||
for cmd in commands:
|
|
||||||
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
|
||||||
ssl_logger.debug(f"Certutil-Befehl ausgeführt: {' '.join(cmd)}")
|
|
||||||
|
|
||||||
ssl_logger.info("Zertifikat erfolgreich im System-Zertifikatsspeicher installiert")
|
|
||||||
return True
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
ssl_logger.error(f"Fehler bei der Installation des Zertifikats im System: {e}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
ssl_logger.error(f"Unerwarteter Fehler bei der Zertifikatsinstallation: {e}")
|
print(f"Fehler beim Anzeigen der Zertifikatsinformationen: {e}")
|
||||||
return False
|
|
||||||
|
|
||||||
def copy_to_raspberry(self, host: str = "raspberrypi", user: str = "user", dest: str = "/home/user/Projektarbeit-MYP/backend/app/certs") -> bool:
|
def certificate_exists(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Kopiert das Zertifikat auf den Raspberry Pi
|
Prüft, ob SSL-Zertifikat und Schlüssel existieren
|
||||||
|
|
||||||
Args:
|
|
||||||
host: Hostname des Raspberry Pi
|
|
||||||
user: Benutzername für SSH
|
|
||||||
dest: Zielverzeichnis auf dem Raspberry Pi
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True bei Erfolg, False bei Fehler
|
bool: True wenn beide Dateien existieren
|
||||||
"""
|
"""
|
||||||
try:
|
return os.path.exists(self.cert_path) and os.path.exists(self.key_path)
|
||||||
if not os.path.exists(self.cert_path) or not os.path.exists(self.key_path):
|
|
||||||
ssl_logger.error("Zertifikatsdateien nicht gefunden")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# SSH-Befehl zum Erstellen des Verzeichnisses
|
def get_certificate_info(self) -> dict:
|
||||||
ssh_command = ["ssh", f"{user}@{host}", f"mkdir -p {dest}"]
|
|
||||||
subprocess.run(ssh_command, check=True)
|
|
||||||
ssl_logger.info(f"Verzeichnis auf Raspberry Pi erstellt: {dest}")
|
|
||||||
|
|
||||||
# SCP-Befehle zum Kopieren der Dateien
|
|
||||||
scp_commands = [
|
|
||||||
["scp", self.cert_path, f"{user}@{host}:{dest}/myp.crt"],
|
|
||||||
["scp", self.key_path, f"{user}@{host}:{dest}/myp.key"]
|
|
||||||
]
|
|
||||||
|
|
||||||
for cmd in scp_commands:
|
|
||||||
subprocess.run(cmd, check=True)
|
|
||||||
ssl_logger.info(f"Datei kopiert: {cmd[1]} -> {cmd[2]}")
|
|
||||||
|
|
||||||
# Berechtigungen setzen
|
|
||||||
chmod_command = ["ssh", f"{user}@{host}", f"chmod 600 {dest}/myp.key"]
|
|
||||||
subprocess.run(chmod_command, check=True)
|
|
||||||
|
|
||||||
# Zertifikat im System registrieren
|
|
||||||
install_command = ["ssh", f"{user}@{host}",
|
|
||||||
f"sudo cp {dest}/myp.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates"]
|
|
||||||
subprocess.run(install_command, check=True)
|
|
||||||
|
|
||||||
ssl_logger.info(f"Zertifikate erfolgreich auf Raspberry Pi installiert: {host}:{dest}")
|
|
||||||
return True
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
ssl_logger.error(f"Fehler beim Kopieren auf Raspberry Pi: {e}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
ssl_logger.error(f"Unerwarteter Fehler beim Raspberry Pi-Transfer: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_certificate_info(self) -> Optional[Dict[str, Any]]:
|
|
||||||
"""
|
"""
|
||||||
Gibt Informationen über das aktuelle Zertifikat zurück
|
Gibt Informationen über das vorhandene Zertifikat zurück
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Dict mit Zertifikatsinformationen oder None bei Fehler
|
dict: Zertifikatsinformationen oder None bei Fehler
|
||||||
"""
|
"""
|
||||||
try:
|
if not self.certificate_exists():
|
||||||
if not os.path.exists(self.cert_path):
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
with open(self.cert_path, "rb") as f:
|
with open(self.cert_path, "rb") as f:
|
||||||
cert = x509.load_pem_x509_certificate(f.read())
|
cert_data = f.read()
|
||||||
|
|
||||||
|
cert = x509.load_pem_x509_certificate(cert_data)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"subject": cert.subject.rfc4514_string(),
|
"subject": cert.subject.rfc4514_string(),
|
||||||
"issuer": cert.issuer.rfc4514_string(),
|
"issuer": cert.issuer.rfc4514_string(),
|
||||||
"serial_number": str(cert.serial_number),
|
"not_valid_before": cert.not_valid_before,
|
||||||
"not_valid_before": cert.not_valid_before.strftime('%d.%m.%Y %H:%M:%S'),
|
"not_valid_after": cert.not_valid_after,
|
||||||
"not_valid_after": cert.not_valid_after.strftime('%d.%m.%Y %H:%M:%S'),
|
"serial_number": cert.serial_number,
|
||||||
"is_expired": cert.not_valid_after < datetime.datetime.now(),
|
"is_expired": datetime.utcnow() > cert.not_valid_after,
|
||||||
"days_until_expiry": (cert.not_valid_after - datetime.datetime.now()).days,
|
"days_until_expiry": (cert.not_valid_after - datetime.utcnow()).days
|
||||||
"fingerprint": cert.fingerprint(hashes.SHA256()).hex(),
|
|
||||||
"key_size": cert.public_key().key_size if hasattr(cert.public_key(), 'key_size') else None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
ssl_logger.error(f"Fehler beim Lesen der Zertifikatsinformationen: {e}")
|
print(f"Fehler beim Lesen der Zertifikatsinformationen: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def is_certificate_valid(self) -> bool:
|
# Globale SSL-Manager-Instanz
|
||||||
|
ssl_manager = SSLManager()
|
||||||
|
|
||||||
|
def ensure_ssl_certificates() -> bool:
|
||||||
"""
|
"""
|
||||||
Prüft, ob das aktuelle Zertifikat gültig ist
|
Stellt sicher, dass SSL-Zertifikate vorhanden sind
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True wenn gültig, False wenn ungültig oder nicht vorhanden
|
bool: True wenn Zertifikate verfügbar sind
|
||||||
"""
|
"""
|
||||||
cert_info = self.get_certificate_info()
|
if ssl_manager.certificate_exists():
|
||||||
if not cert_info:
|
cert_info = ssl_manager.get_certificate_info()
|
||||||
return False
|
if cert_info and not cert_info["is_expired"]:
|
||||||
|
print(f"✓ Gültiges SSL-Zertifikat gefunden (läuft ab in {cert_info['days_until_expiry']} Tagen)")
|
||||||
return not cert_info["is_expired"] and cert_info["days_until_expiry"] > 30
|
|
||||||
|
|
||||||
def regenerate_if_needed(self) -> bool:
|
|
||||||
"""
|
|
||||||
Regeneriert das Zertifikat, falls es ungültig oder bald abgelaufen ist
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: True wenn regeneriert oder bereits gültig, False bei Fehler
|
|
||||||
"""
|
|
||||||
if self.is_certificate_valid():
|
|
||||||
ssl_logger.info("Zertifikat ist noch gültig, keine Regenerierung notwendig")
|
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
print("⚠ SSL-Zertifikat ist abgelaufen, erstelle neues...")
|
||||||
|
|
||||||
ssl_logger.info("Zertifikat ist ungültig oder läuft bald ab, regeneriere...")
|
print("SSL-Zertifikate nicht gefunden, erstelle neue...")
|
||||||
return self.generate_mercedes_certificate()
|
|
||||||
|
|
||||||
# Globale Instanz für einfachen Zugriff
|
|
||||||
ssl_manager = SSLCertificateManager()
|
|
||||||
|
|
||||||
def generate_ssl_certificate() -> bool:
|
|
||||||
"""Wrapper-Funktion für Rückwärtskompatibilität"""
|
|
||||||
return ssl_manager.generate_mercedes_certificate()
|
return ssl_manager.generate_mercedes_certificate()
|
||||||
|
|
||||||
def get_ssl_certificate_info() -> Optional[Dict[str, Any]]:
|
if __name__ == "__main__":
|
||||||
"""Wrapper-Funktion für Zertifikatsinformationen"""
|
# Direkte Ausführung für Tests
|
||||||
return ssl_manager.get_certificate_info()
|
print("Mercedes-Benz SSL-Zertifikat-Generator")
|
||||||
|
print("=====================================")
|
||||||
|
|
||||||
def ensure_valid_ssl_certificate() -> bool:
|
if ssl_manager.certificate_exists():
|
||||||
"""Stellt sicher, dass ein gültiges SSL-Zertifikat vorhanden ist"""
|
print("Vorhandene Zertifikate gefunden:")
|
||||||
return ssl_manager.regenerate_if_needed()
|
info = ssl_manager.get_certificate_info()
|
||||||
|
if info:
|
||||||
|
print(f" Subject: {info['subject']}")
|
||||||
|
print(f" Gültig bis: {info['not_valid_after']}")
|
||||||
|
print(f" Status: {'Abgelaufen' if info['is_expired'] else 'Gültig'}")
|
||||||
|
|
||||||
|
success = ssl_manager.generate_mercedes_certificate()
|
||||||
|
if success:
|
||||||
|
print("✓ SSL-Zertifikat erfolgreich generiert!")
|
||||||
|
else:
|
||||||
|
print("✗ Fehler beim Generieren des SSL-Zertifikats!")
|
Reference in New Issue
Block a user