SSHD实践(一)简介和远程文件的操作
Sftpadmin 发布于:2023-11-25 20:01:40
阅读:loading
(1)Apache MINA SSHD(Secure Shell Daemon)是一个开源的Java库,专门用于提供SSH(Secure Shell)服务。它是基于Apache MINA(Multipurpose Infrastructure for Network Applications)开发的,这也使得它具备了高度可定制和可扩展的特性。官网地址为:“https://mina.apache.org/sshd-project/”、“https://github.com/apache/mina-sshd”。
(2)SSH是一种网络协议,用于在不安全的网络环境中进行安全通信和远程操作。它主要用于远程登录、文件传输、以及安全的命令执行等场景。
(3)Apache MINA SSHD提供了一系列的SSH协议实现,包括SSH1和SSH2。它的设计目标是提供一个可靠、安全、高性能的SSH服务器,可以用于构建各种基于SSH的应用程序。
(4)在安全性方面,Apache MINA SSHD支持使用TLS/SSL协议进行加密传输,保护传输的数据安全。它还提供了丰富的身份验证机制,包括密码、公钥、证书和键盘交互等多种方式,以确保用户的身份安全。
(5)Apache MINA SSHD的可定制性非常强,它提供了多种配置选项和扩展点,开发人员可以根据自己的需求进行定制和扩展。这使得它非常灵活,适用于各种复杂的应用场景。
(6)在性能方面,Apache MINA SSHD采用了异步I/O和多线程处理的机制,确保了高性能的网络通信能力。这使得它在高并发的场景下表现出色,能够处理大量的连接和数据传输。
另外,由于Apache MINA SSHD是基于Java开发的,它可以运行在几乎所有的操作系统和硬件平台上,具备了很好的跨平台兼容性。
(7)总的来说,Apache MINA SSHD是一个功能强大、可定制、可靠和高性能的SSH服务器实现。它已经被广泛应用于服务器管理、远程调试、分布式计算等领域。无论是开发基于SSH的应用程序,还是构建安全的网络通信环境,Apache MINA SSHD都是一个优秀的选择。
(1)安全性:Apache MINA SSHD提供了可靠的安全传输机制,通过TLS/SSL协议进行加密,保护数据的机密性。它支持多种身份验证方式,如密码、公钥、证书等,确保只有合法用户能够访问系统。通过使用Apache MINA SSHD,您可以建立一个安全的通信渠道,保护敏感数据和操作。
(2)可定制性:Apache MINA SSHD提供了丰富的配置选项和扩展点,允许开发人员根据自己的需求进行定制和扩展。您可以根据具体应用场景,调整和配置服务器的行为和参数,满足特定的业务需求。这种灵活性和可定制性是Apache MINA SSHD的重要特点,使得它适用于各种复杂的应用场景。
(3)高性能:Apache MINA SSHD采用了异步I/O和多线程处理的机制,实现了高性能的网络通信。它能够处理大量的并发连接和数据传输,支持高并发场景下的应用需求。如果您需要解决高并发连接和数据传输的问题,Apache MINA SSHD是一个值得考虑的选择。
(4)跨平台兼容性:由于Apache MINA SSHD是基于Java开发的,它可以运行在不同的操作系统和硬件平台上。这意味着无论您使用的是Windows、Linux还是Mac系统,无论您部署的是x86、ARM还是其他架构的服务器,Apache MINA SSHD都能够很好地适应和兼容。这种跨平台的优势使得Apache MINA SSHD成为一个通用的解决方案。
综上所述,使用Apache MINA SSHD可以提供安全的传输通道,并提供灵活的定制性和高性能的网络通信能力。无论您是开发基于SSH的应用程序,还是需要构建安全的远程访问环境,Apache MINA SSHD都是一个值得选择和使用的工具。
SftpClient是基于Apache MINA SSHD库的一个SFTP(SSH File Transfer Protocol)客户端实现,它提供了一套方便且易于使用的API,用于在Java应用程序中与远程SFTP服务器进行文件传输和管理,参考如下示例:
(1)文件上传
@Test
public void uploadFileTest() throws Exception {
final SftpUtils sftp = SftpUtils.newInstance(new SftpParam());
try {
String file = getClass().getResource("SftpTest.class").getFile();
sftp.uploadFile(new File(file), "/app/arthas/arthas-class/SftpTest.class");
} finally {
sftp.disconnect();
}
}
(2)文件下载
@Test
public void downloadFileTest() throws Exception {
final SftpUtils sftp = SftpUtils.newInstance(new SftpParam());
try {
File destFile = new File(FileUtils.getTempDirectory() , "SftpTest.class");
sftp.downloadFile("/app/arthas/arthas-class/SftpTest.class" , destFile);
} finally {
sftp.disconnect();
}
}
(3)文件夹列表
@Test
public void listFileTest() throws Exception {
SftpUtils sftp = SftpUtils.newInstance(new SftpParam());
try {
List<SftpUtils.FileEntry> files = sftp.listFiles("/app/arthas/arthas-class");
for (SftpUtils.FileEntry file : files) {
System.out.println((file.isDir() ? "文件夹 " : "文件 ") + file.getLongname());
}
} finally {
sftp.disconnect();
}
}
(4)SftpUtils工具类
package cn.chendd.sshd.utils;
import ...;
/**
* 操作 Sftp 工具类
*
* @author chendd
* @date 2023/11/18 18:06
*/
public final class SftpUtils {
/**
* 路径分隔符
*/
private static final String SEPARATOR = "/";
private SshClient sshClient;
private ClientSession session;
private SftpClient sftpClient;
public static SftpUtils newInstance(SftpParam param) {
final SftpUtils sftp = new SftpUtils();
try {
sftp.connect(param);
} catch (IOException e) {
if (sftp.sshClient != null) {
try {
sftp.sshClient.close();
} catch (IOException ignore) {}
}
if (sftp.session != null) {
try {
sftp.session.close();
} catch (IOException ignore) {}
}
throw new RuntimeException(e);
}
return sftp;
}
public void connect(SftpParam param) throws IOException {
if (sftpClient != null) {
sftpClient.close();
}
if (session != null && session.isAuthenticated()) {
session.close();
}
if (sshClient == null || !sshClient.isOpen()) {
sshClient = SshClient.setUpDefaultClient();
sshClient.start();
}
session = sshClient.connect(param.getUsername(), param.getHost(), param.getPort()).verify().getSession();
session.addPasswordIdentity(param.getPassword());
session.auth().verify();
sftpClient = SftpClientFactory.instance().createSftpClient(session);
}
/**
* 上传文件
* @param srcFile 源文件
* @param dest 目标文件
* @throws IOException 异常处理
*/
public void uploadFile(File srcFile , String dest) throws IOException {
try (OutputStream outputStream = this.sftpClient.write(dest)) {
Files.copy(srcFile.toPath(), outputStream);
}
}
/**
* 下载文件
* @param src 源文件
* @param destFile 目标文件
* @throws IOException 异常处理
*/
public void downloadFile(String src , File destFile) throws IOException {
try (InputStream inputStream = this.sftpClient.read(src)) {
Files.copy(inputStream , destFile.toPath() , StandardCopyOption.REPLACE_EXISTING);
}
}
}
(5)运行结果
(运行过程)
(文件列表)
(1)本次实践Apache MINA SSHD共计四块知识,分别是使用Sftp访问远程服务器、Exec执行远程服务器命令、Shell执行远程服务器命令、SftpFileSystem,至于它还可以作用于的端口转发等功能不做摸索;
(2)本文实现了基于SSHD ChannelSftp的文件的上传、下载、删除、重命名、文件列表、路径是否存在等多个常用的功能,完整示例代码可见《附件下载.zip》;
(3)工具类代码的封装像极了使用原生JDBC操作数据库的实现:① 每个方法都需要处理异常;② 每次操作都获取 Connection连接,使用完后关闭连接;
(4)工具类代码的封装应该以池化的形式,可以使用Apache Commons pool组件进行连接池的方式管理,在实际应用中将会更加科学;
所谓的同类组件是指使用Java来操作远程Linux服务器,包含对远程服务器对文件的操作、Shell命令的执行等,本次代码是对相关的组件JSch和Apache Mina SSHD项目的案例实践,以下是个人以为的区别:
(1)JSch组件最后的更新是2018年的,已经不再更新了,而Apache Mina SSHD最新版本的更新仍然是2023年(今年),更新维护仍在继续;
(2)JSch组件的核心API代码均抛出组件内的自定义异常(JSchException),而Apache Mina SSHD抛出的是Java中常见的IOException;
(3)JSch组件的核心API代码偏重于自身内部的定义,而Apache Mina SSHD侧重于对Java nio文件操作的API,更加现代化一些;
(4)JSch组件主要提供了Sftp Client客户端的操作,而Apache Mina SSHD不仅提供了SSH Client,还有提供SSH Server端,功能更加丰富;
(5)JSch组件不依赖于其它组件,而Apache Mina SSHD细分了挺多的功能module,同时也集成了日志框架Slf4j;
(6)二者的API的封装和使用非常相似;
所以,我个人更加推荐有同类的需求时使用Apache Mina SSHD。
点赞