使用 Ruby 通过 SSH 创建 Telnet 连接
Create a Telnet connection via SSH using Ruby
我有一个小问题。首先,我从来没有写过一行 Ruby 直到被赋予这项任务,所以它有点超出了我的职权范围和舒适范围。这可能是一个愚蠢的问题,但我已经搜索了感觉像是永恒的东西,但一无所获。
我找到了大量关于如何使用 Net::Telnet 从我的本地计算机远程登录以及如何使用 Net::SSH:Telnet 基于当前 SSH 会话创建 Telnet 会话的信息,但没有找到任何专门处理我的问题的东西。
我需要使用一组凭证通过 SSH 连接到一台机器上;这不是问题:
objSsh=Net::SSH.start("xxx.xxx.xxx.xx",
"sshUser",
:Password=>"sshPass")
上面的工作很有用,例如,我可以获得 ls 的输出(我知道,最简单的简单任务)。
我遇到的问题是我需要使用不同的凭据从 SSH 会话远程登录,因此以下内容不符合我的目的:
ssh = Net::SSH.start("xxx.xxx.xxx.xxx",
:username=>"sshUser",
:password=>"sshPass"
)
s = Net::SSH::Telnet.new(
"Dump_log" => "/dev/stdout",
"Session" => ssh
)
这将使用相同的凭据进行 Telnet,因此不是我所需要的。
但同时我不能使用下面的,因为它只会尝试从正在执行的机器进行 Telnet,这不是必需的。
s = Net::SSH::Telnet.new(
"Dump_log" => "/dev/stdout",
"Host" => "0",
"Username" => "telnetUser",
"Password" => "telnetUser"
)
基本上,我需要通过 SSH 连接到一台机器,然后使用不同的凭据,使用 "telnet 0 xxxxx" 远程登录到本地主机,但我一辈子都不知道该怎么做。
我已经在 ssh 提示符下尝试 运行ning telnet 0 xxxxx,但它只是挂起,大概是因为显示了 username/password 提示符。
我在迷茫的圈子里徘徊,在这里。任何有关正确方向踢球的帮助都将不胜感激。
谢谢,
CJL.
更新 1:
感谢 cherrysoft 快速而有用的回复。我将研究我们是否能够将文件放到他们的服务器上以直接通过 SSH 触发。这会让生活更简单!
更新 2:
好的,所以在绝望中我尝试了一些东西,它让我比以前更进一步。以下代码通过 SSH 连接,创建基于 SSH 的 Telnet 会话,通过输出一个简单的 SSH 命令确保一切正常,尝试启动 Telnet 会话....然后失败。
#Create SSH connection.
objSsh=Net::SSH.start("xxx.xxx.xxx.xxx",
"sshPass",
:password=>"sshPass")
#Crete a Net:SSH:Telnet object based on the SSH connection.
objTelnet = Net::SSH::Telnet.new("Session" => objSsh)
#Ensure simple SSH commands can still be run by outputting ls results.
p objTelnet.cmd("ls")
#Try to kick off a telnet session and show what is displayed.
p objTelnet.cmd("telnet 0 xxxxx")
#Wait for the Username prompt.
objTelnet.waitfor("Match" => /.*?Username:.$/)
#Enter username.
objTelnet.puts("telnetUser")
#Wait for password prompt.
objTelnet.waitfor("Match" => /.*?Password:.$/)
#enter password.
objTelnet.puts("telnetPass")
#Try the command.
p objTelnet.cmd("cluster stats")
它达到了 Telnet 连接,但 Waitfor 调用似乎不起作用。当下面的行 运行s 输出结果提示用户名:
objTelnet.cmd("telnet 0 xxxxx")
"telnet 0 xxxxx\nTrying 0.0.0.0...\r\nConnected to 0.\r\nEscape character is '^]'.\r\nUsername: "
我原以为 Waitfor 会匹配输出中显示的内容,然后输入用户名。这可能是正则表达式问题吗?我通过 Rubular 运行 它,它似乎匹配,但我可能遗漏了一些与语法相关的东西?
再次感谢您的宝贵时间。
CJL.
更新 3 和决议:
谢谢 Kimmo Lehto。只需要很小的调整就可以完美地工作。它仍然卡在 Telnet 登录处,但是当如下所示传递凭据时(与 user/pass 相对),它很有用!
loginInfo = {"Name" => telnetUser,
"Password" => telnetpass,
"LoginPrompt" => /Username:/
}
objGateway = Net::SSH::Gateway.new(hostIp, user, :password => password)
objLocalPort = objGateway.open("localhost", port)
objTelnet = Net::Telnet::new("Host" => "127.0.0.1", "Port" => objLocalPort)
objTelnet.login(loginInfo)
objTelnet.cmd("cluster lrm res sum") { |c| print c}
objTelnet.close
objGateway.shutdown!
再次感谢您花时间和精力解决这个问题。
CJL 输出...
您可以在SSH中执行如下命令...
Net::SSH.start('host', 'user', password: "password") do |ssh|
output = ssh.exec!("echo {your command} | telnet {host} {port}")
puts output
end
您可以尝试使用 net-ssh-gateway
进行隧道传输,并使用常规的 net-telnet
进行 telnet(它本身已经非常过时,net-telnet-ssh
是那种可怕的替代品):
gateway = Net::SSH::Gateway.new(ssh_host, ssh_user)
local_port = gateway.open(target_host, target_port)
telnet = Net::Telnet::new("Host" => "localhost", "Port" => local_port)
telnet.login(telnet_user, telnet_password)
telnet.cmd("ls -al") { |c| print c }
telnet.close
gateway.shutdown!
快速谷歌搜索没有找到任何看起来像今天的 ruby 的替代 telnet 库。
我有一个小问题。首先,我从来没有写过一行 Ruby 直到被赋予这项任务,所以它有点超出了我的职权范围和舒适范围。这可能是一个愚蠢的问题,但我已经搜索了感觉像是永恒的东西,但一无所获。
我找到了大量关于如何使用 Net::Telnet 从我的本地计算机远程登录以及如何使用 Net::SSH:Telnet 基于当前 SSH 会话创建 Telnet 会话的信息,但没有找到任何专门处理我的问题的东西。
我需要使用一组凭证通过 SSH 连接到一台机器上;这不是问题:
objSsh=Net::SSH.start("xxx.xxx.xxx.xx",
"sshUser",
:Password=>"sshPass")
上面的工作很有用,例如,我可以获得 ls 的输出(我知道,最简单的简单任务)。
我遇到的问题是我需要使用不同的凭据从 SSH 会话远程登录,因此以下内容不符合我的目的:
ssh = Net::SSH.start("xxx.xxx.xxx.xxx",
:username=>"sshUser",
:password=>"sshPass"
)
s = Net::SSH::Telnet.new(
"Dump_log" => "/dev/stdout",
"Session" => ssh
)
这将使用相同的凭据进行 Telnet,因此不是我所需要的。
但同时我不能使用下面的,因为它只会尝试从正在执行的机器进行 Telnet,这不是必需的。
s = Net::SSH::Telnet.new(
"Dump_log" => "/dev/stdout",
"Host" => "0",
"Username" => "telnetUser",
"Password" => "telnetUser"
)
基本上,我需要通过 SSH 连接到一台机器,然后使用不同的凭据,使用 "telnet 0 xxxxx" 远程登录到本地主机,但我一辈子都不知道该怎么做。
我已经在 ssh 提示符下尝试 运行ning telnet 0 xxxxx,但它只是挂起,大概是因为显示了 username/password 提示符。
我在迷茫的圈子里徘徊,在这里。任何有关正确方向踢球的帮助都将不胜感激。
谢谢,
CJL.
更新 1:
感谢 cherrysoft 快速而有用的回复。我将研究我们是否能够将文件放到他们的服务器上以直接通过 SSH 触发。这会让生活更简单!
更新 2:
好的,所以在绝望中我尝试了一些东西,它让我比以前更进一步。以下代码通过 SSH 连接,创建基于 SSH 的 Telnet 会话,通过输出一个简单的 SSH 命令确保一切正常,尝试启动 Telnet 会话....然后失败。
#Create SSH connection.
objSsh=Net::SSH.start("xxx.xxx.xxx.xxx",
"sshPass",
:password=>"sshPass")
#Crete a Net:SSH:Telnet object based on the SSH connection.
objTelnet = Net::SSH::Telnet.new("Session" => objSsh)
#Ensure simple SSH commands can still be run by outputting ls results.
p objTelnet.cmd("ls")
#Try to kick off a telnet session and show what is displayed.
p objTelnet.cmd("telnet 0 xxxxx")
#Wait for the Username prompt.
objTelnet.waitfor("Match" => /.*?Username:.$/)
#Enter username.
objTelnet.puts("telnetUser")
#Wait for password prompt.
objTelnet.waitfor("Match" => /.*?Password:.$/)
#enter password.
objTelnet.puts("telnetPass")
#Try the command.
p objTelnet.cmd("cluster stats")
它达到了 Telnet 连接,但 Waitfor 调用似乎不起作用。当下面的行 运行s 输出结果提示用户名:
objTelnet.cmd("telnet 0 xxxxx")
"telnet 0 xxxxx\nTrying 0.0.0.0...\r\nConnected to 0.\r\nEscape character is '^]'.\r\nUsername: "
我原以为 Waitfor 会匹配输出中显示的内容,然后输入用户名。这可能是正则表达式问题吗?我通过 Rubular 运行 它,它似乎匹配,但我可能遗漏了一些与语法相关的东西?
再次感谢您的宝贵时间。
CJL.
更新 3 和决议:
谢谢 Kimmo Lehto。只需要很小的调整就可以完美地工作。它仍然卡在 Telnet 登录处,但是当如下所示传递凭据时(与 user/pass 相对),它很有用!
loginInfo = {"Name" => telnetUser,
"Password" => telnetpass,
"LoginPrompt" => /Username:/
}
objGateway = Net::SSH::Gateway.new(hostIp, user, :password => password)
objLocalPort = objGateway.open("localhost", port)
objTelnet = Net::Telnet::new("Host" => "127.0.0.1", "Port" => objLocalPort)
objTelnet.login(loginInfo)
objTelnet.cmd("cluster lrm res sum") { |c| print c}
objTelnet.close
objGateway.shutdown!
再次感谢您花时间和精力解决这个问题。
CJL 输出...
您可以在SSH中执行如下命令...
Net::SSH.start('host', 'user', password: "password") do |ssh|
output = ssh.exec!("echo {your command} | telnet {host} {port}")
puts output
end
您可以尝试使用 net-ssh-gateway
进行隧道传输,并使用常规的 net-telnet
进行 telnet(它本身已经非常过时,net-telnet-ssh
是那种可怕的替代品):
gateway = Net::SSH::Gateway.new(ssh_host, ssh_user)
local_port = gateway.open(target_host, target_port)
telnet = Net::Telnet::new("Host" => "localhost", "Port" => local_port)
telnet.login(telnet_user, telnet_password)
telnet.cmd("ls -al") { |c| print c }
telnet.close
gateway.shutdown!
快速谷歌搜索没有找到任何看起来像今天的 ruby 的替代 telnet 库。