Website veroeffentlicht und die Diagnose des Skripts geschaerft
https://jamulix.de/OR/ steht auf dem Stand des heutigen Baus: 213 Dateien uebertragen, 35 geloescht, alle vierzehn HTTP-Proben richtig - darunter die entscheidende: /OR/anhang-glossar-literatur.html liefert jetzt 404 statt 200. Der zweite Lauf unmittelbar danach uebertrug 0 Dateien und loeschte nichts. Die Abbruchgrenze hat gleich beim ersten Einsatz gegriffen: 35 Loeschungen ueber der Vorgabe von 30. Die Liste war vollstaendig erklaerbar - 33 verwaiste PNGs aus dem Aufraeumschritt, das leere bilder_04/__pycache__/ aus dem spiegle_bilder()-Fehler und die geteilte Anhangseite. Dass ein scp-Upload alle 35 stehen gelassen haette, ist damit belegt statt behauptet. Zwei Huerden auf dem Weg, beide ins Skript uebersetzt: ssh-copy-id braucht ein echtes Terminal. In der Claude-Code-Sitzung gibt es keins, aber DISPLAY ist gesetzt - ssh sucht daraufhin ssh-askpass, das nicht installiert ist. Der Schritt gehoert in ein normales Terminalfenster. Danach sperrte fail2ban den Port: erste Verbindung erfolgreich, die folgenden "Connection refused", waehrend die Website weiter mit 200 antwortete. Nach sieben Minuten war die Sperre weg; weitere Versuche haetten sie verlaengert. pruefe_ziel_erreichbar() unterscheidet jetzt die abgewiesene Verbindung von der abgelehnten Anmeldung. Vorher meldete es in beiden Faellen "Der Schluessel liegt noch nicht auf dem Server" - beim zweiten Mal glatt falsch, denn er lag laengst dort. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
d566cf8dac
commit
ef79e6fdc1
2 changed files with 66 additions and 9 deletions
|
|
@ -205,23 +205,39 @@ def rsync_befehl(env: dict[str, str], probelauf: bool) -> list[str]:
|
||||||
|
|
||||||
|
|
||||||
def pruefe_ziel_erreichbar(env: dict[str, str]) -> None:
|
def pruefe_ziel_erreichbar(env: dict[str, str]) -> None:
|
||||||
"""Ein Handschlag, bevor 23 MB losgeschickt werden - und er unterscheidet
|
"""Ein Handschlag, bevor 23 MB losgeschickt werden. Er unterscheidet die
|
||||||
die beiden Fehlerursachen, die sonst leicht verwechselt werden: Anmeldung
|
Ursachen, die sonst leicht verwechselt werden - alle drei sind hier schon
|
||||||
scheitert (ssh liefert 255) gegen rsync fehlt am Ziel."""
|
aufgetreten: Verbindung abgewiesen, Anmeldung gescheitert, rsync fehlt."""
|
||||||
kennung = f'{env["OR_BENUTZER"]}@{env["OR_HOST"]}'
|
kennung = f'{env["OR_BENUTZER"]}@{env["OR_HOST"]}'
|
||||||
# BatchMode: keine Passwortabfrage, damit der Aufruf nicht haengt. Der
|
# BatchMode: keine Passwortabfrage, damit der Aufruf nicht haengt. Der
|
||||||
# ssh-agent funktioniert weiterhin. stderr laeuft absichtlich durch, damit
|
# ssh-agent funktioniert weiterhin. stderr wird mitgelesen UND
|
||||||
# ssh seine eigene Diagnose zeigen kann.
|
# weitergereicht: gelesen, um die Ursache zu erkennen, gezeigt, damit ssh
|
||||||
|
# seine eigene Diagnose loswird.
|
||||||
ergebnis = subprocess.run(
|
ergebnis = subprocess.run(
|
||||||
ssh_optionen(env).split() + ["-o", "BatchMode=yes", kennung,
|
ssh_optionen(env).split() + ["-o", "BatchMode=yes", kennung,
|
||||||
"command -v rsync || echo KEIN_RSYNC"],
|
"command -v rsync || echo KEIN_RSYNC"],
|
||||||
stdout=subprocess.PIPE, text=True)
|
capture_output=True, text=True)
|
||||||
|
if ergebnis.stderr:
|
||||||
|
print(ergebnis.stderr.rstrip(), file=sys.stderr)
|
||||||
if ergebnis.returncode == 255:
|
if ergebnis.returncode == 255:
|
||||||
|
# Abgewiesene Verbindung ist NICHT dasselbe wie eine gescheiterte
|
||||||
|
# Anmeldung. Beim ersten Einsatz dieses Skripts sperrte fail2ban den
|
||||||
|
# Port, nachdem ssh-copy-id ein paar Passwortversuche verbraucht hatte -
|
||||||
|
# die Meldung "Schluessel liegt nicht auf dem Server" fuehrte da in die
|
||||||
|
# falsche Richtung, denn der Schluessel lag laengst dort.
|
||||||
|
if "Connection refused" in ergebnis.stderr or "timed out" in ergebnis.stderr:
|
||||||
|
raise SystemExit(
|
||||||
|
f"FEHLER: {env['OR_HOST']} weist die Verbindung auf Port 22 ab.\n"
|
||||||
|
f" Wenn die Website selbst antwortet, ist meist eine\n"
|
||||||
|
f" Sperre nach fehlgeschlagenen Anmeldeversuchen die\n"
|
||||||
|
f" Ursache (fail2ban). Sie loest sich nach einigen\n"
|
||||||
|
f" Minuten von selbst - weitere Versuche verlaengern sie.")
|
||||||
raise SystemExit(
|
raise SystemExit(
|
||||||
f"FEHLER: Keine SSH-Verbindung zu {kennung} (siehe Meldung oben).\n"
|
f"FEHLER: Anmeldung an {kennung} abgelehnt (siehe Meldung oben).\n"
|
||||||
f" Haeufigste Ursache: Der oeffentliche Schluessel liegt noch\n"
|
f" Haeufigste Ursache: Der oeffentliche Schluessel liegt noch\n"
|
||||||
f" nicht auf dem Server. Einmalig:\n"
|
f" nicht auf dem Server. Einmalig, in einem ECHTEN Terminal\n"
|
||||||
f" ssh-copy-id {kennung}\n"
|
f" (ssh braucht dafuer ein tty):\n"
|
||||||
|
f" ssh-copy-id -i ~/.ssh/id_ed25519.pub {kennung}\n"
|
||||||
f" Bei passwortgeschuetztem Schluessel: ssh-add einmal "
|
f" Bei passwortgeschuetztem Schluessel: ssh-add einmal "
|
||||||
f"ausfuehren.")
|
f"ausfuehren.")
|
||||||
if ergebnis.returncode != 0:
|
if ergebnis.returncode != 0:
|
||||||
|
|
|
||||||
41
PROGRESS.md
41
PROGRESS.md
|
|
@ -2117,6 +2117,47 @@ rsync installiert" — tatsächlich schlug schon die Anmeldung fehl, weil der ö
|
||||||
Schlüssel noch nicht auf `jamulix.de` liegt. Die Prüfung unterscheidet die Fälle jetzt am
|
Schlüssel noch nicht auf `jamulix.de` liegt. Die Prüfung unterscheidet die Fälle jetzt am
|
||||||
ssh-Rückgabewert 255 und nennt `ssh-copy-id`.
|
ssh-Rückgabewert 255 und nennt `ssh-copy-id`.
|
||||||
|
|
||||||
|
### ✅ Erstmals per Skript veröffentlicht — 08.09.2026
|
||||||
|
|
||||||
|
`https://jamulix.de/OR/` steht auf dem Stand des heutigen Baus. **213 Dateien übertragen, 35
|
||||||
|
gelöscht**, alle vierzehn HTTP-Proben richtig — darunter die entscheidende:
|
||||||
|
`/OR/anhang-glossar-literatur.html` liefert jetzt **404** statt 200. Der zweite Lauf
|
||||||
|
unmittelbar danach übertrug **0 Dateien** und löschte nichts.
|
||||||
|
|
||||||
|
**Die Abbruchgrenze hat gleich beim ersten Einsatz gegriffen** und sich damit bewährt: 35
|
||||||
|
Löschungen über der Vorgabe von 30. Die Liste war anzusehen, bevor sie angehoben wurde — und
|
||||||
|
sie war vollständig erklärbar:
|
||||||
|
|
||||||
|
| Anzahl | Was | Warum |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 33 | `bilder_04/*.png` | die verwaisten PNGs, die im Aufräumschritt lokal gelöscht wurden |
|
||||||
|
| 1 | `bilder_04/__pycache__/` | das leere Verzeichnis aus dem `spiegle_bilder()`-Fehler |
|
||||||
|
| 1 | `anhang-glossar-literatur.html` | die geteilte Anhangseite |
|
||||||
|
|
||||||
|
Dass ein `scp`-Upload alle 35 stehen gelassen hätte, ist damit belegt statt behauptet.
|
||||||
|
|
||||||
|
**Zwei Hürden auf dem Weg, beide in Konsequenzen übersetzt:**
|
||||||
|
|
||||||
|
*`ssh-copy-id` braucht ein echtes Terminal.* In der Claude-Code-Sitzung gibt es keins
|
||||||
|
(`tty` → „kein Terminal"), aber `DISPLAY=:1` ist gesetzt. `ssh` schließt daraus auf einen
|
||||||
|
grafischen Passwortdialog und sucht `/usr/bin/ssh-askpass`, das nicht installiert ist. Ein
|
||||||
|
Passwort über die normale Eingabe nimmt `ssh` grundsätzlich nicht entgegen. Der Schritt
|
||||||
|
gehört in ein normales Terminalfenster.
|
||||||
|
|
||||||
|
*Danach sperrte der Server den Port.* Die fehlgeschlagenen Passwortversuche plus die
|
||||||
|
Verbindungen des Skripts lösten eine Sperre aus (fail2ban): erste Verbindung erfolgreich,
|
||||||
|
die folgenden `Connection refused` — während die Website selbst weiter mit 200 antwortete.
|
||||||
|
Nach sieben Minuten Warten war sie weg. **Weitere Versuche hätten sie verlängert.**
|
||||||
|
|
||||||
|
Beides steckt jetzt im Skript: `pruefe_ziel_erreichbar()` unterscheidet die abgewiesene
|
||||||
|
Verbindung von der abgelehnten Anmeldung — vorher meldete es in beiden Fällen „Der
|
||||||
|
Schlüssel liegt noch nicht auf dem Server", was beim zweiten Mal glatt falsch war, denn er
|
||||||
|
lag längst dort.
|
||||||
|
|
||||||
|
Damit ist der seit dem Colab-Umbau offene Punkt erledigt: Online steht kein toter
|
||||||
|
Colab-Link mehr, `Notebooks_04/` liefert statt 403 eine Übersichtsseite, und das PDF
|
||||||
|
entspricht byte-genau dem gebauten.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. Commit-Historie des V04-Strangs
|
## 8. Commit-Historie des V04-Strangs
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue