Apache MINA SSHD

目录

1.远程登录

1.1密码登录

1.2密钥登录

2.执行命令

[2.1 ChannelExec](#2.1 ChannelExec)

[2.2 ChannelShell](#2.2 ChannelShell)

3.文件传输

[3.1 上传文件](#3.1 上传文件)

[3.2 下载文件](#3.2 下载文件)

[3.3 SftpFileSystem](#3.3 SftpFileSystem)


Apache MINA SSHD(Secure Shell Daemon)是基于Apache MINA(Multipurpose Infrastructure for Network Applications)开发的一个开源的Java库,专门用于提供SSH(Secure Shell)服务。SSH是一种网络协议,用于在不安全的网络环境中进行安全通信和远程操作:主要用于远程登录、文件传输、以及安全的命令执行等场景。

1.远程登录

1.1密码登录

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Sshd工具类
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {
		

	}

    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密码登录
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 */
	public SshdTest(String host, int port, String username, String password) {
		connect(host,port,username);
		try  {
			session.addPasswordIdentity(password); // for password-based authentication

			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}




	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}

1.2密钥登录

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Sshd工具类
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {


	}

    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密钥登录
	 * @param host
	 * @param port
	 * @param username
	 */
	public SshdTest(String host, int port, String username) {
		connect(host,port,username);
		try  {

			String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
			String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));

			//获取密钥对
			KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
			KeyPair keyPair = rsa.generateKeyPair();
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(privateKeyContent.getBytes());
			ObjectOutputStream o = new ObjectOutputStream(stream);
			o.writeObject(keyPair);

			session.addPublicKeyIdentity(keyPair);


			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}



	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}

2.执行命令

2.1 ChannelExec

ChannelExec是Apache Mina SSHD中的一个类,它提供了一种在SSH连接上执行远程命令的方式,以及处理命令输入、输出、参数和状态的能力。它灵活性高、可扩展性强,适用于需要与远程服务器进行命令交互和执行的场景。

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Sshd工具类
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {

		SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
		sshUtil.execCommand("pwd");
	}
	
    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密码登录
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 */
	public SshdTest(String host, int port, String username, String password) {
		connect(host,port,username);
		try  {
			session.addPasswordIdentity(password); // for password-based authentication

			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}
	/**
	 * 密钥登录
	 * @param host
	 * @param port
	 * @param username
	 */
	public SshdTest(String host, int port, String username) {
		connect(host,port,username);
		try  {

			String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
			String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));

			//获取密钥对
			KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
			KeyPair keyPair = rsa.generateKeyPair();
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(privateKeyContent.getBytes());
			ObjectOutputStream o = new ObjectOutputStream(stream);
			o.writeObject(keyPair);

			session.addPublicKeyIdentity(keyPair);


			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 执行命令
	 * @param command
	 * @return
	 */
	public String execCommand(String command){
		session.resetAuthTimeout();
		System.out.println("exe cmd: "+ command);

		// 返回结果流
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		// 错误信息
		ByteArrayOutputStream err = new ByteArrayOutputStream();
		try(ChannelExec channelExec = session.createExecChannel(command)) {

			channelExec.setOut(out);
			channelExec.setErr(err);
			// 执行并等待
			channelExec.open();

			Set<ClientChannelEvent> events =
					channelExec.waitFor(
							EnumSet.of(ClientChannelEvent.CLOSED),
							TimeUnit.SECONDS.toMillis(100000));
			// 检查请求是否超时
			if (events.contains(ClientChannelEvent.TIMEOUT)) {
				throw new RuntimeException("请求连接超时");
			}
			// 一般退出状态为0表示正常
			int exitStatus = channelExec.getExitStatus();
			if (exitStatus == 1) {
				log.info("exitStatus:{}",exitStatus);
//				throw new RuntimeException("执行命令失败:"+exitStatus);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return out.toString().trim();
	}

	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}

2.2 ChannelShell

ChannelShell是Apache Mina SSHD中的一个用于使用交互式shell的类,它提供了在远程服务器上执行交互式命令和脚本,并与其进行实时交互的功能。与 ChannelExec 相比,可以更灵活地与远程服务器进行交互和执行复杂的命令。

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Sshd工具类
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {

		SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
		String[] commends ={"pwd","cd ","pwd"};
		sshUtil.execCommand(commends);
	}

    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密码登录
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 */
	public SshdTest(String host, int port, String username, String password) {
		connect(host,port,username);
		try  {
			session.addPasswordIdentity(password); // for password-based authentication

			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}
	/**
	 * 密钥登录
	 * @param host
	 * @param port
	 * @param username
	 */
	public SshdTest(String host, int port, String username) {
		connect(host,port,username);
		try  {

			String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
			String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));

			//获取密钥对
			KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
			KeyPair keyPair = rsa.generateKeyPair();
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(privateKeyContent.getBytes());
			ObjectOutputStream o = new ObjectOutputStream(stream);
			o.writeObject(keyPair);

			session.addPublicKeyIdentity(keyPair);


			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 执行命令
	 * @param commands
	 * @return
	 */
	public String execCommand(String[] commands){
		session.resetAuthTimeout();
		System.out.println("exe cmd: "+ String.join(";",commands));
		// 命令返回的结果
		StringBuffer resultBuf = new StringBuffer("");
		try (ChannelShell channel = session.createShellChannel()) {
			channel.open().verify(5 , TimeUnit.SECONDS);
			// 执行命令
			try (PrintStream out = new PrintStream(channel.getInvertedIn())) {
				for (String command:commands){
					out.println(command);
					out.flush();
				}

				out.println("exit");
				out.flush();
			}
			//channel.waitFor(Collections.singleton(ClientChannelEvent.CLOSED), 0);
			try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(channel.getInvertedOut()))) {
				String line;
				while ((line = bufferedReader.readLine()) != null) {
					System.out.println(line);
					resultBuf.append(line);
				}
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return resultBuf.toString().trim();
	}

	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}

3.文件传输

SftpClient是基于Apache MINA SSHD库的一个SFTP(SSH File Transfer Protocol)客户端实现,它提供了一套方便且易于使用的API,用于在Java应用程序中与远程SFTP服务器进行文件传输和管理。

3.1 上传文件

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;
import org.apache.sshd.sftp.client.fs.SftpPath;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.PosixFilePermissions;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Sshd工具类
 *
 * https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {

		SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
		sshUtil.uploadFile(new File("F:\\24\\tmp.txt"),"/home/weisx/");
	}

    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密码登录
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 */
	public SshdTest(String host, int port, String username, String password) {
		connect(host,port,username);
		try  {
			session.addPasswordIdentity(password); // for password-based authentication

			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}
	/**
	 * 密钥登录
	 * @param host
	 * @param port
	 * @param username
	 */
	public SshdTest(String host, int port, String username) {
		connect(host,port,username);
		try  {

			String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
			String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));

			//获取密钥对
			KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
			KeyPair keyPair = rsa.generateKeyPair();
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(privateKeyContent.getBytes());
			ObjectOutputStream o = new ObjectOutputStream(stream);
			o.writeObject(keyPair);

			session.addPublicKeyIdentity(keyPair);


			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 上传文件
	 * @param uploadFile 上传的文件
	 * @param remotePath 远程目录
	 */
	public  String uploadFile(File uploadFile,String remotePath) {
		try(SftpClient  sftpClient = SftpClientFactory.instance().createSftpClient(session);
			OutputStream outputStream = sftpClient.write(remotePath)
		) {
			Files.copy(uploadFile.toPath(), outputStream);
			return remotePath;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}

3.2 下载文件

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;
import org.apache.sshd.sftp.client.fs.SftpPath;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.PosixFilePermissions;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Sshd工具类
 *
 * https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {

		SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
		sshUtil.downloadFile("/home/weisx/tmp.txt","F:\\24\\");
	}

    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密码登录
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 */
	public SshdTest(String host, int port, String username, String password) {
		connect(host,port,username);
		try  {
			session.addPasswordIdentity(password); // for password-based authentication

			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}
	/**
	 * 密钥登录
	 * @param host
	 * @param port
	 * @param username
	 */
	public SshdTest(String host, int port, String username) {
		connect(host,port,username);
		try  {

			String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
			String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));

			//获取密钥对
			KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
			KeyPair keyPair = rsa.generateKeyPair();
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(privateKeyContent.getBytes());
			ObjectOutputStream o = new ObjectOutputStream(stream);
			o.writeObject(keyPair);

			session.addPublicKeyIdentity(keyPair);


			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 下载文件
	 * @param remoteFilePath 下载的文件
	 * @param savePath 保存的目录
	 */
	public  void downloadFile(String remoteFilePath,String savePath) {
		try(SftpClient  sftpClient = SftpClientFactory.instance().createSftpClient(session);
			InputStream inputStream = sftpClient.read(remoteFilePath)
		) {
			File destFile = new File(savePath);
			Files.copy(inputStream , destFile.toPath() , StandardCopyOption.REPLACE_EXISTING);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}

3.3 SftpFileSystem

SftpFileSystem是Apache Mina SSHD中实现的基于VFS框架的SFTP文件系统,它供了一套统一的API和一些额外的高级功能,方便用户访问和操作远程文件系统,适用于复杂的文件系统操作和要求更高级功能的场景。

java 复制代码
package com.yichenkeji.starter.ssh;

import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.client.fs.SftpFileSystem;
import org.apache.sshd.sftp.client.fs.SftpPath;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.PosixFilePermissions;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Sshd工具类
 *
 * https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
 */
@Slf4j
public class SshdTest {
	private SshClient client;
	private ClientSession session;
	public static void main(String[] args) throws Exception {

		SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
		sshUtil.fileMeta("/home/weisx/tmp.txt");
	}

    /**
     * 连接
	 * @param host
     * @param port
     * @param username
	 */
	private void connect(String host, int port, String username)  {
		client = SshClient.setUpDefaultClient();
		client.start();
		try  {
			session = client.connect(username, host, port)
					.verify(5000)
					.getSession();

		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 密码登录
	 * @param host
	 * @param port
	 * @param username
	 * @param password
	 */
	public SshdTest(String host, int port, String username, String password) {
		connect(host,port,username);
		try  {
			session.addPasswordIdentity(password); // for password-based authentication

			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}
	/**
	 * 密钥登录
	 * @param host
	 * @param port
	 * @param username
	 */
	public SshdTest(String host, int port, String username) {
		connect(host,port,username);
		try  {

			String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
			String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));

			//获取密钥对
			KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
			KeyPair keyPair = rsa.generateKeyPair();
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(privateKeyContent.getBytes());
			ObjectOutputStream o = new ObjectOutputStream(stream);
			o.writeObject(keyPair);

			session.addPublicKeyIdentity(keyPair);


			if (session.auth().verify(5000).isFailure()) {
				throw new RuntimeException("验证失败");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 获取文件信息
	 * @param filePath 文件路径
	 */
	public  void fileMeta(String filePath) {
		try(SftpFileSystem sftp = SftpClientFactory.instance().createSftpFileSystem(session)) {

			SftpPath path = sftp.getPath(filePath);
			System.out.println("文件名:" + path.getFileName());
			System.out.println("文件大小:" + Files.size(path));
			System.out.println("最后更新时间:" + Files.getLastModifiedTime(path));
			//如果是目录,则可以列出目录下全部文件
			try (Stream<Path> stream = Files.list(path)) {
				List<Path> paths = stream.collect(Collectors.toList());
				for (Path p : paths) {
					if (Files.isDirectory(p)) {
						System.out.println("文件夹:" + p.getFileName());
					} else {
						System.out.println("文件:  " + p.getFileName());
					}
				}
			}

		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 关闭连接
	 */
	public void close(){
		log.info("关闭 SSH");
		closeSession();
		if(client != null){
			try {
				client.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

	}
	private void closeSession() {
		if(session != null){
			try {
				session.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}
}
相关推荐
小钱c75 小时前
Mac下安装Apache JMeter并启动
jmeter·macos·apache
FserSuN2 天前
Apache Calcite - 查询优化之自定义优化规则
apache·calcite
黑风风2 天前
Ubuntu 22 安装 Apache Doris 3.0.3 笔记
笔记·ubuntu·apache
网络安全指导员3 天前
常见网络安全设备默认口令
服务器·网络·安全·web安全·php·apache
Mr_Xuhhh3 天前
Linux第一个小程序-进度条
linux·运维·visualstudio·小程序·编辑器·apache
风口上的吱吱鼠4 天前
20241031 Apache2修改日志里面的时间格式
服务器·apache
小刘同学++4 天前
在 Ubuntu 22.04 上部署Apache 服务, 访问一张照片
linux·ubuntu·apache
cgqyw4 天前
Apache 负载均衡详细配置步骤
运维·apache·负载均衡
Mitch3114 天前
【环境搭建】Apache Kylin 各个版本Docker搭建汇总
docker·apache·kylin
cyt涛5 天前
Apache POI—读写Office格式文件
apache·excel·poi·office·单元格·xssfworkbook·sxssfworkbook