当前位置:   article > 正文

Apache MINA SSHD

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

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClientFactory;
  9. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  10. import java.io.*;
  11. import java.nio.file.Files;
  12. import java.nio.file.Path;
  13. import java.nio.file.Paths;
  14. import java.security.KeyPair;
  15. import java.security.KeyPairGenerator;
  16. import java.util.EnumSet;
  17. import java.util.Set;
  18. import java.util.concurrent.TimeUnit;
  19. /**
  20. * Sshd工具类
  21. */
  22. @Slf4j
  23. public class SshdTest {
  24. private SshClient client;
  25. private ClientSession session;
  26. public static void main(String[] args) throws Exception {
  27. }
  28. /**
  29. * 连接
  30. * @param host
  31. * @param port
  32. * @param username
  33. */
  34. private void connect(String host, int port, String username) {
  35. client = SshClient.setUpDefaultClient();
  36. client.start();
  37. try {
  38. session = client.connect(username, host, port)
  39. .verify(5000)
  40. .getSession();
  41. } catch (IOException e) {
  42. throw new RuntimeException(e);
  43. }
  44. }
  45. /**
  46. * 密码登录
  47. * @param host
  48. * @param port
  49. * @param username
  50. * @param password
  51. */
  52. public SshdTest(String host, int port, String username, String password) {
  53. connect(host,port,username);
  54. try {
  55. session.addPasswordIdentity(password); // for password-based authentication
  56. if (session.auth().verify(5000).isFailure()) {
  57. throw new RuntimeException("验证失败");
  58. }
  59. } catch (IOException e) {
  60. throw new RuntimeException(e);
  61. }
  62. }
  63. /**
  64. * 关闭连接
  65. */
  66. public void close(){
  67. log.info("关闭 SSH");
  68. closeSession();
  69. if(client != null){
  70. try {
  71. client.close();
  72. } catch (IOException e) {
  73. log.error(e.getMessage());
  74. }
  75. }
  76. }
  77. private void closeSession() {
  78. if(session != null){
  79. try {
  80. session.close();
  81. } catch (IOException e) {
  82. log.error(e.getMessage());
  83. }
  84. }
  85. }
  86. }

1.2密钥登录

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClientFactory;
  9. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  10. import java.io.*;
  11. import java.nio.file.Files;
  12. import java.nio.file.Path;
  13. import java.nio.file.Paths;
  14. import java.security.KeyPair;
  15. import java.security.KeyPairGenerator;
  16. import java.util.EnumSet;
  17. import java.util.Set;
  18. import java.util.concurrent.TimeUnit;
  19. /**
  20. * Sshd工具类
  21. */
  22. @Slf4j
  23. public class SshdTest {
  24. private SshClient client;
  25. private ClientSession session;
  26. public static void main(String[] args) throws Exception {
  27. }
  28. /**
  29. * 连接
  30. * @param host
  31. * @param port
  32. * @param username
  33. */
  34. private void connect(String host, int port, String username) {
  35. client = SshClient.setUpDefaultClient();
  36. client.start();
  37. try {
  38. session = client.connect(username, host, port)
  39. .verify(5000)
  40. .getSession();
  41. } catch (IOException e) {
  42. throw new RuntimeException(e);
  43. }
  44. }
  45. /**
  46. * 密钥登录
  47. * @param host
  48. * @param port
  49. * @param username
  50. */
  51. public SshdTest(String host, int port, String username) {
  52. connect(host,port,username);
  53. try {
  54. String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
  55. String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));
  56. //获取密钥对
  57. KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  58. KeyPair keyPair = rsa.generateKeyPair();
  59. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  60. stream.write(privateKeyContent.getBytes());
  61. ObjectOutputStream o = new ObjectOutputStream(stream);
  62. o.writeObject(keyPair);
  63. session.addPublicKeyIdentity(keyPair);
  64. if (session.auth().verify(5000).isFailure()) {
  65. throw new RuntimeException("验证失败");
  66. }
  67. } catch (Exception e) {
  68. throw new RuntimeException(e);
  69. }
  70. }
  71. /**
  72. * 关闭连接
  73. */
  74. public void close(){
  75. log.info("关闭 SSH");
  76. closeSession();
  77. if(client != null){
  78. try {
  79. client.close();
  80. } catch (IOException e) {
  81. log.error(e.getMessage());
  82. }
  83. }
  84. }
  85. private void closeSession() {
  86. if(session != null){
  87. try {
  88. session.close();
  89. } catch (IOException e) {
  90. log.error(e.getMessage());
  91. }
  92. }
  93. }
  94. }

2.执行命令

2.1 ChannelExec

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

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClient;
  9. import org.apache.sshd.sftp.client.SftpClientFactory;
  10. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  11. import java.io.*;
  12. import java.nio.file.Files;
  13. import java.nio.file.Path;
  14. import java.nio.file.Paths;
  15. import java.nio.file.StandardCopyOption;
  16. import java.security.KeyPair;
  17. import java.security.KeyPairGenerator;
  18. import java.util.EnumSet;
  19. import java.util.Set;
  20. import java.util.concurrent.TimeUnit;
  21. /**
  22. * Sshd工具类
  23. */
  24. @Slf4j
  25. public class SshdTest {
  26. private SshClient client;
  27. private ClientSession session;
  28. public static void main(String[] args) throws Exception {
  29. SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
  30. sshUtil.execCommand("pwd");
  31. }
  32. /**
  33. * 连接
  34. * @param host
  35. * @param port
  36. * @param username
  37. */
  38. private void connect(String host, int port, String username) {
  39. client = SshClient.setUpDefaultClient();
  40. client.start();
  41. try {
  42. session = client.connect(username, host, port)
  43. .verify(5000)
  44. .getSession();
  45. } catch (IOException e) {
  46. throw new RuntimeException(e);
  47. }
  48. }
  49. /**
  50. * 密码登录
  51. * @param host
  52. * @param port
  53. * @param username
  54. * @param password
  55. */
  56. public SshdTest(String host, int port, String username, String password) {
  57. connect(host,port,username);
  58. try {
  59. session.addPasswordIdentity(password); // for password-based authentication
  60. if (session.auth().verify(5000).isFailure()) {
  61. throw new RuntimeException("验证失败");
  62. }
  63. } catch (IOException e) {
  64. throw new RuntimeException(e);
  65. }
  66. }
  67. /**
  68. * 密钥登录
  69. * @param host
  70. * @param port
  71. * @param username
  72. */
  73. public SshdTest(String host, int port, String username) {
  74. connect(host,port,username);
  75. try {
  76. String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
  77. String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));
  78. //获取密钥对
  79. KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  80. KeyPair keyPair = rsa.generateKeyPair();
  81. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  82. stream.write(privateKeyContent.getBytes());
  83. ObjectOutputStream o = new ObjectOutputStream(stream);
  84. o.writeObject(keyPair);
  85. session.addPublicKeyIdentity(keyPair);
  86. if (session.auth().verify(5000).isFailure()) {
  87. throw new RuntimeException("验证失败");
  88. }
  89. } catch (Exception e) {
  90. throw new RuntimeException(e);
  91. }
  92. }
  93. /**
  94. * 执行命令
  95. * @param command
  96. * @return
  97. */
  98. public String execCommand(String command){
  99. session.resetAuthTimeout();
  100. System.out.println("exe cmd: "+ command);
  101. // 返回结果流
  102. ByteArrayOutputStream out = new ByteArrayOutputStream();
  103. // 错误信息
  104. ByteArrayOutputStream err = new ByteArrayOutputStream();
  105. try(ChannelExec channelExec = session.createExecChannel(command)) {
  106. channelExec.setOut(out);
  107. channelExec.setErr(err);
  108. // 执行并等待
  109. channelExec.open();
  110. Set<ClientChannelEvent> events =
  111. channelExec.waitFor(
  112. EnumSet.of(ClientChannelEvent.CLOSED),
  113. TimeUnit.SECONDS.toMillis(100000));
  114. // 检查请求是否超时
  115. if (events.contains(ClientChannelEvent.TIMEOUT)) {
  116. throw new RuntimeException("请求连接超时");
  117. }
  118. // 一般退出状态为0表示正常
  119. int exitStatus = channelExec.getExitStatus();
  120. if (exitStatus == 1) {
  121. log.info("exitStatus:{}",exitStatus);
  122. // throw new RuntimeException("执行命令失败:"+exitStatus);
  123. }
  124. } catch (Exception e) {
  125. throw new RuntimeException(e);
  126. }
  127. return out.toString().trim();
  128. }
  129. /**
  130. * 关闭连接
  131. */
  132. public void close(){
  133. log.info("关闭 SSH");
  134. closeSession();
  135. if(client != null){
  136. try {
  137. client.close();
  138. } catch (IOException e) {
  139. log.error(e.getMessage());
  140. }
  141. }
  142. }
  143. private void closeSession() {
  144. if(session != null){
  145. try {
  146. session.close();
  147. } catch (IOException e) {
  148. log.error(e.getMessage());
  149. }
  150. }
  151. }
  152. }

2.2 ChannelShell

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

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClient;
  9. import org.apache.sshd.sftp.client.SftpClientFactory;
  10. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  11. import java.io.*;
  12. import java.nio.file.Files;
  13. import java.nio.file.Path;
  14. import java.nio.file.Paths;
  15. import java.nio.file.StandardCopyOption;
  16. import java.security.KeyPair;
  17. import java.security.KeyPairGenerator;
  18. import java.util.EnumSet;
  19. import java.util.Set;
  20. import java.util.concurrent.TimeUnit;
  21. /**
  22. * Sshd工具类
  23. */
  24. @Slf4j
  25. public class SshdTest {
  26. private SshClient client;
  27. private ClientSession session;
  28. public static void main(String[] args) throws Exception {
  29. SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
  30. String[] commends ={"pwd","cd ","pwd"};
  31. sshUtil.execCommand(commends);
  32. }
  33. /**
  34. * 连接
  35. * @param host
  36. * @param port
  37. * @param username
  38. */
  39. private void connect(String host, int port, String username) {
  40. client = SshClient.setUpDefaultClient();
  41. client.start();
  42. try {
  43. session = client.connect(username, host, port)
  44. .verify(5000)
  45. .getSession();
  46. } catch (IOException e) {
  47. throw new RuntimeException(e);
  48. }
  49. }
  50. /**
  51. * 密码登录
  52. * @param host
  53. * @param port
  54. * @param username
  55. * @param password
  56. */
  57. public SshdTest(String host, int port, String username, String password) {
  58. connect(host,port,username);
  59. try {
  60. session.addPasswordIdentity(password); // for password-based authentication
  61. if (session.auth().verify(5000).isFailure()) {
  62. throw new RuntimeException("验证失败");
  63. }
  64. } catch (IOException e) {
  65. throw new RuntimeException(e);
  66. }
  67. }
  68. /**
  69. * 密钥登录
  70. * @param host
  71. * @param port
  72. * @param username
  73. */
  74. public SshdTest(String host, int port, String username) {
  75. connect(host,port,username);
  76. try {
  77. String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
  78. String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));
  79. //获取密钥对
  80. KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  81. KeyPair keyPair = rsa.generateKeyPair();
  82. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  83. stream.write(privateKeyContent.getBytes());
  84. ObjectOutputStream o = new ObjectOutputStream(stream);
  85. o.writeObject(keyPair);
  86. session.addPublicKeyIdentity(keyPair);
  87. if (session.auth().verify(5000).isFailure()) {
  88. throw new RuntimeException("验证失败");
  89. }
  90. } catch (Exception e) {
  91. throw new RuntimeException(e);
  92. }
  93. }
  94. /**
  95. * 执行命令
  96. * @param commands
  97. * @return
  98. */
  99. public String execCommand(String[] commands){
  100. session.resetAuthTimeout();
  101. System.out.println("exe cmd: "+ String.join(";",commands));
  102. // 命令返回的结果
  103. StringBuffer resultBuf = new StringBuffer("");
  104. try (ChannelShell channel = session.createShellChannel()) {
  105. channel.open().verify(5 , TimeUnit.SECONDS);
  106. // 执行命令
  107. try (PrintStream out = new PrintStream(channel.getInvertedIn())) {
  108. for (String command:commands){
  109. out.println(command);
  110. out.flush();
  111. }
  112. out.println("exit");
  113. out.flush();
  114. }
  115. //channel.waitFor(Collections.singleton(ClientChannelEvent.CLOSED), 0);
  116. try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(channel.getInvertedOut()))) {
  117. String line;
  118. while ((line = bufferedReader.readLine()) != null) {
  119. System.out.println(line);
  120. resultBuf.append(line);
  121. }
  122. }
  123. } catch (IOException e) {
  124. throw new RuntimeException(e);
  125. }
  126. return resultBuf.toString().trim();
  127. }
  128. /**
  129. * 关闭连接
  130. */
  131. public void close(){
  132. log.info("关闭 SSH");
  133. closeSession();
  134. if(client != null){
  135. try {
  136. client.close();
  137. } catch (IOException e) {
  138. log.error(e.getMessage());
  139. }
  140. }
  141. }
  142. private void closeSession() {
  143. if(session != null){
  144. try {
  145. session.close();
  146. } catch (IOException e) {
  147. log.error(e.getMessage());
  148. }
  149. }
  150. }
  151. }

