zoukankan      html  css  js  c++  java
  • SFTP信任公钥配置及JSCH库

    1、SFTP信用公钥配置

    1.1 客户端生成密钥对

    以DSA举例: 

    ssh-keygen –t dsa

    执行该命令后,在home/用户名/.ssh目录下,会生成id_dsa和id_dsa.pub两个文件

    1.2 将id_dsa.pub公钥文件上传至服务端的home/用户名/.ssh目录下

    scp id_dsa.pub 用户名@服务端IP:/home/用户名/.ssh

    此时还需要输入密码

    1.3服务端添加信任公钥

    登录服务端,进入到/home/用户名/.ssh目录,将刚刚拷贝的id_dsa.pub文件的内容加入到authorized_keys文件中

    cat id_dsa.pub >> authorized_keys

    1.4 服务端分别修改authorized_key文件和.ssh的权限为600700

    chmod 600 authorized_keys

    chmod 700 .ssh

    1.5 测试

    在客户端执行:

    sftp –oPort=端口 用户名@服务端IP

    如果不需要输入密码就可以连上,则说明配置成功

    2、基于JSCH库的sftp操作

    Java代码  
    1. public class SftpUtil {  
    2.     private final static Logger          log       = LoggerFactory.getLogger(SftpUtil.class);  
    3.   
    4.     /** SFTP */  
    5.     public static final String           SFTP      = "sftp";  
    6.     /** 通道 */  
    7.     private ChannelSftp                  channel;  
    8.     /** session */  
    9.     private Session                      session;  
    10.   
    11.     /** 规避多线程并发 */  
    12.     private static ThreadLocal<SftpUtil> sftpLocal = new ThreadLocal<SftpUtil>();  
    13.   
    14.     /** 
    15.      * 获取sftpchannel 
    16.      *  
    17.      * @param connectConfig 连接配置 
    18.      * @return 
    19.      * @throws Exception  
    20.      * @throws JSchException 
    21.      */  
    22.     private void init(ConnectConfig connectConfig) throws Exception {  
    23.         String host = connectConfig.getHost();  
    24.         int port = connectConfig.getPort();  
    25.   
    26.         String userName = connectConfig.getUserName();  
    27.   
    28.         //创建JSch对象  
    29.         JSch jsch = new JSch();  
    30.   
    31.         //添加私钥(信任登录方式)  
    32.         if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {  
    33.             jsch.addIdentity(connectConfig.getPrivateKey());  
    34.         }  
    35.   
    36.         session = jsch.getSession(userName, host, port);  
    37.         if (log.isInfoEnabled()) {  
    38.             log.info(" JSCH Session created,sftpHost = {}, sftpUserName={}", host, userName);  
    39.         }  
    40.   
    41.         //设置密码  
    42.         if (StringUtils.isNotBlank(connectConfig.getPassWord())) {  
    43.             session.setPassword(connectConfig.getPassWord());  
    44.         }  
    45.   
    46.         Properties config = new Properties();  
    47.         config.put("StrictHostKeyChecking", "no");  
    48.         session.setConfig(config);  
    49.         //设置超时  
    50.         session.setTimeout(connectConfig.getTimeout());  
    51.         //建立连接  
    52.         session.connect();  
    53.         if (log.isInfoEnabled()) {  
    54.             log.info("JSCH Session connected.sftpHost = {}, sftpUserName={}", host, userName);  
    55.         }  
    56.   
    57.         //打开SFTP通道  
    58.         channel = (ChannelSftp) session.openChannel(SFTP);  
    59.         //建立SFTP通道的连接  
    60.         channel.connect();  
    61.         if (log.isInfoEnabled()) {  
    62.             log.info("Connected successfully to sftpHost = {}, sftpUserName={}", host, userName);  
    63.         }  
    64.     }  
    65.   
    66.     /** 
    67.      * 是否已连接 
    68.      *  
    69.      * @return 
    70.      */  
    71.     private boolean isConnected() {  
    72.         return null != channel && channel.isConnected();  
    73.     }  
    74.   
    75.     /** 
    76.      * 获取本地线程存储的sftp客户端 
    77.      *  
    78.      * @return 
    79.      * @throws Exception  
    80.      */  
    81.     public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {  
    82.         SftpUtil sftpUtil = sftpLocal.get();  
    83.         if (null == sftpUtil || !sftpUtil.isConnected()) {  
    84.             sftpLocal.set(new SftpUtil(connectConfig));  
    85.         }  
    86.         return sftpLocal.get();  
    87.     }  
    88.   
    89.     /** 
    90.      * 释放本地线程存储的sftp客户端 
    91.      */  
    92.     public static void release() {  
    93.         if (null != sftpLocal.get()) {  
    94.             sftpLocal.get().closeChannel();  
    95.             sftpLocal.set(null);  
    96.         }  
    97.     }  
    98.   
    99.     /** 
    100.      * 构造函数 
    101.      * <p> 
    102.      * 非线程安全,故权限为私有 
    103.      * </p> 
    104.      *  
    105.      * @throws Exception  
    106.      */  
    107.     private SftpUtil(ConnectConfig connectConfig) throws Exception {  
    108.         super();  
    109.         init(connectConfig);  
    110.     }  
    111.   
    112.     /** 
    113.      * 关闭通道 
    114.      *  
    115.      * @throws Exception 
    116.      */  
    117.     public void closeChannel() {  
    118.         if (null != channel) {  
    119.             try {  
    120.                 channel.disconnect();  
    121.             } catch (Exception e) {  
    122.                 log.error("关闭SFTP通道发生异常:", e);  
    123.             }  
    124.         }  
    125.         if (null != session) {  
    126.             try {  
    127.                 session.disconnect();  
    128.             } catch (Exception e) {  
    129.                 log.error("SFTP关闭 session异常:", e);  
    130.             }  
    131.         }  
    132.     }  
    133.   
    134.     /** 
    135.      * 下载文件 
    136.      *  
    137.      * @param downDir 下载目录 
    138.      * @param src 源文件 
    139.      * @param dst 保存后的文件名称或目录 
    140.      * @throws Exception 
    141.      */  
    142.     public void downFile(String downDir, String src, String dst) throws Exception {  
    143.         channel.cd(downDir);  
    144.         channel.get(src, dst);  
    145.     }  
    146.   
    147.     /** 
    148.      * 删除文件 
    149.      *  
    150.      * @param filePath 文件全路径 
    151.      * @throws SftpException 
    152.      */  
    153.     public void deleteFile(String filePath) throws SftpException {  
    154.         channel.rm(filePath);  
    155.     }  
    156.   
    157.     @SuppressWarnings("unchecked")  
    158.     public List<String> listFiles(String dir) throws SftpException {  
    159.         Vector<LsEntry> files = channel.ls(dir);  
    160.         if (null != files) {  
    161.             List<String> fileNames = new ArrayList<String>();  
    162.             Iterator<LsEntry> iter = files.iterator();  
    163.             while (iter.hasNext()) {  
    164.                 String fileName = iter.next().getFilename();  
    165.                 if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) {  
    166.                     continue;  
    167.                 }  
    168.                 fileNames.add(fileName);  
    169.             }  
    170.             return fileNames;  
    171.         }  
    172.         return null;  
    173.     }  
    174. }  

     说明:

    2.1 ConnectConfig包含了建立sftp连接所需要的全部参数信息

    2.2 如果按照第一步进行了sftp的信任公钥配置,则需要通过调用jsch的addIdentity方法将密钥对中的私钥id_dsa设置进去
    Java代码  
    1. //添加私钥(信任登录方式)  
    2.         if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {  
    3.             jsch.addIdentity(connectConfig.getPrivateKey());  
    4.         }  
    2.3 为了避免频繁的进行连接建立和连接释放操作,一般会定义为单例模式,但存在某些业务场景,需要在同一个线程执行完连续几次完整的业务操作后,将连接释放掉。如果采用单例,那么多线程并发的场景下会出现共享资源竞争导致的并发问题,譬如在B线程执行业务的过程中,A线程将连接释放。因此,可以借助ThreadLocal来避免该问题。
    Java代码  
    1. /** 
    2.      * 获取本地线程存储的sftp客户端 
    3.      *  
    4.      * @return 
    5.      * @throws Exception  
    6.      */  
    7.     public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {  
    8.         SftpUtil sftpUtil = sftpLocal.get();  
    9.         if (null == sftpUtil || !sftpUtil.isConnected()) {  
    10.             sftpLocal.set(new SftpUtil(connectConfig));  
    11.         }  
    12.         return sftpLocal.get();  
    13.     }  
    14.   
    15.     /** 
    16.      * 释放本地线程存储的sftp客户端 
    17.      */  
    18.     public static void release() {  
    19.         if (null != sftpLocal.get()) {  
    20.             sftpLocal.get().closeChannel();  
    21.             sftpLocal.set(null);  
    22.         }  
    23.     } 
  • 相关阅读:
    linux 操作命令
    Linux 安装问题
    margin和text-align实现水平居中的区别
    javascript关键字typeof、instanceof、constructor判断类型
    jquery经常用到的代码段
    Ubuntu安装Chrome浏览器及解决启动no-sandbox问题
    github基本使用---从零开始
    Jquery的load加载本地文件出现跨域错误的解决方案
    meta标签中设置以极速模式打开网页
    原生js动态创建文本内容的几种方式
  • 原文地址:https://www.cnblogs.com/moonfans/p/3910015.html
Copyright © 2011-2022 走看看