Passa al contenuto principale
Nel mio ultimo blog ho parlato dell'automatizzazione dei trasferimenti di file tramite FTP. Ci sono tre problemi con l'uso dell'FTP. In primo luogo, la password viene inviata attraverso la rete in chiaro, rendendola disponibile a chiunque abbia un analizzatore di protocollo. In secondo luogo, anche i vostri dati vengono inviati in chiaro. Terzo, dovete registrare la vostra password da qualche parte nel modulo, nella macro o nel file .netrc. A causa di questi problemi molti siti hanno imposto o stanno pensando di imporre l'uso di SFTP, il sottosistema FTP sicuro di SSH, al posto di FTP. Tuttavia, non si può semplicemente sostituire ftp con sftp nella macro di comando (figura 1) e aspettarsi che funzioni (figura 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

Figura 1 - sftp1.cm - sostituzione del comando ftp con sftp in una macro di comando

 

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

 

Figura 2 - corsa sftp1.cm
Il problema è un'incompatibilità tra il modo in cui i comandi VOS nativi e POSIX open source trattano gli input. Tuttavia, SFTP, come FTP, permette di creare un file con una lista di richieste (figura 3) che verrà eseguito automaticamente (figura 4).

 


put foo
get bar

 

Figura 3 - sftp2.input - file contenente le richieste di esecuzione di sftp

 


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

 

Figura 4 - esecuzione con un file di input delle richieste e un prompt di password
Noterete nella figura 4 che sftp richiede una password. Non c'è modo di inserire la password nel file di input. L'unico modo per bypassare il prompt della password è quello di usare l'autenticazione a chiave pubblica (figura 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

 

Figura 5 - esecuzione con un file di input delle richieste, utilizzando l'autenticazione a chiave pubblica per eliminare il prompt della password

 

Potete trovare un articolo su come impostare l'autenticazione a chiave pubblica qui - http://members.cox.net/ndav1/self_published/publickey_authentication_setup.html

Sfortunatamente, sftp si limiterà ad eseguire tutte le richieste nel file di input una dopo l'altra, non c'è un meccanismo per testare se il trasferimento ha funzionato o meno.

Poiché le macro di comando non possono essere utilizzate, ci sono alternative? Il prodotto gnu_tools viene fornito con un programma chiamato expect. Può essere usato per inviare comandi, attendere un numero qualsiasi di risposte diverse e fare qualcosa in base a ciò che vede nel flusso di uscita. Non sono un esperto di expect, ma lo script in figura 6 vi aiuterà ad iniziare. Se cercate sul web gli "script di attesa" troverete molti riferimenti che vi aiuteranno a personalizzare il mio semplice esempio.

 

# 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
}
# Questa procedura fa corrispondere l'espressione regolare alla ricerca di stringhe di tasti
# nell'output raccolto dal comando che è stato eseguito. In questo caso
# Sto solo segnalando il tipo di errore, ma altre cose si possono fare
# Anche... # Inoltre, controllo solo 2 errori. Ce ne sono altri. Avrete
# per aggiungerli come li trovi.
#
proc checkforerrors {buf cmd} {
se [regexp {.*non trovato} $buf] {
mette "$cmd FALLITO: non trovato".
ritorno 1
}
se [regexp {.*Permissione negata} $buf] {
mette "$cmd FAILED : problemi di accesso".
ritorno 1
}
ritorno 0
}# impostare il timeout a -1 in modo che non ci sia timeout. Il valore predefinito è 10 secondi
# e la maggior parte dei trasferimenti di file richiede più tempo. Ho deciso di impostare no
# Timeout, puoi cambiarlo. #
impostare il timeout -1

# inizia sftp
spawn sftp nd@172.16.1.116

# attendere il prompt di sftp ma se otteniamo un prompt di autenticazione, che termina con
# sì/no segnaliamo un problema di sicurezza e usciamo.
aspettatevi {
"yes/no?" { puts
"nnnSiamo collegati al server sbagliato o il server è stato ricaricato".
puts
"La chiave del server deve essere convalidata prima che questo script possa essere eseguito di nuovo.nnn"
exit }
sftp>
}

# cambiare in una directory comoda per i test
invia "cd sftp_testr"
expect {
eof { goteof "cd sftp_test" }
sftp>
}

# chiama il controllo degli errori passandogli tutti i caratteri raccolti fino al
# prompt di sftp>. Anche il comando che è stato inviato a sftp. Se la procedura
# procedura checkforerrors restituisce 1 si esce dallo script. Di nuovo, potete
# fare altre cose.
if {[checkforerrors $expect_out(buffer) "cd sftp_test"] == 1} { exit }

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

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

invia "quitr".
aspettatevi eof
mette "script donenn"

 

Figura 6 - sftp3.exp - aspettatevi che lo script automatizzi 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)?
Ci siamo collegati al server sbagliato o il server è stato ricaricato.
La chiave del server deve essere convalidata prima che questo script possa essere eseguito di nuovo.ready 10:41:10

 

Figura 7 - esecuzione dello script sftp3.exp expect con avviso di sicurezza

 

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
Non sono riuscito a stabilire un file remoto: Nessun file o directory di questo tipo
File "/SysAdmin/Noah_Davids/sftp_test/bar" non trovato.
sftp> get bar FAILED : non trovato già 10:42:11

 

Figura 8 - esecuzione dello script sftp3.exp expect senza preavviso ma con un trasferimento fallito

Infine, nel mio blog FTP ho accennato al fatto che l'FTP era in grado di leggere i file ancora aperti e questo a volte ha portato al trasferimento di file incompleti, ho suggerito che se la macro FTP aspetta che un file appaia in un luogo e poi lo trasferisce, la macro dovrebbe controllare per essere sicura che non sia più bloccata. Lo stesso problema può verificarsi con SFTP e la soluzione è la stessa. È possibile inserire il controllo di blocco del file in una macro di comando (figura 9) e poi, quando il file non è più bloccato, la chiamata aspettarsi con lo script appropriato.

&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

 

Figura 9 - comando macro test per il blocco dei file prima della chiamata aspettatevi

© 2020 Stratus Tecnologie.