Wie kann man das Passwort an su / sudo / ssh übergeben, ohne das TTY zu überschreiben?


148

Ich schreibe ein C-Shell-Programm, das suoder sudooder ausgeführt wird ssh. Sie alle möchten ihre Passwörter in der Konsoleneingabe (TTY) anstatt in stdin oder in der Befehlszeile.

Kennt jemand eine Lösung?

Das Einrichten ohne Passwort sudoist keine Option.

könnte eine Option sein, ist aber auf meinem abgespeckten System nicht vorhanden.



Antworten:


215

Für sudo gibt es eine -S-Option zum Akzeptieren des Passworts von der Standardeingabe. Hier ist der Manneintrag:

    -S          The -S (stdin) option causes sudo to read the password from
                the standard input instead of the terminal device.

Auf diese Weise können Sie einen Befehl wie den folgenden ausführen:

echo myPassword | sudo -S ls /tmp

Was ssh betrifft, habe ich viele Versuche unternommen, die Verwendung zu automatisieren / zu skripten, ohne Erfolg. Es scheint keine eingebaute Möglichkeit zu geben, das Kennwort ohne Aufforderung an den Befehl zu übergeben. Wie andere bereits erwähnt haben, scheint das Dienstprogramm " erwarten " darauf ausgerichtet zu sein, dieses Dilemma zu lösen. Letztendlich ist das Einrichten der richtigen Autorisierung für private Schlüssel jedoch der richtige Weg, um dies zu automatisieren.


2
Glücklicherweise verfügt Ruby über einen integrierten SSH-Client, mit dem Sie das Kennwort angeben können. Sie könnten versuchen, ruby ​​-e "erfordern 'net / ssh'; Net :: SSH.start ('example.com', 'test_user' ,: password => 'secret') do | ssh | setzt 'Login erfolgreich angemeldet'; während cmd = bekommt; setzt ssh.exec! (cmd); Ende Ende "
user1158559

13
Ich hasse es, hier ein Party-Pooper zu sein, aber wenn Sie dies tun, wird Ihr Passwort möglicherweise in einer Prozessliste angezeigt. Ich versuchte einen besseren Weg zu finden und stieß auf diesen Artikel und war überrascht, dass niemand darauf hingewiesen hatte. Tolle Lösung, aber Vorsicht vor den Risiken.
Matt

Haben Sie über ssh versucht, ein Passwort in der Verbindungszeichenfolge zu übergeben? wie nonroot:yourpassword@hostname.com? Natürlich sind die Dinge viel einfacher, wenn Sie die Schlüsselauthentifizierung und den Schlüsselmanager verwenden.
Killah

12
Vermeiden Sie, dass Kennwörter in Prozesslisten- oder Protokolldateien angezeigt werden, indem Sie sie in eine Datei einfügen und cat verwenden. 'cat pw | sudo -S <command>und später rm pw.
CAB

Eine andere Möglichkeit wäre, netcat zu verwenden und das Passwort über einen Socket zu übermitteln nc -l 12345 | sudo -S <command>. Auf der sendenden Seite; echo myPassord | nc <target> 12345. Dadurch wird nur das Problem der Kennwortbehandlung verschoben, vermutlich jedoch auf eine Hauptkonsole, auf der Sie mehr Optionen haben.
CAB

36

Ich habe ein Applescript geschrieben, das über ein Dialogfeld zur Eingabe eines Kennworts auffordert und dann einen benutzerdefinierten Bash-Befehl wie folgt erstellt:

echo <password> | sudo -S <command>

Ich bin mir nicht sicher, ob das hilft.

Es wäre schön, wenn sudo ein vorverschlüsseltes Passwort akzeptieren würde, damit ich es in meinem Skript verschlüsseln könnte und mich nicht darum kümmern müsste, Klartext-Passwörter wiederzugeben. Dies funktioniert jedoch für mich und meine Situation.


27

Für sshSie können verwenden sshpass: sshpass -p yourpassphrase ssh user@host.

Sie müssen nur zuerst sshpass herunterladen :)

