All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ailyr.tool.extra.ssh.JschUtil Maven / Gradle / Ivy

The newest version!
package com.ailyr.tool.extra.ssh;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import com.ailyr.tool.core.io.IORuntimeException;
import com.ailyr.tool.core.io.IoUtil;
import com.ailyr.tool.core.lang.LocalPortGenerater;
import com.ailyr.tool.core.util.CharsetUtil;
import com.ailyr.tool.core.util.StrUtil;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

/**
 * JSch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等。
* * @author Looly * @since 4.0.0 */ public class JschUtil { /** 不使用SSH的值 */ public final static String SSH_NONE = "none"; /** 本地端口生成器 */ private static final LocalPortGenerater portGenerater = new LocalPortGenerater(10000); /** 锁 */ private static final Object lock = new Object(); /** * 生成一个本地端口,用于远程端口映射 * * @return 未被使用的本地端口 */ public static int generateLocalPort() { return portGenerater.generate(); } /** * 获得一个SSH跳板机会话,重用已经使用的会话 * * @param sshHost 跳板机主机 * @param sshPort 跳板机端口 * @param sshUser 跳板机用户名 * @param sshPass 跳板机密码 * @return SSH会话 */ public static Session getSession(String sshHost, int sshPort, String sshUser, String sshPass) { final String key = StrUtil.format("{}@{}:{}", sshUser, sshHost, sshPort); Session session = JschSessionPool.INSTANCE.get(key); if (null == session) { synchronized (lock) { session = JschSessionPool.INSTANCE.get(key); if (null == session || false == session.isConnected()) { session = openSession(sshHost, sshPort, sshUser, sshPass); JschSessionPool.INSTANCE.put(key, session); } } } return session; } /** * 打开一个新的SSH跳板机会话 * * @param sshHost 跳板机主机 * @param sshPort 跳板机端口 * @param sshUser 跳板机用户名 * @param sshPass 跳板机密码 * @return SSH会话 */ public static Session openSession(String sshHost, int sshPort, String sshUser, String sshPass) { if (StrUtil.isEmpty(sshHost) || sshPort < 0 || StrUtil.isEmpty(sshUser) || StrUtil.isEmpty(sshPass)) { return null; } Session session; try { session = new JSch().getSession(sshUser, sshHost, sshPort); session.setPassword(sshPass); session.setConfig("StrictHostKeyChecking", "no"); session.connect(); } catch (JSchException e) { throw new JschRuntimeException(e); } return session; } /** * 绑定端口到本地。 一个会话可绑定多个端口 * * @param session 需要绑定端口的SSH会话 * @param remoteHost 远程主机 * @param remotePort 远程端口 * @param localPort 本地端口 * @return 成功与否 * @throws JschRuntimeException 端口绑定失败异常 */ public static boolean bindPort(Session session, String remoteHost, int remotePort, int localPort) throws JschRuntimeException { if (session != null && session.isConnected()) { try { session.setPortForwardingL(localPort, remoteHost, remotePort); } catch (JSchException e) { throw new JschRuntimeException("From [" + remoteHost + "] Mapping to [" + localPort + "] error!", e); } return true; } return false; } /** * 解除端口映射 * * @param session 需要解除端口映射的SSH会话 * @param localPort 需要解除的本地端口 * @return 解除成功与否 */ public static boolean unBindPort(Session session, int localPort) { try { session.delPortForwardingL(localPort); return true; } catch (JSchException e) { throw new JschRuntimeException(e); } } /** * 打开SSH会话,并绑定远程端口到本地的一个随机端口 * * @param sshConn SSH连接信息对象 * @param remoteHost 远程主机 * @param remotePort 远程端口 * @return 映射后的本地端口 * @throws JschRuntimeException 连接异常 */ public static int openAndBindPortToLocal(Connector sshConn, String remoteHost, int remotePort) throws JschRuntimeException { final Session session = openSession(sshConn.getHost(), sshConn.getPort(), sshConn.getUser(), sshConn.getPassword()); if (session == null) { throw new JschRuntimeException("Error to create SSH Session!"); } final int localPort = generateLocalPort(); bindPort(session, remoteHost, remotePort, localPort); return localPort; } /** * 打开SFTP连接 * * @param session Session会话 * @return {@link ChannelSftp} * @since 4.0.3 */ public static ChannelSftp openSftp(Session session) { Channel channel; try { channel = session.openChannel("sftp"); channel.connect(); } catch (JSchException e) { throw new JschRuntimeException(e); } return (ChannelSftp) channel; } /** * 创建Sftp * * @param sshHost 远程主机 * @param sshPort 远程主机端口 * @param sshUser 远程主机用户名 * @param sshPass 远程主机密码 * @return {@link Sftp} * @since 4.0.3 */ public static Sftp createSftp(String sshHost, int sshPort, String sshUser, String sshPass) { return new Sftp(sshHost, sshPort, sshUser, sshPass); } /** * 创建Sftp * * @param session SSH会话 * @return {@link Sftp} * @since 4.0.5 */ public static Sftp createSftp(Session session) { return new Sftp(session); } /** * 打开Shell连接 * * @param session Session会话 * @return {@link ChannelShell} * @since 4.0.3 */ public static ChannelShell openShell(Session session) { Channel channel; try { channel = session.openChannel("shell"); channel.connect(); } catch (JSchException e) { throw new JschRuntimeException(e); } return (ChannelShell) channel; } /** * 打开Exec连接
* 获取ChannelExec后首先 * * @param session Session会话 * @param cmd 命令 * @param charset 发送和读取内容的编码 * @return {@link ChannelExec} * @since 4.0.3 */ public static String exec(Session session, String cmd, Charset charset) { if (null == charset) { charset = CharsetUtil.CHARSET_UTF_8; } ChannelExec channel; try { channel = (ChannelExec) session.openChannel("exec"); } catch (JSchException e) { throw new JschRuntimeException(e); } channel.setCommand(StrUtil.bytes(cmd, charset)); channel.setInputStream(null); channel.setErrStream(System.err); InputStream in = null; try { channel.connect();// 执行命令 等待执行结束 in = channel.getInputStream(); return IoUtil.read(in, CharsetUtil.CHARSET_UTF_8); } catch (IOException e) { throw new IORuntimeException(e); } catch (JSchException e) { throw new JschRuntimeException(e); } finally { IoUtil.close(in); close(channel); } } /** * 关闭SSH连接会话 * * @param session SSH会话 */ public static void close(Session session) { if (session != null && session.isConnected()) { session.disconnect(); } } /** * 关闭会话通道 * * @param channel 会话通道 * @since 4.0.3 */ public static void close(Channel channel) { if (channel != null && channel.isConnected()) { channel.disconnect(); } } /** * 关闭SSH连接会话 * * @param key 主机,格式为user@host:port */ public static void close(String key) { JschSessionPool.INSTANCE.close(key); } /** * 关闭所有SSH连接会话 */ public static void closeAll() { JschSessionPool.INSTANCE.closeAll(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy