FTP 错误 500 非法端口命令 - PORT 命令发送的 IP 与请求源不同

FTP 错误 500 非法端口命令 - PORT 命令发送的 IP 与请求源不同

我遇到的问题是,当我尝试以编程方式上传文件时,从 FTP 服务器收到“500 非法 PORT 命令”响应。

该程序是一个小型的 C# 应用程序,它连接到 FTP 站点并将文件复制到默认目录。该程序已经投入生产好几年了,我相信代码本身运行良好。我还通过使用相同的应用程序连接到我自己的 FTP 站点来测试该应用程序,并且它可以正常工作。被动模式似乎不是一个选项。

尝试连接到我们合作伙伴的 FTP 站点时,程序按预期运行,直到执行 FTP put 命令。我在运行 Wireshark 时注意到,我的请求的源 IP 与 PORT 命令发送的 IP 地址不同。我已在此处上传了捕获的图像(所有敏感信息已使用我的惊人的photoshop 技能):

Wireshark 程序的 FTP 传输截图

我已经联系了我们尝试传输文件的 FTP 站点的所有者,他们已为我们的新静态 IP 地址打开了防火墙。我可以使用 FTP 客户端从两个 LAN IP 上的计算机连接到他们的站点,但这些 PORT 命令始终使用与请求源相同的 LAN IP 发送。我还尝试从程序所在的服务器使用 ftp.exe,并且成功了(但 PORT 命令使用与源相同的 IP)。

因此,我想最大的问题是我如何控制 PORT 命令使用的 IP 地址?或者,如果我无法控制它,ftp 程序如何确定 IP 地址和 PORT?

答案1

事实证明,答案确实与我使用的 FTP 库有关。我确信这不是编码问题,但在我仔细研究了库如何创建请求之后,我想我找到了答案。

下面是使用 ILSpy 的相关部分(我在最重要的行周围留了空格):

private Socket CreateDataSocketActive()
{
    Socket socket = new Socket(2, 1, 6);
    IPHostEntry iPHostEntry = Dns.Resolve(Dns.GetHostName());

    IPEndPoint iPEndPoint = new IPEndPoint(iPHostEntry.get_AddressList()[0], 0);

    socket.Bind(iPEndPoint);
    socket.Listen(5);
    int port = ((IPEndPoint)socket.get_LocalEndPoint()).get_Port();
    IPAddress address = ((IPEndPoint)socket.get_LocalEndPoint()).get_Address();
    this.SetDataPort((IPEndPoint)socket.get_LocalEndPoint());
    return socket;
}

看起来该库只是通过获取可用 IP 地址列表中的第一个地址来创建 IP 端点。对于大多数解决方案来说,这可能是可以接受的,但由于我的服务器上有多个 NIC,所以它对我来说不起作用。

我知道,通过使用 FTP.exe,只要发出的 PORT 命令是使用与请求源相同的 LAN IP 地址发出的,服务器就会接受来自我的两个 LAN IP 子网的连接。

我猜 FTP 服务器会进行某种验证,比较两个地址以确认它们是否相同。否则,理论上,一旦我登录 FTP 站点,我就可以把文件传输到完全不同的网络上的其他设备。

现在我只需要想出一个解决方法,但这应该只是找到一个新的库或自己动手的问题。如果它可以帮助其他可能遇到同样问题的人,我使用的库是 com.enterprisedt.net.ftp。

相关内容