Java - 如何确定服务器是FTP还是SFTP?

时间:2018-02-07 08:50:29

标签: java ftp sftp

我正在用Java编写一个从服务器下载特定文件的类。我有一个方法可以直接从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...
        }
    }

3 个答案:

答案 0 :(得分:0)

你可以做一个telnet。 Apache Commons提供了许多互联网协议的客户端。

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

然后分析答案。

据我所知,所有SSH服务器都在里面用SSH回答。

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

不是SSH

public override void Configure(Container container)
{
    //Handle Exceptions occurring in Services:

    this.ServiceExceptionHandlers.Add((httpReq, request, exception) => {
        //log your exceptions here
        ...
        return null; //continue with default Error Handling

        //or return your own custom response
        //return DtoUtils.CreateErrorResponse(request, exception);
    });

    //Handle Unhandled Exceptions occurring outside of Services
    //E.g. Exceptions during Request binding or in filters:
    this.UncaughtExceptionHandlers.Add((req, res, operationName, ex) => {
         res.Write($"Error: {ex.GetType().Name}: {ex.Message}");
         res.EndRequest(skipHeaders: true);
    });
}

答案 1 :(得分:0)

协议必须是会话设置的一部分以及主机名和凭据。永远不要尝试在安全协议和不安全协议之间自动检测。这是一个可怕的安全漏洞。

通过这种“自动检测”,可能的MITM attacker可以使您的应用程序轻松使用未加密的FTP协议,即使真实服务器实际上使用的是SFTP协议。这将使您的应用程序直接向攻击者发送您的SFTP凭据,未加密!

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

此外,我没有看到明确的检测点。只需尝试连接并通过FTP进行身份验证,如果失败,请尝试SFTP。你永远不会知道过渡将如何发展。他们可以选择让FTP服务器与SFTP一起运行,但禁用登录或任何其他组合。

答案 2 :(得分:-1)

了解基础知识:

关键区别: FTP和SFTP是两种不同的文件传输协议,两者之间的主要区别在于与文件传输相关的安全性。 FTP是第一个文件协议,安全性较低,而SFTP代表安全文件传输协议,顾名思义比FTP更安全。   FTP

互联网等TCP / IP网络使用FTP或文件传输协议将文件从一台计算机传输到另一台计算机。 FTP适用于基于服务器和客户端的体系结构,这意味着客户端可以在任何给定时间访问服务器上的任何信息。某些服务器受密码保护,因此只有在输入ID和密码后才能访问该信息。

关闭mp3音乐或从互联网上免费下载软件是FTP的两个常见示例,其中客户端不需要任何ID或密码来访问和下载信息。另一方面,访问您的电子邮件是SFTP的一个示例,您需要ID和密码才能访问服务器上的信息。

FTP使用两个单独的通道进行数据和控制,这两个通道都是未加密的,这意味着可以拦截和访问来自任一通道的信息。使用未加密的通道是一个巨大的安全循环漏洞,并导致设计更安全的通信模式,如FTPS和SFTP。

SFTP 是更安全的通信方式,基于SSH(安全shell)。 SSH是一种安全的方式,可以访问远程服务器上的所有shell帐户。使用SFTP传送的信息首先被分成小包,与FTP不同,SFTP仅使用一个通道进行数据和控制。在两台计算机之间共享信息之前,SFTP会验证客户端的身份,一旦建立了安全连接,它就会发送加密信息(加密密码是预定义的)。

SFTP