SSHD实践(一)简介和远程文件的操作

Sftp
placeholder image
admin 发布于:2023-11-25 20:01:40
阅读:loading

1.基本介绍

(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都是一个优秀的选择。

2.组件特征

(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都是一个值得选择和使用的工具。

3.文件传输

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)运行结果

SSHD获取远程目录列表.gif

(运行过程)

image.png

(文件列表)

4.其它说明

(1)本次实践Apache MINA SSHD共计四块知识,分别是使用Sftp访问远程服务器、Exec执行远程服务器命令、Shell执行远程服务器命令、SftpFileSystem,至于它还可以作用于的端口转发等功能不做摸索;

(2)本文实现了基于SSHD ChannelSftp的文件的上传、下载、删除、重命名、文件列表、路径是否存在等多个常用的功能,完整示例代码可见《附件下载.zip》;

(3)工具类代码的封装像极了使用原生JDBC操作数据库的实现:① 每个方法都需要处理异常;② 每次操作都获取 Connection连接,使用完后关闭连接;

(4)工具类代码的封装应该以池化的形式,可以使用Apache Commons pool组件进行连接池的方式管理,在实际应用中将会更加科学;

5.同类组件对比

所谓的同类组件是指使用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


 点赞


 发表评论

当前回复:作者

 评论列表


留言区