3.文件传输

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

 3.1 上传文件

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClient;
  9. import org.apache.sshd.sftp.client.SftpClientFactory;
  10. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  11. import org.apache.sshd.sftp.client.fs.SftpPath;
  12. import java.io.*;
  13. import java.nio.file.Files;
  14. import java.nio.file.Path;
  15. import java.nio.file.Paths;
  16. import java.nio.file.StandardCopyOption;
  17. import java.nio.file.attribute.PosixFilePermissions;
  18. import java.security.KeyPair;
  19. import java.security.KeyPairGenerator;
  20. import java.util.EnumSet;
  21. import java.util.List;
  22. import java.util.Set;
  23. import java.util.concurrent.TimeUnit;
  24. import java.util.stream.Collectors;
  25. import java.util.stream.Stream;
  26. /**
  27. * Sshd工具类
  28. *
  29. * https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
  30. */
  31. @Slf4j
  32. public class SshdTest {
  33. private SshClient client;
  34. private ClientSession session;
  35. public static void main(String[] args) throws Exception {
  36. SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
  37. sshUtil.uploadFile(new File("F:\\24\\tmp.txt"),"/home/weisx/");
  38. }
  39. /**
  40. * 连接
  41. * @param host
  42. * @param port
  43. * @param username
  44. */
  45. private void connect(String host, int port, String username) {
  46. client = SshClient.setUpDefaultClient();
  47. client.start();
  48. try {
  49. session = client.connect(username, host, port)
  50. .verify(5000)
  51. .getSession();
  52. } catch (IOException e) {
  53. throw new RuntimeException(e);
  54. }
  55. }
  56. /**
  57. * 密码登录
  58. * @param host
  59. * @param port
  60. * @param username
  61. * @param password
  62. */
  63. public SshdTest(String host, int port, String username, String password) {
  64. connect(host,port,username);
  65. try {
  66. session.addPasswordIdentity(password); // for password-based authentication
  67. if (session.auth().verify(5000).isFailure()) {
  68. throw new RuntimeException("验证失败");
  69. }
  70. } catch (IOException e) {
  71. throw new RuntimeException(e);
  72. }
  73. }
  74. /**
  75. * 密钥登录
  76. * @param host
  77. * @param port
  78. * @param username
  79. */
  80. public SshdTest(String host, int port, String username) {
  81. connect(host,port,username);
  82. try {
  83. String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
  84. String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));
  85. //获取密钥对
  86. KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  87. KeyPair keyPair = rsa.generateKeyPair();
  88. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  89. stream.write(privateKeyContent.getBytes());
  90. ObjectOutputStream o = new ObjectOutputStream(stream);
  91. o.writeObject(keyPair);
  92. session.addPublicKeyIdentity(keyPair);
  93. if (session.auth().verify(5000).isFailure()) {
  94. throw new RuntimeException("验证失败");
  95. }
  96. } catch (Exception e) {
  97. throw new RuntimeException(e);
  98. }
  99. }
  100. /**
  101. * 上传文件
  102. * @param uploadFile 上传的文件
  103. * @param remotePath 远程目录
  104. */
  105. public String uploadFile(File uploadFile,String remotePath) {
  106. try(SftpClient sftpClient = SftpClientFactory.instance().createSftpClient(session);
  107. OutputStream outputStream = sftpClient.write(remotePath)
  108. ) {
  109. Files.copy(uploadFile.toPath(), outputStream);
  110. return remotePath;
  111. } catch (IOException e) {
  112. throw new RuntimeException(e);
  113. }
  114. }
  115. /**
  116. * 关闭连接
  117. */
  118. public void close(){
  119. log.info("关闭 SSH");
  120. closeSession();
  121. if(client != null){
  122. try {
  123. client.close();
  124. } catch (IOException e) {
  125. log.error(e.getMessage());
  126. }
  127. }
  128. }
  129. private void closeSession() {
  130. if(session != null){
  131. try {
  132. session.close();
  133. } catch (IOException e) {
  134. log.error(e.getMessage());
  135. }
  136. }
  137. }
  138. }

