Zum Hauptinhalt springen
In meinem letzten Blog habe ich über die Automatisierung von Dateiübertragungen mit FTP gesprochen. Bei der Verwendung von FTP gibt es drei Probleme. Erstens wird Ihr Kennwort im Klartext über das Netzwerk gesendet, so dass es für jeden mit einem Protokollanalysator zugänglich ist. Zweitens: Ihre Daten werden ebenfalls im Klartext übertragen. Drittens müssen Sie Ihr Kennwort irgendwo auf dem Modul speichern, entweder im Makro oder in der .netrc-Datei. Aufgrund dieser Probleme haben viele Websites die Verwendung von SFTP, dem sicheren FTP-Subsystem von SSH, anstelle von FTP vorgeschrieben oder denken darüber nach, dies zu tun. Sie können jedoch nicht einfach ftp durch sftp in Ihrem Befehlsmakro ersetzen (Abbildung 1) und erwarten, dass es funktioniert (Abbildung 2).

 

&attach_input
sftp 172.16.1.116
nd
MYPASSWORD
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return

Abbildung 1 - sftp1.cm - Ersetzen des Befehls ftp durch sftp in einem Befehlsmakro

 

sftp1
Connecting to 172.16.1.116...
dup2: Bad file number.
Error on line 3 of sftp1.
command_processor: Object not found. nd. In command macro
%phx_vos#m15_mas>SysAdmin>Noah_Davids>sftp1.cm
ready  12:39:59

 

Abbildung 2 - Ausführung von sftp1.cm
Das Problem ist eine Inkompatibilität zwischen der Art und Weise, wie native VOS-Befehle und POSIX Open Source Eingaben behandeln. SFTP ermöglicht jedoch wie FTP die Erstellung einer Datei mit einer Liste von Anfragen (Abbildung 3), die automatisch ausgeführt werden (Abbildung 4).

 


put foo
get bar

 

Abbildung 3 - sftp2.input - Datei mit Anfragen an sftp zur Ausführung

 


sftp -b sftp2_input nd@172.16.1.116
nd@172.16.1.116's password:
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:06:45

 

Abbildung 4 - Ausführung mit einer Eingabedatei von Anfragen und einer Passwortabfrage
In Abbildung 4 sehen Sie, dass sftp nach einem Passwort fragt. Es gibt keine Möglichkeit, das Passwort in die Eingabedatei zu schreiben. Die einzige Möglichkeit, die Passwortabfrage zu umgehen, ist die Verwendung der Authentifizierung mit öffentlichem Schlüssel (Abbildung 5).

 

sftp -b sftp2_input nd@172.16.1.116
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:12:28

 

Abbildung 5 - Ausführung mit einer Eingabedatei von Anfragen, unter Verwendung der Authentifizierung mit öffentlichem Schlüssel, um die Passwortabfrage zu eliminieren

 

Einen Artikel über die Einrichtung der Authentifizierung mit öffentlichem Schlüssel finden Sie hier - http://members.cox.net/ndav1/self_published/publickey_authentication_setup.html

Leider führt sftp einfach alle Anfragen in der Eingabedatei nacheinander aus, es gibt keinen Mechanismus, um zu testen, ob die Übertragung funktioniert hat oder nicht.

Da Befehlsmakros nicht verwendet werden können, gibt es irgendwelche Alternativen? Das gnu_tools-Produkt wird mit einem Programm namens expect ausgeliefert. Es kann dazu verwendet werden, Befehle zu senden, auf eine beliebige Anzahl verschiedener Antworten zu warten und etwas auf der Grundlage dessen zu tun, was es im Ausgabestrom sieht. Ich bin kein expect-Experte, aber das Skript in Abbildung 6 wird Ihnen den Einstieg erleichtern. Wenn Sie im Internet nach "expect scripts" suchen, werden Sie viele Hinweise finden, die Ihnen helfen werden, mein einfaches Beispiel anzupassen.

 

# If we get an end-of-file (eof) it means that the sftp process
# terminated. Report the last command that was sent.
#
proc goteof {cmd} {
puts "sftp connection unexpectedly closed n"
puts "last text received wasn"
puts "<<"
puts $cmd
puts ">>nnn"
exit
}
Diese Prozedur führt Übereinstimmungen mit regulären Ausdrücken auf der Suche nach Schlüsselstrings durch.
# in der Ausgabe, die von dem ausgeführten Befehl gesammelt wurde. In diesem Fall
Ich melde nur die Art des Fehlers, aber es können auch andere Dinge getan werden.
# auch. Ich prüfe auch nur auf 2 Fehler. Es gibt noch andere. Sie haben
# um sie hinzuzufügen, wenn Sie sie finden.
#
proc checkforerrors {buf cmd} {
if [regexp {.*nicht gefunden} $buf] {
puts "$cmd FAILED : not foundnnn"
Rückgabe 1
}
if [regexp {.*Erlaubnis verweigert} $buf] {
puts "$cmd FAILED : Zugriffsproblemennn"
Rückgabe 1
}
Rückgabe 0
}# Setzen Sie die Zeitüberschreitung auf -1, damit es keine Zeitüberschreitung gibt. Der Standardwert ist 10 Sekunden
# und die meisten Dateiübertragungen dauern länger als das. Ich habe beschlossen, keine
Timeout, können Sie das ändern.
Zeitüberschreitung -1 setzen

