Pular para o conteúdo principal
No meu último blog, falei sobre a automatização de transferências de arquivos usando FTP. Existem três problemas com o uso do FTP. Primeiro, sua senha é enviada pela rede em texto simples, tornando-a disponível para qualquer pessoa com um analisador de protocolo. Segundo, seus dados também são enviados em texto simples. Terceiro, você precisa registrar sua senha em algum lugar no módulo, seja na macro ou no arquivo .netrc. Devido a esses problemas, muitos sites exigiram ou estão pensando em exigir que o SFTP, o subsistema FTP seguro do SSH, seja usado em vez do FTP. No entanto, você não pode simplesmente substituir o ftp pelo sftp em sua macro de comando (figura 1) e esperar que funcione (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 – substituindo o comando ftp por sftp em uma macro de 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 – executando sftp1.cm
O problema é uma incompatibilidade entre a forma como os comandos VOS nativos e o código aberto POSIX tratam a entrada. No entanto, o SFTP, tal como o FTP, permite criar um ficheiro com uma lista de pedidos (figura 3) que será executado automaticamente (figura 4).

 


put foo
get bar

 

Figura 3 – sftp2.input – arquivo contendo solicitações para o sftp executar

 


sftp -b sftp2_input [email protected]
[email protected]'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 – execução com um arquivo de entrada de solicitações e uma solicitação de senha
Você notará na figura 4 que o sftp está solicitando uma senha. Não há como inserir a senha no arquivo de entrada. A ÚNICA maneira de ignorar a solicitação de senha é usar a autenticação por chave pública (figura 5).

 

sftp -b sftp2_input [email protected]
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 – execução com um arquivo de entrada de solicitações, usando autenticação por chave pública para eliminar a solicitação de senha

 

Você pode encontrar um artigo sobre como configurar a autenticação por chave pública aqui – http://members.cox.net/ndav1/self_published/publickey_authentication_setup.html

Infelizmente, o sftp apenas executará todas as solicitações no arquivo de entrada, uma após a outra, não havendo nenhum mecanismo para testar se a transferência funcionou ou não.

Como as macros de comando não podem ser usadas, há alguma alternativa? O produto gnu_tools vem com um programa chamado expect. Ele pode ser usado para enviar comandos, aguardar qualquer número de respostas diferentes e realizar alguma ação com base no que vê no fluxo de saída. Não sou especialista em expect, mas o script na figura 6 ajudará você a começar. Se pesquisar “scripts expect” na web, encontrará muitas referências que ajudarão você a personalizar meu exemplo simples.

 

# 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
}
# Este procedimento faz correspondências de expressões regulares procurando por strings-chave
# na saída coletada do comando que foi executado. Neste caso
Estou apenas relatando o tipo de erro, mas outras coisas podem ser feitas.
# também. Eu também verifico apenas 2 erros. Existem outros. Você terá
# para adicioná-los à medida que os encontrar.
#
proc verificar erros {buf cmd} {
if [regexp {.*não encontrado} $buf] {
coloca "$cmd FALHA: não encontrado"
retornar 1
}
if [regexp {.*Permissão negada} $buf] {
coloca “$cmd FALHA: problemas de acesso”
retornar 1
}
retornar 0
}# defina o tempo limite como -1 para que não haja tempo limite. O padrão é 10 segundos.
# e a maioria das transferências de arquivos leva mais tempo do que isso. Decidi não definir
# tempo limite, você pode alterar isso.
definir tempo limite -1

# iniciar sftp
spawn sftp [email protected]

# aguarde o prompt sftp, mas se recebermos um prompt de autenticação, terminando em
# sim/não, relate um problema de segurança e saia.
expect {
“sim/não?” { puts
“nnnNós nos conectamos ao servidor errado ou o servidor foi recarregado.”
puts
“A chave do servidor deve ser validada antes que este script possa ser executado novamente.nnn”
exit }
sftp>
}

# mude para um diretório conveniente para teste
envie “cd sftp_testr”
espere {
eof { goteof “cd sftp_test” }
sftp>
}

# verificação de erros passando todos os caracteres coletados para o prompt
# sftp>. Também o comando que foi enviado para sftp. Se o procedimento
# checkforerrors retornar 1, saia do script. Novamente, você pode
# fazer outras coisas.
if {[checkforerrors $expect_out(buffer) “cd sftp_test”] == 1} { exit }

enviar “put foor”
esperar {
eof {goteof “put foo”}
sftp>
}
if {[checkforerrors $expect_out(buffer) “put foo”] == 1} {exit}

enviar “get barr”
esperar {
eof { goteof “get bar” }
sftp>
}
if {[checkforerrors $expect_out(buffer) “get bar”] == 1} { sair }

enviar “quitr”
esperar eof
colocar “script concluído”

 

Figura 6 – sftp3.exp – script expect para automatizar SFTP

 

expect sftp3.exp
spawn sftp [email protected]
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)?
Conectamos ao servidor errado ou o servidor foi recarregado.
A chave do servidor deve ser validada antes que este script possa ser executado novamente. pronto 10:41:10

 

Figura 7 – execução do script sftp3.exp expect com aviso de segurança

 

expect sftp3.exp
spawn sftp [email protected]
Connecting to 172.16.1.116...
sftp> cd sftp_test
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/sftp_test/foo
sftp> obter barra
Não foi possível localizar o arquivo remoto: Não existe tal arquivo ou diretório
Arquivo “/SysAdmin/Noah_Davids/sftp_test/bar” não encontrado.
sftp> obter barra FALHA: não encontrado pronto 10:42:11

 

Figura 8 – execução do script sftp3.exp expect sem aviso, mas com uma transferência falhada

Por fim, no meu blog sobre FTP, mencionei que o FTP era capaz de ler arquivos que ainda estavam abertos e que, ocasionalmente, isso resultou na transferência de arquivos incompletos. Sugeri que, se a macro FTP aguarda que um arquivo apareça em um local e, em seguida, o transfere, a macro deve verificar se ele não está mais bloqueado. O mesmo problema pode ocorrer com o SFTP e a solução é a mesma. Você pode colocar a verificação de bloqueio do arquivo em uma macro de comando (figura 9) e, quando o arquivo não estiver mais bloqueado, chamar o expect com o script apropriado.

&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 – teste da macro de comando para bloqueio de arquivo antes de chamar o expect

© 2024 Stratus Technologies.