Remote Access: Unterschied zwischen den Versionen
Ca (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
Sv (Diskussion | Beiträge) Native SSH/SFTP |
||
| Zeile 1: | Zeile 1: | ||
'''Fernzugriff''' bezeichnet die Möglichkeit, einen entfernten |
|||
Remote access is the ability to access a remote computer or a remote network from a local computer. |
|||
Rechner oder ein entferntes Netzwerk aus diesem expecco-Image heraus |
|||
Remote desktop software lets you access your computer and all its applications over the Internet |
|||
zu bedienen — Shells zu öffnen, Befehle abzusetzen, Dateien zu |
|||
using another device, essentially by streaming a feed of your desktop. To do this, you’ll need |
|||
verschieben oder ein Testgerät anzusteuern. Drei Protokoll-Familien |
|||
to set up a remote desktop server on the PC you want to connect to. |
|||
sind unterstützt, in absteigender Empfehlungsreihenfolge: |
|||
* '''SSH und SFTP''' (empfohlen) — verschlüsselte Shell und sichere |
|||
Telnet |
|||
Dateiübertragung über einen SSH-2-Tunnel. Reine |
|||
Telnet is an application protocol used on the Internet or local area network to provide a |
|||
Smalltalk-Implementierung in <code>exept:libcrypt/ssh</code>; |
|||
bidirectional interactive text-oriented communication facility using a virtual terminal |
|||
keine externe Abhängigkeit von OpenSSL oder libssh. Für alles |
|||
connection. User data is interspersed in-band with Telnet control information in an 8-bit |
|||
mit Zugangsdaten oder sensiblen Nutzdaten. |
|||
byte oriented data connection over the Transmission Control Protocol (TCP). |
|||
* '''Lokale Kommando-Shell''' — fork + exec auf der lokalen |
|||
Telnet is a strongly outdated network protocol with few security mechanisms. Passwords |
|||
Maschine. Für die Anbindung lokaler Werkzeuge und für die |
|||
are transmitted in plain text. |
|||
lokale Seite eines hybriden Workflows. |
|||
A connection between two computers is established, even if these are under |
|||
* '''Telnet''' (veraltet) — Klartext-Terminalsitzung. Keine |
|||
run different operating systems. |
|||
Verschlüsselung, Passwörter im Klartext auf der Leitung. Nur |
|||
einsetzen, wenn die Gegenstelle keine Alternative bietet. |
|||
= SSH und SFTP = |
|||
Only use Telnet when you really need it. |
|||
Der SSH-Stack deckt das vollständige SSH-2-Protokoll ab |
|||
Example: (see RemoteAccess Library) |
|||
(RFC 4251–4254, RFC 5656, RFC 8709, RFC 8731) inklusive der |
|||
Telnet - Open Remote Connection With Login |
|||
chacha20-poly1305-Transportchiffrierung von OpenSSH sowie das |
|||
Telnet - Execute Remote Command |
|||
SFTP-v3-Subsystem (draft-ietf-secsh-filexfer-02). Zwei Schichten: |
|||
Example - Remote Device Control via Telnet (used internal only) |
|||
* '''<code>SSH::Client</code>''' — programmatischer SSH-Zugriff |
|||
Command Shell |
|||
(entferntes <code>exec</code>, TTY-Shell, Agent-Weiterleitung, |
|||
Command shell on your local computer. Typical applications include local command-line, |
|||
ProxyJump-Bastion). |
|||
and local command execution. |
|||
* '''<code>SSH::SftpFilename</code>''' — eine |
|||
<code>Filename</code>-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: |
|||
Example: (see RemoteAccess Library) |
|||
zuerst das, was der Anwender sieht und tut, darunter die |
|||
CmdShell - Open |
|||
expecco-Bibliotheks-Anbindung, ganz unten Implementierungsdetails |
|||
CmdShell - Close |
|||
für Interessierte. |
|||
== Aus dem FileBrowserV2 == |
|||
Im Adress-Dropdown eine <code>sftp://</code>-URL einfügen. Der |
|||
SSH (Secure Shell) |
|||
Browser-Tab füllt sich wie bei einem lokalen Pfad. |
|||
Secure Shell (SSH) is a cryptographic network protocol for operating network services |
|||
Baum-Ausklappen, Spaltensortierung (Name / Größe / mtime), |
|||
securely over an unsecured network. Typical applications include remote command-line, |
|||
Vorschau und Doppelklick zum Öffnen im Editor verhalten sich |
|||
login, and remote command execution, but any network service can be secured with SSH. |
|||
normal. Der erste Klick auf einen Host dauert ~200–500 ms |
|||
If you want to send confidential data, you better use an SSH connection. |
|||
(TCP + KEX + Auth); folgende Klicks nutzen die gepoolte |
|||
SSH can also implement the Telnet protocol, but encrypt it. |
|||
Verbindung weiter. |
|||
URL-Syntax: |
|||
SSHconnect-Input on Action [CmdShell - Open SSH Remote Connection] |
|||
On windows we are using the plink which is a command-line connection tool similar |
|||
to UNIX (download the PuTTY from Internet). |
|||
To have a public and private key you can can call the puttygen. |
|||
<pre> |
|||
Example: (see RemoteAccess Library) |
|||
sftp://[user@]host[:port]/remote/path |
|||
CmdShell - Open SSH Remote Connection |
|||
</pre> |
|||
CmdShell - Open SSH Remote Connection and PublicKey |
|||
Fehlt <code>user</code>, wird der lokale Login-Name verwendet, Port |
|||
To run the examples you need the private and public keys. The public key |
|||
ist standardmäßig 22, Pfad standardmäßig <code>/</code>. |
|||
should be installed on the remote host. |
|||
Das Menü '''Tools''' im FileBrowserV2 bietet drei SSH-Aktionen, |
|||
sichtbar nur bei geladener SSH-Bibliothek: |
|||
* '''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. |
|||
== 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 <code>ssh</code>-Binary |
|||
(PuTTYs <code>plink</code> unter 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 |
|||
<code>~/.ssh/authorized_keys</code> des Zielhosts). Schlüssel |
|||
erzeugen entweder über den Dialog unten oder über |
|||
<code>ssh-keygen</code>. |
|||
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 <code>stx@<hostname></code>). |
|||
* '''Storage''': |
|||
** ''Save to disk file only'' — schreibt |
|||
<code>~/.ssh/id_ed25519_stx</code> (oder wohin man will) samt |
|||
zugehöriger <code>.pub</code>-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 |
|||
<code>ssh-ed25519 AAAA... comment</code>-Zeichenfolge, die |
|||
ssh-keygen ausgibt) in die System-Zwischenablage kopiert — zum |
|||
direkten Einfügen in die <code>~/.ssh/authorized_keys</code> des |
|||
Zielhosts. |
|||
=== Aus einem Workspace === |
|||
Für Headless-Deployments, Sandbox-Builds oder Skripte stellt |
|||
<code>SSH::Client</code> einen reinen Smalltalk-Schlüsselgenerator |
|||
bereit, dessen Ausgabe bit-kompatibel zu |
|||
<code>ssh-keygen -t ed25519</code> ist: |
|||
<pre> |
|||
| 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). |
|||
</pre> |
|||
Die so erzeugten Schlüssel sind mit den OpenSSH-Werkzeugen voll |
|||
interoperabel (<code>ssh-keygen -y -f ...</code> rekonstruiert den |
|||
öffentlichen Schlüssel, <code>ssh-keygen -p -f ...</code> ändert |
|||
die Passphrase usw.). |
|||
=== Mit den Shell-Werkzeugen === |
|||
Der klassische Weg funktioniert weiterhin: |
|||
<pre> |
|||
ssh-keygen -t ed25519 -C "stx@your.host" |
|||
ssh-copy-id user@remotehost |
|||
ssh-add ~/.ssh/id_ed25519 |
|||
</pre> |
|||
== 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 |
|||
<code>$SSH_AUTH_SOCK</code> '''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: |
|||
<pre> |
|||
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 |
|||
</pre> |
|||
Läuft gar kein Agent, dieses Snippet in die Shell-rc-Datei |
|||
aufnehmen: |
|||
<pre> |
|||
# ~/.bashrc oder ~/.zshrc |
|||
if [ -z "$SSH_AUTH_SOCK" ]; then |
|||
eval "$(ssh-agent -s)" > /dev/null |
|||
fi |
|||
</pre> |
|||
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 |
|||
<code>~/.local/bin/</code>, 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 <code>openssh-clients</code> |
|||
ausgelieferte Per-User-systemd-Unit aktivieren: |
|||
<pre> |
|||
systemctl --user enable --now ssh-agent.service |
|||
</pre> |
|||
Anschließend <code>SSH_AUTH_SOCK</code> in der Shell-rc auf den |
|||
User-Service-Socket zeigen lassen (ersetzt das |
|||
<code>eval $(ssh-agent -s)</code>-Snippet oben): |
|||
<pre> |
|||
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/ssh-agent.socket" |
|||
</pre> |
|||
==== Schlüssel automatisch beim ersten Einsatz laden ==== |
|||
Um den manuellen <code>ssh-add</code>-Schritt zu sparen, kann |
|||
OpenSSH Schlüssel beim ersten Bedarf selbst in den Agent laden. |
|||
In <code>~/.ssh/config</code> eintragen: |
|||
<pre> |
|||
Host * |
|||
AddKeysToAgent yes |
|||
IdentityFile ~/.ssh/id_ed25519 |
|||
</pre> |
|||
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''' (<code>services.msc</code>) als Administrator öffnen. |
|||
# '''OpenSSH Authentication Agent''' suchen, Starttyp auf |
|||
'''Automatisch''' setzen, '''Starten''' anklicken. |
|||
# In PowerShell: <code>ssh-add $HOME\.ssh\id_ed25519</code>. |
|||
# Prüfen: <code>ssh-add -l</code>. |
|||
Der Windows-OpenSSH-Agent lauscht auf einer Named Pipe |
|||
(<code>\\.\pipe\openssh-ssh-agent</code>), nicht auf einem |
|||
Unix-Socket. ST/X unterstützt beide Transporte, jedoch setzt das |
|||
Windows-ssh-add <code>SSH_AUTH_SOCK</code> '''nicht''' selbst. |
|||
Daher einmalig systemweit setzen: |
|||
# {{Key|Win}} drücken → "Umgebungsvariablen" → „Systemumgebungs- |
|||
variablen bearbeiten". |
|||
# '''Umgebungsvariablen''' → unter '''Benutzervariablen''', |
|||
'''Neu''' klicken. |
|||
# Name: <code>SSH_AUTH_SOCK</code> |
|||
# Wert: <code>\\.\pipe\openssh-ssh-agent</code> |
|||
# 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: |
|||
<pre> |
|||
# 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 |
|||
</pre> |
|||
Für einen einmaligen Agent-Start ohne dauerhafte Aktivierung |
|||
(z.B. Einzelsitzung) die <code>Set-Service</code>-Zeile weglassen |
|||
und nur <code>Start-Service ssh-agent</code> ausführen. Die |
|||
env-var-Zeile lässt sich ebenfalls weglassen, wenn |
|||
<code>SSH_AUTH_SOCK</code> nur in der aktuellen Shell gebraucht |
|||
wird — dann statt der <code>[Environment]</code>-Variante |
|||
<code>$env:SSH_AUTH_SOCK = '...'</code> 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 |
|||
<code>SSH::Agent</code> '''nicht''' unterstützt. Schlüssel zu |
|||
OpenSSH migrieren. |
|||
* '''Git für Windows ssh-agent''' — funktioniert; |
|||
<code>SSH_AUTH_SOCK</code> 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 <code>npiperelay</code> + <code>socat</code> ist |
|||
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 |
|||
<code>ssh-add</code> aufrufen zu müssen, dieselbe Lazy-Load- |
|||
Konfiguration in <code>%USERPROFILE%\.ssh\config</code> |
|||
eintragen: |
|||
<pre> |
|||
Host * |
|||
AddKeysToAgent yes |
|||
IdentityFile ~/.ssh/id_ed25519 |
|||
</pre> |
|||
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. |
|||
== Konfiguration == |
|||
Alle Stellschrauben sind klassenseitig auf |
|||
<code>SSH::SftpFilename</code> erreichbar: |
|||
{| class="wikitable" |
|||
! Accessor !! Voreinstellung !! Steuert |
|||
|- |
|||
| <code>#idleEvictionSeconds:</code> || 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 |
|||
<code>ClientAliveInterval × ClientAliveCountMax</code> des sshd, |
|||
damit wir uns recyceln, bevor der Server uns mit TCP-RESET |
|||
trennt. <code>nil</code> setzt auf Voreinstellung zurück. |
|||
|- |
|||
| <code>#attrsCacheTtlSeconds:</code> || 5 || Maximales Alter (s) |
|||
eines gecachten STAT, bevor <code>#ensureAttrs</code> neu am |
|||
Server fragt. Eltern-listDir stempelt ohnehin frische Attribute |
|||
auf alle Kinder, daher zahlt das Navigieren im offenen |
|||
Verzeichnis das TTL nicht. <code>0</code> schaltet den Cache |
|||
ab. |
|||
|- |
|||
| <code>#closeAllConnections</code> || (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 === |
|||
<code>SemaphoreMonitor</code> über das Untermenü „Status" des |
|||
Launchers öffnen. Der pro-Host-SFTP-Mutex erscheint als |
|||
<code>SFTP/<user@host:port></code>, der pool-weite Mutex als |
|||
<code>SFTP/pool</code>. 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 |
|||
<code>readWait</code> innerhalb von |
|||
<code>withSftpClientDo:</code> 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 <code>Logger</code> geloggt: |
|||
* <code>warning:</code> bei automatischem Reconnect nach toter |
|||
Verbindung. |
|||
* <code>warning:</code> bei Idle-Verdrängung eines Pool-Eintrags. |
|||
* <code>warning:</code> 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 |
|||
(<code>#isSymbolicLink</code> liefert immer <code>false</code>, |
|||
<code>#linkInfo</code> die normale stat-Info). SFTPv5+-Features |
|||
(atomares Überschreibungs-rename via |
|||
<code>SSH_FXF_OVERWRITE</code>) werden nicht unterstützt. |
|||
* '''Serialisierung pro Host.''' Zwei gleichzeitige Operationen |
|||
am selben Host stehen am Host-Mutex an. Siehe [[#Ausblick]]. |
|||
* '''<code>#renameTo:</code> hat ein TOCTOU-Fenster.''' |
|||
POSIX-typisches Überschreiben wird als Delete-dann-Rename |
|||
emuliert; ein anderer Prozess kann sich dazwischenschieben. |
|||
* '''<code>#isNonEmptyDirectory</code> ist eine Heuristik.''' |
|||
Liefert immer <code>#isDirectory</code> (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: |
|||
{| class="wikitable" |
|||
! Klasse !! Aufgabe |
|||
|- |
|||
| <code>SSH::SftpFilename</code> || Filename-Unterklasse, die |
|||
öffentliche API. Bildet <code>sftp://...</code>-URLs auf |
|||
entfernte Dateien ab und stellt <code>directoryContents</code>, |
|||
<code>readingFileDo:</code>, <code>renameTo:</code> usw. bereit. |
|||
|- |
|||
| <code>SSH::SftpClient</code> || SFTP-v3-Protokoll |
|||
(Request/Response-Codec, listDir, stat, open, read, write, mkdir). |
|||
Wird von SftpFilename angesteuert. |
|||
|- |
|||
| <code>SSH::Channel</code> || SSH-Kanal-Multiplexer (CHANNEL_OPEN, |
|||
DATA, EOF, CLOSE, WINDOW_ADJUST). Eine logische Sitzung pro |
|||
Channel-Instanz. |
|||
|- |
|||
| <code>SSH::Client</code> || High-Level-SSH-Client: öffnet den |
|||
Transport, führt KEX, Hostschlüssel-Prüfung und userauth durch und |
|||
verteilt anschließend Kanäle. |
|||
|- |
|||
| <code>SSH::Transport</code> || Drahtschicht. Banner- und |
|||
KEXINIT-Austausch, ChaCha20-Poly1305-Paket-Framing, sendSeq / |
|||
recvSeq, Heartbeat, SSH_MSG_DISCONNECT. |
|||
|} |
|||
=== Verbindungs-Pooling === |
|||
Alle <code>SftpFilename</code>-Instanzen, die auf dasselbe Tripel |
|||
<code>user@host:port</code> zeigen, teilen sich einen |
|||
<code>SSH::Client</code> samt einem <code>SSH::SftpClient</code>. |
|||
Der Pool ist klassenseitig und wird von einem einzigen |
|||
<code>ConnectionPoolMutex</code> bewacht: |
|||
* '''Lazy-Aufbau''' — TCP + KEX + userauth + SFTP-INIT laufen |
|||
erst beim ersten SFTP-Aufruf, nicht in <code>forUrl:</code>. |
|||
* '''Serialisierung pro Host''' — SFTP-Anfragen an einen |
|||
bestimmten Host werden durch einen <code>RecursionLock</code> |
|||
mit dem Namen <code>SFTP/<user@host:port></code> |
|||
serialisiert (sichtbar im SemaphoreMonitor). |
|||
* '''Idle-Verdrängung''' — ein Pool-Eintrag, der länger als |
|||
<code>idleEvictionSeconds</code> 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 <code>#isNonEmptyDirectory</code>''' via 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 atomares Überschreibungs- |
|||
rename, erweiterte Attribute und FTP-artige Kanonisierung. |
|||
= 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 = |
|||
[[File:Warning.svg|24px|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|SSH::Client]] — die SSH-Schicht (exec, TTY, |
|||
Agent-Weiterleitung, ProxyJump). |
|||
* [[FileBrowserV2]] — die Haupt-UI dieses Stacks. |
|||
* [[ClaudeCode plugin|Claude Code]] — nutzt denselben SSH-Stack |
|||
als HTTPS-Transport. |
|||
* [[Wikipedia:Secure Shell|RFC 4251 (SSH-2 Architecture)]] |
|||
* [[Wikipedia:Telnet|RFC 854 (Telnet Protocol)]] |
|||
[[Category:Plugins]] |
|||
[[Category:Netz]] |
|||
[[Category:SSH]] |
|||
Version vom 26. Mai 2026, 08:44 Uhr
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
(entferntes exec, 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@]host[:port]/remote/path
Fehlt user, wird der lokale Login-Name verwendet, Port
ist standardmäßig 22, Pfad standardmäßig /.
Das Menü Tools im FileBrowserV2 bietet drei SSH-Aktionen, sichtbar nur bei geladener SSH-Bibliothek:
- 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.
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 plattformeigenessh-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 pernpiperelay+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.
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 inreadWaitinnerhalb vonwithSftpClientDo: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,#linkInfodie normale stat-Info). SFTPv5+-Features (atomares Überschreibungs-rename viaSSH_FXF_OVERWRITE) werden nicht unterstützt.
- Serialisierung pro Host. Zwei gleichzeitige Operationen
am selben Host stehen am Host-Mutex an. Siehe #Ausblick.
#renameTo:hat ein TOCTOU-Fenster.
POSIX-typisches Überschreiben wird als Delete-dann-Rename emuliert; 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. |
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 einenRecursionLockmit 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 atomares Überschreibungs-
rename, erweiterte Attribute und FTP-artige Kanonisierung.
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.