3.2 下载文件

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClient;
  9. import org.apache.sshd.sftp.client.SftpClientFactory;
  10. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  11. import org.apache.sshd.sftp.client.fs.SftpPath;
  12. import java.io.*;
  13. import java.nio.file.Files;
  14. import java.nio.file.Path;
  15. import java.nio.file.Paths;
  16. import java.nio.file.StandardCopyOption;
  17. import java.nio.file.attribute.PosixFilePermissions;
  18. import java.security.KeyPair;
  19. import java.security.KeyPairGenerator;
  20. import java.util.EnumSet;
  21. import java.util.List;
  22. import java.util.Set;
  23. import java.util.concurrent.TimeUnit;
  24. import java.util.stream.Collectors;
  25. import java.util.stream.Stream;
  26. /**
  27. * Sshd工具类
  28. *
  29. * https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
  30. */
  31. @Slf4j
  32. public class SshdTest {
  33. private SshClient client;
  34. private ClientSession session;
  35. public static void main(String[] args) throws Exception {
  36. SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
  37. sshUtil.downloadFile("/home/weisx/tmp.txt","F:\\24\\");
  38. }
  39. /**
  40. * 连接
  41. * @param host
  42. * @param port
  43. * @param username
  44. */
  45. private void connect(String host, int port, String username) {
  46. client = SshClient.setUpDefaultClient();
  47. client.start();
  48. try {
  49. session = client.connect(username, host, port)
  50. .verify(5000)
  51. .getSession();
  52. } catch (IOException e) {
  53. throw new RuntimeException(e);
  54. }
  55. }
  56. /**
  57. * 密码登录
  58. * @param host
  59. * @param port
  60. * @param username
  61. * @param password
  62. */
  63. public SshdTest(String host, int port, String username, String password) {
  64. connect(host,port,username);
  65. try {
  66. session.addPasswordIdentity(password); // for password-based authentication
  67. if (session.auth().verify(5000).isFailure()) {
  68. throw new RuntimeException("验证失败");
  69. }
  70. } catch (IOException e) {
  71. throw new RuntimeException(e);
  72. }
  73. }
  74. /**
  75. * 密钥登录
  76. * @param host
  77. * @param port
  78. * @param username
  79. */
  80. public SshdTest(String host, int port, String username) {
  81. connect(host,port,username);
  82. try {
  83. String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
  84. String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));
  85. //获取密钥对
  86. KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  87. KeyPair keyPair = rsa.generateKeyPair();
  88. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  89. stream.write(privateKeyContent.getBytes());
  90. ObjectOutputStream o = new ObjectOutputStream(stream);
  91. o.writeObject(keyPair);
  92. session.addPublicKeyIdentity(keyPair);
  93. if (session.auth().verify(5000).isFailure()) {
  94. throw new RuntimeException("验证失败");
  95. }
  96. } catch (Exception e) {
  97. throw new RuntimeException(e);
  98. }
  99. }
  100. /**
  101. * 下载文件
  102. * @param remoteFilePath 下载的文件
  103. * @param savePath 保存的目录
  104. */
  105. public void downloadFile(String remoteFilePath,String savePath) {
  106. try(SftpClient sftpClient = SftpClientFactory.instance().createSftpClient(session);
  107. InputStream inputStream = sftpClient.read(remoteFilePath)
  108. ) {
  109. File destFile = new File(savePath);
  110. Files.copy(inputStream , destFile.toPath() , StandardCopyOption.REPLACE_EXISTING);
  111. } catch (IOException e) {
  112. throw new RuntimeException(e);
  113. }
  114. }
  115. /**
  116. * 关闭连接
  117. */
  118. public void close(){
  119. log.info("关闭 SSH");
  120. closeSession();
  121. if(client != null){
  122. try {
  123. client.close();
  124. } catch (IOException e) {
  125. log.error(e.getMessage());
  126. }
  127. }
  128. }
  129. private void closeSession() {
  130. if(session != null){
  131. try {
  132. session.close();
  133. } catch (IOException e) {
  134. log.error(e.getMessage());
  135. }
  136. }
  137. }
  138. }

