【问题标题】:Telnet commands into (through, inside) SSH sessionTelnet 命令进入(通过,内部)SSH 会话
【发布时间】:2021-11-20 09:58:25
【问题描述】:

我有一个任务: 通过 ssh 会话执行 telnet 命令。

我看过类似的问题:

  1. Running telnet command on remote SSH session using JSch
  2. telnet through SSH
  3. Execution hangs after Running telnet command on remote SSH session using JSch

我编写了代码(使用 lib https://mvnrepository.com/artifact/com.jcraft/jsch):

  1. 类 SSH:

    公共类 SSH { 私有最终字符串用户; 私人最终字符串密码; 私有最终字符串主机;

     public Ssh(String user, String password, String host) {
         this.USER = user;
         this.PASSWORD = password;
         this.HOST = host;
     }
    
     public Session runSsh() {
         try {
             Session session = new JSch().getSession(USER, HOST, 22);
             session.setPassword(PASSWORD);
             // It must not be recommended, but if you want to skip host-key check,
             session.setConfig("StrictHostKeyChecking", "no");
             session.connect(3000);
             return session;
         } catch (JSchException e) {
             System.out.println(e);
         }
         return null;
     }
    

    }

  2. 类 Telnet

    公共类 Telnet {

     public String runCommand(Session session, String command) throws Exception {
         Channel channel = session.openChannel("shell");
         channel.connect(3000);
    
         DataOutputStream outputStream = new DataOutputStream(channel.getOutputStream());
    
         outputStream.writeBytes("telnet localhost 5000\r\n");
         outputStream.writeBytes(command + "\r\n");
         outputStream.writeBytes("exit\r\n");
         outputStream.flush();
    
         DataInputStream inputStream = new DataInputStream(channel.getInputStream());
         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    
         channel.setInputStream(inputStream, true);
    
         String line = reader.readLine();
         String result = line +"\n";
         while (!(line= reader.readLine()).equals("exit")){
             result += line +"\n";
         }
         result += "Connection closed by foreign host";
    
         outputStream.close();
         inputStream.close();
         channel.disconnect();
         session.disconnect();
    
         return result;
     }
    

    }

  3. 类主

    公共类主{

     public static void main(String[] arg) {
         Ssh ssh = new Ssh("user","password","ip-server");
         Telnet telnet = new Telnet();
         try {
             Session sessionSsh = ssh.runSsh();
             String result = telnet.runCommand(sessionSsh, "H");
             System.out.println(result);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    

    }

我得到了结果:

telnet localhost 5000


Entering character mode

Escape character is '^]'.




 Command Shell 1 on intelpc-1 (Port: 5000)

 b01_1_1 (5000) >
H

Connection closed by foreign host

Process finished with exit code 0

我没有看到执行命令 telnet 的结果...

我通过 telnet 发出了不同的命令:

- H
or
- u s3

但我看不到他们的结果:(

请告诉我。如何获取 telnet 命令执行的结果?

【问题讨论】:

    标签: java ssh telnet jsch


    【解决方案1】:

    我调试了您的示例,就我而言,我需要等待您通过 telnet 连接的程序,直到它准备好接收命令。

    在第二步中,您可以发送命令和退出命令来停止远程登录,因此您可以从流中读取,直到通过说“连接关闭...”停止。请注意,从 telnet 退出可以有不同的命令,有些使用 quit,有些使用 exit 或只等待终止信号。

     class Telnet {
    
            public String runCommand(Session session, String command) throws Exception {
                Channel channel = session.openChannel("shell");
                channel.connect(3000);
    
                DataOutputStream outputStream = new DataOutputStream(channel.getOutputStream());
    
                outputStream.writeBytes("telnet localhost 16379\r\n");
                outputStream.flush();
    
                DataInputStream inputStream = new DataInputStream(channel.getInputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    
                channel.setInputStream(inputStream, true);
    
                // Read until we are ready to write
                String line;
                while (!(line= reader.readLine()).equals("Escape character is '^]'.")){
                    System.out.println(line);
                }
    
                // write command and exit telnet
                outputStream.writeBytes(command + "\r\n");
                outputStream.writeBytes("quit\r\n");
                outputStream.flush();
    
                // read until telnet has closed
                String result = "";
                while (!(line= reader.readLine()).equals("Connection closed by foreign host.")){
                    result += line +"\n";
                }
    
                outputStream.close();
                inputStream.close();
                channel.disconnect();
                session.disconnect();
    
                return result;
            }
        }
    

    最后,还有其他无需 telnet 的通信方式,即本地端口转发。

    【讨论】:

    • 感谢您的回复。我使用了你的代码,但没有得到结果(你还写了:最后,还有其他方法可以不用telnet进行通信,即本地端口转发。非常感谢。我开始使用ssh隧道:ssh Session。 setPortForwardingL(9999, ssh Session.getHost(), 5000); 如果先创建ssh隧道,然后telnet命令给出结果。我稍后会详细写我的结果。
    【解决方案2】:

    感谢马蒂亚斯·维德曼。

    按照 Matthias Wiedemann 的建议,我使用了 SSH 隧道 https://www.ssh.com/academy/ssh/tunneling/example

    总计:

    1 步。通过 SSH 连接并创建会话 SSH

    SSH ssh = new SSH(user, password, host, port);
    Session session = SSHUtil.createSession(ssh);
    

    2 步。使用 SSH 创建隧道

    SSHUtil.createChannel(session, outputConsole);
    SSHUtil.createSshTunnel(session, port);
    

    3 步。通过 Telnet 连接并使用隧道端口(而不是 5000,端口变为 9999)执行 Telnet 命令。

    clientForTelnet = new ClientForTelnet(new Telnet(host, port));
    outputConsole.print(TelnetUtil.connect(clientForTelnet));
    

    outputConsole 是 PrintStream。

    我得到了以下信息:

    1.

    public class SSHUtil{
    
        private final static Logger LOGGER = LogManager.getLogger(SSHUtil.class);
    
        public static Session createSession(SSH ssh) {
            Session session = null;
            try {
                session = new JSch().getSession(ssh.getUSER(), ssh.getHOST().getIp(), ssh.getPORT().getPort());
                session.setPassword(ssh.getPASSWORD());
                session.setConfig("StrictHostKeyChecking", "no"); // It must not be recommended, but if you want to skip host-key check
                session.connect(10000);
                LOGGER.info("SSH session created");
            } catch (JSchException e) {
                LOGGER.error("SSH session not created " + e);
            }
            return session;
        }
    
        public static Channel createChannel(Session session, PrintStream output) {
            Channel channel = null;
            try {
                channel = session.openChannel("shell");
                channel.setInputStream(System.in);
                channel.setOutputStream(output);
                //  streamOut = channel.getOutputStream();
    
                channel.connect(10000);
                LOGGER.info("SSH channel created");
            } catch (JSchException e) {
                LOGGER.error("SSH channel not created " + e);
            }
            return channel;
        }
    
        public static void createSshTunnel(Session session, Port port) {
            // TODO сделать пул портов, чтобы исключить вероятность, что порт 9999 занят
            try {
                session.setPortForwardingL(9999, session.getHost(), port.getPort());
                LOGGER.info("Tunnel created localhost:" + 9999 + " -> " + session.getHost() + ":" + port.getPort());
            } catch (JSchException e) {
                LOGGER.error("SSH tunnel not created " + e);
            }
        }
    
        public static void disconnect(Session session) {
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    
    }
    
    1. 公共类 TelnetUtil {
        private final static Logger LOGGER = LogManager.getLogger(TelnetUtil.class);
    
        public static String connect(ClientForTelnet clientForTelnet) {
            try {
                // Connect to the server
                clientForTelnet.getTc().connect(clientForTelnet.getTelnet().getHOST().getIp(), clientForTelnet.getTelnet().getPORT().getPort());
    
                // Get input and output stream references
                clientForTelnet.setIn(clientForTelnet.getTc().getInputStream());
                clientForTelnet.setOut(new PrintStream(clientForTelnet.getTc().getOutputStream()));
            } catch (IOException e) {
                LOGGER.error(e);
            }
    
            return readUntil(clientForTelnet.getPrompt(), clientForTelnet.getIn());
        }
    
        public static String readUntil(String pattern, InputStream in) {
            StringBuilder sb = new StringBuilder();
            try {
                char lastChar = pattern.charAt(pattern.length() - 1);
                boolean found = false;
                char ch = (char) in.read();
                while (true) {
               //     System.out.print(ch);
                    sb.append(ch);
                    if (ch == lastChar) {
                        if (sb.toString().endsWith(pattern)) {
                            return sb.toString();
                        }
                    }
                    ch = (char) in.read();
                }
            } catch (IOException e) {
                LOGGER.error(e);
            }
            return sb.toString();
        }
    
        public static void write(String value, PrintStream out) {
            out.println(value);
            out.flush();
        }
    
        public static String sendCommand(ClientForTelnet clientForTelnet, String command) {
            write(command, clientForTelnet.getOut());
            return readUntil(clientForTelnet.getPrompt(), clientForTelnet.getIn());
        }
    
        public static void disconnect(TelnetClient tc) {
            try {
                tc.disconnect();
            } catch (IOException e) {
                LOGGER.error(e);
            }
        }
    
    }
    
    1. 公共类 SSH { 私有最终字符串用户; 私人最终字符串密码; 私有最终主机 HOST; 私有最终端口 PORT;

        private final Port DEFAULT_PORT = new Port(22);
      
        public SSH(String user, String password, Host host, Port port) {
            this.USER = user;
            this.PASSWORD = password;
            this.HOST = host;
            this.PORT = port;
        }
      
        public SSH(String user, String password, Host host) {
            this.USER = user;
            this.PASSWORD = password;
            this.HOST = host;
            this.PORT = DEFAULT_PORT;
        }
      
        public String getUSER() {
            return USER;
        }
      
        public String getPASSWORD() {
            return PASSWORD;
        }
      
        public Host getHOST() {
            return HOST;
        }
      
        public Port getPORT() {
            return PORT;
        }
      

      }

    2. 公共类 Telnet {

        private final Host HOST;
        private final Port PORT;
      
        private final Port DEFAULT_PORT = new Port(5000);
      
        public Telnet(Host host, Port port) {
            this.HOST = host;
            this.PORT = port;
        }
      
        public Telnet(Host host) {
            this.HOST = host;
            this.PORT = DEFAULT_PORT;
        }
      
        public Host getHOST() {
            return HOST;
        }
      
        public Port getPORT() {
            return PORT;
        }
      

      }

    3. 公共类 ClientForTelnet {

        private final TelnetClient TC = new TelnetClient();
        private final String PROMT = ">";
        private final Telnet TELNET;
      
        private InputStream in;
        private PrintStream out;
      
        public ClientForTelnet(Telnet telnet) {
            this.TELNET = telnet;
        }
      
        public InputStream getIn() {
            return in;
        }
      
        public PrintStream getOut() {
            return out;
        }
      
        public Telnet getTelnet() {
            return TELNET;
        }
      
        public String getPrompt() {
            return PROMT;
        }
      
        public TelnetClient getTc() {
            return TC;
        }
      
        public void setIn(InputStream in) {
            this.in = in;
        }
      
        public void setOut(PrintStream out) {
            this.out = out;
        }
      

      }

    public class Host {
    
        private final static Logger LOGGER = LogManager.getLogger(Host.class);
    
        private String ip;
    
        public Host(String ip) {
            this.ip = ip;
        }
    
        public String getIp() {
            return ip;
        }
    
    }
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2020-09-01
    • 2015-01-24
    • 2022-05-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2021-10-09
    • 2010-12-22
    • 2013-10-21
    相关资源
    最近更新 更多