Apache MINA SSHD

      

目录

1.远程登录

1.1密码登录

1.2密钥登录

2.执行命令

2.1 ChannelExec

2.2 ChannelShell

3.文件传输

 3.1 上传文件

3.2 下载文件

3.3 SftpFileSystem


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

1.远程登录

1.1密码登录

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密钥登录

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连接上执行远程命令的方式,以及处理命令输入、输出、参数和状态的能力。它灵活性高、可扩展性强,适用于需要与远程服务器进行命令交互和执行的场景。

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 相比,可以更灵活地与远程服务器进行交互和执行复杂的命令。

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 上传文件

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 下载文件

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和一些额外的高级功能,方便用户访问和操作远程文件系统,适用于复杂的文件系统操作和要求更高级功能的场景。

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());
			}
		}
	}
}

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
org.apache.sshd.client.SshClient是一个Java库,用于创建SSH客户端连接到远程服务器。它是Apache MINA SSHD项目的一部分,MINA SSHD是一个基于Apache MINA网络应用框架开发的SSH服务器和客户端的实现。 使用SshClient,你可以通过SSH协议与远程服务器进行安全的数据传输和命令执行。它提供了一些方便的方法来建立和管理SSH连接,包括身份验证、端口转发、SCP文件传输等。 你可以使用SshClient的API来创建一个SSH连接,并执行远程命令或传输文件。首先,你需要创建一个SshClient实例,然后使用该实例来建立连接并执行操作。以下是一个简单的示例代码: ```java import org.apache.sshd.client.SshClient; import org.apache.sshd.client.session.ClientSession; public class SSHClientExample { public static void main(String[] args) { try (SshClient client = SshClient.setUpDefaultClient()) { client.start(); // 建立SSH连接 try (ClientSession session = client.connect("hostname", 22).await().getSession()) { session.authPassword("username", "password"); // 执行远程命令 String command = "ls -l"; ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL); channel.setIn(new NoCloseInputStream(new ByteArrayInputStream(command.getBytes()))); channel.setOut(new NoCloseOutputStream(System.out)); channel.open().verify(5, TimeUnit.SECONDS); channel.waitFor(ClientChannel.CLOSED, 0); channel.close(false); // 传输文件 String localFile = "localfile.txt"; String remoteFile = "remotefile.txt"; try (SftpClient sftpClient = session.createSftpClient()) { sftpClient.put(localFile, remoteFile); } } } catch (Exception e) { e.printStackTrace(); } } } ``` 请注意,这只是一个简单的示例,你需要根据你的实际需求进行相应的配置和处理。你可以在Apache MINA SSHD的官方文档中找到更多关于SshClient的详细信息和用法示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_37559973

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值