[英]Java - How to determine if server is FTP or 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...
}
}
你可以做一个telnet。 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
该协议必须与主机名和凭据一起成为会话设置的一部分。 切勿尝试在安全和不安全协议之间进行自动检测。 这是一个可怕的安全漏洞。
通过这种“自动检测”,可能的MITM 攻击者可以轻松地使您的应用程序使用未加密的 FTP 协议,即使真实服务器实际上使用的是 SFTP 协议。 这将使您的应用程序将您的 SFTP 凭据直接发送给攻击者,未加密!
如果您想让您的应用程序与将来可能切换到 SFTP 兼容,至少,一旦 SFTP 连接成功,请使其永不回退到 FTP 。
我也没有看到明确检测的要点。 只需尝试连接并使用 FTP 进行身份验证,如果失败,请尝试 SFTP。 您永远无法知道过渡将如何进行。 他们可以选择让 FTP 服务器与 SFTP 一起运行,但禁用登录或任何其他组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.