add flatnotes and ssh config for jenkins
This commit is contained in:
1 parent
f8b25d7c78
commit
23f06afd53
21 files changed
+1016
-22
No files matched your search
+6
-1
@@ -6,4 +6,9 @@
|
||||
/WEBSERVER/BACKUP/
|
||||
/HAPROXY/backups/
|
||||
/SESSIONS/
|
||||
/DNSMASQ/
|
||||
/DNSMASQ/
|
||||
/JENKINS/
|
||||
/HOMARR/
|
||||
/PORTAINER/
|
||||
/VAULTWARDEN/
|
||||
/FLATNOTES/.*
|
||||
@@ -0,0 +1,7 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACAFJzKQPw2rfnzyqWMirnkl8tqLqV9TgirJ6MKkWkd8LwAAAKDrYKuh62Cr
|
||||
oQAAAAtzc2gtZWQyNTUxOQAAACAFJzKQPw2rfnzyqWMirnkl8tqLqV9TgirJ6MKkWkd8Lw
|
||||
AAAEAnp+zgBUYl+xVBxUpR3pEOtg6Ci1z9pzpg+7crZztYuAUnMpA/Dat+fPKpYyKueSXy
|
||||
2oupX1OCKsnowqRaR3wvAAAAGXJvb3RAdjIyMDI2MDczMzI4NDY0ODIzMDEBAgME
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAUnMpA/Dat+fPKpYyKueSXy2oupX1OCKsnowqRaR3wv root@v2202607332846482301
|
||||
Binary file not shown.
Executable
+125
@@ -0,0 +1,125 @@
|
||||
# 🏗️ Backend MVC Dokumentation
|
||||
|
||||
Dieses Projekt nutzt eine moderne **Model-View-Controller (MVC)** Struktur mit einem **modularen Block-Layout**. Dies trennt die Geschäftslogik vom Design und macht den Code wartbar und erweiterbar.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Verzeichnisstruktur
|
||||
|
||||
- `WEBROOT/src/MVC/Core/`: Basisklassen (`Controller`, `View`).
|
||||
- `WEBROOT/src/MVC/Controller/`: Hier liegt die Logik (PHP-Klassen).
|
||||
- `WEBROOT/src/MVC/View/`: Hier liegen die Templates (HTML/PHP).
|
||||
- `WEBROOT/src/MVC/Layout/`: Das globale Layout-System und die Blöcke.
|
||||
- `WEBROOT/index.php`: Der "Entry Point", der alles zusammenfügt.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Einen neuen Service erstellen
|
||||
|
||||
1. **Dateien anlegen:** Nutze das Script `php create_module.php <name>`.
|
||||
2. **Controller registrieren:** Trage den neuen Controller in der `$controllers`-Liste in `WEBROOT/index.php` ein.
|
||||
3. **In Config eintragen:** Füge den Service in der `config.php` (oder über die Admin-Oberfläche) hinzu, damit er in der Sidebar erscheint.
|
||||
|
||||
---
|
||||
|
||||
## 💡 Arbeiten mit Controller & View
|
||||
|
||||
### Daten vom Controller an die View übergeben
|
||||
Im Controller nutzt du die `render()` Methode:
|
||||
|
||||
```php
|
||||
public function mein_service() {
|
||||
$userCount = 42;
|
||||
return $this->render('meine_view', [
|
||||
'anzahl' => $userCount,
|
||||
'status' => 'aktiv'
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
In der View (`meine_view.php`) sind diese Variablen direkt verfügbar:
|
||||
```html
|
||||
<p>Es sind <?= $anzahl ?> Benutzer im Status <?= $status ?>.</p>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Mehrere Funktionen in einer View nutzen
|
||||
|
||||
Wenn du innerhalb eines Projekts verschiedene Aktionen ausführen willst (z.B. Anzeigen, Bearbeiten, Löschen), gibt es zwei gängige Wege:
|
||||
|
||||
### 1. Über URL-Parameter (Empfohlen für einfache Logik)
|
||||
Du nutzt einen Parameter wie `?action=edit` in deinen Links.
|
||||
|
||||
**Im Controller:**
|
||||
```php
|
||||
public function mein_service() {
|
||||
$action = $_GET['action'] ?? 'list';
|
||||
$data = [];
|
||||
|
||||
if ($action === 'edit') {
|
||||
$data = ["mode" => "Bearbeiten"];
|
||||
} else {
|
||||
$data = ["mode" => "Listenansicht"];
|
||||
}
|
||||
|
||||
return $this->render('mein_view', $data);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Formular-Aktionen (POST)
|
||||
Wenn du Buttons für verschiedene Funktionen hast, kannst du diese im Controller abfangen:
|
||||
|
||||
**In der View:**
|
||||
```html
|
||||
<form method="POST">
|
||||
<button type="submit" name="save_data">Speichern</button>
|
||||
<button type="submit" name="delete_data">Löschen</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
**Im Controller:**
|
||||
```php
|
||||
public function mein_service() {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (isset($_POST['save_data'])) {
|
||||
// Logik für Speichern
|
||||
}
|
||||
if (isset($_POST['delete_data'])) {
|
||||
// Logik für Löschen
|
||||
}
|
||||
// Nach POST immer Redirect, um "F5-Resubmit" zu verhindern
|
||||
header("Location: ?service=mein_service");
|
||||
exit;
|
||||
}
|
||||
return $this->render('mein_view');
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧱 Das Block-Layout System
|
||||
|
||||
Das Layout besteht aus Blöcken. In der `index.php` kannst du diese Blöcke füllen, bevor das Layout gerendert wird:
|
||||
|
||||
- `title`: Der Tab-Titel.
|
||||
- `header`: Der obere Balken.
|
||||
- `sidebar`: Das Seitenmenü.
|
||||
- `content`: Der Hauptinhalt (kommt meist aus dem Controller).
|
||||
- `scripts`: Zusätzliches JavaScript für die Seite.
|
||||
|
||||
Beispiel für zusätzliche Scripte im Controller:
|
||||
```php
|
||||
// In index.php könnte man das Layout erweitern:
|
||||
$layout->setBlock('scripts', '<script src="mein_script.js"></script>');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Wichtige Regeln (Best Practices)
|
||||
|
||||
1. **Kein HTML im Controller:** Controller bereiten nur Daten vor. HTML gehört ausschließlich in die `View`.
|
||||
2. **Globale Klassen:** Nutze `\` vor globalen Funktionen oder Klassen (z.B. `\DatabaseShow()`), wenn du dich innerhalb eines Namespaces befindest.
|
||||
3. **Security:** Nutze immer `htmlspecialchars()` beim Ausgeben von Variablen in der View, um XSS-Angriffe zu verhindern.
|
||||
4. **Redirects:** Nach einem `POST` (Daten speichern) solltest du immer ein `header("Location: ...")` machen, damit die Seite beim Neuladen die Daten nicht doppelt sendet.
|
||||
5. **Namespaces:** Achte darauf, dass neue Controller immer `namespace MVC\Controller;` am Anfang stehen haben.
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
- Node 1:
|
||||
```
|
||||
MAILTO="bruno.eckhardt07@gmail.com"
|
||||
TERM=xterm
|
||||
SHELL=/bin/bash
|
||||
0 */8 * * * sudo /data/SCRIPTS/GEN-SITEMAP.sh all
|
||||
0 */12 * * * /data/SCRIPTS/MONITOR.sh
|
||||
*/15 * * * * docker exec WEBSERVER-BACKEND php /var/www/html/Commands/WeatherLog.php
|
||||
5 */2 * * * /data/SCRIPTS/DB-backup.sh
|
||||
0 0 10 * * /data/SCRIPTS/certs-renew.sh
|
||||
```
|
||||
|
||||
- Node 2:
|
||||
```
|
||||
MAILTO="bruno.eckhardt07@gmail.com"
|
||||
TERM=xterm
|
||||
SHELL=/bin/bash
|
||||
0 */12 * * * /data/SCRIPTS/MONITOR.sh
|
||||
```
|
||||
|
||||
- Node 3
|
||||
```
|
||||
MAILTO="bruno.eckhardt07@gmail.com"
|
||||
TERM=xterm
|
||||
SHELL=/bin/bash
|
||||
0 */12 * * * /data/SCRIPTS/MONITOR.sh
|
||||
5 */2 * * * /data/SCRIPTS/DB-import.sh
|
||||
```
|
||||
|
||||
- Node 4
|
||||
```
|
||||
MAILTO="bruno.eckhardt07@gmail.com"
|
||||
TERM=xterm
|
||||
SHELL=/bin/bash
|
||||
0 */2 * * * /data/SCRIPTS/DB-export.sh
|
||||
0 */12 * * * /data/SCRIPTS/MONITOR.sh
|
||||
```
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
- Datenbank export:
|
||||
```
|
||||
docker exec mariadb mariadb-dump -u worker -pbBHofurUJWKzPE8Z DEV > /data/TEMP/DEV.sql
|
||||
echo "Die Datenbank wurde um $(date) nach /data/TEMP/DEV.sql exportiert"
|
||||
```
|
||||
|
||||
- Datenbank import nach DEV:
|
||||
```
|
||||
mariadb -h 10.233.1.243 -u worker -pbBHofurUJWKzPE8Z DEV < /data/TEMP/DEV.sql
|
||||
echo "Die Datenbank wurde um $(date) von /data/TEMP/DEV.sql nach DEV importiert"
|
||||
```
|
||||
|
||||
- Datenbank import nach Backup
|
||||
```
|
||||
mariadb -h 10.233.1.241 -u worker -pbBHofurUJWKzPE8Z DEV < /data/TEMP/DEV.sql
|
||||
echo "Die Datenbank wurde um $(date) von /data/TEMP/DEV.sql nach BACKUP importiert"
|
||||
```
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
Löschen alter inhalte:
|
||||
|
||||
1. `sudo apt remove docker docker.io containerd runc`
|
||||
|
||||
System Pakete Aktuallisieren und installieren:
|
||||
|
||||
2. `sudo apt update `
|
||||
3. `sudo apt install -y ca-certificates curl gnupg`
|
||||
|
||||
Docker GPG Key hinzufügen
|
||||
```
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) \
|
||||
signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
|
||||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
|
||||
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
```
|
||||
|
||||
Docker installieren
|
||||
```
|
||||
sudo apt update
|
||||
|
||||
sudo apt install -y docker-ce docker-ce-cli containerd.io \
|
||||
docker-buildx-plugin docker-compose-plugin
|
||||
```
|
||||
|
||||
Rechte Anpassen:
|
||||
```sudo usermod -aG docker $USER ```
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
git config --global credential.helper store
|
||||
git config --global user.name "bruno"
|
||||
git config --global user.email "bruno.eckhardt07@gmail.com"
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
1. Docker installieren
|
||||
2. msmtp configurieren
|
||||
3. crontab anlegen
|
||||
4. directorys erstellen
|
||||
5. alle nötigen dateien holen von anderen servern
|
||||
6. deployen
|
||||
1. deploy.sh fetch
|
||||
2. deploy.sh public
|
||||
3. deploy.sh backend
|
||||
7. docker container hochfahren
|
||||
1. docker compose up -d [COMPOSEFILE] up -d --build
|
||||
2. docker ps
|
||||
8. Wenn nötig datenbank in /data/WEBSERVER/BACKEND|PUBLIC/controller/DatabaseConnect.php umstellen
|
||||
9. docker container neustarten
|
||||
1. docker restart WEBSERVER-PUBLIC
|
||||
2. docker restart WEBSERVER-BACKEND
|
||||
10. Wenn nötig neue ssl zertifikate erstellen mit /data/HAPROXY/certs.sh
|
||||
11. Wenn nötig neue haproxy einträge machen auf node 1 in /data/HAPROXY/haproxy.cfg
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
# Mitschrift: Subnetting, VLSM, IP-Grundlagen & Binär-Berechnung
|
||||
|
||||
## 1. Grundlagen: Was ist Subnetting?
|
||||
Subnetting bedeutet, ein großes IP-Netzwerk in mehrere, kleinere logische Netzwerke zu unterteilen.
|
||||
|
||||
* Zweck: Reduzierung des Broadcast-Verkehrs, Verbesserung der Sicherheit und effiziente Verwaltung von IP-Adressen.
|
||||
* Wichtige Begriffe:
|
||||
* Netzwerk-ID: Die Adresse des Netzwerks selbst (erste IP).
|
||||
* Broadcast-Adresse: Die letzte IP im Netz (für Nachrichten an alle Teilnehmer).
|
||||
* Host-Bits: Die Anzahl der Bits, die für die Geräte (Hosts) zur Verfügung stehen.
|
||||
|
||||
---
|
||||
|
||||
## 2. Berechnung der Subnetzmaske für X Hosts
|
||||
Wenn du ein Subnetz für eine bestimmte Anzahl an Hosts (X) benötigst:
|
||||
|
||||
Formel: 2^h - 2 >= X
|
||||
(h = Anzahl der Host-Bits; -2 = Abzug der Netzwerk-ID und Broadcast-Adresse)
|
||||
|
||||
### Schritt-für-Schritt-Anleitung:
|
||||
1. Formel anwenden: Suche das kleinste h, bei dem die Formel erfüllt ist.
|
||||
2. Subnetzmaske bestimmen: Praefix = 32 - h.
|
||||
3. Dezimal umrechnen: Setze die ersten (32-h) Bits auf 1 und die restlichen h Bits auf 0.
|
||||
|
||||
---
|
||||
|
||||
## 3. VLSM (Variable Length Subnet Masking)
|
||||
VLSM erlaubt es, Subnetze mit unterschiedlich großen Masken innerhalb eines übergeordneten Netzwerks zu verwenden.
|
||||
Goldene Regel: Sortiere immer vom größten zum kleinsten Subnetzbedarf.
|
||||
|
||||
---
|
||||
|
||||
## 4. IP-Berechnung (Schritt für Schritt)
|
||||
Um aus einer IP-Adresse und einer Subnetzmaske die Netzwerk-Parameter zu bestimmen:
|
||||
|
||||
* Netzwerk-Adresse: Alle Host-Bits auf 0 setzen.
|
||||
* Broadcast-Adresse: Alle Host-Bits auf 1 setzen.
|
||||
* Erste nutzbare IP: Netzwerk-Adresse + 1.
|
||||
* Letzte nutzbare IP: Broadcast-Adresse - 1.
|
||||
|
||||
---
|
||||
|
||||
## 5. Die binäre Berechnung (Die "Bit-Tabelle")
|
||||
Jedes Oktett besteht aus 8 Bit mit festen Werten. Damit kannst du jede Netzmaske berechnen:
|
||||
|
||||
| Bit-Position | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
||||
| **Wert** | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
|
||||
| **Ges Adr** | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 |
|
||||
| **Hosts** | 254 | 126 | 62 | 30 | 14 | 6 | 2 | 0 |
|
||||
|
||||
### Wie man damit rechnet:
|
||||
Die Subnetzmaske besteht immer aus einer Kette von Einsen (Netzwerk-Teil).
|
||||
Beispiel /26:
|
||||
* 26 Einsen gesamt.
|
||||
* 3 Oktette komplett voll (255.255.255.0).
|
||||
* Im 4. Oktett: 26 - 24 = 2 Einsen.
|
||||
|
||||
Berechnung des 4. Oktetts für /26:
|
||||
* Setze die ersten 2 Bits auf 1: 128 + 64 = 192.
|
||||
* Subnetzmaske: 255.255.255.192.
|
||||
|
||||
**Die "Magic Number" (Blockgröße):**
|
||||
Die Magic Number ist der Wert des letzten Bits im Netzwerk-Teil (das letzte gesetzte Bit).
|
||||
Bei /26 (192) ist die 64 (Bit-Position 2) das letzte gesetzte Bit.
|
||||
Das bedeutet: Deine Netzwerke springen immer in 64er Schritten (0, 64, 128, 192).
|
||||
|
||||
---
|
||||
|
||||
## 6. Netzklassen (Classful Addressing - Historisch)
|
||||
| Klasse | Erster Oktett-Bereich | Standard-Maske |
|
||||
| :--- | :--- | :--- |
|
||||
| A | 1 - 126 | 255.0.0.0 (/8) |
|
||||
| B | 128 - 191 | 255.255.0.0 (/16) |
|
||||
| C | 192 - 223 | 255.255.255.0 (/24) |
|
||||
|
||||
---
|
||||
|
||||
## 7. Referenz-Tabelle (bis /16)
|
||||
| CIDR | Subnetzmaske | Host-Anzahl (nutzbar) |
|
||||
| :--- | :--- | :--- |
|
||||
| /30 | 255.255.255.252 | 2 |
|
||||
| /29 | 255.255.255.248 | 6 |
|
||||
| /28 | 255.255.255.240 | 14 |
|
||||
| /27 | 255.255.255.224 | 30 |
|
||||
| /26 | 255.255.255.192 | 62 |
|
||||
| /25 | 255.255.255.128 | 126 |
|
||||
| /24 | 255.255.255.0 | 254 |
|
||||
| /23 | 255.255.254.0 | 510 |
|
||||
| /22 | 255.255.252.0 | 1.022 |
|
||||
| /21 | 255.255.248.0 | 2.046 |
|
||||
| /20 | 255.255.240.0 | 4.094 |
|
||||
| /19 | 255.255.224.0 | 8.190 |
|
||||
| /18 | 255.255.192.0 | 16.382 |
|
||||
| /17 | 255.255.128.0 | 32.766 |
|
||||
| /16 | 255.255.0.0 | 65.534 |
|
||||
Executable
+306
@@ -0,0 +1,306 @@
|
||||
#lf5
|
||||
# Python – if-Statements & Schleifen
|
||||
|
||||
Eine kompakte Referenz zu Bedingungen und Schleifen in Python.
|
||||
|
||||
---
|
||||
|
||||
## 1. if / elif / else
|
||||
|
||||
Führt Code abhängig von einer Bedingung aus.
|
||||
|
||||
### Grundstruktur
|
||||
|
||||
```python
|
||||
if bedingung:
|
||||
# wird ausgeführt wenn True
|
||||
print("Bedingung erfüllt")
|
||||
elif andere_bedingung:
|
||||
# wird ausgeführt wenn erste False, diese True
|
||||
print("Andere Bedingung erfüllt")
|
||||
else:
|
||||
# wird ausgeführt wenn alle Bedingungen False
|
||||
print("Keine Bedingung erfüllt")
|
||||
```
|
||||
|
||||
### Vergleichs- und logische Operatoren
|
||||
|
||||
| Operator | Bedeutung |
|
||||
|----------|-----------|
|
||||
| `==` | gleich |
|
||||
| `!=` | ungleich |
|
||||
| `<`, `>`, `<=`, `>=` | kleiner/größer (gleich) |
|
||||
| `and` | logisches UND |
|
||||
| `or` | logisches ODER |
|
||||
| `not` | logisches NICHT |
|
||||
| `in` | Mitgliedschaft |
|
||||
| `not in` | keine Mitgliedschaft |
|
||||
|
||||
```python
|
||||
x = 42
|
||||
|
||||
if x > 0 and x < 100:
|
||||
print("im Bereich")
|
||||
|
||||
if x % 2 == 0:
|
||||
print("gerade")
|
||||
elif x % 2 != 0:
|
||||
print("ungerade")
|
||||
|
||||
farbe = "rot"
|
||||
if farbe in ["rot", "blau", "gelb"]:
|
||||
print("Primärfarbe")
|
||||
```
|
||||
|
||||
### Ternärer Ausdruck
|
||||
|
||||
Kurze Schreibweise für einfaches if/else:
|
||||
|
||||
```python
|
||||
ergebnis = "gerade" if x % 2 == 0 else "ungerade"
|
||||
```
|
||||
|
||||
> **Hinweis:** Python kennt kein `switch`-Statement. Stattdessen nutzt man `elif`-Ketten oder ab Python 3.10 das `match`-Statement.
|
||||
|
||||
---
|
||||
|
||||
## 2. for-Schleife
|
||||
|
||||
Iteriert über jedes Element einer Sequenz (Liste, Tuple, String, Range, …).
|
||||
|
||||
### Grundstruktur
|
||||
|
||||
```python
|
||||
for element in sequenz:
|
||||
print(element)
|
||||
```
|
||||
|
||||
### Häufige Anwendungsfälle
|
||||
|
||||
**Liste iterieren:**
|
||||
|
||||
```python
|
||||
früchte = ["Apfel", "Birne", "Kirsche"]
|
||||
for frucht in früchte:
|
||||
print(frucht)
|
||||
```
|
||||
|
||||
**Zahlenbereich mit `range()`:**
|
||||
|
||||
```python
|
||||
for i in range(5): # 0, 1, 2, 3, 4
|
||||
print(i)
|
||||
|
||||
for i in range(1, 10, 2): # 1, 3, 5, 7, 9
|
||||
print(i)
|
||||
```
|
||||
|
||||
`range(start, stop, step)` – `stop` ist **nicht** enthalten.
|
||||
|
||||
**Index + Wert mit `enumerate()`:**
|
||||
|
||||
```python
|
||||
namen = ["Anna", "Ben", "Clara"]
|
||||
for i, name in enumerate(namen):
|
||||
print(f"{i}: {name}")
|
||||
# 0: Anna
|
||||
# 1: Ben
|
||||
# 2: Clara
|
||||
```
|
||||
|
||||
**Zwei Listen parallel mit `zip()`:**
|
||||
|
||||
```python
|
||||
namen = ["Anna", "Ben"]
|
||||
noten = [1, 2]
|
||||
for name, note in zip(namen, noten):
|
||||
print(f"{name}: {note}")
|
||||
```
|
||||
|
||||
**Dictionary iterieren:**
|
||||
|
||||
```python
|
||||
person = {"name": "Max", "alter": 30}
|
||||
for key, value in person.items():
|
||||
print(f"{key} = {value}")
|
||||
```
|
||||
|
||||
**String zeichenweise:**
|
||||
|
||||
```python
|
||||
for zeichen in "Python":
|
||||
print(zeichen)
|
||||
```
|
||||
|
||||
### List Comprehension (kompakte for-Schleife)
|
||||
|
||||
```python
|
||||
quadrate = [x**2 for x in range(10)]
|
||||
gerade = [x for x in range(20) if x % 2 == 0]
|
||||
```
|
||||
|
||||
### for / else
|
||||
|
||||
Der `else`-Block wird ausgeführt, wenn die Schleife **normal endet** (kein `break`):
|
||||
|
||||
```python
|
||||
zahlen = [1, 3, 5, 7]
|
||||
for n in zahlen:
|
||||
if n < 0:
|
||||
print("Negative Zahl gefunden!")
|
||||
break
|
||||
else:
|
||||
print("Alle Zahlen sind positiv.")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. while-Schleife
|
||||
|
||||
Wiederholt Code, **solange** eine Bedingung `True` ist.
|
||||
|
||||
### Grundstruktur
|
||||
|
||||
```python
|
||||
while bedingung:
|
||||
# wird wiederholt solange True
|
||||
code_hier()
|
||||
```
|
||||
|
||||
### Beispiele
|
||||
|
||||
**Zähler:**
|
||||
|
||||
```python
|
||||
i = 0
|
||||
while i < 5:
|
||||
print(i)
|
||||
i += 1 # wichtig: ohne dies → Endlosschleife!
|
||||
```
|
||||
|
||||
**Benutzereingabe bis Abbruch:**
|
||||
|
||||
```python
|
||||
while True:
|
||||
eingabe = input("Eingabe (oder 'exit'): ")
|
||||
if eingabe == "exit":
|
||||
break
|
||||
print(f"Du hast eingegeben: {eingabe}")
|
||||
```
|
||||
|
||||
**Bedingung abhängig vom Ergebnis:**
|
||||
|
||||
```python
|
||||
zahl = 256
|
||||
while zahl > 1:
|
||||
zahl //= 2
|
||||
print(zahl)
|
||||
```
|
||||
|
||||
### while / else
|
||||
|
||||
Wie bei `for`: `else` läuft nur, wenn keine `break`-Anweisung ausgeführt wurde.
|
||||
|
||||
```python
|
||||
i = 0
|
||||
while i < 3:
|
||||
print(i)
|
||||
i += 1
|
||||
else:
|
||||
print("Schleife regulär beendet.")
|
||||
```
|
||||
|
||||
> **Achtung:** Die häufigste Fehlerquelle ist eine vergessene Variable-Aktualisierung, die zu einer **Endlosschleife** führt. Immer sicherstellen, dass die Bedingung irgendwann `False` wird!
|
||||
|
||||
---
|
||||
|
||||
## 4. do-while – Gibt es in Python nicht!
|
||||
|
||||
Python hat **kein** `do-while`-Statement wie in C, Java oder JavaScript. Das Verhalten lässt sich aber mit `while True` und `break` nachbauen:
|
||||
|
||||
**do-while Äquivalent:**
|
||||
|
||||
```python
|
||||
# Entspricht: do { ... } while (bedingung)
|
||||
while True:
|
||||
# Code wird mindestens einmal ausgeführt
|
||||
eingabe = input("Zahl eingeben: ")
|
||||
zahl = int(eingabe)
|
||||
if zahl > 0: # Schleife läuft weiter solange zahl <= 0
|
||||
break
|
||||
|
||||
print(f"Positive Zahl: {zahl}")
|
||||
```
|
||||
|
||||
**Vergleich mit anderen Sprachen:**
|
||||
|
||||
```
|
||||
// Java / C / JavaScript:
|
||||
do {
|
||||
eingabe = scanner.nextLine();
|
||||
} while (!eingabe.equals("exit"));
|
||||
|
||||
# Python-Äquivalent:
|
||||
while True:
|
||||
eingabe = input()
|
||||
if eingabe == "exit":
|
||||
break
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Steueranweisungen
|
||||
|
||||
Gelten für `for`- **und** `while`-Schleifen.
|
||||
|
||||
### break – Schleife sofort beenden
|
||||
|
||||
```python
|
||||
for i in range(10):
|
||||
if i == 5:
|
||||
break # verlässt die Schleife
|
||||
print(i) # gibt 0, 1, 2, 3, 4 aus
|
||||
```
|
||||
|
||||
### continue – aktuelle Iteration überspringen
|
||||
|
||||
```python
|
||||
for i in range(6):
|
||||
if i == 3:
|
||||
continue # überspringt i = 3
|
||||
print(i) # gibt 0, 1, 2, 4, 5 aus
|
||||
```
|
||||
|
||||
### pass – Platzhalter / nichts tun
|
||||
|
||||
```python
|
||||
for i in range(5):
|
||||
pass # leere Schleife, kein Fehler
|
||||
|
||||
if bedingung:
|
||||
pass # noch nicht implementiert
|
||||
```
|
||||
|
||||
### Verschachtelte Schleifen
|
||||
|
||||
`break` und `continue` wirken nur auf die **innerste** Schleife:
|
||||
|
||||
```python
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
if j == 1:
|
||||
break # beendet nur die innere Schleife
|
||||
print(i, j)
|
||||
```
|
||||
|
||||
> **Tipp:** Für den Ausbruch aus mehreren verschachtelten Schleifen die Schleife in eine Funktion auslagern und `return` verwenden.
|
||||
|
||||
---
|
||||
|
||||
## Kurzübersicht
|
||||
|
||||
| Schleife | Wann verwenden | Python-Syntax |
|
||||
|----------|---------------|---------------|
|
||||
| `for` | Anzahl der Iterationen bekannt / Iteration über Sequenz | `for x in sequenz:` |
|
||||
| `while` | Anzahl unbekannt, abhängig von Bedingung | `while bedingung:` |
|
||||
| do-while | Mind. einmal ausführen (kein natives Keyword) | `while True: ... if ...: break` |
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
Installieren:
|
||||
1. `sudo apt install msmtp msmtp-mta -y`
|
||||
1. Apparmor = enable
|
||||
2. ` sudo vim ~/.msmtprc`
|
||||
```
|
||||
defaults
|
||||
auth on
|
||||
tls on
|
||||
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
||||
logfile ~/.msmtp.log
|
||||
|
||||
account gmail
|
||||
host smtp.gmail.com
|
||||
port 587
|
||||
from bruno.eckhardt07@gmail.com
|
||||
user bruno.eckhardt07@gmail.com
|
||||
password qrwj rnqp qoks qzpy
|
||||
|
||||
account default : gmail
|
||||
```
|
||||
|
||||
3. `sudo chown worker:worker /home/worker/.msmtprc`
|
||||
4. `chmod 600 /home/worker/.msmtprc`
|
||||
5. `echo -e "Subject: Testmail\n\nHallo, das ist eine Testmail." | msmtp bruno.eckhardt07@gmail.com`
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
### SERVER ###
|
||||
|
||||
## Installieren
|
||||
`sudo apt update`
|
||||
`sudo apt install nfs-kernel-server`
|
||||
|
||||
## Share verzeichnis erstellen
|
||||
`sudo mkdir -p /share/folder`
|
||||
|
||||
## Rechte vergeben
|
||||
`sudo chown nobody:nogroup /share/folder`
|
||||
`sudo chmod 7777 /share/folder`
|
||||
|
||||
## NFS-Export datei ändern für wirksamkeit
|
||||
`/share/folder *(rw,sync,no_subtree_check)`
|
||||
|
||||
## Export-Tabelle aktualisieren
|
||||
`sudo exportfs -a`
|
||||
|
||||
## NFS Service neu starten
|
||||
`sudo systemctl restart nfs-kernel-server`
|
||||
|
||||
|
||||
### Client ###
|
||||
|
||||
## Installieren
|
||||
`sudo apt install nfs-common`
|
||||
|
||||
## Mount Verzeichnis errichten
|
||||
`sudo mkdir -p /client/folder`
|
||||
|
||||
## NFS-Server mounten
|
||||
`sudo mount <NFS-Server-IP>:/share/folder /client/folder`
|
||||
|
||||
## Dauerhaften mount-punkt in der /etc/fstab hinzufügen
|
||||
`<NFS-Server-IP>:/share/folder /client/folder nfs default 0 0`
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
### Es wird Täglich, Wöchentlich, Monatlich gebackupt
|
||||
|
||||
Täglich:
|
||||
- 21 Uhr
|
||||
- behalte die letzten 3
|
||||
- auf NFS4
|
||||
|
||||
Wöchentlich:
|
||||
- Sonntags 01:00 Uhr
|
||||
- behalte die letzten 2
|
||||
- auf NFS3
|
||||
|
||||
Monatlich:
|
||||
- erster des Monats um 00:00 Uhr
|
||||
- behalte die letzten 2
|
||||
- auf NFS3
|
||||
|
||||
Anmerkung:
|
||||
- Es kann bis zu einer halben stunde laufen und ist stand jetzt 16.03.2026 ca. 47GiB groß.
|
||||
- Es geht auch eine Status mail an bruno.eckhardt07@gmail.com
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
Proxmox no subscription repo einbauen
|
||||
|
||||
1. `mv /etc/apt/sources.list.d/ceph.sources /etc/apt/sources.list.d/ceph.sources.disabled`
|
||||
2. `mv /etc/apt/sources.list.d/pve-enterprise.sources /etc/apt/sources.list.d/pve-enterprise.sources.disabled`
|
||||
3. `echo > /etc/apt/sources.list`
|
||||
4. `echo "deb http://download.proxmox.com/debian/pve trixie pve-no-subscription" >> /etc/apt/pve-no-subscription.list`
|
||||
5. `echo "deb http://download.proxmox.com/debian/pve trixie pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list`
|
||||
6. `apt update`
|
||||
7. `apt full-upgrade`
|
||||
8. `reboot`
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
# Datei-Verschlüsselung mit Python
|
||||
|
||||
Dieses Python-Skript verschlüsselt oder entschlüsselt Dateien rekursiv mit mehreren `Fernet`-Schlüsseln aus der Bibliothek `cryptography`.
|
||||
|
||||
---
|
||||
|
||||
# Funktionen
|
||||
|
||||
- Mehrfache Verschlüsselung (`ROUNDS`)
|
||||
- Automatische Schlüssel-Erstellung
|
||||
- Speicherung der Schlüssel in `keys.txt`
|
||||
- Versand der Schlüssel per Gmail
|
||||
- Entschlüsselung mit umgekehrter Schlüssel-Reihenfolge
|
||||
- Rekursive Verarbeitung aller Dateien im aktuellen Ordner
|
||||
|
||||
---
|
||||
|
||||
# Voraussetzungen
|
||||
|
||||
Benötigte Bibliothek installieren:
|
||||
|
||||
```bash
|
||||
pip install cryptography
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Konfiguration
|
||||
|
||||
Passe diese Variablen an:
|
||||
|
||||
```python
|
||||
GMAIL_USER = "deine_mail@gmail.com"
|
||||
GMAIL_APP_PASSWORD = "gmail_app_passwort"
|
||||
RECEIVER_MAIL = "empfaenger@gmail.com"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Nutzung
|
||||
|
||||
Skript starten:
|
||||
|
||||
```bash
|
||||
python encrypt.py
|
||||
```
|
||||
|
||||
Danach auswählen:
|
||||
|
||||
- `e` → Dateien verschlüsseln
|
||||
- `d` → Dateien entschlüsseln
|
||||
|
||||
---
|
||||
|
||||
# Sicherheitshinweise
|
||||
|
||||
- Die Datei `keys.txt` enthält alle Schlüssel.
|
||||
- Ohne diese Schlüssel können die Dateien nicht entschlüsselt werden.
|
||||
- Die Reihenfolge der Schlüssel ist wichtig.
|
||||
- Vor Nutzung unbedingt ein Backup erstellen.
|
||||
- Dateien aus `EXCLUDE` werden ignoriert.
|
||||
|
||||
---
|
||||
|
||||
# Vollständiger Code
|
||||
|
||||
```python
|
||||
import pathlib
|
||||
import smtplib
|
||||
from email.message import EmailMessage
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
GMAIL_USER = ""
|
||||
GMAIL_APP_PASSWORD = ""
|
||||
RECEIVER_MAIL = ""
|
||||
EXCLUDE = {"encrypt.py", "keys.txt"}
|
||||
ROUNDS = 10
|
||||
|
||||
def send_keys_via_mail(keys):
|
||||
msg = EmailMessage()
|
||||
key_text = "\n".join([f"Runde {i+1}: {k}" for i, k in enumerate(keys)])
|
||||
msg.set_content(f"Bewahre diese Schlüssel gut auf (Reihenfolge ist wichtig!):\n\n{key_text}")
|
||||
msg['Subject'] = f"🔒 Deine {len(keys)} Entschlüsselungs-Keys"
|
||||
msg['From'] = GMAIL_USER
|
||||
msg['To'] = RECEIVER_MAIL
|
||||
|
||||
try:
|
||||
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
|
||||
smtp.login(GMAIL_USER, GMAIL_APP_PASSWORD)
|
||||
smtp.send_message(msg)
|
||||
print("E-Mail mit allen Schlüsseln wurde versendet.")
|
||||
except Exception as e:
|
||||
print(f"E-Mail Fehler: {e}. Keys werden NUR lokal gespeichert!")
|
||||
|
||||
def get_or_create_keys(count):
|
||||
path = pathlib.Path("keys.txt")
|
||||
if not path.exists():
|
||||
keys = [Fernet.generate_key().decode() for _ in range(count)]
|
||||
path.write_text("\n".join(keys))
|
||||
send_keys_via_mail(keys)
|
||||
return [k.encode() for k in keys]
|
||||
return [k.encode() for k in path.read_text().splitlines()]
|
||||
|
||||
def process_files(mode, keys):
|
||||
# Bei Decrypt müssen wir die Keys in umgekehrter Reihenfolge nutzen!
|
||||
active_keys = keys[::-1] if mode == "decrypt" else keys
|
||||
|
||||
for path in pathlib.Path(".").rglob("*"):
|
||||
if path.is_file() and path.name not in EXCLUDE:
|
||||
try:
|
||||
data = path.read_bytes()
|
||||
for k in active_keys:
|
||||
fernet = Fernet(k)
|
||||
data = fernet.decrypt(data) if mode == "decrypt" else fernet.encrypt(data)
|
||||
path.write_bytes(data)
|
||||
print(f"{mode.capitalize()} erfolgreich: {path.name}")
|
||||
except Exception as e:
|
||||
print(f"Fehler bei {path.name}: {e} (Evtl. falscher Key oder Modus?)")
|
||||
|
||||
def main():
|
||||
choice = input("Möchtest du (e)ncrypten oder (d)ecrypten? ").lower()
|
||||
|
||||
if choice == 'e':
|
||||
keys = get_or_create_keys(ROUNDS)
|
||||
process_files("encrypt", keys)
|
||||
elif choice == 'd':
|
||||
if not pathlib.Path("keys.txt").exists():
|
||||
print("Fehler: keys.txt nicht gefunden!")
|
||||
return
|
||||
keys = [k.encode() for k in pathlib.Path("keys.txt").read_text().splitlines()]
|
||||
process_files("decrypt", keys)
|
||||
else:
|
||||
print("Ungültige Auswahl.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
Ordner:
|
||||
|
||||
- Spezifische Compose files:
|
||||
/data/COMPOSE/
|
||||
```
|
||||
-rwxrwxrwx 1 root root 2195 Feb 21 12:04 app.ini
|
||||
-rwxrwxrwx 1 root root 1252 Feb 6 08:27 docker-compose-dev.yml
|
||||
-rwxrwxrwx 1 root root 1002 Jan 10 12:16 docker-compose.yml
|
||||
-rwxrwxrwx 1 root root 431 Jan 10 12:12 Dockerfile
|
||||
-rwxrwxrwx 1 root root 339 Dec 4 11:26 gitea.yml
|
||||
-rwxrwxrwx 1 root root 226 Dec 10 09:11 haproxy.yml
|
||||
-rwxrwxrwx 1 root root 364 Feb 22 11:23 mariadb-backup.yml
|
||||
-rwxrwxrwx 1 root root 362 Feb 24 08:03 mariadb-test.yml
|
||||
-rwxrwxrwx 1 root root 349 Feb 22 11:20 mariadb.yml
|
||||
```
|
||||
|
||||
- Gitea Daten:
|
||||
/data/GITEA/
|
||||
|
||||
- Live Datenbank:
|
||||
/data/MARIADB/
|
||||
|
||||
- DEV Datenbank:
|
||||
/data/MARIADB-TEST/
|
||||
|
||||
- Backup Datenbank
|
||||
/data/MARIADB-BACKUP/
|
||||
|
||||
- Shell skripte
|
||||
/data/SCRIPTS/
|
||||
```
|
||||
-rwxrwxrwx 1 root root 294 Dec 10 09:19 certs-renew.sh
|
||||
-rwxrwxrwx 1 root root 22 Nov 27 15:39 CPU_Temp_Mess.sh
|
||||
-rwxrwxrwx 1 root root 283 Mar 2 20:15 DB-backup.sh
|
||||
-rwxrwxrwx 1 root root 69 Feb 17 13:29 DB-connect.sh
|
||||
-rwxrwxrwx 1 root root 161 Feb 17 14:09 DB-export.sh
|
||||
-rwxrwxrwx 1 root root 280 Feb 22 13:58 DB-import.sh
|
||||
-rwxrwxrwx 1 root root 5772 Feb 17 13:26 deploy.sh
|
||||
-rwxrwxrwx 1 root root 40 Nov 15 16:40 disk-mount.sh
|
||||
-rwxrwxrwx 1 root root 44 Nov 18 08:17 Docker_Build.sh
|
||||
-rwxrwxrwx 1 root root 4346 Mar 4 10:23 GEN-SITEMAP.sh
|
||||
-rwxrwxrwx 1 root root 1330 Dec 9 09:09 GIT-MGMT.sh
|
||||
-rwxrwxrwx 1 root root 1680 Feb 26 13:51 hydra.sh
|
||||
-rwxrwxrwx 1 root root 1680 Feb 26 13:51 MAIN.sh
|
||||
-rwxrwxrwx 1 root root 1379 Feb 17 13:49 MONITOR.sh
|
||||
-rwxrwxrwx 1 root root 286 Feb 26 17:17 output.txt
|
||||
-rwxrwxrwx 1 root root 139921497 Jul 23 2025 rockyou.txt
|
||||
-rwxrwxrwx 1 root root 43 Jan 22 12:45 Wake_Up.sh
|
||||
-rwxrwxrwx 1 root root 1857 Feb 20 22:37 Web_Crawler.py
|
||||
```
|
||||
|
||||
- Temporäre Daten:
|
||||
/data/TEMP/
|
||||
|
||||
- öffentliche website:
|
||||
/data/WEBSERVER/PUBLIC
|
||||
|
||||
- Backend website:
|
||||
/data/WEBSERVER/BACKEND
|
||||
|
||||
- rollback backups
|
||||
/data/WEBSERVER/BACKUP
|
||||
```
|
||||
drwxrwxrwx 1 root root 4096 Mar 1 20:15 BACKEND-20260302-115230-node1
|
||||
drwxrwxrwx 1 root root 4096 Mar 3 10:00 BACKEND-20260303-131821-node1
|
||||
drwxrwxrwx 1 root root 4096 Feb 5 15:48 PUBLIC-20260216-145443-node1
|
||||
drwxrwxrwx 1 root root 4096 Feb 16 14:54 PUBLIC-20260216-163846-node1
|
||||
|
||||
```
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
1. `sudo apt-get install squid -y`
|
||||
2. `sudo systemctl enable squid`
|
||||
3. `sudo systemctl stop squid`
|
||||
4. `vim /etc/squid/squid.conf`
|
||||
```
|
||||
http_port 3128
|
||||
forwarded_for transparent
|
||||
|
||||
acl localnet src 10.233.1.0/24 100.0.0.0/8
|
||||
acl localhost src 127.0.0.1/32 ::1
|
||||
|
||||
http_access allow localnet
|
||||
http_access allow localhost
|
||||
http_access deny all
|
||||
|
||||
cache_dir ufs /var/spool/squid 20480 16 256
|
||||
|
||||
maximum_object_size 1024 MB
|
||||
minimum_object_size 0 KB
|
||||
|
||||
cache_mem 256 MB
|
||||
|
||||
refresh_pattern ^ftp: 1440 20% 10080
|
||||
refresh_pattern ^gopher: 1440 0% 1440
|
||||
refresh_pattern -i \.deb$ 1500 20% 40320
|
||||
refresh_pattern -i \.rpm$ 1500 20% 40320
|
||||
refresh_pattern -i \.(exe|iso)$ 1500 20% 40320
|
||||
refresh_pattern . 0 20% 4320
|
||||
|
||||
access_log /var/log/squid/access.log squid
|
||||
cache_log /var/log/squid/cache.log
|
||||
```
|
||||
5. `sudo systemctl restart squid`
|
||||
6. `sudo touch /var/log/squid/access.log`
|
||||
7. `sudo touch /var/log/squid/cache.log`
|
||||
8. `sudo chmod 777 /var/log/squid/access.log`
|
||||
9. `sudo chmod 777 /var/log/squid/cache.log`
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
# Drives
|
||||
|
||||
| | D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| Typ | SSD | SSD | HDD | SSD | SSD | SSD | SSD |
|
||||
| Size | 230GB | 230GB | 1,8TB | 230GB | 120GB | 230GB | 120GB |
|
||||
| Tasks | NFS | NFS | | NFS | | NFS | |
|
||||
| Device ID | sdb1 | sdc1 | sdd2 | sde1 | sdf1 | sdg1 | sdh1 |
|
||||
| Used For | Proxmox VMs | Proxmox LXCs | | Proxmox BK | | Proxmox BK | |
|
||||
+24
-21
@@ -1,29 +1,32 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgRXzLH/jwuk2w+3Se
|
||||
5PcY6d/GrWahEUDgaCakiCML4iChRANCAARNru+Mcv4BstET3VWTZ2cW0lmBVun7
|
||||
yF0Dd+19UNtYhoz3eB2QSnTGV306BYM5VJRuHYJuvaZg5NPaMnDIT18G
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgQtlzxuifivsTzzVq
|
||||
U7pd6Mi2dBfyLCYIIHsz2Gem58WhRANCAATmirvi3Zy3DGTfPRMtvMV8BVrcdie3
|
||||
QpYtwVYS7EQlqWj8pd9CYqeQxyFvDxcKLJiUiuLyfwAu0eVwpyvgfhOW
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDuTCCAz+gAwIBAgISBZl61oPt/oKJ1zGciZ01eCSEMAoGCCqGSM49BAMDMDMx
|
||||
MIIEODCCA76gAwIBAgISBdWSjlaF9AO04oKMLLF4CF6GMAoGCCqGSM49BAMDMDMx
|
||||
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQDEwNZ
|
||||
RTIwHhcNMjYwNzEzMTE0MzEyWhcNMjYxMDExMTE0MzExWjAVMRMwEQYDVQQDEwpt
|
||||
cmhvc3NhLmRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETa7vjHL+AbLRE91V
|
||||
k2dnFtJZgVbp+8hdA3ftfVDbWIaM93gdkEp0xld9OgWDOVSUbh2Cbr2mYOTT2jJw
|
||||
yE9fBqOCAk8wggJLMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
|
||||
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTmNfRC8thoWS9xd5pNQpMOoAuCzzAf
|
||||
RTIwHhcNMjYwODAxMDgzODQzWhcNMjYxMDMwMDgzODQyWjAVMRMwEQYDVQQDEwpt
|
||||
cmhvc3NhLmRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5oq74t2ctwxk3z0T
|
||||
LbzFfAVa3HYnt0KWLcFWEuxEJalo/KXfQmKnkMchbw8XCiyYlIri8n8ALtHlcKcr
|
||||
4H4TlqOCAs4wggLKMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD
|
||||
ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRV54SDB/8S5Ac25sgMG5qsGDM1KDAf
|
||||
BgNVHSMEGDAWgBS5WfKOzyLwhtM3SP92FBi6gthVhzAzBggrBgEFBQcBAQQnMCUw
|
||||
IwYIKwYBBQUHMAKGF2h0dHA6Ly95ZTIuaS5sZW5jci5vcmcvME0GA1UdEQRGMESC
|
||||
EmJhY2tlbmQubXJob3NzYS5kZYIQZ2l0ZWEubXJob3NzYS5kZYIKbXJob3NzYS5k
|
||||
ZYIQc3RhdHMubXJob3NzYS5kZTATBgNVHSAEDDAKMAgGBmeBDAECATAtBgNVHR8E
|
||||
JjAkMCKgIKAehhxodHRwOi8veWUyLmMubGVuY3Iub3JnLzUuY3JsMIIBDAYKKwYB
|
||||
BAHWeQIEAgSB/QSB+gD4AH0ARq+GPTs+5Z+ld96oJF02sNntIqIj9GF3QSKUUu6V
|
||||
UF8AAAGfW39ivAAIAAAFAAzOLYIEAwBGMEQCIA3O3m+v4QXXj5Bk/sbP/nQQA6A1
|
||||
oJ8rBXMcKCNvuGWJAiBW2SkMum780BhxnKY3IaS/sFLqzgbOF/XoSUWAK4wXxQB3
|
||||
ANgJVTuUT3r/yBYZb5RPhauw+Pxeh1UmDxXRLnK7RUsUAAABn1t/YowAAAQDAEgw
|
||||
RgIhALDpjsHgUB7W+MbHa7pECcxMRvNS4+rfZoapQSXRNKazAiEAmM37lPhV83en
|
||||
4JHtv87ijP0ZCS9d5lX1zCFhxnXHy5IwCgYIKoZIzj0EAwMDaAAwZQIwJCREcbS2
|
||||
Qu7kE8EBE5CSmAYWb20UiVUw1eh1vR8Ok3f0wFRBeZmSaIoc/sOPXfYZAjEAtF4N
|
||||
0zP9ATWQVE7m/gL+4mH3d7Y+ZgbgDRZbXloo3EAMSezyk/+ZAZfSEcMIFZkw
|
||||
IwYIKwYBBQUHMAKGF2h0dHA6Ly95ZTIuaS5sZW5jci5vcmcvMIHKBgNVHREEgcIw
|
||||
gb+CEmJhY2tlbmQubXJob3NzYS5kZYIOZG5zLm1yaG9zc2EuZGWCFGZsYXRub3Rl
|
||||
cy5tcmhvc3NhLmRlghBnaXRlYS5tcmhvc3NhLmRlghFob21hcnIubXJob3NzYS5k
|
||||
ZYISamVua2lucy5tcmhvc3NhLmRlggptcmhvc3NhLmRlghRwb3J0YWluZXIubXJo
|
||||
b3NzYS5kZYIQc3RhdHMubXJob3NzYS5kZYIWdmF1bHR3YXJkZW4ubXJob3NzYS5k
|
||||
ZTATBgNVHSAEDDAKMAgGBmeBDAECATAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8v
|
||||
eWUyLmMubGVuY3Iub3JnLzcuY3JsMIIBDQYKKwYBBAHWeQIEAgSB/gSB+wD5AHcA
|
||||
r2eIO1ewTt2Pptl+9i6o64EKx3Fg8CReVdYML+eFhzoAAAGfvK9RtgAABAMASDBG
|
||||
AiEAuuXZH1Lhu05cqWCVglLQmvSOXBqS+xW83YT/ZYFaHKkCIQC/+blHhYE4U/J+
|
||||
GhuQZBkydJv8wTTaYc3mLIk3Dg5t2wB+AKgmy+MKxjUSRlM/4GXxTxnZbhkIE8Qd
|
||||
2W15ALMSPFUnAAABn7yvU50ACAAABQAXpAqtBAMARzBFAiAJs54FrTbuyVlKvYCt
|
||||
ai+duY/nau5vY7u/s5VfcAy2aQIhAP+gyhwcvp4aQyTRNKQ5yC3o34Iuv5OB/wc6
|
||||
02FwlWi5MAoGCCqGSM49BAMDA2gAMGUCMQDh9CzmCu7kWOawhSekYKOKyD613ONn
|
||||
qRD2A02ilKHQKvBPE0HVah8xzXSnE7K1tYICMBEcTg0N/cRzJiKIZhNRZLkx3KaM
|
||||
ex/3aJ6MvtALR69VvA4MRKsDKWKEZdKdyXpf5A==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICjDCCAhGgAwIBAgIQTfOxXdbAeExQfNN7WObxFTAKBggqhkjOPQQDAzAuMQsw
|
||||
|
||||
Reference in new issue
Block a user