我需要一些关于如何使用Ruby Net :: SSH和Net :: SCP gem来代理几个系统以执行命令或复制文件的建议。
它与我上一篇文章非常相似(如果不是几乎完全相同),使用linux命令行中的基本ssh。
How to script multiple ssh and scp commands to various systems
例如,LOCAL是我的本地系统。
系统A是连接到LOCAL的第二个系统
系统B是仅连接到系统A的第三个系统。此外,系统B配置为仅允许通过其ssh密钥从系统A进行访问。
对于命令行中的普通ssh,我以这种方式设置了我的.ssh / config文件:
Host systemA
HostName 192.168.0.10
User A-user
Host systemB
ProxyCommand ssh -e none systemA exec /bin/nc %h %p 2>/dev/null
HostName 192.168.0.11
User B-user
IdentityFile ~/.ssh/systemA_id_dsa
从这一点开始,只要我的pub键位于sysA的authorized_hosts中(让我们假设它总是如此),并且sysA的pub键位于authorized_hosts sysB中(相同的假设),以下内容将无缝地工作:
ssh systemB
我想在Ruby中实现这个确切的行为。我有一些类似于以下的代码:
require 'net/ssh'
require 'net/ssh/proxy/command'
str = 'ssh -l A-user -i /home/A-user/.ssh/id_dsa -e none 192.168.0.10 exec /bin/nc %h %p 2>/dev/null'
proxy = Net::SSH::Proxy::Command.new(str)
Net::SSH.start('192.168.0.11', 'B-user', :proxy => proxy) do |ssh|
ssh.exec! "ls -lA"
end
不幸的是,这不起作用。我的身份验证失败了。
~/.rvm/gems/ruby-1.9.3-p327/gems/net-ssh-2.6.2/lib/net/ssh.rb:201:in `start': root (Net::SSH::AuthenticationFailed)
我在这里缺少什么?
答案 0 :(得分:1)
您是否从命令行验证了您的代理命令是否真的可以自行运行?您似乎可能混合了身份密钥的顺序。
SystemA已经知道你(?),你不需要为它指定身份。这也基于您发布的config
设置。
相反,我似乎需要在start
命令中将SystemA的身份转发给SystemB:
Net::SSH.start('192.168.0.11', 'B-user',
:proxy => proxy,
:keys => [ "~/.ssh/systemA_id_dsa" ] ) do |ssh|
ssh.exec! "ls -lA"
end
然后跳过,只需跳过代理设置命令中的身份文件。
答案 1 :(得分:0)
我用Net :: SSH解决了这个问题,但不需要外部配置文件。 Net :: SSH :: Gateway在我的解决方案中也很有帮助。我将解决方案包装到名为tunneler的宝石中。
require "tunneler"
# Create SSH tunnel
tunnel = Tunneler::SshTunnel.new(bastion_user, bastion_host, {:keys => [bastion_key]})
# Establish remote connection
destination_host_connection = tunnel.remote(destination_user, destination_host, {:keys => [destination_key]})
# Upload file to destination host via tunnel
destination_host_connection.scp(local_file_path, destination_file_path)
# Execute command on destination host via tunnel
response = destination_host_connection.ssh(command)