服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同
Posted
技术标签:
【中文标题】服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同【英文标题】:The server returned an address in response to the PASV command that is different than the address to which the FTP connection was made 【发布时间】:2010-04-25 19:06:50 【问题描述】:System.Net.WebException:。 在 System.Net.FtpWebRequest.CheckError() 在 System.Net.FtpWebRequest.SyncRequestCallback(Object obj) 在 System.Net.CommandStream.Abort(异常 e) 在 System.Net.FtpWebRequest.FinishRequestStage(RequestStage 阶段) 在 System.Net.FtpWebRequest.GetRequestStream() 在 D:\PROJEKTI\BackupDB\BackupDB\Program.cs:line 119 中的 BackupDB.Program.FTPUploadFile(String serverPath, String serverFile, FileInfo LocalFile, NetworkCredential Cred)
代码:
FTPMakeDir(new Uri(serverPath + "/"), Cred);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath+serverFile);
request.UsePassive = true;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = Cred;
byte[] buffer = new byte[10240]; // Read/write 10kb
using (FileStream sourceStream = new FileStream(
LocalFile.ToString(), FileMode.Open))
using (Stream requestStream = request.GetRequestStream())
int bytesRead;
do
bytesRead = sourceStream.Read(buffer, 0, buffer.Length);
requestStream.Write(buffer, 0, bytesRead);
while (bytesRead > 0);
response = (FtpWebResponse)request.GetResponse();
response.Close();
【问题讨论】:
【参考方案1】:天哪。购买他们的 3rd 方解决方案而不是通知您更改一行代码的所有这些都是怎么回事?
尝试切换 Passive 值以查看哪个有效:
request.UsePassive = false;
这可能取决于机器(客户端和服务器)之间的防火墙。
我注意到如果我通过我们的防火墙,那么我需要将其保留为 True,否则它将返回异常:
远程服务器返回错误:(500) 语法错误,命令 无法识别。
但是,如果我在防火墙后面(比如两台机器在数据中心内直接相互连接),那么我需要将其设置为 False,否则它将返回异常:
服务器响应 PASV 命令返回的地址与 FTP 连接的地址不同 制作。
如果这可行并且您想让您的解决方案更具适应性,您可以使用默认 True 值将您的请求包装在 try-catch 块中,如果您收到 500 错误,则将 UsePassive 切换为 False 并再次尝试.
【讨论】:
这个答案并没有解决问题,它只是在没有任何洞察力的情况下解决实际的根本原因。检查 philwilks 和 senzacionale 的答案。并不是说这些答案特别好,但它们至少表明问题主要出在服务器端。 你好@MartinPrikryl 我同意,问题可能是一些深奥的服务器端配置,但我的回答确实可以作为一种方便的解决方法(甚至可能是一个黑客——我通常会避免)。我的问题是:1.)我不是网络工程师。 2.) 我们不再有网络工程师。 3.) 即使我们这样做了,也不能保证他们会改变我们所有的生产服务器——他们可能有当前配置的正当理由。 4.) 我想编写一个半通用的可重用 FTP 包装器(满足我们的所有需求),它可以轻松处理此类问题。【参考方案2】:如果有人有同样的问题,这是proftpd的解决方案
http://www.proftpd.org/docs/howto/NAT.html
【讨论】:
【参考方案3】:在被动模式下,FTP 会话如下:
client: PASV
(i would like to transfer files. Tell me which port and ip address should I use)
server: 227 Entering Passive Mode (172,16,3,4,204,173)
(ok, use port 52397 on IP address 172.16.3.4.)
client: connects to this IP address/port and starts data transfer.
看起来具有两个公共 IP 地址(例如 1.2.3.4)的 FTP 服务器返回一个私有 IP 地址作为对 PASV 命令的响应。
解决方案
切换到活动模式。
在主动模式下,FTP 服务器连接到 FTP 客户端进行数据传输。它将解决此问题,但对防火墙不友好。当传入连接被阻塞时它将不起作用(非常常见)。
忽略 IP 地址作为对 PASV 命令的响应发送
如果公共 ftp 服务器 IP 地址是公共 IP 地址,并且作为 PASV 命令响应返回的 IP 地址来自私有范围(例如 10.、192.168.)。在这种情况下,FTP 客户端应该使用公共 IP 地址。
这正是我们的Rebex FTP 在这种情况下所做的。它运行良好(可以关闭此行为)。它甚至可以为具有多个公共 IP 地址的服务器打开。
我不知道 FtpWebRequest 是否可以使用类似的解决方法。
您可以download trial查看是否解决了您的问题。
【讨论】:
我认为这就像filezilla中的“使用服务器的外部IP地址”选项一样。【参考方案4】:经过大量挖掘,我发现解决此问题的唯一方法是更改服务器上的 PASV 设置。
幸运的是,我控制了客户端和服务器机器,所以我能够告诉服务器(在我的例子中是 FileZilla)使用公共 IP 而不是私有 IP。
【讨论】:
【参考方案5】:您的 FTP 服务器配置错误。
在被动模式下,服务器报告客户端应连接到的 IP 地址和端口以进行数据传输。您的 FTP 服务器在内部网络中报告其 IP 地址,尽管它位于防火墙/NAT 后面。由于显而易见的原因,客户端无法连接到该内部地址。您必须配置 FTP 服务器以报告其外部 IP 地址。
这是如何完成的取决于服务器,而您没有告诉我们您的 FTP 服务器是什么。
IIS:在 IIS 管理器 中,打开 FTP > FTP 防火墙支持。请参阅我的installing IIS server 指南中的Servers behind external Firewall/NAT 部分。 FileZilla FTP 服务器:转到编辑 > 设置 > 被动模式设置 > IPv4 特定 > 被动模式传输的外部服务器 IP 地址。见FTP server running on Port 2000 over NAT not working on Passive Mode。 ProFTPD:使用MasqueradeAddress
directive。
vsftpd:pasv_address
directive。
这里的一些答案建议使用主动模式。
request.UsePassive = false;
但这只有在客户端和服务器之间没有防火墙/NAT 的情况下才有帮助,在这种情况下,您一开始就不会遇到问题(除非服务器真的坏了并且报告了一个完全错误的 IP 地址,不仅是内部的)。或者,如果防火墙/NAT 被配置为允许入站连接,则不常见。
另一种方法是使用不同的 FTP 库,该库可以通过忽略服务器报告的错误 IP 地址并使用主/控制连接 IP 地址来解决该问题。或者使用EPSV
命令代替隐式使用主/控制连接IP 地址的PASV
命令。
【讨论】:
以上是关于服务器响应 PASV 命令返回的地址与建立 FTP 连接的地址不同的主要内容,如果未能解决你的问题,请参考以下文章