# sftp starten
sftp ablaufen lassen nd@172.16.1.116

# auf die sftp-Eingabeaufforderung warten, aber wenn wir eine Authentifizierungsaufforderung erhalten, die mit
# ja/nein ein Sicherheitsproblem melden und beenden.
expect {
"yes/no?" { puts
"nnnWir haben uns mit dem falschen Server verbunden oder der Server wurde neu geladen."
puts
"Der Serverschlüssel muss überprüft werden, bevor dieses Skript erneut ausgeführt werden kann.nnn"
exit }
sftp>
}

# Wechseln Sie in ein geeignetes Verzeichnis zum Testen
send "cd sftp_testr"
expect {
eof { goteof "cd sftp_test" }
sftp>
}

# check for errors aufrufen und alle gesammelten Zeichen an den
sftp> Eingabeaufforderung. Auch der Befehl, der an sftp gesendet wurde. Wenn die
# checkforerrors-Prozedur 1 zurückgibt, beenden Sie das Skript. Auch hier können Sie
# andere Dinge tun.
if {[checkforerrors $expect_out(buffer) "cd sftp_test"] == 1} { exit }

sendet "put foor"
erwarten {
eof { goteof "put foo" }
sftp>
}
if {[checkforerrors $expect_out(buffer) "put foo"] == 1} { exit }

sendet "get barr"
erwarten {
eof { goteof "get bar" }
sftp>
}
if {[checkforerrors $expect_out(buffer) "get bar"] == 1} { exit }

senden "quitr"
erwarte eof
puts "skript donenn"

 

Abbildung 6 - sftp3.exp - expect-Skript zur Automatisierung von SFTP

 

expect sftp3.exp
spawn sftp nd@172.16.1.116
Connecting to 172.16.1.116...
The authenticity of host 172.16.1.116(172.16.1.116)' can't be established
+.
RSA key fingerprint is 37:f4:1a:56:64:af:ab:8a:7c:0b:36:47:c5:6c:1d:1a.
Are you sure you want to continue connecting (yes/no)?
Wir haben uns mit dem falschen Server verbunden oder der Server wurde neu geladen.
Der Serverschlüssel muss validiert werden, bevor dieses Skript erneut ausgeführt werden kann.ready 10:41:10

 

Abbildung 7 - Ausführung des Skripts sftp3.exp expect mit Sicherheitswarnung

 

expect sftp3.exp
spawn sftp nd@172.16.1.116
Connecting to 172.16.1.116...
sftp> cd sftp_test
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/sftp_test/foo
sftp> get bar
Die entfernte Datei konnte nicht gefunden werden: No such file or directory
Datei "/SysAdmin/Noah_Davids/sftp_test/bar" nicht gefunden.
sftp> get bar FAILED : nicht gefundenready 10:42:11

 

Abbildung 8 - Ausführung des Skripts sftp3.exp expect ohne Warnung, aber mit einer fehlgeschlagenen Übertragung

Schließlich habe ich in meinem FTP-Blog erwähnt, dass FTP in der Lage war, Dateien zu lesen, die noch geöffnet waren, was gelegentlich dazu führte, dass unvollständige Dateien übertragen wurden. Ich schlug vor, dass das FTP-Makro, wenn es darauf wartet, dass eine Datei an einem Ort erscheint und sie dann überträgt, überprüfen sollte, ob sie nicht mehr gesperrt ist. Das gleiche Problem kann bei SFTP auftreten, und die Lösung ist dieselbe. Sie können die Prüfung der Dateisperre in ein Befehlsmakro einbauen (Abbildung 9) und dann, wenn die Datei nicht mehr gesperrt ist, expect mit dem entsprechenden Skript aufrufen.

&label AGAIN
&if (exists new_file) = 1 & (locked new_file) = 0 &then &goto EXPECT
display_line new_file not ready for transfer as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label EXPECT
expect sftp3.exp

 

Abbildung 9 - Befehlsmakro, das vor dem Aufruf von expect auf eine Dateisperre prüft

© 2020 Stratus Technologies.