
Warum beendet OpenSSH_8.4p1 andere Sitzungen, die dieselbe Verbindung nutzen, wenn ProxyCommand verwendet wird? Gibt es eine Möglichkeit, dies zu verhindern?
Hinweis: Dieses Verhalten scheint nicht aufzutreten, wenn das ProxyCommand-Argument weggelassen wird.
Schritte zum Reproduzieren:
- Beenden Sie alle bestehenden gemeinsamen Verbindungen zum lokalen Host:
ssh -o ControlPath=/tmp/%C -O exit 127.0.0.1 2>/dev/null
ssh -o ControlPath=/tmp/%C -O exit localhost 2>/dev/null
- Führen Sie den folgenden Befehl zweimal parallel in jeweils einem anderen Terminal aus:
ssh -F none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
-o ControlMaster=auto -o ControlPath=/tmp/%C -o ControlPersist=1d \
-o ProxyCommand='ssh -W %h:%p 127.0.0.1' \
localhost 'sleep 3600'
- Unterbrechen Sie den ersten SSH-Prozess mit SIGINT, indem Sie Strg-C eingeben.
Erwartetes Verhalten
- Nur der SIGINT-Prozess wird beendet.
- Andere Prozesse laufen unverändert weiter.
Tatsächliches Verhalten
- Beide Prozesse werden beendet.
Antwort1
Nur der SIGINT-Prozess wird beendet.
"Prozess" ist eine falsche Prämisse. Ctrl+C sendet SIGINT
an den VordergrundprozessGruppedes TerminalsEine Prozessgruppe kann mehr als einen Prozess umfassen.
Dann ist folgendes relevant:
ProxyCommand
Gibt den Befehl an, der zur Verbindung mit dem Server verwendet werden soll. Die Befehlszeichenfolge reicht bis zum Ende der Zeile und wird mit der Shell-exec
Direktive des Benutzers ausgeführt, um einen verzögerten Shell-Prozess zu vermeiden.
[…]
(Quelle)
Der Befehl wird lokal in derselben Prozessgruppe wie der Hauptbefehl ausgeführt ssh
. In Ihrem Beispiel lautet der Befehl, ssh …
aber im Allgemeinen kann es alles sein. In jedem Fall ist der Befehl nicht bekannt ControlMaster
und ControlPersist
Sie haben ihn für den Hauptbefehl verwendet ssh
.
Wenn Sie Ctrl+ drücken C, erhält jeder Prozess in der Vordergrundprozessgruppe SIGINT
. Der "Haupt" ssh
-Prozess wird beendet, ohne den Socket in der zu beeinflussen, ControlPath
da dieser Socket im Fall von ControlPersist
anderen no
von Anfang an von gehandhabt wirdnoch ein anderer ssh
Prozess, der absichtlich in seiner eigenen Prozessgruppe erzeugt wird, damit er überleben kann. In diesem Kontext kann man ihn als den wirklich wichtigsten bezeichnen ssh
.
Das unerwartete Verhalten liegt daran, dass der mit angegebene Befehl ProxyCommand
in der Vordergrundprozessgruppe erzeugt wird und SIGINT
mit dem ssh
von Ihnen zu unterbrechenden Befehl gut zurechtkommt. Der Befehl reagiert auf das Signal wie gewohnt. In Ihrem Fall wird der Befehl bei beendet SIGINT
. Und da der Befehl alle Daten weiterleiten sollte, ssh
ist die Masterverbindung (die wirklich wichtigste) jetzt nutzlos. Sie wird zusammen mit allen abhängigen ssh
Prozessen beendet.
Das Original ssh
leistet also zusätzliche Arbeit, um sicherzustellen, ssh
dass die Handhabung der Master-Verbindung (und des Sockets) überlebt Ctrl+ C, aber es tut dies nicht für den angegebenen Befehl, ProxyCommand
der ebenso wichtig ist. Ich denke, man kann es als Fehler bezeichnen.
Es wäre wahrscheinlich besser, wenn der in angegebene Befehl durch das Immune in ProxyCommand
erzeugt würdessh
es istProzessgruppe. Ich habe das nicht gründlich genug analysiert. Jedenfalls ist das im Moment nicht der Fall, der Befehl wird in der Prozessgruppe gestartet, die die Vordergrundprozessgruppe ist, wenn Sie Ctrl+ drücken C, also wird es SIGINT
.
Ein Workaround besteht darin, den Befehl immun gegen zu machen SIGINT
. Darin können Sie nicht direkt ProxyCommand
verwenden, da die Verwendung automatisch erfolgt und keinen Sinn ergibt und nicht funktioniert. Sie benötigen noch eine weitere Shell:trap
ProxyCommand
exec
exec trap …
ssh -F none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
-o ControlMaster=auto -o ControlPath=/tmp/%C -o ControlPersist=1d \
-o ProxyCommand='sh -c "trap \"\" INT; exec ssh -W %h:%p 127.0.0.1"' \
localhost 'sleep 3600'
Meine Tests zeigen, dass die Immunität SIGINT
nicht verhindert, dass dieses Innere ssh
zu gegebener Zeit beendet wird und die Master-Verbindung aufgrund der endlichen ControlPersist
Einstellung beendet werden sollte.