引入maven包
<!--jsch java secure channel ssh连接-->
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
连接使用,直接连接到ssh服务器
一般服务器都是ssh服务器,可以直接连接,username,ip,port,password jsch执行命令有单个指令的执行方式也有多个指令执行的方式(exec,shell)
如何查看服务器ssh的状态?systemctl status sshd
执行多个命令时需要输出流,PrintWriter
public void test5() throws JSchException {
try {
JSch jSch = new JSch();
Session schSession = jSch.getSession("root", "192.168.247.132", 22);
schSession.setPassword("123456");
schSession.setConfig("StrictHostKeyChecking","no");
schSession.connect();
System.out.println(StrUtil.format( "SSH服务器版本:{}", schSession.getServerVersion()));
String s = execCommandByJSch(schSession, "cat /root/elastic-search/jvm.options\n", "UTF-8");
System.out.println(s);
schSession.disconnect();
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(2222);
}
}
@org.junit.Test
public void test6() throws JSchException {
try {
JSch jSch = new JSch();
Session schSession = jSch.getSession("root", "192.168.247.132", 22);
schSession.setPassword("123456");
schSession.setConfig("StrictHostKeyChecking","no");
schSession.connect();
System.out.println(StrUtil.format( "SSH服务器版本:{}", schSession.getServerVersion()));
List<String> commands = Arrays.asList("cd /root/elastic-search", "ls");
String s = execMultipleCommandsByPrintWriter(schSession, commands, "UTF-8");
System.out.println(s);
schSession.disconnect();
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println(2222);
}
}
/**
* 单个指令执行
* */
public static String execCommandByJSch(Session session, String command, String resultEncoding) throws IOException, JSchException {
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
InputStream in = null;
try {
channelExec.setCommand(command);
in = channelExec.getInputStream();
channelExec.connect();
String result = MyIOUtils.toString(in, resultEncoding);
return result;
} finally {
if (in != null) {
in.close();
}
channelExec.disconnect();
}
}
/**
* 执行多个命令
* */
public static String execMultipleCommandsByPrintWriter(Session session,List<String> commands,String resultEncoding) throws JSchException, IOException {
ChannelShell channelShell = (ChannelShell)session.openChannel("shell");
InputStream inputStream = channelShell.getInputStream();
OutputStream outputStream = channelShell.getOutputStream();
channelShell.setPty(true);//设置shell通道为伪终端,支持本地命令在远程执行
channelShell.connect();
PrintWriter printWriter = new PrintWriter(outputStream);
for (String command : commands) {
printWriter.println(command);
}
printWriter.println("exit");//结束本次交互
printWriter.flush();
String string = MyIOUtils.toString(inputStream, "UTF-8");
while (!channelShell.isClosed()){
try {
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
}
//关闭
printWriter.close();
outputStream.close();
inputStream.close();
channelShell.disconnect();
return string;
}
/**
* 读取流转化为string
* */
static class MyIOUtils {
public static String toString(InputStream inputStream, String encoding) throws IOException {
String result="";
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, encoding))) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}catch (IOException e){
e.printStackTrace();
System.out.println(StrUtil.format("读取流转化异常:{}",e.getMessage()));
}
return result;
}
}
堡垒机使用
如果有堡垒机,一般是通过堡垒机访问远程服务器,堡垒机本身也是一个远程服务器(ssh)
public void test7() {
try {
//先连接到堡垒机
JSch jsch = new JSch();
session = jsch.getSession(this.jumpServerUser, this.jumpServerHost, this.jumpServerPort);
session.setPassword(this.jumpServerPassword);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
//再本地端口映射,访问远程服务器(自己需要访问的服务器)
int assingedPort = session.setPortForwardingL(localPort, remoteHost, remotePort);
log.info("访问地址映射:localhost:{}--->{}:{}", assingedPort, this.remoteHost, this.remotePort);
} catch (Exception e) {
if (this.session != null) {
this.session.disconnect();
}
}
}