简体   繁体   English

使用ruby Net :: SSH通过sudo读取远程文件

[英]use ruby Net::SSH to read a remote file via sudo

I have to read the contents of a remote file I have permissions to (sudo) read with cat,less or tail. 我必须读取一个远程文件的内容,我有权使用cat,less或tail读取(sudo)。

I am going to be doing this in Ruby so I assume I should be using Net::SSH to do it. 我将在Ruby中执行此操作,因此我假设我应该使用Net :: SSH来执行此操作。

The file is a log file so it can be quite big. 该文件是一个日志文件,因此它可能非常大。

This is the code I am trying now: 这是我现在正在尝试的代码:

require 'rubygems'
require 'net/ssh'

cmd = "sudo cat /var/logs/httpd/ACCESS_log.2012.03.23"

Net::SSH.start( "SERVER" , "USER", :password => "PASSWORD") do |ssh|
  ssh.open_channel do |channel|
    channel.request_pty
     channel.exec(cmd);

     channel.on_close do
       puts "shell terminated"
     end
    channel.on_eof do |ch|
      puts "remote end is done sending data"
    end
    channel.on_extended_data do |ch, type, data|
      puts "got stderr: #{data.inspect}"
    end
    channel.on_data do |channel, data|
      if data =~ /^\[sudo\] password for USER:/
        puts "data works"
        channel.send_data 'PASSWORD'
      end
     channel.on_data do |ch,data|
        puts "in third"
        puts data.inspect
     end
    end
   channel.on_process do |ch|
     puts "in process"
   end
  ssh.loop
  end
end

When I run that I get the following output: 当我运行时,我得到以下输出:

in process in process in process data works in process in process in process in third "\\r\\n" remote end is done sending data shell terminated 在进程中进程中的数据工作进程中进程中的第三个“\\ r \\ n”远程端完成发送数据shell终止

The log actually currently has a few thousand lines of data in it, because I can read it from the actual server using putty. 该日志实际上当前有几千行数据,因为我可以使用putty从实际服务器读取它。

How do I get that out from channel.on_data ? 我如何从channel.on_data中解决这个问题?

Thanks 谢谢

I think you need to add a \\n to the password you send. 我认为您需要在发送的密码中添加\\n This works for me. 这适合我。 Note, The place where I commented out the else clause, you could possibly get the info from there too, but it works as you have it, but with a \\n in the password. 注意,我注释掉else子句的地方,你也可以从那里获取信息,但是它可以正常工作,但密码中有\\n

require 'rubygems'
require 'net/ssh'

cmd = "sudo cat /var/log/mail.log"
HOSTNAME = "myhost.example.com"
USERNAME = "me"
PASSWORD = "12345"


Net::SSH.start( HOSTNAME , USERNAME, :password => PASSWORD) do |ssh|
  ssh.open_channel do |channel|
    channel.request_pty
     channel.exec(cmd);

     channel.on_close do
       puts "shell terminated"
     end
    channel.on_eof do |ch|
      puts "remote end is done sending data"
    end
    channel.on_extended_data do |ch, type, data|
      puts "got stderr: #{data.inspect}"
    end
    channel.on_data do |channel, data|
      if data =~ /^\[sudo\] password for #{USERNAME}:/
        puts "data works"
        channel.send_data "#{PASSWORD}\n"
      else
        #puts "OUTPUT NOT MATCHED: #{data}"
      end
       channel.on_data do |ch,data|
         puts "in third"
        puts data.inspect
       end
    end
   channel.on_process do |ch|
     puts "in process"
   end
  ssh.loop
  end
end

You are replacing a new on_data callback while executing an on_data callback. 您正在执行on_data回调时替换新的on_data回调。 I haven't spelunked the internals of Net::SSH, but that could produce surprising behavior. 我没有考虑Net :: SSH的内部,但这可能会产生令人惊讶的行为。

Try changing your code in your two on_data callbacks to be one, and see if that helps. 尝试将两个on_data回调中的代码更改为一个,看看是否有帮助。

channel.on_data do |channel, data|
  if data =~ /^\[sudo\] password for USER:/
    puts "data works"
    channel.send_data 'PASSWORD'
  else
    puts "in third"
    puts data.inspect
  if
end

As a side note, since you need sudo to read the logs, someone thinks they and that server are worth protecting. 作为旁注,由于您需要sudo来阅读日志,因此有人认为他们和该服务器值得保护。 It looks like you're embedding passwords which give privileged access to the server in this ruby program. 看起来你正在嵌入密码,这些密码可以在这个ruby程序中提供对服务器的特权访问。 That implies anyone who can read the program gains the same privileged access. 这意味着任何能够阅读该程序的人都可以获得相同的特权访问权限。 What will you do to limit access to the password in this program? 您将如何限制在此程序中访问密码?

require 'net/ssh'

Net::SSH.start('host', 'user', :password => "password") do |ssh|
  # capture all stderr and stdout output from a remote process
  output = ssh.exec!("hostname")
  puts output

  # capture only stdout matching a particular pattern
  stdout = ""
  ssh.exec!("ls -l /home/jamis") do |channel, stream, data|
    stdout << data if stream == :stdout
  end
  puts stdout

  # run multiple processes in parallel to completion
  ssh.exec "sed ..."
  ssh.exec "awk ..."
  ssh.exec "rm -rf ..."
  ssh.loop

  # open a new channel and configure a minimal set of callbacks, then run
  # the event loop until the channel finishes (closes)
  channel = ssh.open_channel do |ch|
    ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success|
      raise "could not execute command" unless success

      # "on_data" is called when the process writes something to stdout
      ch.on_data do |c, data|
        $stdout.print data
      end

      # "on_extended_data" is called when the process writes something to stderr
      ch.on_extended_data do |c, type, data|
        $stderr.print data
      end

      ch.on_close { puts "done!" }
    end
  end

  channel.wait

  # forward connections on local port 1234 to port 80 of www.capify.org
  ssh.forward.local(1234, "www.capify.org", 80)
  ssh.loop { true }
end

Latest Document 17.11.25 最新文件17.11.25

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

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