Forum: PC-Programmierung Linux cron job ssh und Daten abholen


von Martin (Gast)


Lesenswert?

es gibt bestimmt einen Weg, aber ich brauche etwas Starthilfe zur 
Lösung:

Ich melde mich momentan von einem Ubuntu-Rechner an einem anderen Gerät 
per Terminal / ssh an, gebe mein Kennwort ein, tippe dann ein paar 
Befehle und bekomme Daten, die ich mir kopiere und auf meinem Rechner 
weiterverwende.

Nun würde ich das gerne automatisieren, also z.B. als Cron-Job ein 
Script aufrufen, das meine Sachen tippt (immer gleich, kann man in eine 
Datei tun) und die Ausgaben in eine Datei tut, also prinzipiell

ssh user@irgendwo << eingaben.txt > Ergebnis.txt

aber ich scheitere schon am Passwort. Auch wenn es in der Eingabedatei 
ist, wird es nicht "getippt" - wie macht man sowas / geht das?

Also ich habe gedacht ich fange klein an mit einer Datei "pw.txt" und 
rufe auf

ssh user@host < pw.txt

aber ich bekomme als Ergebnis:

Pseudo-terminal will not be allocated because stdin is not a terminal.

und die Eingabe ist nicht umgeleitet..

von (prx) A. K. (prx)


Lesenswert?

Mit Zertifikaten arbeiten.

von Martin (Gast)


Lesenswert?

A. K. schrieb:
> Mit Zertifikaten arbeiten.

Hab ich versucht, wird aber vom Gerät nicht unterstützt.

von R. M. (Gast)


Lesenswert?

Da hilft es eventuell, wenn Du dich (deine Maschine) gegenüber dem 
fremden System mit Host-Key authentifizierst, dann wird kein Passwort 
benötigt.
Eventuell hilft dieses Tutorial:
http://www.online-tutorials.net/security/secure-ssh-tutorial-part-1-host-key/tutorials-t-69-201.html
mfG

von Gerd E. (robberknight)


Lesenswert?

Zertifikate, von mir aus mit dem Private-Key ohne Passwort, sind die 
beste Lösung.

Wenn das aus irgendeinem Grund nicht gehen sollte, gibt es noch sshpass 
als Notlösung.

von c.m. (Gast)


Lesenswert?


von Martin (Gast)


Lesenswert?

Gerd E. schrieb:
> Wenn das aus irgendeinem Grund nicht gehen sollte, gibt es noch sshpass
> als Notlösung.

Das kannte ich noch nicht, könnte passen.

von Sheeva P. (sheevaplug)


Lesenswert?

Martin schrieb:
> es gibt bestimmt einen Weg, aber ich brauche etwas Starthilfe zur
> Lösung:
>
> Ich melde mich momentan von einem Ubuntu-Rechner an einem anderen Gerät
> per Terminal / ssh an, gebe mein Kennwort ein, tippe dann ein paar
> Befehle und bekomme Daten, die ich mir kopiere und auf meinem Rechner
> weiterverwende.
>
> Nun würde ich das gerne automatisieren,

sshpass(1) wurde bereits erwähnt, ist aber aus Sicherheitssicht unschön 
-- daß ssh(1) nur eine interaktive Paßworteingabe zuläßt, hat ja Gründe. 
Aber wenn Du zudem auch noch Befehle auf der Gegenseite ausführen 
willst, sind Python und dessen Modul "paramiko" vielleicht etwas für 
Dich.

von Julius J. (joe_joule)


Lesenswert?


von kghvkxkbhy (Gast)


Lesenswert?

Hier sogar deutsch:

http://www.schlittermann.de/doc/ssh.html

kghvkxkbhy

von Martin (Gast)


Lesenswert?

Sheeva P. schrieb:
> Aber wenn Du zudem auch noch Befehle auf der Gegenseite ausführen
> willst, sind Python und dessen Modul "paramiko" vielleicht etwas für
> Dich.

Klingt mir ein bischen nach overkill .. aber wenn ich nichts anderes 
finde, versuche ich das...

Julius J. schrieb:
> Expect ist dafür erfunden worden.
> https://debaan.blogspot.de/2007/09/simple-expect-ssh-example.html

Klingt interessant, mal sehen, ob ich das Script verstehe.

von Martin (Gast)


Lesenswert?

Momentan probiere ich gerade noch:

sshpass -f ./pw.txt ssh user@host

und bekomme "permission denied"

stimmt die syntax? und welche Permission?

von René H. (Gast)


Lesenswert?

Martin schrieb:
> stimmt die syntax? und welche Permission?

sollte stimmen. Versuchs erst mal mit

sshpass -p passwort ssh user@host

Grüsse,
René

von Martin (Gast)


Lesenswert?

Ich hab mir mal das "Except" script angeschaut und es so verstanden wie 
unten immer in der Zeile davor kommentiert (ist das richtig?)

#lies Kommandos aus dieser Datei
#!/usr/bin/expect

#keine Ahnung wofür
set timeout 1

#keine Ahnung wofür
set cmd {uname -a}

#neuen Prozess starten, ssh mit root auf die Maschine aus dem 
Aufrufparameter
spawn ssh root@$argv

#wenn eof (welcher Datei?) steig aus ohne Fehler
expect_after eof { exit 0 }


