Java - 如何判断服务器是FTP还是SFTP?

Java - How to determine if server is FTP or SFTP?

我正在 Java 中制作一个 class 从服务器下载特定文件。我有一种方法可以直接从 FTP 服务器下载,另一种方法可以从 SFTP 服务器下载。

不对主机名做任何假设(不检查它是否以 ftp:// 或 sftp:// 开头,因为有时服务器可能是本地的),是否存在有什么方法可以确定服务器是 FTP 还是 SFTP,因此要使用哪种方法?

理想情况下,我想以编程方式确定,而不仅仅是在失败时尝试替代方案。提前感谢您的帮助!

编辑: 对于任何感兴趣的人,我的非常基本但绝对不完美的解决方案是这样的:

private int determineServerProtocol(String host, String port) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try (Socket socket = new Socket(host, Integer.parseInt(port))) {
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            result = in.readLine();
            out.close();
            in.close();
        } catch (NumberFormatException | IOException e) {
            e.printStackTrace();
        }
        if (result.contains("SSH")) {
            System.out.println("Server is SFTP");
            // do things...
        } else {
            System.out.println("Server is FTP");
            // do things...
        }
    }

您可以远程登录。 Apache Commons 提供了许多互联网协议的客户端。

https://commons.apache.org/proper/commons-net/

然后分析答案。

据我所知,所有的 SSH 服务器都在内部使用 SSH 进行响应。

telnet demo.wftpserver.com 2222
Trying 199.71.215.197...
Connected to demo.wftpserver.com.
Escape character is '^]'.
SSH-2.0-WingFTPServer

不是 SSH

telnet  ftp.funet.fi 21
Trying 193.166.3.2...
Connected to ftp.funet.fi.
Escape character is '^]'.
220 FTP Welcome

协议必须与主机名和凭据一起成为会话设置的一部分。切勿尝试在安全协议和不安全协议之间进行自动检测。这是一个可怕的安全漏洞。

有了这样的 "autodetection",可能的 MITM attacker 可以使您的应用程序轻松使用未加密的 FTP 协议,即使真实服务器实际上使用的是 SFTP协议。这将使您的应用程序 将您的 SFTP 凭据直接发送给攻击者,未加密!


如果您想让您的应用程序向前兼容,以便将来可能切换到 SFTP,至少,让它永远不会退回到 FTP,一旦 SFTP 连接成功。


我也没有看到显式检测的一点。只需尝试连接并使用 FTP 进行身份验证,如果失败,请尝试 SFTP。你永远无法知道过渡将如何进行。他们可以选择保留 FTP 服务器 运行 和 SFTP,但禁用登录或任何其他组合。