$ apt-get install sshpass
$ sshpass -p 'password' ssh username@server

12

Ich habe:

ssh user@host bash -c "echo mypass | sudo -S mycommand"

Funktioniert bei mir.


Hat bei mir nicht funktioniert. ssh fordert immer noch zur Eingabe des Passworts auf.
AKS

Ausgezeichnet, endlich etwas, das ich benutzen kann! Vielen Dank. Ich verwende dies in einem Bash-Skript, das eine SSH-Sitzung startet und Sudo-Befehle an den Client übergibt. Mein Skript hat Zeilen die Auflösung zu: ssh -t Benutzername @ Hostname bash -c "Sudo Echo Fartjuice"
James T Snell

12

Für sudo können Sie dies auch tun:

sudo -S <<< "password" command

10

Die übliche Lösung für dieses Problem besteht darin, eine Hilfs-App einzurichten, die die Aufgabe ausführt, für die Superuser-Zugriff erforderlich ist: http://en.wikipedia.org/wiki/Setuid

Sudo darf nicht offline verwendet werden.

Spätere Bearbeitung: SSH kann mit der Authentifizierung mit privatem und öffentlichem Schlüssel verwendet werden. Wenn der private Schlüssel keine Passphrase hat, kann ssh ohne Aufforderung zur Eingabe eines Kennworts verwendet werden.


10

Dies kann durch Einrichten öffentlicher / privater Schlüssel auf den Zielhosts erfolgen, zu denen Sie eine Verbindung herstellen. Der erste Schritt besteht darin, einen SSH-Schlüssel für den Benutzer zu generieren, der das Skript auf dem lokalen Host ausführt, indem Folgendes ausgeführt wird:

ssh-keygen
Enter file in which to save the key (/home/myuser/.ssh/id_rsa): <Hit enter for default>
Overwrite (y/n)? y

Geben Sie dann ein leeres Passwort ein. Kopieren Sie anschließend Ihren SSH-Schlüssel auf den Zielhost, zu dem Sie eine Verbindung herstellen möchten.

ssh-copy-id <remote_user>@<other_host>
remote_user@other_host's password: <Enter remote user's password here>

Nachdem Sie die SSH-Schlüssel registriert haben, können Sie ssh remote_user@other_hostvon Ihrem lokalen Host aus eine Stummschaltung durchführen .


7

Vielleicht können Sie einen expectBefehl verwenden?:

expect -c 'spawn ssh root@your-domain.com;expect password;send "your-password\n";interact

Dieser Befehl gibt das Passwort automatisch.


Sieht gut aus, aber wie kann ich den Befehl expected auf einer Maschine ohne Root-Berechtigungen aktivieren?
Radon8472

1
@ Radon8472 Eine ausführbare Datei kann zu ~ / bin hinzugefügt werden, wenn Sie keine Berechtigungen zum Installieren haben. Wenn Ihr System Ihrem PATH nicht automatisch ~ / bin hinzufügt, können Sie dies manuell mit export PATH = "$ PATH: ~ / bin" tun oder diesen Befehl zu Ihrem Profil hinzufügen, um dies automatisch zu tun. Wenn Sie Ihren PATH nicht ändern möchten, können Sie den Befehl stattdessen unter Verwendung seines absoluten Pfads ausführen: ~ / bin / expected [Argumente]
Denken Sie

6