3.3 SftpFileSystem

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

  1. package com.yichenkeji.starter.ssh;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.sshd.client.SshClient;
  4. import org.apache.sshd.client.channel.ChannelExec;
  5. import org.apache.sshd.client.channel.ChannelShell;
  6. import org.apache.sshd.client.channel.ClientChannelEvent;
  7. import org.apache.sshd.client.session.ClientSession;
  8. import org.apache.sshd.sftp.client.SftpClient;
  9. import org.apache.sshd.sftp.client.SftpClientFactory;
  10. import org.apache.sshd.sftp.client.fs.SftpFileSystem;
  11. import org.apache.sshd.sftp.client.fs.SftpPath;
  12. import java.io.*;
  13. import java.nio.file.Files;
  14. import java.nio.file.Path;
  15. import java.nio.file.Paths;
  16. import java.nio.file.StandardCopyOption;
  17. import java.nio.file.attribute.PosixFilePermissions;
  18. import java.security.KeyPair;
  19. import java.security.KeyPairGenerator;
  20. import java.util.EnumSet;
  21. import java.util.List;
  22. import java.util.Set;
  23. import java.util.concurrent.TimeUnit;
  24. import java.util.stream.Collectors;
  25. import java.util.stream.Stream;
  26. /**
  27. * Sshd工具类
  28. *
  29. * https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
  30. */
  31. @Slf4j
  32. public class SshdTest {
  33. private SshClient client;
  34. private ClientSession session;
  35. public static void main(String[] args) throws Exception {
  36. SshdTest sshUtil = new SshdTest("192.168.179.131",22,"weisx","123456");
  37. sshUtil.fileMeta("/home/weisx/tmp.txt");
  38. }
  39. /**
  40. * 连接
  41. * @param host
  42. * @param port
  43. * @param username
  44. */
  45. private void connect(String host, int port, String username) {
  46. client = SshClient.setUpDefaultClient();
  47. client.start();
  48. try {
  49. session = client.connect(username, host, port)
  50. .verify(5000)
  51. .getSession();
  52. } catch (IOException e) {
  53. throw new RuntimeException(e);
  54. }
  55. }
  56. /**
  57. * 密码登录
  58. * @param host
  59. * @param port
  60. * @param username
  61. * @param password
  62. */
  63. public SshdTest(String host, int port, String username, String password) {
  64. connect(host,port,username);
  65. try {
  66. session.addPasswordIdentity(password); // for password-based authentication
  67. if (session.auth().verify(5000).isFailure()) {
  68. throw new RuntimeException("验证失败");
  69. }
  70. } catch (IOException e) {
  71. throw new RuntimeException(e);
  72. }
  73. }
  74. /**
  75. * 密钥登录
  76. * @param host
  77. * @param port
  78. * @param username
  79. */
  80. public SshdTest(String host, int port, String username) {
  81. connect(host,port,username);
  82. try {
  83. String privateKeyPath = System.getProperty("user.home") + "/.ssh/id_rsa";
  84. String privateKeyContent = new String(Files.readAllBytes(Paths.get(privateKeyPath)));
  85. //获取密钥对
  86. KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
  87. KeyPair keyPair = rsa.generateKeyPair();
  88. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  89. stream.write(privateKeyContent.getBytes());
  90. ObjectOutputStream o = new ObjectOutputStream(stream);
  91. o.writeObject(keyPair);
  92. session.addPublicKeyIdentity(keyPair);
  93. if (session.auth().verify(5000).isFailure()) {
  94. throw new RuntimeException("验证失败");
  95. }
  96. } catch (Exception e) {
  97. throw new RuntimeException(e);
  98. }
  99. }
  100. /**
  101. * 获取文件信息
  102. * @param filePath 文件路径
  103. */
  104. public void fileMeta(String filePath) {
  105. try(SftpFileSystem sftp = SftpClientFactory.instance().createSftpFileSystem(session)) {
  106. SftpPath path = sftp.getPath(filePath);
  107. System.out.println("文件名:" + path.getFileName());
  108. System.out.println("文件大小:" + Files.size(path));
  109. System.out.println("最后更新时间:" + Files.getLastModifiedTime(path));
  110. //如果是目录,则可以列出目录下全部文件
  111. try (Stream<Path> stream = Files.list(path)) {
  112. List<Path> paths = stream.collect(Collectors.toList());
  113. for (Path p : paths) {
  114. if (Files.isDirectory(p)) {
  115. System.out.println("文件夹:" + p.getFileName());
  116. } else {
  117. System.out.println("文件: " + p.getFileName());
  118. }
  119. }
  120. }
  121. } catch (IOException e) {
  122. throw new RuntimeException(e);
  123. }
  124. }
  125. /**
  126. * 关闭连接
  127. */
  128. public void close(){
  129. log.info("关闭 SSH");
  130. closeSession();
  131. if(client != null){
  132. try {
  133. client.close();
  134. } catch (IOException e) {
  135. log.error(e.getMessage());
  136. }
  137. }
  138. }
  139. private void closeSession() {
  140. if(session != null){
  141. try {
  142. session.close();
  143. } catch (IOException e) {
  144. log.error(e.getMessage());
  145. }
  146. }
  147. }
  148. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/416622
推荐阅读
相关标签
  

闽ICP备14008679号