JSch - 配置SFTP服务器SSH免密登录
创始人
2025-01-20 15:05:49
0次

文章目录

    • 1. 什么是SFTP
    • 2. 什么是Jsch以及它的作用
    • 3. Linux中配置SSH密钥登录
    • 4. sftp服务器认证机制
    • 5. publickey和password两种方式登录sftp的API调用
    • 6. 代码可以如下改造:

需求:做一个通过ssh免密登录的需求,是基于原先密码登录sftp服务器的代码上进行改造

1. 什么是SFTP

SFTP是一个安全文件传送协议,可以为传输文件提供一种安全的加密方法。SFTP 为 SSH的一部份,是一种传输文件到服务器的安全方式。SFTP是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。

2. 什么是Jsch以及它的作用

Jsch是一个纯粹的用java实现SSH功能的java library。如果要知道Jsch的功能需先了解一下SSH。SSH是一个安全协议,用来在不同系统或者服务器之间进行安全连接,在连接和传送数据的过程中会进行加密。SSH一般是基于客户端的或者Linux命令行,比如window同过OpenSSH、putty等客户端的工具,在linux上可以通过ssh username@host命令进行连接。但是如果在Java中如何实现SSH呢?这时候便是通过JSCH来实现此的功能。

3. Linux中配置SSH密钥登录

SSH 免密登录可以让用户在不输入密码的情况下登录远程服务器,提高登录效率和安全性

步骤:

  1. 在本机中生成秘钥,SSH有专门创建SSH密钥的工具ssh-keygen 🚩

    - 生成旧版密钥的命令:ssh-keygen -m PEM -t rsa - 生成新版密钥命令:ssh-keygen -t rsa 
    • passphrase:生成密钥时的密码
    • 执行结束后,~/.ssh/目录下会多两个文件:id_rsa(私钥)、id_rsa.pub(公钥)
    id_rsa:私钥 id_rsa.pub:公钥 
  2. 给目标服务器添加公钥

    ssh-copy-id 用户名@主机

    公钥将被复制到目标服务器的~/.ssh/authorized_keys文件中。

    ssh-copy-id -p 19222 lihw@10.1.61.118 

    或

    将公钥ftp到目标服务器的.ssh后,cd ~/.ssh,手动将公钥导入到authorized_keys信任列表:

    cat 公钥 >> authorized_keys 
  3. 更新权限公钥权限

    # 自此SSH免密登录配置完成。 chmod 644 authorized_keys 
  4. 配置服务器

    在目标服务器上使用文本编辑器打开SSH服务器的配置文件(通常为/etc/ssh/sshd_config):

    sudo nano /etc/ssh/sshd_config 

    确保以下配置选项的值为"yes",如果不是,请进行相应修改:

    RSAAuthentication yes PubkeyAuthentication yes 

    保存修改并关闭配置文件。
    重新启动SSH服务器以应用更改:

    sudo service ssh restart 
  5. 测试使用密钥登录

    ssh -p 19222 lihw@10.1.61.118 

4. sftp服务器认证机制

Jsch提供了四种认证机制:

  • password 密码方式
  • publickey(DSA,RSA) 公私钥方式
  • keyboard-interactive
  • gss-api-with-mic

其中publickey方式通过配置公私钥实现SSH免密登录,这里也只是简单讲一下它的使用。

5. publickey和password两种方式登录sftp的API调用

SSH公钥检查机制:

公钥检查机制是一个安全机制,可以防范中间人劫持等黑客攻击。SSH连接远程主机时,会检查主机的公钥。如果是第一次该主机,会显示该主机的公钥摘要,提示用户是否信任该主机。当选择接受,就会将该主机的公钥追加到文件 ~/.ssh/known_hosts 中。当再次连接该主机时,就不会再提示该问题了。 但是在某些特殊的情况下,严格的SSH公钥检查可能会破坏一些依赖SSH协议的自动化任务如Java的Jsch免密登录sftp程序。解决方式为调整StrictHostKeyChecking配置指令。StrictHostKeyChecking选项如下3种:

session.setConfig("StrictHostKeyChecking", "no/ask/yes👇"); 
  • no 最不安全的级别,当然也没有那么多烦人的提示了,相对安全的内网测试时建议使用。如果连接server的key在本地不存在,那么就自动添加到文件中(默认是known_hosts),并且给出一个警告。
  • ask 默认的级别,就是出现刚才的提示了。如果连接和key不匹配,给出提示,并拒绝登录。
  • yes 最安全的级别,如果连接与key不匹配,就拒绝连接,不会提示详细信息。

