Erro de script FTP do Powershell: O servidor remoto retornou um erro: 227 Inserindo o modo passivo

1

Estou tendo problemas de script FTP do Powershell. Eu puxei meu cabelo por cima deste aqui.

Recentemente, configurei um "servidor de compilação automatizado" para meus projetos de software. Todos os projetos de software são criados e empacotados em um arquivo zip. Em teoria, esse arquivo zip será baixado via FTP para vários servidores diferentes. Eu estou tentando construir um script powershell que irá baixar o meu pacote e descompactá-lo nos diretórios desejados.

A parte que estou tendo problema é baixar o arquivo via FTP. Eu sou capaz de acessar o arquivo de origem manualmente fazendo login no FTP via janela de comando do DOS. Eu posso baixar o arquivo muito bem, então eu sei que isso não é um problema de firewall. Pelo menos eu não acho que seja.

Sempre que o powershell começa a baixar o arquivo .zip de origem, ele trava. Eu posso ver o arquivo aparecer no disco rígido, mas depois desaparece quando o script falha. Nunca recebe nenhum byte do servidor FTP. Eu então recebo este erro:

Powershell FTP Script Error: The remote server returned an error: 227 Entering Passive Mode (10,255,130,77,231,5) Blockquote

Aqui está o meu script:

#create destination directory (this is where the build files will be dropped)
[IO.Directory]::CreateDirectory("C:\tempftp")

"Creating staging folder..."
#create staging folder for deployment package bundle unzip
[IO.Directory]::CreateDirectory("C:\FINALDEPLOYMENTFOLDER")

#create destination and source paths for FTP copy command
$File = "C:\tempftp\MyPackageT.zip"
$ftp = "ftp://AdminiUser:[email protected]/MyPackage.zip"

"ftp url: $ftp"

$webclient = New-Object System.Net.WebClient
$uri = New-Object System.Uri($ftp)

"Downloading $File..."

#perform the actual data transfer via FTP
$webclient.DownloadFile($ftp, $File)

"Unzip build package..."
#unzip the file that was transferred via FTP
$shell_app=new-object -com shell.application 
$zip_file = $shell_app.namespace("C:\tempftp\MyPackage.zip")         #source
$destination = $shell_app.namespace("C:\FINALDEPLOYMENTFOLDER")       #final destination

#unzip to destination folder
foreach ($item in $zip_file.Items())
{
$destination.CopyHere($item, 16)
}

Eu posso executar esse script, localmente, no meu servidor de compilação e ele é executado corretamente. Eu sei que esse script funciona. Meu problema é, por que esse script vomita em meus servidores que não são de compilação? Por que o modo passivo é um problema para esse cenário e como corrigi-lo? Tentei regras de endereço FTP IPv4, alterações de suporte do Firewall FTP, etc. Mas não tive sucesso.

Vale a pena observar uma mensagem de aviso na seção Suporte do firewall de FTP do IIS7. Afirma:

To accept passive connections when you are using FTP over SSL (FTPS) or when your firewall does not filter packets, configure the external IPv4 address of your firewall.

^ Não tenho certeza do que isso realmente significa, mas vou tentar. Alguma idéia do porque o Modo Passivo é tão doloroso no meu pescoço? Eu não deveria estar usando o WebClient? Eu realmente quero evitar ter que baixar outro programa / patch para fazer este trabalho. Eu prefiro este trabalho em Powershell nativo ... então não, eu não posso usar bibliotecas de cliente FTP!

**** EDIT: Consegui corrigir esse problema abrindo "All Ports" no meu firewall, mas isso parece um pouco assustador. Alguma sugestão sobre o rastreamento de quais portas são necessárias para que esse erro do Modo Passivo desapareça? Eu já tinha uma regra que permitia algumas portas específicas que eu achava que o FTP estava usando ... mas como posso ver quais portas eu preciso ativar? **

    
por D3vtr0n 29.03.2011 / 17:52

1 resposta

2

Quando você se conecta ao site FTP a partir de um prompt de comando, está usando o FTP ativo (apenas um disponível), o que é muito mais previsível por parte do firewall. Quando você se conecta usando o System.Net.WebClient , você está se conectando usando o PASV, que recebe uma porta aleatória de um intervalo disponível predefinido. Essas solicitações estão sendo interrompidas no seu firewall. Você também pode tentar abrir o intervalo de portas no firewall se tiver que ficar com o PASV. Caso contrário, você precisa descobrir como especificar o uso de uma conexão FTP ativa. Isso não pode ser feito usando System.Net.WebClient .

Dê uma olhada no System.Net.FtpWebRequest , ele pode fazer o que quiser. Eu vejo que há uma propriedade UsePassive .

    
por 29.03.2011 / 18:16