【问题标题】:use ruby Net::SSH to read a remote file via sudo使用 ruby​​ Net::SSH 通过 sudo 读取远程文件
【发布时间】:2017-11-25 17:15:15
【问题描述】:

我必须读取我有权(sudo)读取的远程文件的内容 猫,少或尾巴。

我将在 Ruby 中执行此操作,因此我假设我应该使用 Net::SSH 来执行此操作。

该文件是一个日志文件,因此它可能非常大。

这是我现在正在尝试的代码:

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

当我运行它时,我得到以下输出:

进行中 进行中 进行中 数据工程 进行中 进行中 进行中 第三名 “\r\n” 远端完成发送数据 外壳终止

日志实际上目前有几千行数据,因为我可以使用 putty 从实际服务器读取它。

如何从 channel.on_data 中获取?

谢谢

【问题讨论】:

  • 我在我自己的一个日志文件上运行它,它运行良好......不用等,那是作为 root 用户,挂在实际用户身上
  • -在预览中,我在第一次发送密码之间确实挂了很长时间。
  • 您已验证该特定日志文件确实有内容?直接用ssh看到什么ssh USER@SERVER sudo cat /var/logs/httpd/ACCESS_log.2012.03.23

标签: ruby ssh


【解决方案1】:

我认为您需要在发送的密码中添加\n。这对我有用。请注意,在我注释掉 else 子句的地方,您也可以从那里获取信息,但它可以正常工作,但密码中有 \n

需要“红宝石” 需要'net/ssh' cmd = "sudo cat /var/log/mail.log" 主机名 = "myhost.example.com" 用户名 = “我” 密码 = "12345" Net::SSH.start( 主机名 , 用户名, :password => PASSWORD) 做 |ssh| ssh.open_channel 做 |channel| channel.request_pty 通道.exec(cmd); channel.on_close 做 提出“外壳终止” 结尾 channel.on_eof 做 |ch| puts "远程端完成发送数据" 结尾 channel.on_extended_data 做 |ch, type, data| 提出“得到标准错误:#{data.inspect}” 结尾 channel.on_data 做 |频道,数据| 如果数据 =~ /^\[sudo\] #{USERNAME} 的密码:/ 提出“数据工程” channel.send_data "#{PASSWORD}\n" 别的 #puts“输出不匹配:#{data}” 结尾 channel.on_data 做 |ch,data| 将“排在第三位” 放 data.inspect 结尾 结尾 channel.on_process 做 |ch| 将“进行中” 结尾 ssh.loop 结尾 结尾

【讨论】:

  • 我同意@dbenhur,多次调用 on_data 肯定会让人感到困惑,因为它取代了前一个代码块......将所有处理保存在一个数据块中会更好。
  • 看起来@DGM 搞定了,密码需要一个“\n”。与我的测试一起工作
【解决方案2】:

您在执行 on_data 回调时替换了新的 on_data 回调。我还没有深入研究 Net::SSH 的内部结构,但这可能会产生令人惊讶的行为。

尝试将两个 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

附带说明,由于您需要 sudo 来读取日志,因此有人认为他们和该服务器值得保护。看起来您正在嵌入密码,这些密码可以在此 ruby​​ 程序中授予对服务器的特权访问权限。这意味着任何可以阅读该程序的人都可以获得相同的特权访问。您将如何限制对该程序中密码的访问?

【讨论】:

  • 我现在正在嵌入密码,只是为了看看我是否可以让某些东西正常工作。该解决方案导致:在过程中在过程中在过程中数据在过程中在过程中工作,然后什么也没有。这是其中一件事,其他代码示例使我这样做。它似乎应该是递归的..
【解决方案3】:
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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 2017-05-15
    • 2014-01-20
    • 2017-11-24
    • 2011-01-11
    • 2012-11-22
    • 1970-01-01
    相关资源
    最近更新 更多