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.     } 
  • 相关阅读:
    101. Symmetric Tree(js)
    100. Same Tree(js)
    99. Recover Binary Search Tree(js)
    98. Validate Binary Search Tree(js)
    97. Interleaving String(js)
    96. Unique Binary Search Trees(js)
    95. Unique Binary Search Trees II(js)
    94. Binary Tree Inorder Traversal(js)
    93. Restore IP Addresses(js)
    92. Reverse Linked List II(js)
  • 原文地址:https://www.cnblogs.com/moonfans/p/3910015.html
Copyright © 2011-2022 走看看