为了调试主动 FTP 的问题,我们使用在 GKE 节点上的工具箱容器中运行的 tcpdump 来跟踪主动 FTP 会话流量。主动 FTP 会话在数据通道上失败。
我熟悉主动模式和被动模式 FTP 之间的区别(我们的平台必须同时支持这两种模式,并且我们尽可能使用被动模式)。
为了调试失败的主动 FTP 数据通道,我们正在跟踪成功的主动 FTP 会话,以通过我们的 FTP 服务器实现明确我们环境中的流程。这里的问题是:
在成功的主动 FTP 会话中从数据通道捕获数据包
看过这个问题虽然类似,但似乎没有解决,我们的情况可能不同。跟踪运行如下:
tcpdump -vnn -w 002.pcap -i eth0
然后在 Wireshark 中打开 pcap 文件。对 FTP 协议进行过滤可以清晰地显示会话的控制通道部分。FTP 客户端/服务器通信在客户端的临时端口和服务器端口 21 之间均符合预期。此流程包括预期的身份验证命令、设置 TYPE I、将 CWD 设置为正确的文件夹、SIZE、PORT 和文件名的 RETR。
PORT 命令看起来不错,包括服务器在会话的后续数据通道部分(下载一个文件)使用的客户端 IP 和端口。例如:
PORT 1,2,3,4,51,105
转换:(51x256+105)至端口 13161。
然而,在Wireshark中:
client:27154 > server:21 RETR <filename>
server:21 > client:27154 150 File status okay; about to open data connection.
捕获的额外数据包仅有:
server:21 > client:27154 226 Transfer complete.
client:27154 > server:21 6 QUIT
server:21 > client:27154 221 Goodbye.
我们的 FTP 服务器实现不使用端口 20 作为数据通道,而是使用随机可用端口。无论如何,我们希望看到服务器像这样建立数据通道:
server:<random port> > client:13161
另外还有一两行显示实际转账情况。
- tcpdump 过滤本身是否存在问题?
- 还有别的吗?
谢谢。
答案1
这是我的错误。检查后RFC 959以及对 TYPE I(图像/二进制)数据通道的描述,并调整 Wireshark 中的视图以按顺序(按时间)进行简单跟踪;数据通道的 TCP 数据包实际上就在那里。
对于遇到此问题的人来说,使用主动 FTP,在控制通道:
对 REQUEST SIZE 的响应如下:
FTP ... Response: 213 3981
这表明文件大小为 3981 字节,并且 PORT 命令如下:
FTP ... Request: PORT 1,2,3,4,51,105
表示服务器在与客户端建立TCP连接以启动数据通道时使用的IP和端口。
将第 5 和第 6 个八位字节转换为端口号:
51x256+105=13161
Wireshark 应该显示数据通道像这样的数据包:
No. | Time | Source | Destination | Protocol | Length | Info
----------------------------------------------------------------------------------------------------------------------------------------------------------------
89 | 6.982066 | 10.5.4.3 | 1.2.3.4 | TCP | 76 | 33841 → 13161 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=3979605739 TSecr=0 WS=128
93 | 7.390712 | 1.2.3.4 | 10.5.4.3 | TCP | 64 | 13161 → 33841 [SYN, ACK] Seq=0 Ack=1 Win=64240 Len=0 MSS=1360 SACK_PERM=1
98 | 7.390818 | 10.5.4.3 | 1.2.3.4 | TCP | 56 | 33841 → 13161 [ACK] Seq=1 Ack=1 Win=28400 Len=0
101 | 7.395054 | 10.5.4.3 | 1.2.3.4 | TCP | 2776 | 33841 → 13161 [ACK] Seq=1 Ack=1 Win=28400 Len=2720
104 | 7.395068 | 10.5.4.3 | 1.2.3.4 | TCP | 1317 | 33841 → 13161 [PSH, ACK] Seq=2721 Ack=1 Win=28400 Len=1261
107 | 7.395096 | 10.5.4.3 | 1.2.3.4 | TCP | 56 | 33841 → 13161 [FIN, ACK] Seq=3982 Ack=1 Win=28400 Len=0
上面的 TCP 数据包显示了三次 TCP 握手:SYN、SYN-ACK、ACK,然后是实际的二进制传输。您可以将数据包 101 和 104 的有效负载长度相加(在信息列中),以获得先前在控制通道中确认的文件大小。
Len=2720 + Len=1261 = 3981
然后你应该在控制通道:
FTP ... Response: 226 Transfer complete.