## interact with SSH
#wenn die ssh-session yes/no fragt, sende yes und RETURN
expect "yes/no" { send "yes\r" }
#dto
expect "password:" { send "rootpasswd\r" }

#keine Ahnung wozu
expect "# "
send "$cmd\r"
expect "$cmd\r"
expect "(.*)\r"
send "exit\r

von Martin (Gast)


Lesenswert?

René H. schrieb:
> sollte stimmen. Versuchs erst mal mit
>
> sshpass -p passwort ssh user@host

nee, funktioniert auch nicht - gleicher Fehler

von Ashoka (Gast)


Lesenswert?

scp

von Julius J. (joe_joule)


Lesenswert?

So, ich antworte mal in den Kommentarzeilen:
1
#!/usr/bin/expect
2
3
# Zeit in Sekunden, die expect auf einen Match wartet, bis es beendet. 
4
set timeout 1
5
6
# Kommando, welches remote ausgeführt werden soll, hier "uname -a". Hier wird eine Variable "cmd" definiert.
7
set cmd {uname -a}
8
9
#neuen Prozess starten, ssh mit root auf die Maschine aus dem 
10
Aufrufparameter
11
spawn ssh root@$argv
12
13
# wenn ssh beendet wird, wird exit 0 ausgeführt. Expect bezieht sich auf das Programm, was mit "spawn" gestartet wurde.
14
expect_after eof { exit 0 }
15
16
17
## interact with SSH
18
#wenn die ssh-session yes/no fragt, sende yes und RETURN
19
expect "yes/no" { send "yes\r" }
20
#dto
21
expect "password:" { send "rootpasswd\r" }
22
23
# Die Raute zeigt, dass hier ein rootprompt vorliegt. ("root@xyz:/#")
24
# Als normaler user wäre hier expect {$ } eventuell ausreichend.
25
expect "# "
26
# sendet das in "set cmd .." festgelegte Kommando
27
send "$cmd\r"
28
# erwartet das Echo des Kommandos
29
expect "$cmd\r"
30
# erwartet einen beliebigen String, der mit \r endet. Naja. Besser ist es an dieser Stelle erneut auf den Prompt zu matchen, da dieser erscheint sobald das Kommando vorbei ist. Außer man erwartet genau eine Zeile.
31
expect "(.*)\r"
32
# Beendet ssh
33
send "exit\r

So würde ich das machen (ohne Gewähr):
1
#!/usr/bin/expect
2
3
set prompt {user@host:~$}
4
set cmd "ps aux"
5
6
spawn "ssh user@host"
7
8
expect {
9
    -nocase "login:" {
10
        exp_send "username\n"
11
        exp_continue
12
    }
13
    -nocase "password:" {
14
        exp_send "password\n"
15
        exp_continue
16
    }
17
    $prompt {
18
        # Prompt, d.h. Kommando kann gesendet werden
19
    }
20
    timeout {
21
        # Hier beliebige Fehlerbehandlung einfuegen, falls von Interesse
22
    }
23
}
24
exp_send "$cmd\n"
25
expect {
26
    $prompt {
27
        # Prompt, d.h. das Kommando ist durchgelaufen
28
    }
29
    timeout {
30
        # Hier beliebige Fehlerbehandlung einfuegen, falls von Interesse
31
    }
32
}
33
exit 0

edit: Formatierung

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

Also diese expect-Scripte sind recht nützlich. Jetzt habe ich noch eine 
Frage zu "interact": Mal angenommen, ich mache eine shell per ssh so 
auf:

spawn /usr/bin/ssh user@host
expect -nocase "password:" { interact }


Dann kann ich an dieser Stelle das Passwort eingeben und bin dann im 
"interaktiven" Modus. Aber was muss ich tun, um diesen Modus wieder zu 
verlassen, wenn ich danach mit send / expect weiter Kommandos senden 
will, also als nächste Zeile

expect -nocase "/home/user$" { exp_send "help\n" }

?
Momentan bekomme ich dann den Fehler "expect: spawn id exp5 not open"

von Julius J. (joe_joule)


Lesenswert?

Entweder du machst dir einen eigenen Passwortdialog in deinem Tcl/Expect 
script, welches dich vor dem ssh-Kommando nach einem Passwort fragt und 
in einer Variable speichert.
Oder: was funktionieren könnte:
1
...
2
expect {
3
        password: {
4
            interact \r inter_return
5
        }
6
....
interact wird, sobald ein "\r" eingegeben wird, beendet.
Problem ist jetzt aber, dass das \r (habs gerade kurz ausprobiert) nicht 
gesendet wird. Lösung:
1
...
2
expect {
3
        password: {
4
            interact \r inter_return
5
            exp_send \r
6
        }
7
....
Das vom user eingegebene \r (also "Enter") wird von interact abgefangen. 
Damit wird die Passwordeingabe beendet. Jetzt fehlt dem Remotelogin aber 
noch ein \r, welche durch exp_send hinterhergeschickt wird.

edit: Statt "return" kann "inter_return" benutzt werden, dann bleibt die 
spawn_id erhalten.

: Bearbeitet durch User
von Martin (Gast)


Lesenswert?

danke, das mit den Variablen hat gut funktioniert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.