Schritte zum Reproduzieren:

Schritte zum Reproduzieren:

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:

  1. 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
  1. 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'
  1. 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 SIGINTan 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- execDirektive 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 ControlMasterund ControlPersistSie 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, ControlPathda dieser Socket im Fall von ControlPersistanderen novon Anfang an von gehandhabt wirdnoch ein anderer sshProzess, 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 ProxyCommandin der Vordergrundprozessgruppe erzeugt wird und SIGINTmit dem sshvon 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, sshist die Masterverbindung (die wirklich wichtigste) jetzt nutzlos. Sie wird zusammen mit allen abhängigen sshProzessen beendet.

Das Original sshleistet also zusätzliche Arbeit, um sicherzustellen, sshdass die Handhabung der Master-Verbindung (und des Sockets) überlebt Ctrl+ C, aber es tut dies nicht für den angegebenen Befehl, ProxyCommandder 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 ProxyCommanderzeugt würdesshes 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 ProxyCommandverwenden, da die Verwendung automatisch erfolgt und keinen Sinn ergibt und nicht funktioniert. Sie benötigen noch eine weitere Shell:trapProxyCommandexecexec 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 SIGINTnicht verhindert, dass dieses Innere sshzu gegebener Zeit beendet wird und die Master-Verbindung aufgrund der endlichen ControlPersistEinstellung beendet werden sollte.

verwandte Informationen