Remote Access: Unterschied zwischen den Versionen
Sv (Diskussion | Beiträge) Fold bullet continuation lines onto a single physical line so MediaWiki keeps them inside <li> |
Sv (Diskussion | Beiträge) password authentication: URL form, code API, auth order; launcher menu entries |
||
| (3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 42: | Zeile 42: | ||
<pre> |
<pre> |
||
sftp://[user@]host[:port]/remote/path |
sftp://[user[:password]@]host[:port]/remote/path |
||
</pre> |
</pre> |
||
Fehlt <code>user</code>, wird der lokale Login-Name verwendet, Port |
Fehlt <code>user</code>, wird der lokale Login-Name verwendet, Port |
||
ist standardmäßig 22, Pfad standardmäßig <code>/</code>. |
ist standardmäßig 22, Pfad standardmäßig <code>/</code>. Das |
||
optionale <code>:password</code>-Segment ist das RFC-3986-Userinfo-Passwort |
|||
— wann es angebracht ist und welche Sicherheitsabwägungen |
|||
damit verbunden sind, beschreibt [[#Passwort-Authentifizierung]]. |
|||
Wenn vorhanden, dient es als USERAUTH-Fallback nach den üblichen |
|||
Publickey-/Agent-Versuchen und wird '''niemals''' wieder von der |
|||
druckbaren URL-Form ausgegeben — das Protokollieren des |
|||
Dateinamens leakt also nicht das Credential. |
|||
Die Schaltfläche '''Refresh''' in der Symbolleiste |
|||
(Pfeil-Kreis-Symbol zwischen ''Forward'' und ''DirectoryUp'') liest |
|||
Baum und Inhalts-Panel auf Anforderung neu ein. Funktioniert |
|||
einheitlich für lokale und SFTP-Pfade; bei SFTP wird zusätzlich der |
|||
per-Datei-STAT-Cache geleert, sodass Änderungen, die direkt auf |
|||
der Gegenseite gemacht wurden, sofort sichtbar werden — ohne auf |
|||
den Ablauf der 5-Sekunden-Cache-TTL zu warten. |
|||
Der kleine Pfeil neben dem Refresh-Symbol öffnet ein Aufklappmenü |
|||
mit einem einzelnen Kontrollkästchen, '''Automatic Refresh''', das |
|||
den Hintergrund-Task an- bzw. abschaltet, der alle expandierten |
|||
Baumeinträge auf externe Änderungen prüft. Die Vorgabe richtet |
|||
sich nach der aktuellen Wurzel: |
|||
* Lokales Dateisystem → '''an''' (10-Sekunden-Zyklus, entspricht dem bisherigen Verhalten). |
|||
* SFTP → '''aus'''. Jeder Zyklus kostet einen STAT-Roundtrip pro Kind — für eine Handvoll lokaler Verzeichnisse harmlos, über das Netz schmerzhaft. Bei Bedarf manuell auf Refresh klicken, um Änderungen zu sehen. |
|||
Beim Wechsel zwischen lokalen und SFTP-Wurzeln wird der Schalter |
|||
automatisch umgelegt — aber nur, sofern man ihn für die |
|||
vorherige Wurzel nicht selbst verstellt hat. Eine explizite |
|||
Benutzerwahl bleibt über Navigationen hinweg erhalten. |
|||
Das Menü '''Tools''' im FileBrowserV2 bietet vier Aktionen — die |
Das Menü '''Tools''' im FileBrowserV2 bietet vier Aktionen — die |
||
| Zeile 61: | Zeile 90: | ||
liefert, damit ein TB-großes Volume als ''X TiB'' statt |
liefert, damit ein TB-großes Volume als ''X TiB'' statt |
||
''10240 GiB'' erscheint. |
''10240 GiB'' erscheint. |
||
== Aus dem Launcher == |
|||
Das Untermenü '''Workspace''' im Launcher enthält zwei eigenständige |
|||
Einträge (nur sichtbar bei geladenem SSH-Paket): |
|||
* '''SSH Terminal''' — fragt nach einem Ziel der Form <code>user[:password]@host[:port]</code> und öffnet ein VT100-Terminal als eigenständiges Fenster. Das ist das Launcher-Pendant zum FileBrowserV2-Eintrag '''Tools → SSH Connect...'''. |
|||
* '''SFTP Connection''' — fragt nach einem SFTP-Ziel (gleiche URL-Grammatik wie in der FileBrowserV2-Adresszeile, siehe [[#Aus dem FileBrowserV2]]) und öffnet einen frischen FileBrowserV2, der bereits dorthin navigiert ist. |
|||
Beide Einträge unterstützen die in [[#Passwort-Authentifizierung]] |
|||
beschriebene URL-Form mit eingebettetem Passwort. |
|||
== Aus expecco-Aktionen == |
== Aus expecco-Aktionen == |
||
| Zeile 313: | Zeile 353: | ||
(fragt einmal nach der Passphrase) und nutzt ihn für die übrige |
(fragt einmal nach der Passphrase) und nutzt ihn für die übrige |
||
Sitzung weiter. |
Sitzung weiter. |
||
== Passwort-Authentifizierung == |
|||
Empfohlen ist Public-Key-Authentifizierung (mit oder ohne |
|||
ssh-agent). Passwort-Authentifizierung ist als Fallback gedacht, |
|||
wenn keine Schlüssel verfügbar sind: Altsysteme, Ad-hoc-Zugriff |
|||
auf einen Testserver, Skripte gegen ein Konto, dessen Besitzer den |
|||
Public Key nicht hinterlegen möchte. Zu beachten: |
|||
* Das Klartext-Passwort liegt auf ST/X-Seite für die Lebensdauer des <code>SSH::Client</code> im Speicher — entsprechend behandeln wie jedes andere In-Memory-Geheimnis. |
|||
* Der Server entscheidet, welche Methoden er akzeptiert. Steht in <code>sshd_config</code> <code>PasswordAuthentication no</code>, kann keine Smalltalk-seitige Einstellung das überschreiben. |
|||
* Auf Drahtebene entspricht der Vorgang RFC 4252 §8: das Passwort wandert innerhalb der verschlüsselten SSH-Transportschicht, niemals im Klartext über das Netz. |
|||
=== Aus einer URL === |
|||
Sowohl die FileBrowserV2-Adressleiste als auch die Launcher-Dialoge |
|||
'''Workspace → SFTP Connection''' / '''Workspace → SSH |
|||
Terminal''' akzeptieren ein eingebettetes Passwort an der |
|||
standardmäßigen RFC-3986-Userinfo-Position: |
|||
<pre> |
|||
sftp://alice:s3cret@host.example.com/srv/data |
|||
ssh alice:s3cret@host.example.com:2222 |
|||
</pre> |
|||
Der Parser splittet am '''letzten''' <code>@</code>, sodass |
|||
Passwörter mit enthaltenem <code>@</code> dennoch korrekt geparst |
|||
werden; der erste <code>:</code> im Userinfo-Teil trennt Benutzer |
|||
und Passwort. Passwörter, die selbst ein <code>:</code> enthalten, |
|||
werden in dieser Form nicht unterstützt — dafür die |
|||
programmatische API unten verwenden. |
|||
Das Passwort wird aus der druckbaren URL entfernt: jede Stelle, die |
|||
am Ende den Dateinamen ausgibt (Statuszeile, |
|||
<code>printOn:</code>, <code>nameString</code>, die Breadcrumb-Leiste) |
|||
zeigt die credential-freie Form |
|||
<code>sftp://alice@host.example.com/...</code>. |
|||
=== Aus Code === |
|||
Zwei äquivalente Wege, einem <code>SSH::Client</code> ein Passwort |
|||
mitzugeben: |
|||
<pre> |
|||
"/ Literal -- am einfachsten, Passwort ist nur ein Ivar |
|||
client := SSH::Client newToHost:'host.example.com' port:22 user:'alice'. |
|||
client password:'s3cret'. |
|||
client connect. |
|||
</pre> |
|||
<pre> |
|||
"/ Callback -- lazy; das Passwort lebt nie auf dem Client. |
|||
"/ Praktisch für interaktive Abfrage, Keychain-Lookup oder ein |
|||
"/ Vault-gespeichertes Geheimnis, das nicht langlebig im Speicher |
|||
"/ liegen soll. |
|||
client passwordCallback:[ Dialog requestPassword:'SSH-Passwort' ]. |
|||
client connect. |
|||
</pre> |
|||
Sind beide gesetzt, gewinnt der Callback. Beide werden lazy |
|||
während <code>#connect</code> ausgewertet, nachdem die |
|||
Publickey-/Agent-Versuche abgelehnt wurden — ein |
|||
funktionierender Schlüssel schlägt also immer ein parallel |
|||
konfiguriertes Passwort. |
|||
=== Reihenfolge der Authentifizierungsversuche === |
|||
<code>SSH::Client>>authenticate</code> geht jedes verfügbare |
|||
Credential der Reihe nach durch und kehrt beim ersten zurück, das |
|||
der Server akzeptiert: |
|||
# ssh-agent-Identitäten, sofern <code>#useAgent</code> aufgerufen wurde und der Agent Schlüssel geladen hat. |
|||
# ed25519-Privatschlüssel-Seed, sofern <code>#privateKeyFromFile:</code> einen geladen hat. |
|||
# RSA-Privatschlüssel. |
|||
# ECDSA-Privatschlüssel. |
|||
# Passwort, sofern <code>#password:</code> / <code>#passwordCallback:</code> gesetzt ist '''und''' der Server <code>password</code> in seiner USERAUTH_FAILURE-Methodenliste weiterhin anbietet. |
|||
Jeder Schritt wird übersprungen, wenn die letzte |
|||
<code>USERAUTH_FAILURE</code>-Antwort des Servers die jeweilige |
|||
Methode aus der erlaubten Liste gestrichen hat — auf |
|||
<code>publickey</code> wird also nicht weiter herumgehämmert, |
|||
sobald der Server damit aufhört. Der Passwortversuch läuft nur, |
|||
wenn der Server <code>password</code> noch verlangt; ein falsch |
|||
konfiguriertes Passwort gegen einen reinen Schlüssel-Server erzeugt |
|||
also einen sauberen <code>SSH::AuthenticationError</code> ohne |
|||
zusätzlichen nutzlosen Roundtrip. |
|||
== Konfiguration == |
== Konfiguration == |
||
Aktuelle Version vom 8. Juni 2026, 14:26 Uhr
| Language: | Deutsch • English |
|---|
Fernzugriff bezeichnet die Möglichkeit, einen entfernten Rechner oder ein entferntes Netzwerk aus diesem expecco-Image heraus zu bedienen — Shells zu öffnen, Befehle abzusetzen, Dateien zu verschieben oder ein Testgerät anzusteuern. Drei Protokoll-Familien sind unterstützt, in absteigender Empfehlungsreihenfolge:
- SSH und SFTP (empfohlen) — verschlüsselte Shell und sichere Dateiübertragung über einen SSH-2-Tunnel. Reine Smalltalk-Implementierung in
exept:libcrypt/ssh; keine externe Abhängigkeit von OpenSSL oder libssh. Für alles mit Zugangsdaten oder sensiblen Nutzdaten. - Lokale Kommando-Shell — fork + exec auf der lokalen Maschine. Für die Anbindung lokaler Werkzeuge und für die lokale Seite eines hybriden Workflows.
- Telnet (veraltet) — Klartext-Terminalsitzung. Keine Verschlüsselung, Passwörter im Klartext auf der Leitung. Nur einsetzen, wenn die Gegenstelle keine Alternative bietet.
SSH und SFTP
Der SSH-Stack deckt das vollständige SSH-2-Protokoll ab (RFC 4251–4254, RFC 5656, RFC 8709, RFC 8731) inklusive der chacha20-poly1305-Transportchiffrierung von OpenSSH sowie das SFTP-v3-Subsystem (draft-ietf-secsh-filexfer-02). Zwei Schichten:
SSH::Client— programmatischer SSH-Zugriff (entferntesexec, TTY-Shell, Agent-Weiterleitung, ProxyJump-Bastion).SSH::SftpFilename— eine
Filename-Unterklasse, die es dem restlichen ST/X
erlaubt, einen entfernten SFTP-Pfad zu behandeln wie eine lokale
Datei.
Die folgenden Abschnitte sind nutzeraufgaben-zuerst aufgebaut: zuerst das, was der Anwender sieht und tut, darunter die expecco-Bibliotheks-Anbindung, ganz unten Implementierungsdetails für Interessierte.
Aus dem FileBrowserV2
Im Adress-Dropdown eine sftp://-URL einfügen. Der
Browser-Tab füllt sich wie bei einem lokalen Pfad.
Baum-Ausklappen, Spaltensortierung (Name / Größe / mtime),
Vorschau und Doppelklick zum Öffnen im Editor verhalten sich
normal. Der erste Klick auf einen Host dauert ~200–500 ms
(TCP + KEX + Auth); folgende Klicks nutzen die gepoolte
Verbindung weiter.
URL-Syntax:
sftp://[user[:password]@]host[:port]/remote/path
Fehlt user, wird der lokale Login-Name verwendet, Port
ist standardmäßig 22, Pfad standardmäßig /. Das
optionale :password-Segment ist das RFC-3986-Userinfo-Passwort
— wann es angebracht ist und welche Sicherheitsabwägungen
damit verbunden sind, beschreibt #Passwort-Authentifizierung.
Wenn vorhanden, dient es als USERAUTH-Fallback nach den üblichen
Publickey-/Agent-Versuchen und wird niemals wieder von der
druckbaren URL-Form ausgegeben — das Protokollieren des
Dateinamens leakt also nicht das Credential.
Die Schaltfläche Refresh in der Symbolleiste (Pfeil-Kreis-Symbol zwischen Forward und DirectoryUp) liest Baum und Inhalts-Panel auf Anforderung neu ein. Funktioniert einheitlich für lokale und SFTP-Pfade; bei SFTP wird zusätzlich der per-Datei-STAT-Cache geleert, sodass Änderungen, die direkt auf der Gegenseite gemacht wurden, sofort sichtbar werden — ohne auf den Ablauf der 5-Sekunden-Cache-TTL zu warten.
Der kleine Pfeil neben dem Refresh-Symbol öffnet ein Aufklappmenü mit einem einzelnen Kontrollkästchen, Automatic Refresh, das den Hintergrund-Task an- bzw. abschaltet, der alle expandierten Baumeinträge auf externe Änderungen prüft. Die Vorgabe richtet sich nach der aktuellen Wurzel:
- Lokales Dateisystem → an (10-Sekunden-Zyklus, entspricht dem bisherigen Verhalten).
- SFTP → aus. Jeder Zyklus kostet einen STAT-Roundtrip pro Kind — für eine Handvoll lokaler Verzeichnisse harmlos, über das Netz schmerzhaft. Bei Bedarf manuell auf Refresh klicken, um Änderungen zu sehen.
Beim Wechsel zwischen lokalen und SFTP-Wurzeln wird der Schalter automatisch umgelegt — aber nur, sofern man ihn für die vorherige Wurzel nicht selbst verstellt hat. Eine explizite Benutzerwahl bleibt über Navigationen hinweg erhalten.
Das Menü Tools im FileBrowserV2 bietet vier Aktionen — die drei SSH-spezifischen sind nur bei geladener SSH-Bibliothek sichtbar:
- Generate SSH Key Pair... — öffnet den Schlüsselerzeugungs-Dialog, siehe #Einen SSH-Schlüssel erzeugen unten.
- SSH Connect... — öffnet ein interaktives VT100-Terminal zu einem entfernten Host.
- SFTP Connect... — navigiert diesen Browser-Tab über SFTP auf ein entferntes Dateisystem.
- Filesystem Info... — zeigt Größe, freien Platz und Belegung des Dateisystems, das das aktuell angezeigte Verzeichnis enthält. Funktioniert einheitlich für lokale und SFTP-Pfade; bei SFTP setzt der Aufruf voraus, daß der Server die Erweiterung
statvfs@openssh.com ankündigt (jedes moderne OpenSSH
tut das). Größen werden in IEC-Binäreinheiten ausgegeben (MiB,
GiB, TiB) — gewählt wird die größte Einheit, die einen Wert ≥ 1
liefert, damit ein TB-großes Volume als X TiB statt
10240 GiB erscheint.
Aus dem Launcher
Das Untermenü Workspace im Launcher enthält zwei eigenständige Einträge (nur sichtbar bei geladenem SSH-Paket):
- SSH Terminal — fragt nach einem Ziel der Form
user[:password]@host[:port]und öffnet ein VT100-Terminal als eigenständiges Fenster. Das ist das Launcher-Pendant zum FileBrowserV2-Eintrag Tools → SSH Connect.... - SFTP Connection — fragt nach einem SFTP-Ziel (gleiche URL-Grammatik wie in der FileBrowserV2-Adresszeile, siehe #Aus dem FileBrowserV2) und öffnet einen frischen FileBrowserV2, der bereits dorthin navigiert ist.
Beide Einträge unterstützen die in #Passwort-Authentifizierung beschriebene URL-Form mit eingebettetem Passwort.
Aus expecco-Aktionen
Das Expecco-RemoteAccess-Plugin (Expecco::RemoteAccessImportPlugin) stellt folgende Testaktionen in der expecco-Aktionspalette bereit:
- CmdShell - Open SSH Remote Connection — öffnet eine SSH-Sitzung über das plattformeigene
ssh-Binary (PuTTYsplinkunter Windows). - CmdShell - Open SSH Remote Connection and PublicKey — dasselbe, jedoch mit expliziter Public-Key-Authentifizierung.
Voraussetzung: ein eingerichtetes Schlüsselpaar (privater
Schlüssel auf dieser Maschine, öffentlicher Teil in der
~/.ssh/authorized_keys des Zielhosts). Schlüssel
erzeugen entweder über den Dialog unten oder über
ssh-keygen.
Das Plugin fügt zusätzlich eine Settings-Seite hinzu: Extras → Settings → Plugins → Remote Access — SSH Keys mit einer einzelnen Schaltfläche Generate SSH Key Pair..., die denselben Dialog öffnet.
Einen SSH-Schlüssel erzeugen
Der Dialog (FileBrowserV2 / Settings-Seite)
Der Dialog fragt alle Parameter in einem Formular ab:
- Comment — wird in den erzeugten Schlüssel eingebettet (Voreinstellung
stx@<hostname>). - Storage:
- Save to disk file only — schreibt
~/.ssh/id_ed25519_stx (oder wohin man will) samt
zugehöriger .pub-Datei daneben.
- Save to disk AND load into ssh-agent — schreibt die Datei UND übergibt den Schlüssel dem laufenden ssh-agent.
- Load into ssh-agent only — der Schlüssel lebt nur im Speicher des Agents; nach Agent-Neustart ist er verloren.
- Private key file — vollständiger Pfad; ausgegraut im Agent-only-Modus.
- Passphrase / Confirm — leer lässt die On-Disk-Datei unverschlüsselt (Agent-only-Modus ignoriert die Passphrase, da das OpenSSH-Agent-Wire-Protokoll nur den entschlüsselten Schlüssel transportiert).
Bei Generate wird die Public-Key-Zeile (dieselbe
ssh-ed25519 AAAA... comment-Zeichenfolge, die
ssh-keygen ausgibt) in die System-Zwischenablage kopiert — zum
direkten Einfügen in die ~/.ssh/authorized_keys des
Zielhosts.
Aus einem Workspace
Für Headless-Deployments, Sandbox-Builds oder Skripte stellt
SSH::Client einen reinen Smalltalk-Schlüsselgenerator
bereit, dessen Ausgabe bit-kompatibel zu
ssh-keygen -t ed25519 ist:
| seed comment priv |
seed := SSH::Client generateEd25519Seed.
comment := 'stx@', OperatingSystem getHostName.
"/ Passphrase-verschlüsselt auf Platte speichern"
priv := (Filename homeDirectory / '.ssh' / 'id_ed25519_stx') pathName.
SSH::Client
saveOpenSshEd25519Seed:seed
toFile:priv
comment:comment
passphrase:'choose-something-long'.
"/ UND in den laufenden Agent laden"
SSH::Client addEd25519SeedToAgent:seed comment:comment.
"/ Public-Key-Zeile zum Einfügen in authorized_keys ausgeben"
Transcript showCR:
(SSH::Client authorizedKeysLineForEd25519Seed:seed comment:comment).
Die so erzeugten Schlüssel sind mit den OpenSSH-Werkzeugen voll
interoperabel (ssh-keygen -y -f ... rekonstruiert den
öffentlichen Schlüssel, ssh-keygen -p -f ... ändert
die Passphrase usw.).
Mit den Shell-Werkzeugen
Der klassische Weg funktioniert weiterhin:
ssh-keygen -t ed25519 -C "stx@your.host" ssh-copy-id user@remotehost ssh-add ~/.ssh/id_ed25519
ssh-agent vorbereiten
Der Weg über den Agent ist dem direkten Lesen von Schlüsseldateien deutlich vorzuziehen: er hält verschlüsselte private Schlüssel einmal pro Sitzung entsperrt und kann Identitäten verwalten (hardware-tokengestützte Schlüssel, KeePassXC-Einträge), die ST/X nie direkt sehen soll.
ST/X erkennt den Agent-Pfad automatisch, sobald
$SSH_AUTH_SOCK zum Zeitpunkt des Starts von stx
in der Prozessumgebung gesetzt ist. Eine spätere Zuweisung aus
einem Workspace nützt nichts.
Linux / macOS
Die meisten Desktop-Distributionen starten einen Agent automatisch beim Login (gnome-keyring unter GNOME, ssh-agent.service unter systemd, KWallet unter KDE). Prüfen im Terminal:
echo $SSH_AUTH_SOCK # /run/user/1000/keyring/ssh oder ähnlich ssh-add -l # listet geladene Identitäten ssh-add ~/.ssh/id_ed25519 # eigene laden, falls nicht da
Läuft gar kein Agent, dieses Snippet in die Shell-rc-Datei aufnehmen:
# ~/.bashrc oder ~/.zshrc
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
fi
ST/X muss aus einer Shell gestartet werden, die diese rc bereits
gelesen hat — ein Desktop-Launcher aus dem Dateimanager erbt die
Variable nicht. Empfehlung: ein kleines Wrapper-Skript unter
~/.local/bin/, das die rc sourcet und dann stx
startet.
Die Settings-Seite (Extras → Settings → Plugins → Remote Access — SSH Keys) zeigt an, ob das laufende Image einen Agent sieht.
Permanente Einrichtung via systemd
Für einen wirklich sitzungsübergreifenden Agent (überlebt Desktop-
Abmeldung, kommt beim nächsten Login wieder hoch) die bei den
meisten Distros mit dem Paket openssh-clients
ausgelieferte Per-User-systemd-Unit aktivieren:
systemctl --user enable --now ssh-agent.service
Anschließend SSH_AUTH_SOCK in der Shell-rc auf den
User-Service-Socket zeigen lassen (ersetzt das
eval $(ssh-agent -s)-Snippet oben):
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/ssh-agent.socket"
Schlüssel automatisch beim ersten Einsatz laden
Um den manuellen ssh-add-Schritt zu sparen, kann
OpenSSH Schlüssel beim ersten Bedarf selbst in den Agent laden.
In ~/.ssh/config eintragen:
Host *
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
Die erste SSH-Verbindung fragt dann einmal nach der Passphrase und übergibt den entsperrten Schlüssel an den Agent; weitere Verbindungen nutzen die gespeicherte Identität ohne Prompt.
Windows
Windows 10+ bringt das native OpenSSH inklusive Agent-Dienst mit. Einmalige Einrichtung:
- Dienste (
services.msc) als Administrator öffnen. - OpenSSH Authentication Agent suchen, Starttyp auf Automatisch setzen, Starten anklicken.
- In PowerShell:
ssh-add $HOME\.ssh\id_ed25519. - Prüfen:
ssh-add -l.
Der Windows-OpenSSH-Agent lauscht auf einer Named Pipe
(\\.\pipe\openssh-ssh-agent), nicht auf einem
Unix-Socket. ST/X unterstützt beide Transporte, jedoch setzt das
Windows-ssh-add SSH_AUTH_SOCK nicht selbst.
Daher einmalig systemweit setzen:
- Vorlage:Key drücken → "Umgebungsvariablen" → „Systemumgebungs- variablen bearbeiten".
- Umgebungsvariablen → unter Benutzervariablen, Neu klicken.
- Name:
SSH_AUTH_SOCK - Wert:
\\.\pipe\openssh-ssh-agent - Ab- und wieder anmelden (oder stx neu starten), damit die neue Umgebung übernommen wird.
PowerShell-Schnelleinrichtung
Derselbe Aufbau aus einer Administrator-PowerShell heraus, z.B. für Skripte oder unbeaufsichtigte Bereitstellung:
# Agent jetzt und bei jedem Neustart starten (permanent).
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
# SSH_AUTH_SOCK dauerhaft für den Benutzer setzen (übersteht Reboots).
[Environment]::SetEnvironmentVariable(
'SSH_AUTH_SOCK',
'\\.\pipe\openssh-ssh-agent',
'User')
# Schlüssel laden (fragt nach Passphrase, falls die Datei verschlüsselt ist).
ssh-add $HOME\.ssh\id_ed25519
Für einen einmaligen Agent-Start ohne dauerhafte Aktivierung
(z.B. Einzelsitzung) die Set-Service-Zeile weglassen
und nur Start-Service ssh-agent ausführen. Die
env-var-Zeile lässt sich ebenfalls weglassen, wenn
SSH_AUTH_SOCK nur in der aktuellen Shell gebraucht
wird — dann statt der [Environment]-Variante
$env:SSH_AUTH_SOCK = '...' verwenden.
Auf stark abgespeckten Windows-Installationen ist der ssh-agent-Dienst eventuell nicht vorhanden. Einmalig nachrüsten über Einstellungen → Apps → Optionale Features → OpenSSH- Client.
Alternative Agenten:
- PuTTY pageant — eigenes Protokoll; von ST/X's
SSH::Agent nicht unterstützt. Schlüssel zu
OpenSSH migrieren.
- Git für Windows ssh-agent — funktioniert;
SSH_AUTH_SOCK auf den dort veröffentlichten Socket
zeigen lassen.
- WSL 2 — ein ST/X innerhalb der WSL sieht den WSL-eigenen Agent normal; ein ST/X auf der Windows-Seite nicht. Eine Brücke per
npiperelay+socatist möglich.
Prüfung über die Settings-Seite (Extras → Settings → Plugins → Remote Access — SSH Keys) — die Anzeige dort meldet, ob das laufende Image den Agent sieht.
Schlüssel automatisch beim ersten Einsatz laden
Windows-OpenSSH speichert agent-geladene Schlüssel nicht
über Agent-Neustarts hinweg. Um nicht nach jedem Reboot manuell
ssh-add aufrufen zu müssen, dieselbe Lazy-Load-
Konfiguration in %USERPROFILE%\.ssh\config
eintragen:
Host *
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
OpenSSH lädt den Schlüssel dann beim ersten Einsatz in den Agent (fragt einmal nach der Passphrase) und nutzt ihn für die übrige Sitzung weiter.
Passwort-Authentifizierung
Empfohlen ist Public-Key-Authentifizierung (mit oder ohne ssh-agent). Passwort-Authentifizierung ist als Fallback gedacht, wenn keine Schlüssel verfügbar sind: Altsysteme, Ad-hoc-Zugriff auf einen Testserver, Skripte gegen ein Konto, dessen Besitzer den Public Key nicht hinterlegen möchte. Zu beachten:
- Das Klartext-Passwort liegt auf ST/X-Seite für die Lebensdauer des
SSH::Clientim Speicher — entsprechend behandeln wie jedes andere In-Memory-Geheimnis. - Der Server entscheidet, welche Methoden er akzeptiert. Steht in
sshd_configPasswordAuthentication no, kann keine Smalltalk-seitige Einstellung das überschreiben. - Auf Drahtebene entspricht der Vorgang RFC 4252 §8: das Passwort wandert innerhalb der verschlüsselten SSH-Transportschicht, niemals im Klartext über das Netz.
Aus einer URL
Sowohl die FileBrowserV2-Adressleiste als auch die Launcher-Dialoge Workspace → SFTP Connection / Workspace → SSH Terminal akzeptieren ein eingebettetes Passwort an der standardmäßigen RFC-3986-Userinfo-Position:
sftp://alice:s3cret@host.example.com/srv/data ssh alice:s3cret@host.example.com:2222
Der Parser splittet am letzten @, sodass
Passwörter mit enthaltenem @ dennoch korrekt geparst
werden; der erste : im Userinfo-Teil trennt Benutzer
und Passwort. Passwörter, die selbst ein : enthalten,
werden in dieser Form nicht unterstützt — dafür die
programmatische API unten verwenden.
Das Passwort wird aus der druckbaren URL entfernt: jede Stelle, die
am Ende den Dateinamen ausgibt (Statuszeile,
printOn:, nameString, die Breadcrumb-Leiste)
zeigt die credential-freie Form
sftp://alice@host.example.com/....
Aus Code
Zwei äquivalente Wege, einem SSH::Client ein Passwort
mitzugeben:
"/ Literal -- am einfachsten, Passwort ist nur ein Ivar client := SSH::Client newToHost:'host.example.com' port:22 user:'alice'. client password:'s3cret'. client connect.
"/ Callback -- lazy; das Passwort lebt nie auf dem Client. "/ Praktisch für interaktive Abfrage, Keychain-Lookup oder ein "/ Vault-gespeichertes Geheimnis, das nicht langlebig im Speicher "/ liegen soll. client passwordCallback:[ Dialog requestPassword:'SSH-Passwort' ]. client connect.
Sind beide gesetzt, gewinnt der Callback. Beide werden lazy
während #connect ausgewertet, nachdem die
Publickey-/Agent-Versuche abgelehnt wurden — ein
funktionierender Schlüssel schlägt also immer ein parallel
konfiguriertes Passwort.
Reihenfolge der Authentifizierungsversuche
SSH::Client>>authenticate geht jedes verfügbare
Credential der Reihe nach durch und kehrt beim ersten zurück, das
der Server akzeptiert:
- ssh-agent-Identitäten, sofern
#useAgentaufgerufen wurde und der Agent Schlüssel geladen hat. - ed25519-Privatschlüssel-Seed, sofern
#privateKeyFromFile:einen geladen hat. - RSA-Privatschlüssel.
- ECDSA-Privatschlüssel.
- Passwort, sofern
#password:/#passwordCallback:gesetzt ist und der Serverpasswordin seiner USERAUTH_FAILURE-Methodenliste weiterhin anbietet.
Jeder Schritt wird übersprungen, wenn die letzte
USERAUTH_FAILURE-Antwort des Servers die jeweilige
Methode aus der erlaubten Liste gestrichen hat — auf
publickey wird also nicht weiter herumgehämmert,
sobald der Server damit aufhört. Der Passwortversuch läuft nur,
wenn der Server password noch verlangt; ein falsch
konfiguriertes Passwort gegen einen reinen Schlüssel-Server erzeugt
also einen sauberen SSH::AuthenticationError ohne
zusätzlichen nutzlosen Roundtrip.
Konfiguration
Alle Stellschrauben sind klassenseitig auf
SSH::SftpFilename erreichbar:
| Accessor | Voreinstellung | Steuert |
|---|---|---|
#idleEvictionSeconds: |
240 (4 Min) | Wie lange
eine gepoolte Verbindung im Leerlauf liegen darf, bevor sie beim
nächsten Zugriff proaktiv geschlossen und neu geöffnet wird.
Liegt knapp unter dem typischen
|
#attrsCacheTtlSeconds: |
5 | Maximales Alter (s)
eines gecachten STAT, bevor |
#closeAllConnections |
(Aktion) | Reißt jede
gepoolte Verbindung ab. Nützlich nach einem bekannt schlechten Netzereignis, vor einem bewussten Identitätswechsel oder zum sauberen Image-Shutdown. |
Diagnose
SemaphoreMonitor
SemaphoreMonitor über das Untermenü „Status" des
Launchers öffnen. Der pro-Host-SFTP-Mutex erscheint als
SFTP/<user@host:port>, der pool-weite Mutex als
SFTP/pool. Per Rechtsklick:
- Copy Waiters Stack to Clipboard — schreibt den Walkback des letzten Eigners samt aller Waiter als Text in die Zwischenablage. Unverzichtbar, wenn ein Prozess in
readWait innerhalb von
withSftpClientDo: klemmt.
- Copy List to Clipboard — die ganze Tabelle, ideal für eine E-Mail-Diagnose.
- Detect Deadlocks — DFS über den Wait-for-Graph, meldet Zyklen.
Logger
Interessante Ereignisse werden über Logger geloggt:
warning:bei automatischem Reconnect nach toter Verbindung.warning:bei Idle-Verdrängung eines Pool-Eintrags.warning:wenn eine SSH-Schlüsseldatei nicht geparst werden konnte — die Datei wird übersprungen.
Einschränkungen
- Nur SFTP v3. Kein SETSTAT (kein entferntes chmod / chown / utime), kein SSH_FXP_READLINK exponiert (
#isSymbolicLinkliefert immerfalse,
#linkInfo die normale stat-Info). Einige
SFTPv5+-Annehmlichkeiten werden dennoch über OpenSSH-spezifische
SSH_FXP_EXTENDED-Aufrufe nutzbar — siehe
#OpenSSH-SFTP-Erweiterungen weiter unten.
- Serialisierung pro Host. Zwei gleichzeitige Operationen am selben Host stehen am Host-Mutex an. Siehe #Ausblick.
#renameTo:-Fallback hat ein TOCTOU-Fenster. Bei Servern, dieposix-rename@openssh.comankündigen (jedes moderne OpenSSH tut das), ist das Überschreiben atomar. Beim seltenen Server, der das nicht tut, wird auf Delete-dann-Rename ausgewichen und ein anderer Prozess kann sich dazwischenschieben.#isNonEmptyDirectoryist eine Heuristik. Liefert immer#isDirectory(die genaue Antwort würde drei Roundtrips pro Verzeichnis-Symbol kosten, was das ursprüngliche Baum-Ausklappen unerträglich gebremst hatte).
Implementierungsdetails
Für Leser, die die Architektur verstehen wollen. Fünf Klassen, von oben nach unten:
| Klasse | Aufgabe |
|---|---|
SSH::SftpFilename |
Filename-Unterklasse, die
öffentliche API. Bildet |
SSH::SftpClient |
SFTP-v3-Protokoll
(Request/Response-Codec, listDir, stat, open, read, write, mkdir). Wird von SftpFilename angesteuert. |
SSH::Channel |
SSH-Kanal-Multiplexer (CHANNEL_OPEN,
DATA, EOF, CLOSE, WINDOW_ADJUST). Eine logische Sitzung pro Channel-Instanz. |
SSH::Client |
High-Level-SSH-Client: öffnet den
Transport, führt KEX, Hostschlüssel-Prüfung und userauth durch und verteilt anschließend Kanäle. |
SSH::Transport |
Drahtschicht. Banner- und
KEXINIT-Austausch, ChaCha20-Poly1305-Paket-Framing, sendSeq / recvSeq, Heartbeat, SSH_MSG_DISCONNECT. |
OpenSSH-SFTP-Erweiterungen
SFTP v3 (Entwurf draft-ietf-secsh-filexfer-02) ist bewusst
minimal gehalten. OpenSSH bringt einen offenen
Erweiterungsmechanismus mit: der Server listet im
SSH_FXP_VERSION-Reply die Erweiterungsnamen auf, die
er versteht, und der Client ruft sie über
SSH_FXP_EXTENDED(200)-Pakete mit dem
Erweiterungsnamen als erstem String auf. Jede Erweiterung wird
über SSH::SftpClient>>supportsExtension:
feature-detektiert; Aufrufer fallen zurück, wenn der Server sie
nicht ankündigt.
Der Stack nutzt heute vier OpenSSH-Erweiterungen:
posix-rename@openssh.com— atomares rename-mit-Überschreiben. Wird automatisch von
SftpFilename>>renameTo: aufgegriffen; die
Delete-dann-Rename-Fallback-Variante kommt nur bei Servern zum
Einsatz, die die Erweiterung nicht haben.
hardlink@openssh.com— Erzeugt einen POSIX-Hardlink. Verfügbar alsSftpFilename>>createHardLinkAs:.statvfs@openssh.com— POSIX-
statvfs(3)-typische Dateisystem-Statistik.
Verfügbar als SftpFilename>>fileSystemInfo;
das Ergebnis ist form-kompatibel zu
OperatingSystem getDiskInfoOf:, sodass Aufrufer
lokale und entfernte Pfade einheitlich behandeln können.
Treibt den Menü-Eintrag Tools → Filesystem Info... an,
der am Anfang dieser Seite beschrieben ist.
fsync@openssh.com— schreibt den serverseitigen Schreibpuffer eines geöffneten Handles auf Platte. Liegt als
SftpClient>>fsyncHandle: bereit; noch nicht
in eine "Durable-Write"-API auf Filename-Ebene eingebunden.
Die verbleibenden OpenSSH-Erweiterungen
(lsetstat@openssh.com, fstatvfs@openssh.com)
werden in der angekündigten Liste erkannt, aber nicht auf
Filename-Ebene gekapselt — es gibt dafür noch keinen
Filename-seitigen Aufrufer.
Verbindungs-Pooling
Alle SftpFilename-Instanzen, die auf dasselbe Tripel
user@host:port zeigen, teilen sich einen
SSH::Client samt einem SSH::SftpClient.
Der Pool ist klassenseitig und wird von einem einzigen
ConnectionPoolMutex bewacht:
- Lazy-Aufbau — TCP + KEX + userauth + SFTP-INIT laufen erst beim ersten SFTP-Aufruf, nicht in
forUrl:. - Serialisierung pro Host — SFTP-Anfragen an einen bestimmten Host werden durch einen
RecursionLockmit dem NamenSFTP/<user@host:port>serialisiert (sichtbar im SemaphoreMonitor). - Idle-Verdrängung — ein Pool-Eintrag, der länger als
idleEvictionSeconds ungenutzt liegt, wird beim
nächsten Zugriff proaktiv geschlossen und neu geöffnet.
- Automatischer Reconnect — ein Fehler auf Transportebene (Broken Pipe, EOF, MNU auf nil-Socket) verdrängt den Pool-Eintrag, öffnet einen frischen Client und wiederholt die Anfrage einmal. Anwendungsfehler aus SFTP-STATUS-Antworten werden sofort durchgereicht.
Ausblick
Geplant, aber noch nicht umgesetzt:
- Multi-Channel-Parallelität pro Host — aktuell bedeutet eine TCP- plus eine SFTP-Verbindung pro Host, dass N gleichzeitige Anfragen serialisieren. Pipelining über mehrere SshClients im Pool (bevorzugt) oder ein transport-seitiger Reader-Prozess, der eingehende Pakete in Pro-Kanal-Postfächer demultiplext, würde es dem Baum-Panel erlauben, weiter aufzulisten, während das Inhalts-Panel eine große Datei liest.
- Genaues
#isNonEmptyDirectoryvia OPEN_DIR + READ_DIR (nur erstes Batch) + CLOSE — drei Roundtrips pro Sondierung; lohnt erst, wenn der SftpClient Anfragen pipelinen kann. - SFTP-v5/v6-Aushandlung für erweiterte Attribute und FTP-artige Kanonisierung. (Atomares Überschreibungs-rename ist bereits über die OpenSSH-Erweiterung
posix-rename@openssh.com abgedeckt; siehe
#OpenSSH-SFTP-Erweiterungen.)
Kommando-Shell
Lokale Kommando-Shell auf dieser expecco-Maschine. Typische Anwendungen: lokale Kommandozeile, lokales Hilfsprogramm, Brücke zwischen entferntem Workflow und lokalem Tool.
Das RemoteAccess-Plugin stellt bereit:
- CmdShell - Open
- CmdShell - Close
Keine Zugangsdaten, kein Netzwerk — läuft als der Benutzer des expecco-Prozesses. Ausgaben gehen in das expecco-Log.
Telnet
Warnung Telnet ist ein veraltetes Protokoll ohne Verschlüsselung. Passwörter werden im Klartext über die Leitung übertragen; jeder im Netzpfad kann sie lesen. Telnet NUR einsetzen, wenn die Gegenstelle keine Alternative bietet (typisch: alte Industriesteuerungen, Laborgeräte, eingebettete Messgeräte ohne SSH-Stack). Für alles andere #SSH und SFTP verwenden.
Das expecco-Plugin stellt bereit:
- Telnet - Open Remote Connection With Login
- Telnet - Execute Remote Command
- Example - Remote Device Control via Telnet (interne Demo)
Das Telnet-Protokoll (RFC 854) ist ein bidirektionaler 8-Bit-Byte-Strom über TCP, mit In-Band-Steuersequenzen für Terminal-Optionen. Verbindungsaufbau zum Ziel-Host:Port; nach optionalem In-Band-Login können beide Seiten Daten senden.
Siehe auch
- SSH::Client — die SSH-Schicht (exec, TTY, Agent-Weiterleitung, ProxyJump).
- FileBrowserV2 — die Haupt-UI dieses Stacks.
- Claude Code — nutzt denselben SSH-Stack als HTTPS-Transport.
- RFC 4251 (SSH-2 Architecture)
- RFC 854 (Telnet Protocol)