From 548bab93e55f6e514557571d3c9da9b1c1d59c35 Mon Sep 17 00:00:00 2001
From: Server-Bibliothek <server-bibliothek@lokal>
Date: Do, 23 Jul 2026 15:07:49 +0200
Subject: [PATCH] Zugriffsbeschraenkung: voller Zugriff nur lokal am Server, Netzwerk nur Software-Anforderung + Zugriffsprotokoll

---
 ARCHITEKTUR.md |   92 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/ARCHITEKTUR.md b/ARCHITEKTUR.md
index 3d69a05..9af377f 100644
--- a/ARCHITEKTUR.md
+++ b/ARCHITEKTUR.md
@@ -146,45 +146,101 @@
 ## 6. "Rechner einrichten" – Verteilungs-Mechanismus
 
 Route `/einrichten` (app.py) erzeugt bei Bedarf ein individuelles
-Installations-Paket (ZIP mit `einrichten.ps1` + `Rechner-einrichten-starten.bat`),
+Installations-Paket (ZIP mit `einrichten.ps1` + `Rechner-einrichten-starten.bat`
+**+ den echten Installer-Dateien/ZIPs selbst** unter `tools/<id>.<endung>`),
 statt vorab für jede Mitarbeiter/Tool-Kombination ein festes Skript zu pflegen.
 
+**Wichtige Design-Entscheidung (Runde r16):** Die Installer-Dateien werden
+bereits beim Erzeugen des Pakets (auf dem PC, der die Checkliste ausfüllt)
+eingebettet, nicht erst beim Ausführen auf dem Zielrechner nachgeladen. Ein
+früherer Ansatz lud die Dateien per `Invoke-WebRequest` zur Laufzeit vom
+Server nach – das erforderte Netzwerkzugriff des Zielrechners auf den Server
+in genau dem Moment der Einrichtung, was in der Praxis nicht immer gegeben
+ist (z. B. Rechner noch nicht ans Firmennetz angebunden). Jetzt braucht der
+Zielrechner für die eigentliche Installation **kein Netzwerk mehr** – nur die
+abschließende, optionale Meldung ans zentrale Protokoll (`/zuweisungen/neu`)
+versucht noch einen Netzwerkzugriff, scheitert dieser, bleibt trotzdem das
+lokale Protokoll (`protokoll.log`) vollständig.
+
 Ablauf beim Ausführen auf dem Zielrechner:
-1. `.bat` kopiert sich selbst + das `.ps1` nach `C:\ClientBibliothek`
+1. `.bat` kopiert den **kompletten entpackten Ordner** (inkl. `tools/`-
+   Unterordner mit den echten Installer-Dateien) nach `C:\ClientBibliothek`
+   (per `xcopy /E /I /Y`)
 2. Self-Elevation (Admin-Rechte-Anfrage) über `Start-Process -Verb RunAs`
 3. Automatische Windows-Defender-Ausnahme für `C:\ClientBibliothek`
    (`Add-MpPreference -ExclusionPath`) – ein einziger Pfad statt vieler
    Einzelausnahmen
-4. Pro ausgewähltem Tool: entweder stille Installation (Download + Ausführung
-   mit hinterlegtem Silent-Parameter, `.msi` läuft über `msiexec`) oder – bei
-   Tools ohne einzelne Installer-Datei ("Ordner-Typ", z. B. portable
-   Programme wie Blender) – Download als ZIP nach `C:\ClientBibliothek\pakete\`,
-   **bewusst ohne automatisches Entpacken** (Entscheidung in Runde r14: der
-   Zielort für portable Tools variiert, das soll eine Person bewusst
+4. Pro ausgewähltem Tool: entweder stille Installation aus der **lokal
+   mitgelieferten** Datei unter `tools/<id>.<endung>` (mit hinterlegtem
+   Silent-Parameter, `.msi` läuft über `msiexec`) oder – bei Tools ohne
+   einzelne Installer-Datei ("Ordner-Typ", z. B. portable Programme wie
+   Blender) – die mitgelieferte ZIP-Datei wird nach `C:\ClientBibliothek\pakete\`
+   kopiert, **bewusst ohne automatisches Entpacken** (Entscheidung in Runde
+   r14: der Zielort für portable Tools variiert, das soll eine Person bewusst
    entscheiden)
 5. Lokales Protokoll unter `C:\ClientBibliothek\protokoll.log`
-6. Automatischer POST an `/zuweisungen/neu` auf dem Server, um das zentrale
+6. Optionaler POST an `/zuweisungen/neu` auf dem Server, um das zentrale
    Protokoll zu befüllen (Rechnername wird dabei über `$env:COMPUTERNAME`
-   automatisch erkannt)
+   automatisch erkannt) – best effort, kein Abbruch bei Fehlschlag
 
 Die Ordner-Struktur unter `C:\ClientBibliothek`:
-- `\downloads` – transiente Installer-Dateien, werden nach Gebrauch gelöscht
+- `\tools` – die mitgelieferten Installer-Dateien/ZIPs (Quelle für die
+  Installation, kommen direkt aus dem heruntergeladenen Paket)
 - `\pakete` – ZIPs von portablen Tools, bleiben bewusst liegen
 - `\protokoll.log` – lokale Mitschrift
+
+Serverseitig teilen sich `/einrichten` (POST) und `/software/<id>/download`
+die Hilfsfunktion `_zippe_ordner_in_bytes()` für das ZIP-Packen eines
+Ordners, um Code-Duplikation zu vermeiden.
 
 **Der Client-Ordner-Pfad ist eine Konstante** (`CLIENT_ORDNER` in `app.py`,
 aktuell `C:\ClientBibliothek`) – zentral anpassbar, falls die Infrastruktur
 einen anderen Standardpfad vorgibt.
 
+## 6a. Zugriffsbeschränkung: lokal (Server) vs. Netzwerk
+
+Seit Runde r17 unterscheidet die Anwendung, ob eine Anfrage direkt vom Server
+selbst kommt (z. B. per RDP-Sitzung, im Browser dort `localhost`/`127.0.0.1`
+aufgerufen) oder über das Netzwerk von einem anderen Rechner.
+
+- `ist_lokaler_zugriff()` prüft `request.remote_addr` gegen `127.0.0.1`/`::1`
+- `@app.before_request`-Hook `_zugriff_beschraenken()` blockiert für
+  Netzwerk-Zugriffe alle Routen außer denen in `OEFFENTLICHE_ENDPUNKTE`
+  (aktuell nur `einrichten` und `static`) mit einer 403-Seite
+- Die Seite `/einrichten` zeigt sich bei Netzwerkzugriff unter anderem Namen
+  ("Software anfordern" statt "Rechner einrichten") und mit Hinweis auf die
+  Protokollierung
+- Jeder Aufruf/Download über `/einrichten` wird in der Tabelle `zugriffslog`
+  festgehalten (Zeitpunkt, IP-Adresse, per Reverse-DNS ermittelter
+  Rechnername falls auflösbar, selbst angegebener Name, Aktion) – einsehbar
+  unter `/zugriffslog` (selbst wieder nur lokal erreichbar)
+
+**Wichtige Einschränkung:** Ein echter Windows-Benutzername lässt sich über
+reines HTTP **nicht** zuverlässig ermitteln – dafür wäre eine
+NTLM/Kerberos-Integration nötig (z. B. über einen IIS-Reverse-Proxy vor
+Flask, der die Windows-Anmeldung übernimmt und den Benutzernamen per Header
+an die Flask-App durchreicht). Das ist in diesem Prototyp **nicht**
+umgesetzt. Aktuell basiert die Identifizierung auf der IP-Adresse, einem per
+Reverse-DNS aufgelösten Rechnernamen (funktioniert nur, wenn im
+Firmennetzwerk DNS-Einträge für Client-Rechner existieren) und dem selbst im
+Formular angegebenen Namen (nicht verifiziert). Für eine belastbarere
+Identifizierung müsste diese IIS/NTLM-Integration nachgerüstet werden.
+
+**Anpassung an andere Infrastruktur:** Sollte der Server z. B. hinter einem
+Reverse-Proxy laufen, liefert `request.remote_addr` ggf. die Proxy-IP statt
+der echten Client-IP – in dem Fall müssten `X-Forwarded-For`-Header
+ausgewertet werden (aktuell nicht implementiert, da kein Proxy im Einsatz).
+
 ## 7. Bekannte Grenzen / nicht vollständig getestet
 
-- **Keine Authentifizierung.** Es gibt kein Login-System. Jeder, der den
-  Server im Netzwerk erreichen kann, kann Software verwalten, Installer
-  herunterladen und Installations-Pakete erzeugen. Das war für den internen,
-  vertrauenswürdigen Einsatz im Firmennetz eine bewusste Vereinfachung –
-  **bei einer Anpassung an eine andere/größere Infrastruktur unbedingt
-  prüfen, ob das so bleiben darf**, insbesondere wenn der Server auch von
-  außerhalb des Firmennetzes erreichbar sein könnte.
+- **Keine echte Authentifizierung, nur Herkunfts-Beschränkung.** Seit r17
+  ist die Verwaltung (Katalog, Protokolle, Zugriffsprotokoll) nur noch vom
+  Server selbst aus erreichbar (siehe Abschnitt 6a) – das ist aber eine
+  Netzwerk-/IP-basierte Einschränkung, **kein Login mit Benutzername/Passwort**.
+  Wer direkt am Server sitzt (oder sich als diesen ausgibt, z. B. über
+  IP-Spoofing im selben Netzwerksegment), hat vollen Zugriff. Für ein
+  belastbares Sicherheitskonzept mit echten Benutzerkonten wäre ein
+  richtiges Login-System nötig.
 - **Kein HTTPS/TLS.** Die Kommunikation läuft unverschlüsselt über HTTP. Für
   ein internes, abgeschottetes Netzwerk meist unkritisch, sollte aber vor
   einem größeren Rollout bewertet werden.

--
Gitblit v1.9.3