[Quicktip] Passwort als Parameter an ssh übergeben

Als Erweiterung zu [Quicktip] ssh Verbindung ohne Known-Hosts Eintrag hier noch die Möglichkeit, das Loginpasswort für einen Server an den SSH Befehl zu übergeben:

Aus Sicherheitsgründen ist es nicht möglich, Passwörter an den ssh-Befehl unter Linux/Unix zu übergeben. Damit soll verhindert werden, dass Passwörter in Scripten hardcoded werden und somit nicht mehr sicher sind. Möchte man passwortlos per Script mit anderen Servern arbeiten, gibt es noch immer die Möglichkeit, die RSA Keys zu hinterlegen.

Nun gibt es aber auch einige wenige spezielle Anwendungsfälle, in denen das Passwort nicht wirklich Sicherheitsrelevant ist, man nicht die Möglichkeit hat den RSA Key zu hinterlegen und man immer mit wechselnden Rechnern zu tun hat. Für diese seltenen Fälle kann man sich mit dem “expect” Befehl behelfen. “expect” macht folgendes: man ruft ein Programm per “expect” auf und versieht das ganze mit einem Kontrollscript. Dann kann man mit einer Art regulärer Ausdrücke nach Ausgaben eines Programmes suchen und auf diese reagieren. Im Fall von ssh sucht man nach der Ausgabe “password:”. Findet expect dieses, soll es einen vorgegebenen Wert einsetzen und mittels Enter bestätigen. Wenn man nun noch ein bisschen Bash-Magie betreibt kommt dieses Script heraus.

Der Aufruf läuft dann so:

./sshlogin.exp password 192.168.1.11 who

In dieser Variante wird immer der Benutzer root verwendet, man kann das Script aber einfach noch um einen weiteren Parameter erweitern, schon ist der Benutzername auch variabel.

Und was war mein Anwendungsfall? Darüber gibt es demnächst einen Artikel… 😉

Links:
bash.cyberciti.biz

Published by

bytelude

Softwareentwickler, Technik Fanatiker, Apple Fan, Kinoliebhaber, Prokrastinations-Spezialist

