微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 JSch 在 webapp 中实现 SSH shell 终端

如何解决使用 JSch 在 webapp 中实现 SSH shell 终端

我正在尝试在 spring 中使用 websocket 在 webapp 中实现一个 shell 终端。我能够向 JSch“exec”通道发送一个命令并将输出发送回 websocket。

Image

我遇到的问题是:

  1. 当我发送第二个命令时,我无法像工作目录一样保留 shell 的状态。我怎样才能保持以前的状态?我曾尝试使用相同的会话,但它不起作用。

     public String sendCommand(String command) {
         StringBuilder outputBuffer = new StringBuilder();
    
         try {
             Channel channel = sesConnection.openChannel("exec");
             ((ChannelExec) channel).setCommand(command);
             InputStream commandOutput = channel.getInputStream();
             channel.connect();
             int readByte = commandOutput.read();
    
             while (readByte != 0xffffffff) {
                 outputBuffer.append((char) readByte);
                 readByte = commandOutput.read();
             }
    
             channel.disconnect();
         } catch (IOException ioX) {
             logWarning(ioX.getMessage());
             return null;
         } catch (JSchException jschX) {
             logWarning(jschX.getMessage());
             return null;
         }
    
         return outputBuffer.toString();
     }
    

    要发送回 websocket,在控制器中我有

    private SSHManager getSSHInstance() {
        String errorMessage = null;
    
        if (sshInstance == null) {
            sshInstance = new SSHManager(username,password,host,"",port);
            errorMessage = sshInstance.connect();
            System.out.println("Instance created");
            if (errorMessage != null) {
                throw new RuntimeException("Could not create an ssh connection");
            }
        }
        System.out.println("Returning created instance");
        return sshInstance;
    }
    
    @MessageMapping("/user")
    @SendTo("/topic/user")
    public UserResponse getResponse(String command) {
    
        SSHManager currInstance = getSSHInstance();
        String result = currInstance.sendCommand(command);
        return new UserResponse(result);
    }
    
  2. 我尝试使用“shell”通道而不是“exec”,后者用于通过标准输入和输出获取输入和输出,但我无法从/返回到实时输入和输出网络套接字和用户界面。我不知道如何从这里开始。任何关于在哪里/看什么的方向都会非常有帮助。

    这是我通过标准输入/输出流的 SSH 终端代码

    import com.jcraft.jsch.*;
    
    public class Terminal{
        public static void main(String[] args){
    
            try{
                JSch jsch=new JSch();
    
                String host = "127.0.0.1";
                String user = "user";
                String password = "pass";
    
                Session session=jsch.getSession(user,5679);
    
                session.setPassword(password);
                session.setConfig("StrictHostKeyChecking","no");
                session.connect(10000);
    
                Channel channel=session.openChannel("shell");
    
                channel.setInputStream(system.in);
                channel.setoutputStream(System.out);
                channel.connect(3*1000);
            }
            catch(Exception e){
                System.out.println(e.getMessage());
            }
        }
    }
    

    要从用户界面发送命令,我有以下内容

    function sendCommand() {
        if (stompClient != null) {
            stompClient.send("/app/user",{},JSON.stringify({'command': $("#command").val()}));
        }
    }
    

解决方法

如果你想实现一个交互式shell,你必须使用“shell”通道,而不是“exec”通道。 “exec”通道用于自动执行单个命令。

一些参考:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。