Erzwingen Sie, dass SSH eine bestimmte Shell verwendet

29

Gibt es eine Möglichkeit, SSH zu zwingen, eine bestimmte Shell auf der Remote-Seite zu verwenden, unabhängig von der Standard-Shell des Benutzers?

Ich habe Lösungen ausprobiert, die den folgenden ähneln:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

Leider ist die Standard-Shell auf der Remote-Seite für das Parsen des Teils "Komplizierter Befehl mit mehreren Zeilen" verantwortlich, und ich habe Schwierigkeiten, ihn ausreichend zu maskieren, um sowohl für Bash- als auch C-Shell-Benutzer zu funktionieren.

Plinehan
quelle

Antworten:

8

Ich glaube nicht, dass dies möglich ist, zumindest bei OpenSh-basierten Systemen. Wenn Sie die Möglichkeit haben, ist es möglicherweise eine bessere Lösung, eine Shell-Skript-Datei zu speichern und sie dann mit der von Ihnen angegebenen Methode auszuführen. Dies hätte den Vorteil, dass die benötigte Escape-Zeit minimiert würde, aber eine Datei zurückbleiben würde, die entfernt werden müsste (möglicherweise als letzter Schritt des Skripts).

sysadmin1138
quelle
1
Dies ist, was ich schließlich tat, aber mit SCP. Eine tolle Idee.
Plinehan
16

Benutze einen Heredoc:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF
Ignacio Vazquez-Abrams
quelle
Solltest du nicht "-s" für bash verwenden, um Befehle aus stdin zu lesen?
Weboide
Es ist nicht immer erforderlich.
Ignacio Vazquez-Abrams
Ich würde dies ablehnen, wenn ich könnte, weil es verhindert, dass die Befehle Zugriff auf stdin haben und die Frage nach dem Aufrufen einer bestimmten Shell lautete.
Eric Woodruff
3
@EricWoodruff, ... Aufrufen einer bestimmten Shell (in diesem Fall Bash) ist genau das , was dies zeigt, wie zu tun ist.
Charles Duffy
1
Zu Ihrer Information können Sie auch tun cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash. Anstelle eines Schritts haben Sie also zwei Schritte: Schritt 1 Kopieren Sie Ihr Skript in eine Datei, Schritt 2 catdas Skript in ssh.
Trevor Boyd Smith
10

Verwenden Sie nicht kennwortbasierte, sondern schlüsselbasierte Anmeldungen. Anschließend können Sie Ihrem öffentlichen SSH-Schlüssel (im Feld "Optionen" für SSH1) einen (eine Liste von) "erzwungenen Befehlen" hinzufügen, der auf dem Server installiert ist (in der Datei ~ / .ssh / authorized_keys für SSH1) , ~ / .ssh2 / Autorisierung für SSH2).

Machen Sie Ihren erzwungenen Befehl so, dass Ihre gewünschte Shell aufgerufen wird ...

Mehr: Sie können einem bestimmten Schlüssel höchstens einen erzwungenen Befehl zuordnen. Wenn Sie mehrere erzwungene Befehle für verschiedene Zwecke benötigen, müssen Sie verschiedene Schlüssel einrichten. (Natürlich können Sie mehrere Dinge in ein Skript einfügen, das Sie über einen erzwungenen Befehl aufrufen. Beachten Sie jedoch, dass erzwungene Befehle immer für ein bestimmtes Konto / einen bestimmten Schlüssel ausgeführt werden, wenn sich der Benutzer anmeldet, unabhängig davon, ob er nach einer anderen Ausführung gefragt hat. Wenn Sie den ursprünglich angeforderten Befehl dennoch einhalten möchten, lesen Sie, wie Sie die $SSH_ORIGINAL_COMMANDVariable ausnutzen können ...)

Informieren Sie sich über "erzwungene Befehle" über Google .

Kurt Pfeifle
quelle
Gutes Zeug. Diese Grafik auf der O'Reilly-Seite ist sehr schön. In meinem speziellen Fall möchte ich dies jedoch für alle Benutzer erzwingen können, nicht nur für Benutzer, die ihre Schlüssel korrekt eingerichtet haben. Ich habe auch kein root auf den Servern, daher kann ich keine Dateien wie bearbeiten /etc/sshrc.
2.
Nun, es ist immer der Server (oder besser: derjenige, der die Kontrolle über den Server ausübt), der das Sagen hat, wenn Sie sich mit seinem Dienst verbinden. - Sie können nichts für einen oder mehrere Benutzer erzwingen, wenn Sie keine höheren Berechtigungen als diese haben.
Kurt Pfeifle
Wenn der Client beliebige Befehle ausführen kann, kann der Client auch eine beliebige Shell als Befehl ausführen.
Eric Woodruff
@ KurtPfeifle, die Verbindung zu O'Reilly ist gebrochen
Brian Vandenberg
@BrianVandenberg: Danke für den Hinweis. Ich habe diesen Link jetzt entfernt.
Kurt Pfeifle
2

Sie können die -tOption verwenden, um die Zuweisung einer Pseudotty für das zu startende Programm zu erzwingen, als ob Sie die Standard-Shell ausführen würden. Übergeben Sie dann die gewünschte Shell als einfaches altes Argument.

Mit dieser Technik können Sie nicht nur jede installierte Shell verwenden, sondern auch vim und andere Programme, die eine TTY erfordern, mit einem einzigen Befehl öffnen. Was cool ist, wenn Sie ein Shell-Skript schreiben, das Sie irgendwo anmeldet und eine Datei auf vim oder htop oder so öffnet.

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

Ich bin mir nicht sicher, ob es sich um eine Login-Shell handelt, aber es gibt Optionen, mit denen Bash wie eine Login-Shell agiert.

Fábio Santos
quelle
1

Überraschenderweise sehe ich unterschiedliche Ergebnisse mit den folgenden:

im Strich laufen:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

gegen Bash:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

Das Anzeigen des Befehls in Anführungszeichen funktioniert wie erwartet.

Eric Woodruff
quelle
1
Überhaupt nicht überraschend. Der Remote-SSH-Daemon wird effektiv ausgeführt sh -c "$*". So rennst du sh -c "/bin/bash -c echo <(cat)"; Der echoBefehl selbst ist das einzige Argument, an das übergeben wird -c, und das <(cat)ist insgesamt ein separates Argument.
Charles Duffy
0

Vor einiger Zeit war ich mit einer ähnlichen Situation konfrontiert, in der ich ksh coprocess für sqlplus verwenden musste, und ich hatte nur ein ssh, durch das gelesen und geschrieben werden muss.

Eine Möglichkeit, dies zu tun, besteht darin, alle abhängigen Befehle in eine Zeile (use;) nach / usr / bin / ksh auf dem Remote-Computer zu leiten. beispielsweise:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
aws
quelle