下面根据password来分析publickey方式与其区别:

  • 原来password方式需要这样一段代码来设置密码:session.setPassword (properties.getPassword ()); ,但是ssh key的方式就没有password了,所以这段要删掉。
  • publickey需要设置我们的ssh私钥文件的全路径(privateKeyFile):jsch.addIdentity (properties.getPrivateKeyFile ());
  • 一般私钥文件需要口令(passphrase)才能读取,这需要设置一个配置类对象,在jsch里其实需要自己搞一个简单的接口实现(如下:SftpAuthKeyUserInfo类 ),然后增加:session.setUserInfo(new SftpAuthKeyUserInfo (properties.getPassphrase ()));

6. 代码可以如下改造:

  1. 设置配置类对象

    SftpAuthKeyUserInfo.java

import com.jcraft.jsch.UserInfo; import lombok.extern.slf4j.Slf4j;  /**  * ssh private key passphrase info  */ @Slf4j public class UserInfoImpl implements UserInfo {     /**      * ssh private key passphrase      */     private String passphrase;      public UserInfoImpl (String passphrase) {         this.passphrase = passphrase;     }      @Override     public String getPassphrase() {         return passphrase;     }      @Override     public String getPassword() {         return null;     }      @Override     public boolean promptPassphrase(String s) {         return true;     }      @Override     public boolean promptPassword(String s) {         return false;     }      @Override     public boolean promptYesNo(String s) {         return true;     }          @Override     public void showMessage(String message) {         log.info ("SSH Message:{}", message);     } } 
  1. 改造以适配publickey登录方式
   try {             JSch jsch = new JSch();             session = jsch.getSession(sftpProperties.getUsername(),                                       sftpProperties.getHost(),                                        sftpProperties.getPort());             if (sftpProperties.isCheckToHostKey()) {                 session.setConfig("PreferredAuthentications", "publickey");                 session.setConfig("userauth.gssapi-with-mic", "no");                 session.setConfig("StrictHostKeyChecking", "ask");                 session.setUserInfo(new SftpAuthKeyUserInfo(sftpProperties.getPassword()));                 jsch.addIdentity(sftpProperties.getKeyPath());             } else {                 session.setConfig("PreferredAuthentications", "password");                 session.setConfig("StrictHostKeyChecking", "no");                 session.setPassword(sftpProperties.getPassword());             }             session.setConfig("UseDNS", "no");             session.setConfig("kex", "diffie-hellman-group1-sha1,"                     + "diffie-hellman-group-exchange-sha1,"                     + "diffie-hellman-group-exchange-sha256");             session.connect(sftpProperties.getConnectTimeout());             channelSftp = (ChannelSftp) session.openChannel("sftp");             channelSftp.connect();             originalDir = channelSftp.pwd();         } catch (Exception e) {             disconnect();             throw new IllegalStateException("failed to create sftp Client", e);         } 
  1. properties为自定义sftp服务端配置:
package io.github.lihewei7.easysftp.config;  import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.LinkedHashMap;  /**  * @explain: SFTP client configuration information  * @author: lihewei */ @ConfigurationProperties("sftp") public class SftpProperties {      private String host = "localhost";     private int port = 22;     private String username;     private String password = "";     /**      * Connection timeout.      */     private int connectTimeout = 0;     /**      * Enable jsch log, Cannot be individually turned on or off for one of multiple hosts.      */     private boolean enabledLog = false;     /**      * Whether to use a key to log in      */     private Boolean isCheckToHostKey = false;     /**      * SSH kex algorithms.      */     private String kex;     /**      * host key.      */     private String keyPath;     /**      * Configuring multiple hosts.      */     private LinkedHashMap hosts;      public LinkedHashMap getHosts() {         return hosts;     }      public void setHosts(LinkedHashMap hosts) {         this.hosts = hosts;     }      public String getHost() {         return host;     }      public void setHost(String host) {         this.host = host;     }      public int getPort() {         return port;     }      public void setPort(int port) {         this.port = port;     }      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String getPassword() {         return password;     }      public void setPassword(String password) {         this.password = password;     }      public boolean isEnabledLog() {         return enabledLog;     }      public void setEnabledLog(boolean enabledLog) {         this.enabledLog = enabledLog;     }      public int getConnectTimeout() {         return connectTimeout;     }      public void setConnectTimeout(int connectTimeout) {         this.connectTimeout = connectTimeout;     }      public Boolean isCheckToHostKey() {         return isCheckToHostKey;     }      public void setCheckToHostKey(Boolean checkToHostKey) {         isCheckToHostKey = checkToHostKey;     }      public String getKex() {         return kex;     }      public void setKex(String kex) {         this.kex = kex;     }      public String getKeyPath() {         return keyPath;     }      public void setKeyPath(String keyPath) {         this.keyPath = keyPath;     } } 

相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...