Wenn es keine bessere Wahl gibt (wie von anderen vorgeschlagen), kann man socat helfen:

   (sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
   socat - EXEC:'ssh -l user server',pty,setsid,ctty

          EXEC’utes an ssh session to server. Uses a pty for communication
          between socat and ssh, makes it ssh’s  controlling  tty  (ctty),
          and makes this pty the owner of a new process group (setsid), so
          ssh accepts the password from socat.

Die gesamte Komplexität von pty, setsid und ctty ist notwendig, und obwohl Sie möglicherweise nicht so lange schlafen müssen, müssen Sie schlafen. Die Option echo = 0 ist ebenso einen Blick wert wie die Übergabe des Remote-Befehls über die Befehlszeile von ssh.


1
Dies wird auch tatsächlich funktionieren su. suhat keine -S (stdin) Option.
Aus

Ist es möglich, das Schlafen zu vermeiden und stattdessen etwas Zuverlässigeres zu verwenden?
Michael Pankov

6

Schau es dir an expect Linux-Dienstprogramm an.

Sie können die Ausgabe basierend auf dem einfachen Mustervergleich auf stdin an stdio senden.


1

Richten Sie SSH für die Authentifizierung mit öffentlichem Schlüssel ohne Pasphrase auf dem Schlüssel ein. Jede Menge Anleitungen im Netz. Sie benötigen dann kein Passwort, um sich anzumelden. Sie können dann die Verbindungen für einen Schlüssel basierend auf dem Client-Hostnamen einschränken. Bietet angemessene Sicherheit und eignet sich hervorragend für automatisierte Anmeldungen.


1
ssh -t -t me@myserver.io << EOF
echo SOMEPASSWORD | sudo -S do something
sudo do something else
exit
EOF

Wenn Sie sich als Benutzer mit dem SSH-Schlüssel anmelden können, ist der sudo-Zugriff in Ordnung: ssh -t user @ host "echo mypassword | sudo -S sudocommand"
Jack

0

Ich hatte das gleiche Problem. Dialogskript zum Erstellen eines Verzeichnisses auf einem Remote-PC. Der Dialog mit SSH ist einfach. Ich benutze sshpass (zuvor installiert).

   dialog --inputbox "Enter IP" 8 78 2> /tmp/ip

   IP=$(cat /tmp/ip)


   dialog --inputbox "Please enter username" 8 78 2> /tmp/user

   US=$(cat /tmp/user)


   dialog --passwordbox "enter password for \"$US\" 8 78 2> /tmp/pass

   PASSWORD = $(cat /tmp/pass)


   sshpass -p "$PASSWORD" ssh $US@$IP mkdir -p /home/$US/TARGET-FOLDER


   rm /tmp/ip

   rm /tmp/user

   rm /tmp/pass

Grüße aus Deutschland

Titus


0

Aufbauend auf der Antwort von @ Jahid funktionierte dies für mich unter macOS 10.13:

ssh <remote_username>@<remote_server> sudo -S <<< <remote_password> cat /etc/sudoers

0

Eine bessere sshpassAlternative ist: passh https://github.com/clarkwang/passh

Melden Sie sich bei einem Remote-Server an

 $ passh -p password ssh user@host

Führen Sie einen Befehl auf dem Remote-Server aus

 $ passh -p password ssh user@host date

andere Methoden, um das Passwort zu übergeben

-p Das Passwort (Standard: `Passwort ')

-p env: Passwort von env var lesen

-p Datei: Passwort aus Datei lesen

hier habe ich erklärt, warum es besser ist als sshpass und andere lösungen.


-1
echo <password> | su -c <command> <user> 

Das funktioniert.


1
Dies ist die einzige Arbeit für mich in Fedora. Leute stimmen Antworten ab, nur weil sie in ihrer Situation nicht arbeiten?
Hangchen Yu

2
"su: muss von einem Terminal ausgeführt werden" (RPi1B, Raspbian)
notme1560

Leider nicht in neueren Versionen von su, die stattdessen das Passwort von stdio lesen .
Montag,

-1

Das Hardcodieren eines Passworts in einem Expect-Skript ist dasselbe wie ein passwortloses Sudo, was schlimmer ist, da Sudo zumindest seine Befehle protokolliert.



-1

VERWENDEN:

echo password | sudo command

Beispiel:

echo password | sudo apt-get update; whoami

Ich hoffe es hilft..


-2

Sie können ein Kennwort als Parameter für das zu erwartende Skript angeben.


-11
su -c "Command" < "Password"

Hoffe es ist hilfreich.


1
Es ist nicht. "su: muss von einem Terminal ausgeführt werden" ist die Antwort darauf.
Thelogix
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.