Telnet 命令进入(通过,内部)SSH 会话
Posted
技术标签:
【中文标题】Telnet 命令进入(通过,内部)SSH 会话【英文标题】:Telnet commands into (through, inside) SSH session 【发布时间】:2021-11-20 09:58:25 【问题描述】:我有一个任务: 通过 ssh 会话执行 telnet 命令。
我看过类似的问题:
-
Running telnet command on remote SSH session using JSch
telnet through SSH
Execution hangs after Running telnet command on remote SSH session using JSch
我编写了代码(使用 lib https://mvnrepository.com/artifact/com.jcraft/jsch):
类 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;
类 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;
类主
公共类主
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 命令执行的结果?
【问题讨论】:
【参考方案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();
-
公共类 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);
公共类 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;
公共类 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;
公共类 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。以上是关于Telnet 命令进入(通过,内部)SSH 会话的主要内容,如果未能解决你的问题,请参考以下文章
当我将任何命令通过管道传输到 telnet 会话时会发生啥,为啥会话会关闭
在windows环境下通过帐号密码SSH登录堡垒机,之后telnet到网络设备,通过命令交互对设备