繁体   English   中英

Telnet 命令进入(通过,内部)SSH 会话

[英]Telnet commands into (through, inside) SSH session

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

我读过类似的问题:

  1. 使用 JSch 在远程 SSH 会话上运行 telnet 命令
  2. 通过 SSH 远程登录
  3. 使用 JSch 在远程 SSH 会话上运行 telnet 命令后执行挂起

我写了代码(使用 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命令执行的结果?

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

在第二步中,您可以发送您的命令和退出命令来停止 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 的通信方式,即本地端口转发。

感谢马蒂亚斯·维德曼。

我按照 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 连接并使用隧道端口执行 Telnet 命令(端口变为 9999,而不是 5000)。

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;
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM