我已经编写了一个用于嵌入式系统的基本TLS客户端(用C编写(。它使用TLS1.2,在90%的情况下都能很好地工作。我让它在HTTPS上运行良好,也让它在使用隐式和显式FTPS的各种FTP服务器上运行。本周,我在使用Cerberus FTP和proftpd时遇到了一个问题。当打开端口21上的控制通道时,TLS握手进行得非常顺利,但当使用被动模式并打开被动端口时,我的客户端会向TLS客户端发送hello(我可以看到服务器用TCP ACK回复(,但FTP服务器从不用server hello回复。有人知道为什么会这样吗-我猜Cerberus和ProFTPd实现TLS的方式有所不同,而我的客户端并不满足这一点。我的客户端在两个连接上的hello是相同的(除了tcp标头中的端口号(,我不会重复使用会话数据。在对vsftpd或filezilla服务器进行测试时,我没有这个问题。
找到了没有响应的原因,如果有人正在编写自己的FTP客户端并需要使用FTPS,这是一个有趣的原因。我编写的FTP客户端发出了PASV命令,然后立即打开了数据通道端口,然后在控制通道上发出STOR命令。当使用未加密的FTP时,这种行为适用于所有FTP服务器。然而,正如我所发现的,在使用TLS时必须小心。使用proftpd和cerberus FTP,FTP服务器似乎在您发出STOR命令(或等效命令(之前不会将侦听器连接到该端口,因此在您发出命令之前,它不会在该端口上协商TLS,而其他FTP服务器,如vsftpd和filezilla,则乐于在端口打开后立即协商TLS。因此,解决方案是在发送STOR命令后打开端口。