4 thoughts on “[Quicktip] Passwort als Parameter an ssh übergeben”

  1. Das ist ja mal genial! Nach so einer Lösung suche ich schon sehr lange! Werde ich auf jeden Fall austesten – tausend Dank!

    Wir haben das “Problem”, dass wir sehr viele Kundensysteme haben (und natürlich auch Entwickler). Für jeden Entwickler auf jedem Server einen RSA-Key zu hinterlegen ist also utopisch. Gerade, falls jemand kündigt wäre es eine unglaubliche Arbeit, die Keys von allen Servern wieder zu entfernen.

    Also stehen alle Passwörter in einer Datenbank, welche man immer raussuchen muss. Meine Idee ist nun, ein Script zu schreiben, welches es einem leichter macht, sich mit entsprechenden Servern zu verbinden (ohne jedes Mal die Daten raussuchen zu müssen).

    Schauen wir mal, ob das was wird! Danke nochmal!

  2. Hi,

    erstmal Danke für diesen Tip!

    Ich habe mich darüber sehr gefreut. Denn aus mir unbekannten Gründen ist das Ablegen meiner privaten Keys auf den Servern/Renote-Workstations untersagt. Das ist echt ärgerlich denn Zeitweise muss ich mich parallel auf bis zu 11 Workstations anmelden. Und unsere lokalen Paketquellen enthalten auch keine Tools für parallele Remote-Administration. Fremdquellen zu nuutzen ist natürlich auch strengstens untersagt.

    Also erschuf (auch dank Deines Tips) ich folgendes Expect-Script:
    -schnipp——————————————————————————————–
    #Voreinstellungen
    set timeout -1

    # Variablen setzen
    set USER [lindex $argv 0]
    set HOST [lindex $argv 1]
    set PW [lindex $argv 2]

    #spawn ssh $USER@$HOST
    spawn ssh -X -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $USER@$HOST

    expect “*?assword*”
    sleep 1
    send — “$PW\r”
    interact
    -schnapp——————————————————————————————–

    Der Aufruf geschieht über ein Bash-Script mit unterdrückter Passworteingabe:
    -schnipp——————————————————————————————–
    # Userinfo
    echo -e “Bitte geben Sie nacheinander Username, Hostname und Passwort ein.”
    echo -e “Die Passworteingabe wird aus Sicherheitsgruenden nicht am Bildschirm angezeigt!\n”
    echo -e “———————————————————————-”

    echo -n “User-ID.: ”
    read USER

    echo -n “Hostname: ”
    read HOST

    #verdeckte Passwortabfrage
    echo -n “Passwort: ”
    read -s PATZWORT

    echo -e”\n”

    #Ausfuehren des Expect-Scripts
    COMMAND=”$(which expect) /home/username/bin/myssh/ssh.expect $USER $HOST $PATZWORT”
    nohup konsole –noclose –name taest1 –new-tab -e $COMMAND
    -schnapp——————————————————————————————–
    (Mein eigentliches Script ist etwas umfangreicher und umfasst verschiedene Rechnerlisten zur gleichzeitigen Anmeldung per SSH.
    Aber prinzipiell tut es das Gleiche.)

    So, Scripte erzeugt und getestet: funktioniert – Passwort taucht nirgends in lesbarer Form auf Ich war glücklich.

    Bis ich eines Tages…
    … das Tool “w” startete um zu sehen ob sich ausser mir noch jemand auf meiner Maschine herumtreibt.
    Die Ausgabe versetzte mir einen gehörigen Schrecken:
    -schnipp——————————————————————————————–
    username@hostname:/home/username/ – (bash)
    [11:33 Uhr] 1014$ w
    11:34:51 up 2 days, 22:09, 3 users, load average: 2,04, 2,07, 2,07
    USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
    username tty1 :0 Fri13 2days 16:40 0.02s pam: gdm-password
    username pts/0 :0.0 11:34 15.00s 0.00s 0.00s /usr/bin/expect -f /home/username/bin/myssh/ssh.expect username hostname geheim
    username pts/2 :0.0 Fri15 0.00s 0.07s 0.00s w
    -schnapp——————————————————————————————–

    In der vorletzten Zeile staht doch glatt u. a. der Username, der Hostname und das Passwort im Klartext!
    Das hätte ich mir eigentlich denken können, hab ich aber wohl irdendwie vergessen.

    Kann man die Übergabeparameter irgendwie verstecken?

    1. Naja, du könntest dir ja das ssh.expect Script durch dein Shellscript dynamisch bauen lassen – und damit Login und Passwort direkt in die Datei schreiben. Dann tauchen diese Parameter nicht mehr beim Aufruf von “w” auf.

  3. Hi,

    danke das ist auch eine sehr gute Idee. Vielleicht besser als die Lösung die ich gefunden habe.

    Mein Bash-Script habe ich jetzt wie folgt geändert:
    -schnipp——————————————————————————————–
    # Credetials-Dateinamen generieren
    SFILE=”.”$(tr -dc A-Za-z0-9 $SFILE

    echo -e”\n”

    #Ausfuehren des Expect-Scripts
    # COMMAND=”$(which expect) /home/username/bin/myssh/ssh.expect $USER $HOST $PATZWORT”
    COMMAND=”$(which expect) /home/username/bin/myssh/ssh.expect $USER $HOST $SFILE”

    nohup konsole –noclose –name taest1 –new-tab -e $COMMAND &
    -schnapp——————————————————————————————–

    Damit wird nicht mehr das PW übertragen sondern eine versteckte Datei mit zufälligem Namen.

    Mein Expect-Script zeigt sich nun wie folgt:
    -schnipp——————————————————————————————–
    #Voreinstellungen
    set timeout -1

    # Variablen setzen
    set USER [lindex $argv 0]
    set HOST [lindex $argv 1]
    set PWFILE [lindex $argv 2]
    set PW [exec cat /home/username/bin/myssh/$PWFILE]
    send [exec rm /home/username/bin/myssh/$PWFILE]

    #spawn ssh $USER@$HOST
    spawn ssh -X -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $USER@$HOST

    expect “*?assword*”
    sleep 1
    send — “$PW\r”

    interact
    -schnapp——————————————————————————————–

    bei einem “w” sieht man nun noch soetwas:
    username pts/5 :0.0 16:48 1:02 0.00s 0.00s /usr/bin/expect /home/username/bin/myssh/ssh.expect user host .a3L6rfeY

    Man kann noch sehen dass eine Verbindung zu einem bestimmten Host besteht und kennt auch den Usernamen.
    Die Datei in der das PW übertragen wurde gibt es zu diesem Zeitpunkt schon nicht mehr (sollte es zumindest nicht mehr geben!).

    Dein Vorschlag hat noch den Vorteil dass beim Aufruf von “w” nur “/usr/bin/expect /home/username/bin/myssh/ssh.expect” angezeigt würde.

Leave a Reply

Your email address will not be published.